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) | |
| download | busybox-w32-cce38586aee7fe892ca1c837ee08a96bd3454ee9.tar.gz busybox-w32-cce38586aee7fe892ca1c837ee08a96bd3454ee9.tar.bz2 busybox-w32-cce38586aee7fe892ca1c837ee08a96bd3454ee9.zip | |
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, | |||
| 56 | int chown_main(int argc, char **argv); | 56 | int chown_main(int argc, char **argv); |
| 57 | int chown_main(int argc, char **argv) | 57 | int chown_main(int argc, char **argv) |
| 58 | { | 58 | { |
| 59 | char *groupName; | ||
| 60 | int retval = EXIT_SUCCESS; | 59 | int retval = EXIT_SUCCESS; |
| 61 | 60 | ||
| 62 | opt_complementary = "-2"; | 61 | opt_complementary = "-2"; |
| @@ -65,24 +64,7 @@ int chown_main(int argc, char **argv) | |||
| 65 | 64 | ||
| 66 | if (OPT_NODEREF) chown_func = lchown; | 65 | if (OPT_NODEREF) chown_func = lchown; |
| 67 | 66 | ||
| 68 | /* First, check if there is a group name here */ | 67 | parse_chown_usergroup_or_die(&ugid, argv[0]); |
| 69 | groupName = strchr(*argv, '.'); /* deprecated? */ | ||
| 70 | if (!groupName) | ||
| 71 | groupName = strchr(*argv, ':'); | ||
| 72 | else | ||
| 73 | *groupName = ':'; /* replace '.' with ':' */ | ||
| 74 | |||
| 75 | /* First, try parsing "user[:[group]]" */ | ||
| 76 | if (!groupName) { /* "user" */ | ||
| 77 | ugid.uid = get_ug_id(*argv, xuname2uid); | ||
| 78 | } else if (groupName == *argv) { /* ":group" */ | ||
| 79 | ugid.gid = get_ug_id(groupName + 1, xgroup2gid); | ||
| 80 | } else { | ||
| 81 | if (!groupName[1]) /* "user:" */ | ||
| 82 | *groupName = '\0'; | ||
| 83 | if (!get_uidgid(&ugid, *argv, 1)) | ||
| 84 | bb_error_msg_and_die("unknown user/group %s", *argv); | ||
| 85 | } | ||
| 86 | 68 | ||
| 87 | /* Ok, ready to do the deed now */ | 69 | /* Ok, ready to do the deed now */ |
| 88 | argv++; | 70 | 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 @@ | |||
| 14 | 14 | ||
| 15 | static int signal_nr = 15; | 15 | static int signal_nr = 15; |
| 16 | static int user_id = -1; | 16 | static int user_id = -1; |
| 17 | static int quiet; | ||
| 18 | static char *userspec; | 17 | static char *userspec; |
| 19 | static char *chuid; | ||
| 20 | static char *cmdname; | 18 | static char *cmdname; |
| 21 | static char *execname; | 19 | static char *execname; |
| 22 | static char *pidfile; | 20 | static char *pidfile; |
| 21 | static smallint quiet; | ||
| 23 | 22 | ||
| 24 | struct pid_list { | 23 | struct pid_list { |
| 25 | struct pid_list *next; | 24 | struct pid_list *next; |
| @@ -222,20 +221,28 @@ static const struct option long_options[] = { | |||
| 222 | enum { | 221 | enum { |
| 223 | CTX_STOP = 0x1, | 222 | CTX_STOP = 0x1, |
| 224 | CTX_START = 0x2, | 223 | CTX_START = 0x2, |
| 225 | OPT_BACKGROUND = 0x4, | 224 | OPT_BACKGROUND = 0x4, // -b |
| 226 | OPT_QUIET = 0x8, | 225 | OPT_QUIET = 0x8, // -q |
| 227 | OPT_MAKEPID = 0x10, | 226 | OPT_MAKEPID = 0x10, // -m |
| 228 | OPT_OKNODO = 0x20 * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, | 227 | OPT_a = 0x20, // -a |
| 229 | OPT_VERBOSE = 0x40 * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, | 228 | OPT_n = 0x40, // -n |
| 230 | OPT_NICELEVEL = 0x80 * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, | 229 | OPT_s = 0x80, // -s |
| 230 | OPT_u = 0x100, // -u | ||
| 231 | OPT_c = 0x200, // -c | ||
| 232 | OPT_x = 0x400, // -x | ||
| 233 | OPT_p = 0x800, // -p | ||
| 234 | OPT_OKNODO = 0x1000 * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -o | ||
| 235 | OPT_VERBOSE = 0x2000 * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -v | ||
| 236 | OPT_NICELEVEL = 0x4000 * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -N | ||
| 231 | }; | 237 | }; |
| 232 | 238 | ||
| 233 | int start_stop_daemon_main(int argc, char **argv); | 239 | int start_stop_daemon_main(int argc, char **argv); |
| 234 | int start_stop_daemon_main(int argc, char **argv) | 240 | int start_stop_daemon_main(int argc, char **argv) |
| 235 | { | 241 | { |
| 236 | unsigned opt; | 242 | unsigned opt; |
| 237 | char *signame = NULL; | 243 | char *signame; |
| 238 | char *startas = NULL; | 244 | char *startas; |
| 245 | char *chuid; | ||
| 239 | #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY | 246 | #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY |
| 240 | // char *retry_arg = NULL; | 247 | // char *retry_arg = NULL; |
| 241 | // int retries = -1; | 248 | // int retries = -1; |
| @@ -247,22 +254,22 @@ int start_stop_daemon_main(int argc, char **argv) | |||
| 247 | 254 | ||
| 248 | /* Check required one context option was given */ | 255 | /* Check required one context option was given */ |
| 249 | opt_complementary = "K:S:?:K--S:S--K:m?p:K?xpun:S?xa"; | 256 | opt_complementary = "K:S:?:K--S:S--K:m?p:K?xpun:S?xa"; |
| 250 | opt = getopt32(argc, argv, "KSbqm" | 257 | opt = getopt32(argc, argv, "KSbqma:n:s:u:c:x:p:" |
| 251 | // USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:") | 258 | USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:"), |
| 252 | USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:") | 259 | // USE_FEATURE_START_STOP_DAEMON_FANCY("ovN:R:"), |
| 253 | "a:n:s:u:c:x:p:" | 260 | &startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile |
| 254 | USE_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N) | 261 | USE_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N) |
| 255 | // USE_FEATURE_START_STOP_DAEMON_FANCY(,&retry_arg) | 262 | // USE_FEATURE_START_STOP_DAEMON_FANCY(,&retry_arg) |
| 256 | ,&startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile); | 263 | ); |
| 257 | 264 | ||
| 258 | quiet = (opt & OPT_QUIET) && !(opt & OPT_VERBOSE); | 265 | quiet = (opt & OPT_QUIET) && !(opt & OPT_VERBOSE); |
| 259 | 266 | ||
| 260 | if (signame) { | 267 | if (opt & OPT_s) { |
| 261 | signal_nr = get_signum(signame); | 268 | signal_nr = get_signum(signame); |
| 262 | if (signal_nr < 0) bb_show_usage(); | 269 | if (signal_nr < 0) bb_show_usage(); |
| 263 | } | 270 | } |
| 264 | 271 | ||
| 265 | if (!startas) | 272 | if (!(opt & OPT_a)) |
| 266 | startas = execname; | 273 | startas = execname; |
| 267 | 274 | ||
| 268 | // USE_FEATURE_START_STOP_DAEMON_FANCY( | 275 | // USE_FEATURE_START_STOP_DAEMON_FANCY( |
| @@ -303,11 +310,11 @@ int start_stop_daemon_main(int argc, char **argv) | |||
| 303 | fprintf(pidf, "%d\n", pidt); | 310 | fprintf(pidf, "%d\n", pidt); |
| 304 | fclose(pidf); | 311 | fclose(pidf); |
| 305 | } | 312 | } |
| 306 | if (chuid) { | 313 | if (opt & OPT_c) { |
| 307 | user_id = bb_strtou(chuid, NULL, 10); | 314 | struct bb_uidgid_t ugid; |
| 308 | if (errno) | 315 | parse_chown_usergroup_or_die(&ugid, chuid); |
| 309 | user_id = xuname2uid(chuid); | 316 | if (ugid.gid != (gid_t) -1) xsetgid(ugid.gid); |
| 310 | xsetuid(user_id); | 317 | if (ugid.uid != (uid_t) -1) xsetuid(ugid.uid); |
| 311 | } | 318 | } |
| 312 | #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY | 319 | #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY |
| 313 | if (opt & OPT_NICELEVEL) { | 320 | 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 { | |||
| 443 | uid_t uid; | 443 | uid_t uid; |
| 444 | gid_t gid; | 444 | gid_t gid; |
| 445 | }; | 445 | }; |
| 446 | /* always sets uid and gid */ | ||
| 446 | int get_uidgid(struct bb_uidgid_t*, const char*, int numeric_ok); | 447 | int get_uidgid(struct bb_uidgid_t*, const char*, int numeric_ok); |
| 448 | /* chown-like handling of "user[:[group]" */ | ||
| 449 | void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group); | ||
| 447 | /* what is this? */ | 450 | /* what is this? */ |
| 448 | /*extern char *bb_getug(char *buffer, char *idname, long id, int bufsize, char prefix);*/ | 451 | /*extern char *bb_getug(char *buffer, char *idname, long id, int bufsize, char prefix);*/ |
| 449 | char *bb_getpwuid(char *name, long uid, int bufsize); | 452 | 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 @@ | |||
| 2893 | "\n -N|--nicelevel <N> Add N to process's nice level" \ | 2893 | "\n -N|--nicelevel <N> Add N to process's nice level" \ |
| 2894 | ) \ | 2894 | ) \ |
| 2895 | "\n -s|--signal <signal> Signal to send (default TERM)" \ | 2895 | "\n -s|--signal <signal> Signal to send (default TERM)" \ |
| 2896 | "\n -U|--chuid <username>|<uid> Start process with this name" | 2896 | "\n -c|--chuid <user>[:[<group>]] Change to specified user/group" |
| 2897 | 2897 | ||
| 2898 | #define stat_trivial_usage \ | 2898 | #define stat_trivial_usage \ |
| 2899 | "[OPTION] FILE..." | 2899 | "[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. | |||
| 27 | 27 | ||
| 28 | #include "busybox.h" | 28 | #include "busybox.h" |
| 29 | 29 | ||
| 30 | /* Always sets uid and gid */ | ||
| 30 | int get_uidgid(struct bb_uidgid_t *u, const char *ug, int numeric_ok) | 31 | int get_uidgid(struct bb_uidgid_t *u, const char *ug, int numeric_ok) |
| 31 | { | 32 | { |
| 32 | struct passwd *pwd; | 33 | struct passwd *pwd; |
| @@ -53,6 +54,7 @@ int get_uidgid(struct bb_uidgid_t *u, const char *ug, int numeric_ok) | |||
| 53 | goto skip; | 54 | goto skip; |
| 54 | } | 55 | } |
| 55 | } | 56 | } |
| 57 | /* Either it is not numeric, or caller disallows numeric username */ | ||
| 56 | pwd = getpwnam(user); | 58 | pwd = getpwnam(user); |
| 57 | if (!pwd) | 59 | if (!pwd) |
| 58 | return 0; | 60 | return 0; |
| @@ -75,6 +77,40 @@ int get_uidgid(struct bb_uidgid_t *u, const char *ug, int numeric_ok) | |||
| 75 | return 1; | 77 | return 1; |
| 76 | } | 78 | } |
| 77 | 79 | ||
| 80 | /* chown-like: | ||
| 81 | * "user" sets uid only, | ||
| 82 | * ":group" sets gid only | ||
| 83 | * "user:" sets uid and gid (to user's primary group id) | ||
| 84 | * "user:group" sets uid and gid | ||
| 85 | * ('unset' uid or gid is actually set to -1) | ||
| 86 | */ | ||
| 87 | void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group) | ||
| 88 | { | ||
| 89 | char *group; | ||
| 90 | |||
| 91 | u->uid = -1; | ||
| 92 | u->gid = -1; | ||
| 93 | |||
| 94 | /* Check if there is a group name */ | ||
| 95 | group = strchr(user_group, '.'); /* deprecated? */ | ||
| 96 | if (!group) | ||
| 97 | group = strchr(user_group, ':'); | ||
| 98 | else | ||
| 99 | *group = ':'; /* replace '.' with ':' */ | ||
| 100 | |||
| 101 | /* Parse "user[:[group]]" */ | ||
| 102 | if (!group) { /* "user" */ | ||
| 103 | u->uid = get_ug_id(user_group, xuname2uid); | ||
| 104 | } else if (group == user_group) { /* ":group" */ | ||
| 105 | u->gid = get_ug_id(group + 1, xgroup2gid); | ||
| 106 | } else { | ||
| 107 | if (!group[1]) /* "user:" */ | ||
| 108 | *group = '\0'; | ||
| 109 | if (!get_uidgid(u, user_group, 1)) | ||
| 110 | bb_error_msg_and_die("unknown user/group %s", user_group); | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 78 | #if 0 | 114 | #if 0 |
| 79 | #include <stdio.h> | 115 | #include <stdio.h> |
| 80 | int main() | 116 | int main() |
