(file) Return to main.c CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Executor

  1 mike  1.1.2.1 /*
  2               //%2006////////////////////////////////////////////////////////////////////////
  3               //
  4               // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  5               // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  6               // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  7               // IBM Corp.; EMC Corporation, The Open Group.
  8               // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  9               // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
 10               // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 11               // EMC Corporation; VERITAS Software Corporation; The Open Group.
 12               // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 13               // EMC Corporation; Symantec Corporation; The Open Group.
 14               //
 15               // Permission is hereby granted, free of charge, to any person obtaining a copy
 16               // of this software and associated documentation files (the "Software"), to
 17               // deal in the Software without restriction, including without limitation the
 18               // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 19               // sell copies of the Software, and to permit persons to whom the Software is
 20               // furnished to do so, subject to the following conditions:
 21               // 
 22 mike  1.1.2.1 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 23               // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 24               // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 25               // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 26               // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 27               // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 28               // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 29               // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 30               //
 31               //%/////////////////////////////////////////////////////////////////////////////
 32               */
 33               #include <stdio.h>
 34               #include <sys/types.h>
 35               #include <sys/stat.h>
 36               #include <unistd.h>
 37               #include <string.h>
 38               #include "Config.h"
 39               #include "Child.h"
 40               #include "Parent.h"
 41               #include "User.h"
 42               #include "Fatal.h"
 43 mike  1.1.2.1 #include "Process.h"
 44               #include "Path.h"
 45               #include "Globals.h"
 46               #include "Socket.h"
 47               #include "Log.h"
 48               
 49               /*
 50               **==============================================================================
 51               **
 52               ** GetServerUser
 53               **
 54               **     Determine which user to run cimservermain as.
 55               **
 56               **==============================================================================
 57               */
 58               
 59               int GetServerUser(
 60                   int argc,
 61                   char** argv,
 62                   char path[EXECUTOR_BUFFER_SIZE], 
 63                   int* uid, 
 64 mike  1.1.2.1     int* gid)
 65               {
 66                   struct stat st;
 67                   const char DEFAULT_SERVER_USER[] = "pegasus";
 68               
 69                   /* (1) Try to find serverUser as configuration parameter. */
 70               
 71                   char user[EXECUTOR_BUFFER_SIZE];
 72               
 73                   if (GetConfigParam(argc, argv, "serverUser", user) == 0)
 74                   {
 75                       if (GetUserInfo(user, uid, gid) == 0)
 76                           return 0;
 77               
 78                       Fatal(FL, "serverUser option specifies unknown user: %s", user);
 79                       return -1;
 80                   }
 81               
 82                   /* (2) Use owner of the cimservermain program if not root. */
 83               
 84                   if (stat(path, &st) != 0)
 85 mike  1.1.2.1         Fatal(FL, "stat(%s) failed", path);
 86               
 87                   if (st.st_uid != 0 && st.st_gid != 0)
 88                   {
 89                       *uid = st.st_uid;
 90                       *gid = st.st_gid;
 91                       return 0;
 92                   }
 93               
 94                   /* (3) Try the "pegasus" user (the default). */
 95               
 96                   if (GetUserInfo(DEFAULT_SERVER_USER, uid, gid) == 0 && 
 97                       *uid != 0 && 
 98                       *gid != 0)
 99                   {
100                       return 0;
101                   }
102               
103                   Fatal(FL, 
104                       "cannot determine server user (used to run cimserermain). "
105                       "Please specify this value in one of four ways. (1) pass "
106 mike  1.1.2.1         "serverUser=<username> on the command line, (2) use cimconfig to "
107                       "set serverUser (using -p -s options), (3) make the desired "
108                       "user the owner of %s (i.e., use chown), or (4) create a system "
109                       "user whose user whose name is \"pegasus\".", path);
110               
111                   return -1;
112               }
113               
114               /*
115               **==============================================================================
116               **
117               ** ReadPidFile()
118               **
119               **==============================================================================
120               */
121               
122               static int ReadPidFile(const char* path, int* pid)
123               {
124                   FILE* is = fopen(path, "r");
125               
126                   if (!is) 
127 mike  1.1.2.1         return -1;
128               
129                   *pid = 0;
130               
131                   fscanf(is, "%d\n", pid);
132                   fclose(is);
133               
134                   if (*pid == 0)
135                       return -1;
136               
137                   return 0;
138               }
139               
140               /*
141               **==============================================================================
142               **
143               ** TestCimServerProcess()
144               **
145               **     Returns 0 if cimserver process is running.
146               **
147               **==============================================================================
148 mike  1.1.2.1 */
149               
150               int TestCimServerProcess()
151               {
152                   int pid;
153                   char name[EXECUTOR_BUFFER_SIZE];
154               
155                   if (ReadPidFile(PEGASUS_CIMSERVER_START_FILE, &pid) != 0)
156                       return -1;
157               
158                   if (GetProcessName(pid, name) != 0 || strcmp(name, CIMSERVERMAIN) != 0)
159                       return -1;
160               
161                   return 0;
162               }
163               
164               /*
165               **==============================================================================
166               **
167               ** ExecShutdown()
168               **
169 mike  1.1.2.1 **==============================================================================
170               */
171               
172               void ExecShutdown()
173               {
174                   char* tmpArgv[3];
175               
176                   /* Get absolute cimshutdown program name. */
177               
178                   char cimshutdownPath[EXECUTOR_BUFFER_SIZE];
179               
180                   if (GetInternalPegasusProgramPath(CIMSHUTDOWN, cimshutdownPath) != 0)
181                       Fatal(FL, "Failed to locate Pegasus program: %s", CIMSHUTDOWN);
182               
183                   /* Create argument list. */
184               
185                   tmpArgv[0] = CIMSHUTDOWN;
186                   tmpArgv[1] = EXECUTOR_FINGERPRINT;
187                   tmpArgv[2] = 0;
188               
189                   /* Exec CIMSHUTDOWN program. */
190 mike  1.1.2.1 
191                   /* Flawfinder: ignore */
192                   execv(cimshutdownPath, tmpArgv);
193                   Fatal(FL, "failed to exec %s", cimshutdownPath);
194               }
195               
196               /*
197               **==============================================================================
198               **
199               ** main()
200               **
201               **==============================================================================
202               */
203               
204               void doit();
205               
206               int main(int argc, char** argv)
207               {
208                   int i;
209                   char cimservermainPath[EXECUTOR_BUFFER_SIZE];
210                   int pair[2];
211 mike  1.1.2.1     char username[EXECUTOR_BUFFER_SIZE];
212                   int childPid;
213                   int perror;
214               
215                   /* Save as global so it can be used in error and log messages. */
216               
217 mike  1.1.2.2     globals.arg0 = argv[0];
218 mike  1.1.2.1 
219                   /* Get absolute cimservermain program name. */
220               
221                   if (GetInternalPegasusProgramPath(CIMSERVERMAIN, cimservermainPath) != 0)
222                       Fatal(FL, "Failed to locate Pegasus program: %s", CIMSERVERMAIN);
223               
224                   /* If shuting down, then run "cimshutdown" client. */
225               
226                   for (i = 0; i < argc; i++)
227                   {
228                       if (strcmp(argv[i], "-s") == 0)
229                           ExecShutdown();
230                   }
231               
232                   /* If CIMSERVERMAIN is already running, warn and exit now. */
233               
234                   if (TestCimServerProcess() == 0)
235                   {
236                       fprintf(stderr,
237                           "%s: cimserver is already running (the PID found in the file "
238                           "\"%s\" corresponds to an existing process named \"%s\").\n\n",
239 mike  1.1.2.2             globals.arg0, PEGASUS_CIMSERVER_START_FILE, CIMSERVERMAIN);
240 mike  1.1.2.1 
241                       exit(1);
242                   }
243               
244 mike  1.1.2.2     /* Get enableAuthentication configuration option. */
245               
246                   {
247                       char buffer[EXECUTOR_BUFFER_SIZE];
248               
249                       if (GetConfigParam(argc, argv, "enableAuthentication", buffer) == 0 &&
250                           strcasecmp(buffer, "true") == 0)
251                       {
252                           globals.enableAuthentication = 1;
253                       }
254                   }
255               
256 mike  1.1.2.1     /* Create a socket pair for communicating with the child process. */
257               
258                   if (CreateSocketPair(pair) != 0)
259                       Fatal(FL, "failed to create socket pair");
260               
261                   CloseOnExec(pair[1]);
262               
263                   /* Get the log-level from the configuration parameter. */
264               
265                   GetLogLevel(argc, argv);
266               
267                   /* Extract -p (perror) option. */
268               
269                   perror = 0;
270               
271                   for (i = 0; i < argc; i++)
272                   {
273                       if (strcmp(argv[i], "-p") == 0)
274                       {
275                           perror = 1;
276                           memmove(&argv[i], &argv[i + 1], (argc-i) * sizeof(char*));
277 mike  1.1.2.1             argc--;
278                           break;
279                       }
280                   }
281               
282                   /* Open the log. */
283               
284                   OpenLog("cimexecutor", perror);
285               
286                   Log(LL_INFORMATION, "starting");
287               
288                   /* Be sure this process is running as root (otherwise fail). */
289               
290                   if (setuid(0) != 0 || setgid(0) != 0)
291                   {
292                       Log(LL_FATAL, "attempted to run program as non-root user");
293 mike  1.1.2.2         fprintf(stderr, "%s: this program must be run as root\n", globals.arg0);
294 mike  1.1.2.1         exit(0);
295                   }
296               
297 mike  1.1.2.2     /* Warn if authentication not enabled (strange use of executor if not). */
298               
299                   if (!globals.enableAuthentication)
300                       Log(LL_WARNING, "authentication is NOT enabled");
301                   else
302 mike  1.1.2.3         Log(LL_TRACE, "authentication is enabled");
303 mike  1.1.2.2 
304 mike  1.1.2.1     /* Print user info. */
305               
306                   if (GetUserName(getuid(), username) != 0)
307                       Fatal(FL, "cannot resolve user from uid=%d", getuid());
308               
309                   Log(LL_TRACE, "running as %s (uid=%d, gid=%d)",
310                       username, (int)getuid(), (int)getgid());
311               
312                   /* Determine user for running cimservermain. */
313               
314                   GetServerUser(
315 mike  1.1.2.2         argc, argv, cimservermainPath, &globals.childUid, &globals.childGid);
316 mike  1.1.2.1 
317                   /* Fork child process. */
318               
319                   childPid = fork();
320               
321                   if (childPid == 0)
322                   {
323                       /* Child. */
324                       close(pair[1]);
325                       Child(argc, argv, 
326 mike  1.1.2.2             cimservermainPath, globals.childUid, globals.childGid, pair[0]);
327 mike  1.1.2.1     }
328                   else if (childPid > 0)
329                   {
330                       /* Parent. */
331                       close(pair[0]);
332                       Parent(pair[1], childPid);
333                   }
334                   else
335                   {
336                       Fatal(FL, "fork() failed");
337                   }
338               
339                   return 0;
340               }

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2