(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 mike  1.1.2.6 #include "Strlcpy.h"
 48 mike  1.1.2.11 #include "Strlcat.h"
 49 mike  1.1.2.1  #include "Log.h"
 50 mike  1.1.2.7  #include "Policy.h"
 51 mike  1.1.2.8  #include "Macro.h"
 52 mike  1.1.2.9  #include "Assert.h"
 53 mike  1.1.2.10 #include "Options.h"
 54 mike  1.1.2.1  
 55                /*
 56                **==============================================================================
 57                **
 58                ** GetServerUser
 59                **
 60 mike  1.1.2.9  **     Determine which user to run CIMSERVERMAIN as.
 61 mike  1.1.2.1  **
 62 mike  1.1.2.4  **     Note: this algorithm is no longer in use.
 63                **
 64 mike  1.1.2.1  **==============================================================================
 65                */
 66                
 67 mike  1.1.2.4  int GetServerUser(int* uid, int* gid)
 68 mike  1.1.2.1  {
 69 mike  1.1.2.4      const char* username = PEGASUS_CIMSERVERMAIN_USER;
 70 mike  1.1.2.1  
 71 mike  1.1.2.4      if (GetUserInfo(username, uid, gid) != 0)
 72 mike  1.1.2.1      {
 73 mike  1.1.2.4          Fatal(FL, 
 74 mike  1.1.2.9              "The %s user does not exist: \"%s\". Please create "
 75 mike  1.1.2.4              "a system user with that name or use an OpenPegasus build that "
 76 mike  1.1.2.9              "disables privilege separation.", CIMSERVERMAIN, username);
 77 mike  1.1.2.1      }
 78                
 79                    return -1;
 80                }
 81                
 82                /*
 83                **==============================================================================
 84                **
 85                ** ReadPidFile()
 86                **
 87                **==============================================================================
 88                */
 89                
 90                static int ReadPidFile(const char* path, int* pid)
 91                {
 92                    FILE* is = fopen(path, "r");
 93                
 94                    if (!is) 
 95                        return -1;
 96                
 97                    *pid = 0;
 98 mike  1.1.2.1  
 99                    fscanf(is, "%d\n", pid);
100                    fclose(is);
101                
102                    if (*pid == 0)
103                        return -1;
104                
105                    return 0;
106                }
107                
108                /*
109                **==============================================================================
110                **
111                ** TestCimServerProcess()
112                **
113                **     Returns 0 if cimserver process is running.
114                **
115                **==============================================================================
116                */
117                
118                int TestCimServerProcess()
119 mike  1.1.2.1  {
120                    int pid;
121                    char name[EXECUTOR_BUFFER_SIZE];
122                
123                    if (ReadPidFile(PEGASUS_CIMSERVER_START_FILE, &pid) != 0)
124                        return -1;
125                
126                    if (GetProcessName(pid, name) != 0 || strcmp(name, CIMSERVERMAIN) != 0)
127                        return -1;
128                
129                    return 0;
130                }
131                
132                /*
133                **==============================================================================
134                **
135                ** ExecShutdown()
136                **
137                **==============================================================================
138                */
139                
140 mike  1.1.2.9  void ExecShutdown()
141 mike  1.1.2.1  {
142                    char* tmpArgv[3];
143 mike  1.1.2.9      const char* cimshutdownPath;
144                    const char* shutdownTimeout;
145 mike  1.1.2.1  
146 mike  1.1.2.6      /* Get shutdownTimeout configuration parameter. */
147 mike  1.1.2.1  
148 mike  1.1.2.9      if ((shutdownTimeout = FindMacro("shutdownTimeout")) == NULL)
149                        Fatal(FL, "failed to resolve shutdownTimeout");
150 mike  1.1.2.6  
151 mike  1.1.2.9      /* Get absolute CIMSHUTDOWN program name. */
152 mike  1.1.2.1  
153 mike  1.1.2.9      if ((cimshutdownPath = FindMacro("cimshutdownPath")) == NULL)
154                        Fatal(FL, "failed to resolve cimshutdownPath");
155 mike  1.1.2.1  
156                    /* Create argument list. */
157                
158                    tmpArgv[0] = CIMSHUTDOWN;
159 mike  1.1.2.9      tmpArgv[1] = (char*)shutdownTimeout;
160 mike  1.1.2.1      tmpArgv[2] = 0;
161                
162                    /* Exec CIMSHUTDOWN program. */
163                
164                    /* Flawfinder: ignore */
165                    execv(cimshutdownPath, tmpArgv);
166                    Fatal(FL, "failed to exec %s", cimshutdownPath);
167                }
168                
169                /*
170                **==============================================================================
171                **
172 mike  1.1.2.8  ** DefineExecutorMacros()
173                **
174                **     Define macros used by the executor.
175                **
176                **==============================================================================
177                */
178                
179                void DefineExecutorMacros()
180                {
181                    /* Define ${internalBinDir} */
182                    {
183                        char path[EXECUTOR_BUFFER_SIZE];
184                
185                        if (GetPegasusInternalBinDir(path) != 0)
186                            Fatal(FL, "failed to resolve internal pegasus bin directory");
187                
188                        DefineMacro("internalBinDir", path);
189                    }
190                
191 mike  1.1.2.9      /* Define ${cimservermain} */
192                
193                    DefineMacro("cimservermain", CIMSERVERMAIN);
194                
195                    /* Define ${cimprovagt} */
196                
197                    DefineMacro("cimprovagt", CIMPROVAGT);
198                
199                    /* Define ${cimshutdown} */
200                
201                    DefineMacro("cimshutdown", CIMSHUTDOWN);
202                
203                    /* Define ${cimservera} */
204                
205                    DefineMacro("cimservera", CIMSERVERA);
206                
207 mike  1.1.2.8      /* Define ${cimservermainPath} */
208                    {
209                        char path[EXECUTOR_BUFFER_SIZE];
210                
211 mike  1.1.2.9          if (ExpandMacros("${internalBinDir}/${cimservermain}", path) != 0)
212                            Fatal(FL, "failed to resolve cimservermainPath");
213 mike  1.1.2.8  
214                        DefineMacro("cimservermainPath", path);
215                    }
216                
217                    /* Define ${cimprovagtPath} */
218                    {
219                        char path[EXECUTOR_BUFFER_SIZE];
220                
221 mike  1.1.2.9          if (ExpandMacros("${internalBinDir}/${cimprovagt}", path) != 0)
222                            Fatal(FL, "failed to resolve cimprovagtPath");
223 mike  1.1.2.8  
224                        DefineMacro("cimprovagtPath", path);
225                    }
226                
227 mike  1.1.2.9      /* Define ${cimshutdownPath} */
228                    {
229                        char path[EXECUTOR_BUFFER_SIZE];
230                
231                        if (ExpandMacros("${internalBinDir}/${cimshutdown}", path) != 0)
232                            Fatal(FL, "failed to resolve cimshutdownPath");
233                
234                        DefineMacro("cimshutdownPath", path);
235                    }
236                
237 mike  1.1.2.8      /* Define ${cimserveraPath} */
238                    {
239                        char path[EXECUTOR_BUFFER_SIZE];
240                
241 mike  1.1.2.9          if (ExpandMacros("${internalBinDir}/${cimservera}", path) != 0)
242                            Fatal(FL, "failed to resolve cimserveraPath");
243 mike  1.1.2.8  
244                        DefineMacro("cimserveraPath", path);
245                    }
246                
247 mike  1.1.2.9      /* Define ${shutdownTimeout} */
248                
249                    {
250                        char buffer[EXECUTOR_BUFFER_SIZE];
251                
252                        if (GetConfigParam("shutdownTimeout", buffer) != 0)
253                            Strlcpy(buffer, "5", sizeof(buffer));
254                
255                        DefineMacro("shutdownTimeout", buffer);
256                    }
257                
258 mike  1.1.2.8      /* Define ${currentConfigFilePath} */
259                    {
260                        char path[EXECUTOR_BUFFER_SIZE];
261                
262                        if (GetHomedPath(PEGASUS_CURRENT_CONFIG_FILE_PATH, path) != 0)
263                        {
264                            Fatal(FL, "GetHomedPath() failed on \"%s\"", 
265                                PEGASUS_CURRENT_CONFIG_FILE_PATH);
266                        }
267                
268                        DefineMacro("currentConfigFilePath", path);
269                    }
270                
271                    /* Define ${repositoryDir} */
272                
273                    if (DefineConfigPathMacro("repositoryDir", PEGASUS_REPOSITORY_DIR) != 0)
274                        Fatal(FL, "missing \"repositoryDir\" configuration parameter.");
275                
276                    /* Define ${passwordFilePath} */
277                
278                    if (DefineConfigPathMacro("passwordFilePath", "cimserver.passwd") != 0)
279 mike  1.1.2.8          Fatal(FL, "missing \"passwordFilePath\" configuration parameter.");
280                
281                    /* Define ${traceFilePath} */
282                
283                    if (DefineConfigPathMacro("traceFilePath", NULL) != 0)
284                        Fatal(FL, "missing \"traceFilePath\" configuration parameter.");
285                
286                    /* Define ${sslKeyFilePath} */
287                
288                    if (DefineConfigPathMacro("sslKeyFilePath", "file.pem") != 0)
289                        Fatal(FL, "missing \"sslKeyFilePath\" configuration parameter.");
290                
291                    /* Define ${sslTrustStore} */
292                
293                    if (DefineConfigPathMacro("sslTrustStore", "cimserver_trust") != 0)
294                        Fatal(FL, "missing \"sslTrustStore\" configuration parameter.");
295                
296                    /* Define ${crlStore} */
297                
298                    if (DefineConfigPathMacro("crlStore", "crl") != 0)
299                        Fatal(FL, "missing \"crlStore\" configuration parameter.");
300 mike  1.1.2.11 
301                    /* Define ${policyConfigFilePath} */
302                    {
303 mike  1.1.2.13         char path[EXECUTOR_BUFFER_SIZE];
304 mike  1.1.2.11 
305 mike  1.1.2.13         if (GetHomedPath(PEGASUS_POLICY_CONFIG_FILE_PATH, path) != 0)
306                        {
307                            Fatal(FL, "GetHomedPath() failed on \"%s\"", 
308                                PEGASUS_POLICY_CONFIG_FILE_PATH);
309                        }
310 mike  1.1.2.11 
311 mike  1.1.2.13         DefineMacro("policyConfigFilePath", path);
312 mike  1.1.2.11     }
313 mike  1.1.2.12 
314                    /* Define ${privilegedUser} */
315                
316                    DefineMacro("privilegedUser", "root");
317                
318                    /* Define ${cimserverUser} */
319                
320                    DefineMacro("cimserverUser", PEGASUS_CIMSERVERMAIN_USER);
321 mike  1.1.2.8  }
322                
323                /*
324                **==============================================================================
325                **
326 mike  1.1.2.1  ** main()
327                **
328                **==============================================================================
329                */
330                
331                int main(int argc, char** argv)
332                {
333 mike  1.1.2.9      const char* cimservermainPath;
334 mike  1.1.2.1      int pair[2];
335                    char username[EXECUTOR_BUFFER_SIZE];
336                    int childPid;
337 mike  1.1.2.8      const char* repositoryDir;
338 mike  1.1.2.10     struct Options options;
339 mike  1.1.2.1  
340 mike  1.1.2.10     /* Get options. */
341                
342                    GetOptions(&argc, &argv, &options);
343                
344                    /* Save argc-argv as globals. */
345 mike  1.1.2.1  
346 mike  1.1.2.8      globals.argc = argc;
347                    globals.argv = argv;
348 mike  1.1.2.1  
349 mike  1.1.2.8      /* Define macros needed by the executor. */
350                
351                    DefineExecutorMacros();
352                
353 mike  1.1.2.9      /* If shuting down, then run CIMSHUTDOWN client. */
354                
355 mike  1.1.2.10     if (options.shutdown)
356 mike  1.1.2.9          ExecShutdown();
357                
358 mike  1.1.2.11     /* Load the dynamic policy file. */
359                
360                    LoadDynamicPolicy();
361                
362 mike  1.1.2.10     /* Process --policy and --macros options. */
363 mike  1.1.2.8  
364 mike  1.1.2.10     if (options.policy || options.macros)
365 mike  1.1.2.1      {
366 mike  1.1.2.10         if (options.policy)
367                            DumpPolicy(1);
368 mike  1.1.2.8  
369 mike  1.1.2.10         if (options.macros)
370                            DumpMacros();
371 mike  1.1.2.8  
372                        exit(0);
373 mike  1.1.2.1      }
374                
375 mike  1.1.2.9      /* Get absolute CIMSERVERMAIN program name. */
376 mike  1.1.2.6  
377 mike  1.1.2.9      if ((cimservermainPath = FindMacro("cimservermainPath")) == NULL)
378                        Fatal(FL, "Failed to locate %s program", CIMSERVERMAIN);
379 mike  1.1.2.6  
380 mike  1.1.2.10     /* If CIMSERVERMAIN is already running, warn and exit now, unless one of
381                     * the following options are given: -v, --version, -h, --help (these are
382                     * passed through to CIMSERVERMAIN).
383                     */
384 mike  1.1.2.1  
385 mike  1.1.2.10     if (!options.version && !options.help && TestCimServerProcess() == 0)
386 mike  1.1.2.1      {
387                        fprintf(stderr,
388                            "%s: cimserver is already running (the PID found in the file "
389                            "\"%s\" corresponds to an existing process named \"%s\").\n\n",
390 mike  1.1.2.8              globals.argv[0], PEGASUS_CIMSERVER_START_FILE, CIMSERVERMAIN);
391 mike  1.1.2.1  
392                        exit(1);
393                    }
394                
395 mike  1.1.2.2      /* Get enableAuthentication configuration option. */
396                
397                    {
398                        char buffer[EXECUTOR_BUFFER_SIZE];
399                
400 mike  1.1.2.9          if (GetConfigParam("enableAuthentication", buffer) == 0 &&
401 mike  1.1.2.2              strcasecmp(buffer, "true") == 0)
402                        {
403                            globals.enableAuthentication = 1;
404                        }
405                    }
406                
407 mike  1.1.2.1      /* Create a socket pair for communicating with the child process. */
408                
409                    if (CreateSocketPair(pair) != 0)
410 mike  1.1.2.5          Fatal(FL, "Failed to create socket pair");
411 mike  1.1.2.1  
412                    CloseOnExec(pair[1]);
413                
414                    /* Get the log-level from the configuration parameter. */
415                
416                    GetLogLevel(argc, argv);
417                
418                    /* Open the log. */
419                
420 mike  1.1.2.10     OpenLog("cimexecutor", options.perror);
421 mike  1.1.2.1  
422                    Log(LL_INFORMATION, "starting");
423                
424                    /* Be sure this process is running as root (otherwise fail). */
425                
426                    if (setuid(0) != 0 || setgid(0) != 0)
427 mike  1.1.2.10         Fatal(FL, "attempted to run program as non-root user");
428 mike  1.1.2.1  
429 mike  1.1.2.10     /* Warn if authentication not enabled (suspicious use of executor). */
430 mike  1.1.2.2  
431                    if (!globals.enableAuthentication)
432                        Log(LL_WARNING, "authentication is NOT enabled");
433                    else
434 mike  1.1.2.3          Log(LL_TRACE, "authentication is enabled");
435 mike  1.1.2.2  
436 mike  1.1.2.1      /* Print user info. */
437                
438                    if (GetUserName(getuid(), username) != 0)
439                        Fatal(FL, "cannot resolve user from uid=%d", getuid());
440                
441                    Log(LL_TRACE, "running as %s (uid=%d, gid=%d)",
442                        username, (int)getuid(), (int)getgid());
443                
444 mike  1.1.2.9      /* Determine user for running CIMSERVERMAIN. */
445 mike  1.1.2.1  
446 mike  1.1.2.4      GetServerUser(&globals.childUid, &globals.childGid);
447 mike  1.1.2.1  
448 mike  1.1.2.8      /* Get repositoryDir for child. */
449                
450                    if ((repositoryDir = FindMacro("repositoryDir")) == NULL)
451                        Fatal(FL, "failed to find repositoryDir macro");
452                
453 mike  1.1.2.1      /* Fork child process. */
454                
455                    childPid = fork();
456                
457                    if (childPid == 0)
458                    {
459                        /* Child. */
460                        close(pair[1]);
461 mike  1.1.2.8          Child(argc, argv, cimservermainPath, globals.childUid, 
462                            globals.childGid, pair[0], repositoryDir);
463 mike  1.1.2.1      }
464                    else if (childPid > 0)
465                    {
466                        /* Parent. */
467                        close(pair[0]);
468                        Parent(pair[1], childPid);
469                    }
470                    else
471                    {
472                        Fatal(FL, "fork() failed");
473                    }
474                
475                    return 0;
476                }

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2