diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-26 22:47:42 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-26 22:47:42 +0000 |
commit | cce38586aee7fe892ca1c837ee08a96bd3454ee9 (patch) | |
tree | 2cce1db0f921fdc3e899641dd9c59f459ce4b07d | |
parent | f8ea0f3a66559a00c41fd7877bdc241973a60f8c (diff) |
start_stop_daemon: add -chuid support
-rw-r--r-- | coreutils/chown.c | 20 | ||||
-rw-r--r-- | debianutils/start_stop_daemon.c | 51 | ||||
-rw-r--r-- | include/libbb.h | 3 | ||||
-rw-r--r-- | include/usage.h | 2 | ||||
-rw-r--r-- | libpwdgrp/uidgid_get.c | 36 |
5 files changed, 70 insertions, 42 deletions
diff --git a/coreutils/chown.c b/coreutils/chown.c index dad5ce063..3380677bc 100644 --- a/coreutils/chown.c +++ b/coreutils/chown.c @@ -56,7 +56,6 @@ static int fileAction(const char *fileName, struct stat *statbuf, int chown_main(int argc, char **argv); int chown_main(int argc, char **argv) { - char *groupName; int retval = EXIT_SUCCESS; opt_complementary = "-2"; @@ -65,24 +64,7 @@ int chown_main(int argc, char **argv) if (OPT_NODEREF) chown_func = lchown; - /* First, check if there is a group name here */ - groupName = strchr(*argv, '.'); /* deprecated? */ - if (!groupName) - groupName = strchr(*argv, ':'); - else - *groupName = ':'; /* replace '.' with ':' */ - - /* First, try parsing "user[:[group]]" */ - if (!groupName) { /* "user" */ - ugid.uid = get_ug_id(*argv, xuname2uid); - } else if (groupName == *argv) { /* ":group" */ - ugid.gid = get_ug_id(groupName + 1, xgroup2gid); - } else { - if (!groupName[1]) /* "user:" */ - *groupName = '\0'; - if (!get_uidgid(&ugid, *argv, 1)) - bb_error_msg_and_die("unknown user/group %s", *argv); - } + parse_chown_usergroup_or_die(&ugid, argv[0]); /* Ok, ready to do the deed now */ argv++; diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index eb2427a50..1862f113d 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c @@ -14,12 +14,11 @@ static int signal_nr = 15; static int user_id = -1; -static int quiet; static char *userspec; -static char *chuid; static char *cmdname; static char *execname; static char *pidfile; +static smallint quiet; struct pid_list { struct pid_list *next; @@ -222,20 +221,28 @@ static const struct option long_options[] = { enum { CTX_STOP = 0x1, CTX_START = 0x2, - OPT_BACKGROUND = 0x4, - OPT_QUIET = 0x8, - OPT_MAKEPID = 0x10, - OPT_OKNODO = 0x20 * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, - OPT_VERBOSE = 0x40 * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, - OPT_NICELEVEL = 0x80 * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, + OPT_BACKGROUND = 0x4, // -b + OPT_QUIET = 0x8, // -q + OPT_MAKEPID = 0x10, // -m + OPT_a = 0x20, // -a + OPT_n = 0x40, // -n + OPT_s = 0x80, // -s + OPT_u = 0x100, // -u + OPT_c = 0x200, // -c + OPT_x = 0x400, // -x + OPT_p = 0x800, // -p + OPT_OKNODO = 0x1000 * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -o + OPT_VERBOSE = 0x2000 * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -v + OPT_NICELEVEL = 0x4000 * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -N }; int start_stop_daemon_main(int argc, char **argv); int start_stop_daemon_main(int argc, char **argv) { unsigned opt; - char *signame = NULL; - char *startas = NULL; + char *signame; + char *startas; + char *chuid; #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY // char *retry_arg = NULL; // int retries = -1; @@ -247,22 +254,22 @@ int start_stop_daemon_main(int argc, char **argv) /* Check required one context option was given */ opt_complementary = "K:S:?:K--S:S--K:m?p:K?xpun:S?xa"; - opt = getopt32(argc, argv, "KSbqm" -// USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:") - USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:") - "a:n:s:u:c:x:p:" + opt = getopt32(argc, argv, "KSbqma:n:s:u:c:x:p:" + USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:"), +// USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:"), + &startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile USE_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N) // USE_FEATURE_START_STOP_DAEMON_FANCY(,&retry_arg) - ,&startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile); + ); quiet = (opt & OPT_QUIET) && !(opt & OPT_VERBOSE); - if (signame) { + if (opt & OPT_s) { signal_nr = get_signum(signame); if (signal_nr < 0) bb_show_usage(); } - if (!startas) + if (!(opt & OPT_a)) startas = execname; // USE_FEATURE_START_STOP_DAEMON_FANCY( @@ -303,11 +310,11 @@ int start_stop_daemon_main(int argc, char **argv) fprintf(pidf, "%d\n", pidt); fclose(pidf); } - if (chuid) { - user_id = bb_strtou(chuid, NULL, 10); - if (errno) - user_id = xuname2uid(chuid); - xsetuid(user_id); + if (opt & OPT_c) { + struct bb_uidgid_t ugid; + parse_chown_usergroup_or_die(&ugid, chuid); + if (ugid.gid != (gid_t) -1) xsetgid(ugid.gid); + if (ugid.uid != (uid_t) -1) xsetuid(ugid.uid); } #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY if (opt & OPT_NICELEVEL) { diff --git a/include/libbb.h b/include/libbb.h index a32e6154c..4293ae269 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -443,7 +443,10 @@ struct bb_uidgid_t { uid_t uid; gid_t gid; }; +/* always sets uid and gid */ int get_uidgid(struct bb_uidgid_t*, const char*, int numeric_ok); +/* chown-like handling of "user[:[group]" */ +void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group); /* what is this? */ /*extern char *bb_getug(char *buffer, char *idname, long id, int bufsize, char prefix);*/ char *bb_getpwuid(char *name, long uid, int bufsize); diff --git a/include/usage.h b/include/usage.h index 52f972038..04dddd7c3 100644 --- a/include/usage.h +++ b/include/usage.h @@ -2893,7 +2893,7 @@ "\n -N|--nicelevel <N> Add N to process's nice level" \ ) \ "\n -s|--signal <signal> Signal to send (default TERM)" \ - "\n -U|--chuid <username>|<uid> Start process with this name" + "\n -c|--chuid <user>[:[<group>]] Change to specified user/group" #define stat_trivial_usage \ "[OPTION] FILE..." diff --git a/libpwdgrp/uidgid_get.c b/libpwdgrp/uidgid_get.c index 69c228e16..f10b40654 100644 --- a/libpwdgrp/uidgid_get.c +++ b/libpwdgrp/uidgid_get.c @@ -27,6 +27,7 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "busybox.h" +/* Always sets uid and gid */ int get_uidgid(struct bb_uidgid_t *u, const char *ug, int numeric_ok) { struct passwd *pwd; @@ -53,6 +54,7 @@ int get_uidgid(struct bb_uidgid_t *u, const char *ug, int numeric_ok) goto skip; } } + /* Either it is not numeric, or caller disallows numeric username */ pwd = getpwnam(user); if (!pwd) return 0; @@ -75,6 +77,40 @@ int get_uidgid(struct bb_uidgid_t *u, const char *ug, int numeric_ok) return 1; } +/* chown-like: + * "user" sets uid only, + * ":group" sets gid only + * "user:" sets uid and gid (to user's primary group id) + * "user:group" sets uid and gid + * ('unset' uid or gid is actually set to -1) + */ +void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group) +{ + char *group; + + u->uid = -1; + u->gid = -1; + + /* Check if there is a group name */ + group = strchr(user_group, '.'); /* deprecated? */ + if (!group) + group = strchr(user_group, ':'); + else + *group = ':'; /* replace '.' with ':' */ + + /* Parse "user[:[group]]" */ + if (!group) { /* "user" */ + u->uid = get_ug_id(user_group, xuname2uid); + } else if (group == user_group) { /* ":group" */ + u->gid = get_ug_id(group + 1, xgroup2gid); + } else { + if (!group[1]) /* "user:" */ + *group = '\0'; + if (!get_uidgid(u, user_group, 1)) + bb_error_msg_and_die("unknown user/group %s", user_group); + } +} + #if 0 #include <stdio.h> int main() |