Patch from tito to replace shared memory usage with mlock(), slightly tweaked
[oweals/busybox.git] / miscutils / crontab.c
index 6b9446464eb5707c5f3896415ce51c8877052e3c..bad7f0018b22254343bc7450a8bb7f5a4d32cc6c 100644 (file)
@@ -1,13 +1,13 @@
+/* vi: set sw=4 ts=4: */
 /*
  * CRONTAB
  *
  * usually setuid root, -c option only works if getuid() == geteuid()
  *
  * Copyright 1994 Matthew Dillon (dillon@apollo.west.oic.com)
- * May be distributed under the GNU General Public License
- *
- * Vladimir Oleynik <dzo@simtreas.ru> (C) 2002 to be used in busybox
+ * Vladimir Oleynik <dzo@simtreas.ru> (C) 2002
  *
+ * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
  */
 
 #include <stdio.h>
@@ -148,8 +148,7 @@ crontab_main(int ac, char **av)
      * Change directory to our crontab directory
      */
 
-    if (chdir(CDir) < 0)
-       bb_perror_msg_and_die("cannot change dir to %s", CDir);
+    bb_xchdir(CDir);
 
     /*
      * Handle options as appropriate
@@ -179,20 +178,16 @@ crontab_main(int ac, char **av)
            char buf[1024];
 
            snprintf(tmp, sizeof(tmp), TMPDIR "/crontab.%d", getpid());
-           if ((fd = open(tmp, O_RDWR|O_CREAT|O_TRUNC|O_EXCL, 0600)) >= 0) {
-               chown(tmp, getuid(), getgid());
-               if ((fi = fopen(pas->pw_name, "r"))) {
-                   while ((n = fread(buf, 1, sizeof(buf), fi)) > 0)
-                       write(fd, buf, n);
-               }
-               EditFile(caller, tmp);
-               remove(tmp);
-               lseek(fd, 0L, 0);
-               repFd = fd;
-           } else {
-               bb_error_msg_and_die("unable to create %s", tmp);
+           fd = bb_xopen3(tmp, O_RDWR|O_CREAT|O_TRUNC|O_EXCL, 0600);
+           chown(tmp, getuid(), getgid());
+           if ((fi = fopen(pas->pw_name, "r"))) {
+               while ((n = fread(buf, 1, sizeof(buf), fi)) > 0)
+                   write(fd, buf, n);
            }
-
+           EditFile(caller, tmp);
+           remove(tmp);
+           lseek(fd, 0L, 0);
+           repFd = fd;
        }
        option = REPLACE;
        /* fall through */
@@ -289,11 +284,8 @@ GetReplaceStream(const char *user, const char *file)
     if (ChangeUser(user, 0) < 0)
        exit(0);
 
-    fd = open(file, O_RDONLY);
-    if (fd < 0) {
-       bb_error_msg("unable to open %s", file);
-       exit(0);
-    }
+    bb_default_error_retval = 0;
+    fd = bb_xopen3(file, O_RDONLY, 0);
     buf[0] = 0;
     write(filedes[1], buf, 1);
     while ((n = read(fd, buf, sizeof(buf))) > 0) {
@@ -320,7 +312,7 @@ EditFile(const char *user, const char *file)
            ptr = PATH_VI;
 
        snprintf(visual, sizeof(visual), "%s %s", ptr, file);
-       execl("/bin/sh", "/bin/sh", "-c", visual, NULL);
+       execl(DEFAULT_SHELL, DEFAULT_SHELL, "-c", visual, NULL);
        perror("exec");
        exit(0);
     }
@@ -333,58 +325,32 @@ EditFile(const char *user, const char *file)
     wait4(pid, NULL, 0, NULL);
 }
 
-static void
-log(const char *ctl, ...)
-{
-    va_list va;
-    char buf[1024];
-
-    va_start(va, ctl);
-    vsnprintf(buf, sizeof(buf), ctl, va);
-    syslog(LOG_NOTICE, "%s",buf );
-    va_end(va);
-}
-
 static int
 ChangeUser(const char *user, short dochdir)
 {
     struct passwd *pas;
 
     /*
-     * Obtain password entry and change privilages
+     * Obtain password entry and change privileges
      */
 
-    if ((pas = getpwnam(user)) == 0) {
-       log("failed to get uid for %s", user);
+    if ((pas = getpwnam(user)) == NULL) {
+       bb_perror_msg_and_die("failed to get uid for %s", user);
        return(-1);
     }
     setenv("USER", pas->pw_name, 1);
     setenv("HOME", pas->pw_dir, 1);
-    setenv("SHELL", "/bin/sh", 1);
+    setenv("SHELL", DEFAULT_SHELL, 1);
 
     /*
      * Change running state to the user in question
      */
+    change_identity(pas);
 
-    if (initgroups(user, pas->pw_gid) < 0) {
-       log("initgroups failed: %s %m", user);
-       return(-1);
-    }
-    if (setregid(pas->pw_gid, pas->pw_gid) < 0) {
-       log("setregid failed: %s %d", user, pas->pw_gid);
-       return(-1);
-    }
-    if (setreuid(pas->pw_uid, pas->pw_uid) < 0) {
-       log("setreuid failed: %s %d", user, pas->pw_uid);
-       return(-1);
-    }
     if (dochdir) {
        if (chdir(pas->pw_dir) < 0) {
-           if (chdir(TMPDIR) < 0) {
-               log("chdir failed: %s %s", user, pas->pw_dir);
-               log("chdir failed: %s " TMPDIR, user);
-               return(-1);
-           }
+           bb_perror_msg("chdir failed: %s %s", user, pas->pw_dir);
+           bb_xchdir(TMPDIR);
        }
     }
     return(pas->pw_uid);