X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=miscutils%2Fcrontab.c;h=5557bc491e0f000013207253d093f73b1d95fd0c;hb=7cfec4b3e06cc1414079c4cea23239730959bf62;hp=f8662babbab2f19d1894c3abf1aa171d0aaa6385;hpb=d73cbd31a295ac757e59f129f162d9cd69440224;p=oweals%2Fbusybox.git diff --git a/miscutils/crontab.c b/miscutils/crontab.c index f8662babb..5557bc491 100644 --- a/miscutils/crontab.c +++ b/miscutils/crontab.c @@ -12,29 +12,11 @@ #include "libbb.h" -#ifndef CRONTABS -#define CRONTABS "/var/spool/cron/crontabs" -#endif +#define CRONTABS CONFIG_FEATURE_CROND_DIR "/crontabs" #ifndef CRONUPDATE #define CRONUPDATE "cron.update" #endif -static void change_user(const struct passwd *pas) -{ - setenv("USER", pas->pw_name, 1); - setenv("HOME", pas->pw_dir, 1); - setenv("SHELL", DEFAULT_SHELL, 1); - - /* initgroups, setgid, setuid */ - change_identity(pas); - - if (chdir(pas->pw_dir) < 0) { - bb_perror_msg("chdir(%s) by %s failed", - pas->pw_dir, pas->pw_name); - xchdir("/tmp"); - } -} - static void edit_file(const struct passwd *pas, const char *file) { const char *ptr; @@ -48,7 +30,11 @@ static void edit_file(const struct passwd *pas, const char *file) } /* CHILD - change user and run editor */ - change_user(pas); + /* initgroups, setgid, setuid */ + change_identity(pas); + setup_environment(DEFAULT_SHELL, + SETUP_ENV_CHANGEENV | SETUP_ENV_TO_TMP, + pas); ptr = getenv("VISUAL"); if (!ptr) { ptr = getenv("EDITOR"); @@ -93,6 +79,7 @@ int crontab_main(int argc UNUSED_PARAM, char **argv) char *new_fname; char *user_name; /* -u USER */ int fd; + int src_fd; int opt_ler; /* file [opts] Replace crontab from file @@ -119,21 +106,15 @@ int crontab_main(int argc UNUSED_PARAM, char **argv) argv += optind; if (sanitize_env_if_suid()) { /* Clears dangerous stuff, sets PATH */ - /* run by non-root? */ + /* Run by non-root */ if (opt_ler & (OPT_u|OPT_c)) - bb_error_msg_and_die("only root can use -c or -u"); + bb_error_msg_and_die(bb_msg_you_must_be_root); } if (opt_ler & OPT_u) { - pas = getpwnam(user_name); - if (!pas) - bb_error_msg_and_die("user %s is not known", user_name); + pas = xgetpwnam(user_name); } else { -/* XXX: xgetpwuid */ - uid_t my_uid = getuid(); - pas = getpwuid(my_uid); - if (!pas) - bb_perror_msg_and_die("unknown uid %d", (int)my_uid); + pas = xgetpwuid(getuid()); } #define user_name DONT_USE_ME_BEYOND_THIS_POINT @@ -144,15 +125,15 @@ int crontab_main(int argc UNUSED_PARAM, char **argv) bb_show_usage(); /* Read replacement file under user's UID/GID/group vector */ + src_fd = STDIN_FILENO; if (!opt_ler) { /* Replace? */ if (!argv[0]) bb_show_usage(); if (NOT_LONE_DASH(argv[0])) { - fd = open_as_user(pas, argv[0]); - if (fd < 0) + src_fd = open_as_user(pas, argv[0]); + if (src_fd < 0) bb_error_msg_and_die("user %s cannot read %s", pas->pw_name, argv[0]); - xmove_fd(fd, STDIN_FILENO); } } @@ -180,27 +161,27 @@ int crontab_main(int argc UNUSED_PARAM, char **argv) tmp_fname = xasprintf("%s.%u", crontab_dir, (unsigned)getpid()); /* No O_EXCL: we don't want to be stuck if earlier crontabs * were killed, leaving stale temp file behind */ - fd = xopen3(tmp_fname, O_RDWR|O_CREAT|O_TRUNC, 0600); - xmove_fd(fd, STDIN_FILENO); - fchown(STDIN_FILENO, pas->pw_uid, pas->pw_gid); + src_fd = xopen3(tmp_fname, O_RDWR|O_CREAT|O_TRUNC, 0600); + fchown(src_fd, pas->pw_uid, pas->pw_gid); fd = open(pas->pw_name, O_RDONLY); if (fd >= 0) { - bb_copyfd_eof(fd, STDIN_FILENO); + bb_copyfd_eof(fd, src_fd); close(fd); + xlseek(src_fd, 0, SEEK_SET); } + close_on_exec_on(src_fd); /* don't want editor to see this fd */ edit_file(pas, tmp_fname); - xlseek(STDIN_FILENO, 0, SEEK_SET); /* fall through */ case 0: /* Replace (no -l, -e, or -r were given) */ new_fname = xasprintf("%s.new", pas->pw_name); fd = open(new_fname, O_WRONLY|O_CREAT|O_TRUNC|O_APPEND, 0600); if (fd >= 0) { - bb_copyfd_eof(STDIN_FILENO, fd); + bb_copyfd_eof(src_fd, fd); close(fd); xrename(new_fname, pas->pw_name); } else { - bb_error_msg("cannot create %s/%s", + bb_error_msg("can't create %s/%s", crontab_dir, new_fname); } if (tmp_fname) @@ -227,7 +208,7 @@ int crontab_main(int argc UNUSED_PARAM, char **argv) /* loop */ } if (fd < 0) { - bb_error_msg("cannot append to %s/%s", + bb_error_msg("can't append to %s/%s", crontab_dir, CRONUPDATE); } return 0;