00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00035 #include "OW_config.h"
00036 #include "OW_String.hpp"
00037 #include "OW_Array.hpp"
00038 #include "OW_FileSystem.hpp"
00039 #include "OW_Format.hpp"
00040 #include "OW_LocalAuthenticationCommon.hpp"
00041
00042 #include <unistd.h>
00043 #include <sys/types.h>
00044 #include <pwd.h>
00045 #include <sys/stat.h>
00046 #if defined(OW_HAVE_SYS_TIME_H)
00047 #include <sys/time.h>
00048 #endif
00049 #if defined(OW_HAVE_SYS_RESOURCE_H)
00050 #include <sys/resource.h>
00051 #endif
00052
00053 #include <cstring>
00054 #include <cstdio>
00055 #include <cerrno>
00056 #include <ctime>
00057 #include <iostream>
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 using std::cerr;
00074 using std::endl;
00075 using std::cin;
00076 using std::cout;
00077 using namespace OpenWBEM;
00078 using namespace OpenWBEM::LocalAuthenticationCommon;
00079
00080 namespace
00081 {
00082
00083 const char* OWCIMOMD_USER_STR = "owcimomd";
00084
00085 const int SUCCESS = 0;
00086
00087
00088 const int INVALID_USER = 2;
00089 const int NOT_SETUID_ROOT = 3;
00090 const int INVALID_INPUT = 4;
00091 const int REMOVE_FAILED = 5;
00092 const int UNEXPECTED_EXCEPTION = 6;
00093 const int SETRLIMIT_FAILED = 7;
00094
00095 bool checkRealUser()
00096 {
00097 struct passwd* pw = ::getpwuid(::getuid());
00098 if (pw == 0)
00099 {
00100 perror("owlocalhelper:checkRealUser():getpwuid");
00101 return false;
00102 }
00103 if (strcmp(OWCIMOMD_USER_STR, pw->pw_name) == 0)
00104 {
00105 return true;
00106 }
00107 cerr << "owlocalhelper:checkRealUser(): username is not " << OWCIMOMD_USER_STR << endl;
00108 return false;
00109 }
00110
00111
00112 bool getLineFromStdin(String& line)
00113 {
00114
00115
00116 const int lineBufferSize = 1024;
00117 char buffer[lineBufferSize];
00118 cin.getline(buffer, lineBufferSize, '\n');
00119 int count = cin.gcount();
00120
00121
00122 if (!cin && count == 0)
00123 {
00124 cerr << "owlocalhelper:getLineFromStdin(): expected a line, but hit eof." << endl;
00125 return false;
00126 }
00127
00128
00129 if (cin.eof())
00130 {
00131 line = buffer;
00132 return true;
00133 }
00134
00135
00136 else if (cin.fail())
00137 {
00138 cerr << "owlocalhelper:getLineFromStdin(): line too long." << endl;
00139 return false;
00140 }
00141
00142
00143 else
00144 {
00145 line = buffer;
00146 return true;
00147 }
00148 }
00149
00150 int processRemove()
00151 {
00152 String filename;
00153 if (!getLineFromStdin(filename))
00154 {
00155 return INVALID_INPUT;
00156 }
00157
00158 if (filename.indexOf(OW_FILENAME_SEPARATOR) != String::npos)
00159 {
00160 cerr << "owlocalhelper::processRemove(): filename cannot contain " OW_FILENAME_SEPARATOR << endl;
00161 return INVALID_INPUT;
00162 }
00163
00164 if (filename.empty())
00165 {
00166 cerr << "owlocalhelper::processRemove(): filename cannot be empty." << endl;
00167 return INVALID_INPUT;
00168 }
00169
00170 String fullPath = String(LOCAL_AUTH_DIR) + OW_FILENAME_SEPARATOR + filename;
00171
00172 String realPath;
00173 try
00174 {
00175 realPath = FileSystem::Path::realPath(fullPath);
00176 }
00177 catch (FileSystemException& e)
00178 {
00179 cerr << "owlocalhelper::processRemove(): realPath failed: " << e << endl;
00180 return INVALID_INPUT;
00181 }
00182
00183 String realPathDirname = FileSystem::Path::dirname(realPath);
00184 if (realPath != fullPath || realPathDirname != LOCAL_AUTH_DIR)
00185 {
00186 cerr << "owlocalhelper::processRemove(): real path is not equal. no symlinks allowed in " << fullPath << endl;
00187 return INVALID_INPUT;
00188 }
00189
00190 String cookie;
00191 if (!getLineFromStdin(cookie))
00192 {
00193 return INVALID_INPUT;
00194 }
00195
00196 String realCookie = FileSystem::getFileContents(realPath);
00197
00198 if (realCookie != cookie)
00199 {
00200 cerr << "owlocalhelper::processRemove(): real cookie is not equal, not removing." << endl;
00201 return INVALID_INPUT;
00202 }
00203
00204 if (!FileSystem::removeFile(realPath))
00205 {
00206 perror(Format("owlocalhelper::processRemove(): failed to remove %1", realPath).c_str());
00207 return REMOVE_FAILED;
00208 }
00209
00210 return SUCCESS;
00211 }
00212
00213 int processCreate()
00214 {
00215
00216 String uid;
00217 if (!getLineFromStdin(uid))
00218 {
00219 cerr << "owlocalhelper::processCreate(): expected to get the uid" << endl;
00220 return INVALID_INPUT;
00221 }
00222
00223
00224 String cookie;
00225 if (!getLineFromStdin(cookie))
00226 {
00227 cerr << "owlocalhelper::processCreate(): expected to get the cookie" << endl;
00228 return INVALID_INPUT;
00229 }
00230
00231 cout << createFile(uid, cookie) << endl;
00232
00233 return SUCCESS;
00234 }
00235
00236 int processStdin()
00237 {
00238
00239
00240
00241
00242 String curLine;
00243 if (!getLineFromStdin(curLine))
00244 {
00245 return INVALID_INPUT;
00246 }
00247
00248 if (curLine == REMOVE_CMD)
00249 {
00250 return processRemove();
00251 }
00252 else if (curLine == INITIALIZE_CMD)
00253 {
00254 initializeDir();
00255 return SUCCESS;
00256 }
00257 else if (curLine == CREATE_CMD)
00258 {
00259 return processCreate();
00260 }
00261
00262 return INVALID_INPUT;
00263 }
00264
00265 }
00266
00267
00269 int main(int argc, char* argv[])
00270 {
00271 try
00272 {
00273
00274
00275 ::umask(0);
00276
00277 #ifdef OW_HAVE_SETRLIMIT
00278
00279 struct rlimit rlim;
00280 rlim.rlim_cur = rlim.rlim_max = 0;
00281 if (setrlimit(RLIMIT_CORE, &rlim) < 0)
00282 {
00283 perror("owlocalhelper::setrlimit failed");
00284 return SETRLIMIT_FAILED;
00285 }
00286 #endif
00287
00288
00289
00290 if (!checkRealUser())
00291 {
00292 return INVALID_USER;
00293 }
00294
00295
00296 if (::geteuid() != 0)
00297 {
00298 cerr << "owlocalhelper must be setuid root to work" << endl;
00299 return NOT_SETUID_ROOT;
00300 }
00301
00302 return processStdin();
00303 }
00304 catch (LocalAuthenticationException& e)
00305 {
00306 cerr << e.getMessage() << endl;
00307 return e.getErrorCode();
00308 }
00309 catch (std::exception& e)
00310 {
00311 cerr << "Caught unexpected exception: " << e.what() << endl;
00312 return UNEXPECTED_EXCEPTION;
00313 }
00314 catch (...)
00315 {
00316 cerr << "Caught unexpected exception" << endl;
00317 return UNEXPECTED_EXCEPTION;
00318 }
00319 }
00320
00321