-/*
- * $Source$
- * $Header$
+/* $Id$
+ *
+ * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
*/
-/* (c) Copyright 1988 by the Massachusetts Institute of Technology. */
-/* For copying and distribution information, please see the file */
-/* <mit-copyright.h>. */
-
-#ifndef lint
-static char *rcsid_exec_002_c = "$Header$";
-#endif lint
#include <mit-copyright.h>
-#include <stdio.h>
-#include <sys/wait.h>
-#include <signal.h>
-#include <gdb.h>
#include <moira.h>
+#include "update_server.h"
#include "update.h"
-extern CONNECTION conn;
-extern int code, errno;
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+
+RCSID("$Header$");
-int
-exec_002(str)
- char *str;
+void exec_002(int conn, char *str)
{
- union wait waitb;
- int n, pid, mask;
+ int waitb, n;
+ sigset_t mask, oldmask;
+ pid_t pid;
+ long code;
+
+ if (!have_authorization)
+ {
+ send_int(conn, MR_PERM);
+ return;
+ }
+ if (config_lookup("noexec"))
+ {
+ send_int(conn, EPERM);
+ com_err(whoami, EPERM, "Not allowed to execute");
+ return;
+ }
- str += 8;
- while (*str == ' ')
- str++;
- mask = sigblock(sigmask(SIGCHLD));
- pid = fork();
- switch (pid) {
+ str += 8;
+ while (*str == ' ')
+ str++;
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &mask, &oldmask);
+ pid = fork();
+ switch (pid)
+ {
case -1:
- n = errno;
- sigsetmask(mask);
- log_priority = log_ERROR;
- com_err(whoami, errno, ": can't fork to run install script");
- code = send_object(conn, (char *)&n, INTEGER_T);
- if (code)
- exit(1);
- return;
- case 0:
- sigsetmask(mask);
- execlp(str, str, (char *)NULL);
- n = errno;
- sigsetmask(mask);
- log_priority = log_ERROR;
- com_err(whoami, n, ": %s", str);
- (void) send_object(conn, (char *)&n, INTEGER_T);
+ n = errno;
+ sigprocmask(SIG_UNBLOCK, &oldmask, &mask);
+ com_err(whoami, n, ": can't fork to run install script");
+ code = send_int(conn, n);
+ if (code)
exit(1);
+ return;
+
+ case 0:
+ if (setuid(uid) < 0)
+ {
+ com_err(whoami, errno, "Unable to setuid to %d\n", uid);
+ exit(1);
+ }
+ sigprocmask(SIG_UNBLOCK, &oldmask, &mask);
+ execlp(str, str, NULL);
+ n = errno;
+ sigprocmask(SIG_UNBLOCK, &oldmask, &mask);
+ com_err(whoami, n, ": %s", str);
+ send_int(conn, n);
+ exit(1);
+
default:
- do {
- n = wait(&waitb);
- } while (n != -1 && n != pid);
- sigsetmask(mask);
- if (waitb.w_status) {
- n = waitb.w_retcode + ERROR_TABLE_BASE_sms;
- log_priority = log_ERROR;
- com_err(whoami, n, " child exited with status %d", waitb.w_retcode);
- code = send_object(conn, (char *)&n, INTEGER_T);
- if (code) {
- exit(1);
+ do
+ n = wait(&waitb);
+ while (n != -1 && n != pid);
+
+ sigprocmask(SIG_UNBLOCK, &oldmask, &mask);
+ if ((WIFEXITED(waitb) && (WEXITSTATUS(waitb) != 0)) ||
+ WIFSIGNALED(waitb))
+ {
+ if (WIFSIGNALED(waitb))
+ {
+ n = MR_COREDUMP;
+ com_err(whoami, n, " child exited on signal %d",
+ WTERMSIG(waitb));
+ }
+ else
+ {
+ n = WEXITSTATUS(waitb) + ERROR_TABLE_BASE_sms;
+ com_err(whoami, n, " child exited with status %d",
+ WEXITSTATUS(waitb));
}
- } else {
- code = send_ok();
- if (code)
- exit(1);
+ code = send_int(conn, n);
+ if (code)
+ exit(1);
+ }
+ else
+ {
+ code = send_ok(conn);
+ if (code)
+ exit(1);
}
}
+ return;
}