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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2