X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=miscutils%2Fcrontab.c;h=4787fa08f5dee66b84fac6e2eece54e3ed5cfac2;hb=4c9455f967e21d30db0de2e13b6e1115ab8f36ce;hp=b8a5abc64435069f623c9f575befbfed145e931f;hpb=926031b7640bf5aad2ffcd54b096911743a47d97;p=oweals%2Fbusybox.git diff --git a/miscutils/crontab.c b/miscutils/crontab.c index b8a5abc64..4787fa08f 100644 --- a/miscutils/crontab.c +++ b/miscutils/crontab.c @@ -7,8 +7,31 @@ * Copyright 1994 Matthew Dillon (dillon@apollo.west.oic.com) * Vladimir Oleynik (C) 2002 * - * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. + * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config CRONTAB +//config: bool "crontab (9.7 kb)" +//config: default y +//config: help +//config: Crontab manipulates the crontab for a particular user. Only +//config: the superuser may specify a different user and/or crontab directory. +//config: Note that busybox binary must be setuid root for this applet to +//config: work properly. + +/* Needs to be run by root or be suid root - needs to change /var/spool/cron* files: */ +//applet:IF_CRONTAB(APPLET(crontab, BB_DIR_USR_BIN, BB_SUID_REQUIRE)) + +//kbuild:lib-$(CONFIG_CRONTAB) += crontab.o + +//usage:#define crontab_trivial_usage +//usage: "[-c DIR] [-u USER] [-ler]|[FILE]" +//usage:#define crontab_full_usage "\n\n" +//usage: " -c Crontab directory" +//usage: "\n -u User" +//usage: "\n -l List crontab" +//usage: "\n -e Edit crontab" +//usage: "\n -r Delete crontab" +//usage: "\n FILE Replace crontab by FILE ('-': stdin)" #include "libbb.h" @@ -20,8 +43,9 @@ static void edit_file(const struct passwd *pas, const char *file) { const char *ptr; - int pid = xvfork(); + pid_t pid; + pid = xvfork(); if (pid) { /* parent */ wait4pid(pid); return; @@ -30,7 +54,7 @@ static void edit_file(const struct passwd *pas, const char *file) /* CHILD - change user and run editor */ /* initgroups, setgid, setuid */ change_identity(pas); - setup_environment(DEFAULT_SHELL, + setup_environment(pas->pw_shell, SETUP_ENV_CHANGEENV | SETUP_ENV_TO_TMP, pas); ptr = getenv("VISUAL"); @@ -41,29 +65,7 @@ static void edit_file(const struct passwd *pas, const char *file) } BB_EXECLP(ptr, ptr, file, NULL); - bb_perror_msg_and_die("exec %s", ptr); -} - -static int open_as_user(const struct passwd *pas, const char *file) -{ - pid_t pid; - char c; - - pid = xvfork(); - if (pid) { /* PARENT */ - if (wait4pid(pid) == 0) { - /* exitcode 0: child says it can read */ - return open(file, O_RDONLY); - } - return -1; - } - - /* CHILD */ - /* initgroups, setgid, setuid */ - change_identity(pas); - /* We just try to read one byte. If it works, file is readable - * under this user. We signal that by exiting with 0. */ - _exit(safe_read(xopen(file, O_RDONLY), &c, 1) < 0); + bb_perror_msg_and_die("can't execute '%s'", ptr); } int crontab_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; @@ -97,8 +99,9 @@ int crontab_main(int argc UNUSED_PARAM, char **argv) OPT_ler = OPT_l + OPT_e + OPT_r, }; - opt_complementary = "?1:dr"; /* max one argument; -d implies -r */ - opt_ler = getopt32(argv, "u:c:lerd", &user_name, &crontab_dir); + opt_ler = getopt32(argv, "^" "u:c:lerd" "\0" "?1:dr"/*max one arg; -d implies -r*/, + &user_name, &crontab_dir + ); argv += optind; if (sanitize_env_if_suid()) { /* Clears dangerous stuff, sets PATH */ @@ -126,10 +129,7 @@ int crontab_main(int argc UNUSED_PARAM, char **argv) if (!argv[0]) bb_show_usage(); if (NOT_LONE_DASH(argv[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]); + src_fd = xopen_as_uid_gid(argv[0], O_RDONLY, pas->pw_uid, pas->pw_gid); } } @@ -184,7 +184,6 @@ int crontab_main(int argc UNUSED_PARAM, char **argv) unlink(tmp_fname); /*free(tmp_fname);*/ /*free(new_fname);*/ - } /* switch */ /* Bump notification file. Handle window where crond picks file up