]> andersk Git - moira.git/blob - update/exec_002.c
aeec495c18d5634077fa16aadbbfa05b38c6fcce
[moira.git] / update / exec_002.c
1 /* $Id$
2  *
3  * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
4  * For copying and distribution information, please see the file
5  * <mit-copyright.h>.
6  */
7
8 #include <mit-copyright.h>
9 #include <moira.h>
10 #include "update_server.h"
11 #include "update.h"
12
13 #include <sys/wait.h>
14
15 #include <errno.h>
16 #include <signal.h>
17 #include <stdio.h>
18 #include <unistd.h>
19
20 #include <gdb.h>
21
22 RCSID("$Header$");
23
24 extern CONNECTION conn;
25 extern int code, uid, log_priority, have_authorization;
26 extern char *whoami;
27
28 int exec_002(char *str)
29 {
30   int waitb;
31   sigset_t mask, oldmask;
32   int n, pid;
33
34   if (!have_authorization)
35     {
36       reject_call(MR_PERM);
37       return 0;
38     }
39   if (config_lookup("noexec"))
40     {
41       code = EPERM;
42       send_object(conn, (char *)&code, INTEGER_T);
43       com_err(whoami, code, "Not allowed to execute");
44       return 0;
45     }
46   str += 8;
47   while (*str == ' ')
48     str++;
49   sigemptyset(&mask);
50   sigaddset(&mask, SIGCHLD);
51   sigprocmask(SIG_BLOCK, &mask, &oldmask);
52   pid = fork();
53   switch (pid)
54     {
55     case -1:
56       n = errno;
57       sigprocmask(SIG_UNBLOCK, &oldmask, &mask);
58       log_priority = log_ERROR;
59       com_err(whoami, errno, ": can't fork to run install script");
60       code = send_object(conn, (char *)&n, INTEGER_T);
61       if (code)
62         exit(1);
63       return 0;
64     case 0:
65       if (setuid(uid) < 0)
66         {
67           com_err(whoami, errno, "Unable to setuid to %d\n", uid);
68           exit(1);
69         }
70       sigprocmask(SIG_UNBLOCK, &oldmask, &mask);
71       execlp(str, str, NULL);
72       n = errno;
73       sigprocmask(SIG_UNBLOCK, &oldmask, &mask);
74       log_priority = log_ERROR;
75       com_err(whoami, n, ": %s", str);
76       send_object(conn, (char *)&n, INTEGER_T);
77       exit(1);
78     default:
79       do
80         n = wait(&waitb);
81       while (n != -1 && n != pid);
82       sigprocmask(SIG_UNBLOCK, &oldmask, &mask);
83       if ((WIFEXITED(waitb) && (WEXITSTATUS(waitb) != 0)) ||
84           WIFSIGNALED(waitb))
85         {
86           log_priority = log_ERROR;
87           if (WIFSIGNALED(waitb))
88             {
89               n = MR_COREDUMP;
90               com_err(whoami, n, " child exited on signal %d",
91                       WTERMSIG(waitb));
92             }
93           else
94             {
95               n = WEXITSTATUS(waitb) + ERROR_TABLE_BASE_sms;
96               com_err(whoami, n, " child exited with status %d",
97                       WEXITSTATUS(waitb));
98             }
99           code = send_object(conn, (char *)&n, INTEGER_T);
100           if (code)
101             exit(1);
102         }
103       else
104         {
105           code = send_ok();
106           if (code)
107             exit(1);
108         }
109     }
110   return 0;
111 }
This page took 0.035768 seconds and 3 git commands to generate.