aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-02-26 22:47:42 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-02-26 22:47:42 +0000
commit22bf91ab985f7eb544340977ee6991b114e94e15 (patch)
tree2cce1db0f921fdc3e899641dd9c59f459ce4b07d
parent83da6028ac32b77ec2900a15a0842adba36aa0d3 (diff)
downloadbusybox-w32-22bf91ab985f7eb544340977ee6991b114e94e15.tar.gz
busybox-w32-22bf91ab985f7eb544340977ee6991b114e94e15.tar.bz2
busybox-w32-22bf91ab985f7eb544340977ee6991b114e94e15.zip
start_stop_daemon: add -chuid support
git-svn-id: svn://busybox.net/trunk/busybox@17977 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--coreutils/chown.c20
-rw-r--r--debianutils/start_stop_daemon.c51
-rw-r--r--include/libbb.h3
-rw-r--r--include/usage.h2
-rw-r--r--libpwdgrp/uidgid_get.c36
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,
56int chown_main(int argc, char **argv); 56int chown_main(int argc, char **argv);
57int chown_main(int argc, char **argv) 57int 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
15static int signal_nr = 15; 15static int signal_nr = 15;
16static int user_id = -1; 16static int user_id = -1;
17static int quiet;
18static char *userspec; 17static char *userspec;
19static char *chuid;
20static char *cmdname; 18static char *cmdname;
21static char *execname; 19static char *execname;
22static char *pidfile; 20static char *pidfile;
21static smallint quiet;
23 22
24struct pid_list { 23struct pid_list {
25 struct pid_list *next; 24 struct pid_list *next;
@@ -222,20 +221,28 @@ static const struct option long_options[] = {
222enum { 221enum {
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
233int start_stop_daemon_main(int argc, char **argv); 239int start_stop_daemon_main(int argc, char **argv);
234int start_stop_daemon_main(int argc, char **argv) 240int 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 */
446int get_uidgid(struct bb_uidgid_t*, const char*, int numeric_ok); 447int get_uidgid(struct bb_uidgid_t*, const char*, int numeric_ok);
448/* chown-like handling of "user[:[group]" */
449void 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);*/
449char *bb_getpwuid(char *name, long uid, int bufsize); 452char *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 */
30int get_uidgid(struct bb_uidgid_t *u, const char *ug, int numeric_ok) 31int 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 */
87void 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>
80int main() 116int main()