aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--archival/rpm.c4
-rw-r--r--coreutils/chown.c28
-rw-r--r--coreutils/id.c4
-rw-r--r--coreutils/install.c82
-rw-r--r--debianutils/start_stop_daemon.c4
-rw-r--r--e2fsprogs/old_e2fsprogs/tune2fs.c4
-rw-r--r--include/libbb.h18
-rw-r--r--libbb/bb_pwd.c127
-rw-r--r--libpwdgrp/uidgid_get.c55
-rw-r--r--loginutils/adduser.c4
-rw-r--r--miscutils/makedevs.c4
-rw-r--r--runit/chpst.c4
12 files changed, 186 insertions, 152 deletions
diff --git a/archival/rpm.c b/archival/rpm.c
index c0a1deee2..deb87c180 100644
--- a/archival/rpm.c
+++ b/archival/rpm.c
@@ -348,8 +348,8 @@ static void fileaction_dobackup(char *filename, int fileref)
348static void fileaction_setowngrp(char *filename, int fileref) 348static void fileaction_setowngrp(char *filename, int fileref)
349{ 349{
350 int uid, gid; 350 int uid, gid;
351 uid = bb_xgetpwnam(rpm_getstr(TAG_FILEUSERNAME, fileref)); 351 uid = xuname2uid(rpm_getstr(TAG_FILEUSERNAME, fileref));
352 gid = bb_xgetgrnam(rpm_getstr(TAG_FILEGROUPNAME, fileref)); 352 gid = xgroup2gid(rpm_getstr(TAG_FILEGROUPNAME, fileref));
353 chown(filename, uid, gid); 353 chown(filename, uid, gid);
354} 354}
355 355
diff --git a/coreutils/chown.c b/coreutils/chown.c
index fddce7cf1..a45348a24 100644
--- a/coreutils/chown.c
+++ b/coreutils/chown.c
@@ -54,32 +54,38 @@ static int fileAction(const char *fileName, struct stat *statbuf,
54 54
55int chown_main(int argc, char **argv) 55int chown_main(int argc, char **argv)
56{ 56{
57 int retval = EXIT_SUCCESS;
58 char *groupName; 57 char *groupName;
58 int retval = EXIT_SUCCESS;
59 59
60 opt_complementary = "-2"; 60 opt_complementary = "-2";
61 getopt32(argc, argv, OPT_STR); 61 getopt32(argc, argv, OPT_STR);
62 argv += optind;
62 63
63 if (OPT_NODEREF) chown_func = lchown; 64 if (OPT_NODEREF) chown_func = lchown;
64 65
65 argv += optind;
66
67 /* First, check if there is a group name here */ 66 /* First, check if there is a group name here */
68 groupName = strchr(*argv, '.'); 67 groupName = strchr(*argv, '.'); /* deprecated? */
69 if (!groupName) { 68 if (!groupName) {
70 groupName = strchr(*argv, ':'); 69 groupName = strchr(*argv, ':');
71 } 70 }
72 71
73 /* Check for the username and groupname */ 72 /* First, try parsing "user[:[group]]" */
74 if (groupName) { 73 if (!groupName) { /* "user" */
75 *groupName++ = '\0'; 74 uid = get_ug_id(*argv, xuname2uid);
76 gid = get_ug_id(groupName, bb_xgetgrnam); 75 } else if (groupName == *argv) { /* ":group" */
76 gid = get_ug_id(groupName + 1, xgroup2gid);
77 } else {
78 struct bb_uidgid_t ugid;
79 if (!groupName[1]) /* "user:" */
80 *groupName = '\0';
81 if (!get_uidgid(&ugid, *argv, 1))
82 bb_error_msg_and_die("unknown user/group %s", *argv);
83 uid = ugid.uid;
84 gid = ugid.gid;
77 } 85 }
78 if (--groupName != *argv)
79 uid = get_ug_id(*argv, bb_xgetpwnam);
80 ++argv;
81 86
82 /* Ok, ready to do the deed now */ 87 /* Ok, ready to do the deed now */
88 argv++;
83 do { 89 do {
84 if (!recursive_action(*argv, 90 if (!recursive_action(*argv,
85 OPT_RECURSE, // recurse 91 OPT_RECURSE, // recurse
diff --git a/coreutils/id.c b/coreutils/id.c
index 66874a71e..35f945dba 100644
--- a/coreutils/id.c
+++ b/coreutils/id.c
@@ -62,8 +62,8 @@ int id_main(int argc, char **argv)
62 62
63 if (argv[optind]) { 63 if (argv[optind]) {
64 p = getpwnam(argv[optind]); 64 p = getpwnam(argv[optind]);
65 /* bb_xgetpwnam is needed because it exits on failure */ 65 /* xuname2uid is needed because it exits on failure */
66 uid = bb_xgetpwnam(argv[optind]); 66 uid = xuname2uid(argv[optind]);
67 gid = p->pw_gid; 67 gid = p->pw_gid;
68 /* in this case PRINT_REAL is the same */ 68 /* in this case PRINT_REAL is the same */
69 } 69 }
diff --git a/coreutils/install.c b/coreutils/install.c
index 3e003905e..aa7e8bf2b 100644
--- a/coreutils/install.c
+++ b/coreutils/install.c
@@ -13,58 +13,62 @@
13#include <libgen.h> 13#include <libgen.h>
14#include <getopt.h> /* struct option */ 14#include <getopt.h> /* struct option */
15 15
16#define INSTALL_OPT_CMD 1
17#define INSTALL_OPT_DIRECTORY 2
18#define INSTALL_OPT_PRESERVE_TIME 4
19#define INSTALL_OPT_STRIP 8
20#define INSTALL_OPT_GROUP 16
21#define INSTALL_OPT_MODE 32
22#define INSTALL_OPT_OWNER 64
23
24#if ENABLE_FEATURE_INSTALL_LONG_OPTIONS 16#if ENABLE_FEATURE_INSTALL_LONG_OPTIONS
25static const struct option install_long_options[] = { 17static const struct option install_long_options[] = {
26 { "directory", 0, NULL, 'd' }, 18 { "directory", 0, NULL, 'd' },
27 { "preserve-timestamps", 0, NULL, 'p' }, 19 { "preserve-timestamps", 0, NULL, 'p' },
28 { "strip", 0, NULL, 's' }, 20 { "strip", 0, NULL, 's' },
29 { "group", 0, NULL, 'g' }, 21 { "group", 0, NULL, 'g' },
30 { "mode", 0, NULL, 'm' }, 22 { "mode", 0, NULL, 'm' },
31 { "owner", 0, NULL, 'o' }, 23 { "owner", 0, NULL, 'o' },
32 { 0, 0, 0, 0 } 24 { 0, 0, 0, 0 }
33}; 25};
34#endif 26#endif
35 27
36int install_main(int argc, char **argv) 28int install_main(int argc, char **argv)
37{ 29{
30 struct stat statbuf;
38 mode_t mode; 31 mode_t mode;
39 uid_t uid; 32 uid_t uid;
40 gid_t gid; 33 gid_t gid;
41 char *gid_str = "-1"; 34 const char *gid_str;
42 char *uid_str = "-1"; 35 const char *uid_str;
43 char *mode_str = "0755"; 36 const char *mode_str;
44 int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE; 37 int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE;
45 int ret = EXIT_SUCCESS, flags, i, isdir; 38 int ret = EXIT_SUCCESS, flags, i, isdir;
46 39
40 enum {
41 OPT_CMD = 0x1,
42 OPT_DIRECTORY = 0x2,
43 OPT_PRESERVE_TIME = 0x4,
44 OPT_STRIP = 0x8,
45 OPT_GROUP = 0x10,
46 OPT_MODE = 0x20,
47 OPT_OWNER = 0x40,
48 };
49
47#if ENABLE_FEATURE_INSTALL_LONG_OPTIONS 50#if ENABLE_FEATURE_INSTALL_LONG_OPTIONS
48 applet_long_options = install_long_options; 51 applet_long_options = install_long_options;
49#endif 52#endif
50 opt_complementary = "?:s--d:d--s"; 53 opt_complementary = "?:s--d:d--s";
51 /* -c exists for backwards compatibility, its needed */ 54 /* -c exists for backwards compatibility, its needed */
52 flags = getopt32(argc, argv, "cdpsg:m:o:", &gid_str, &mode_str, &uid_str); /* 'a' must be 2nd */ 55 flags = getopt32(argc, argv, "cdpsg:m:o:", &gid_str, &mode_str, &uid_str);
53 56
54 /* preserve access and modification time, this is GNU behaviour, BSD only preserves modification time */ 57 /* preserve access and modification time, this is GNU behaviour, BSD only preserves modification time */
55 if (flags & INSTALL_OPT_PRESERVE_TIME) { 58 if (flags & OPT_PRESERVE_TIME) {
56 copy_flags |= FILEUTILS_PRESERVE_STATUS; 59 copy_flags |= FILEUTILS_PRESERVE_STATUS;
57 } 60 }
58 bb_parse_mode(mode_str, &mode); 61 mode = 0666;
59 gid = get_ug_id(gid_str, bb_xgetgrnam); 62 if (flags & OPT_MODE) bb_parse_mode(mode_str, &mode);
60 uid = get_ug_id(uid_str, bb_xgetpwnam); 63 uid = (flags & OPT_OWNER) ? get_ug_id(uid_str, xuname2uid) : getuid();
61 umask(0); 64 gid = (flags & OPT_GROUP) ? get_ug_id(gid_str, xgroup2gid) : getgid();
65 if (flags & (OPT_OWNER|OPT_GROUP)) umask(0);
62 66
63 /* Create directories 67 /* Create directories
64 * don't use bb_make_directory() as it can't change uid or gid 68 * don't use bb_make_directory() as it can't change uid or gid
65 * perhaps bb_make_directory() should be improved. 69 * perhaps bb_make_directory() should be improved.
66 */ 70 */
67 if (flags & INSTALL_OPT_DIRECTORY) { 71 if (flags & OPT_DIRECTORY) {
68 for (argv += optind; *argv; argv++) { 72 for (argv += optind; *argv; argv++) {
69 char *old_argv_ptr = *argv + 1; 73 char *old_argv_ptr = *argv + 1;
70 char *argv_ptr; 74 char *argv_ptr;
@@ -75,14 +79,16 @@ int install_main(int argc, char **argv)
75 *argv_ptr = '\0'; 79 *argv_ptr = '\0';
76 old_argv_ptr++; 80 old_argv_ptr++;
77 } 81 }
78 if (mkdir(*argv, mode) == -1) { 82 if (mkdir(*argv, mode | 0111) == -1) {
79 if (errno != EEXIST) { 83 if (errno != EEXIST) {
80 bb_perror_msg("cannot create %s", *argv); 84 bb_perror_msg("cannot create %s", *argv);
81 ret = EXIT_FAILURE; 85 ret = EXIT_FAILURE;
82 break; 86 break;
83 } 87 }
84 } 88 }
85 else if (lchown(*argv, uid, gid) == -1) { 89 if ((flags & (OPT_OWNER|OPT_GROUP))
90 && lchown(*argv, uid, gid) == -1
91 ) {
86 bb_perror_msg("cannot change ownership of %s", *argv); 92 bb_perror_msg("cannot change ownership of %s", *argv);
87 ret = EXIT_FAILURE; 93 ret = EXIT_FAILURE;
88 break; 94 break;
@@ -95,36 +101,36 @@ int install_main(int argc, char **argv)
95 return ret; 101 return ret;
96 } 102 }
97 103
98 { 104 isdir = lstat(argv[argc - 1], &statbuf) < 0 ? 0 : S_ISDIR(statbuf.st_mode);
99 struct stat statbuf; 105
100 isdir = lstat(argv[argc - 1], &statbuf)<0
101 ? 0 : S_ISDIR(statbuf.st_mode);
102 }
103 for (i = optind; i < argc - 1; i++) { 106 for (i = optind; i < argc - 1; i++) {
104 char *dest; 107 char *dest;
105 108
106 dest = argv[argc - 1]; 109 dest = argv[argc - 1];
107 if (isdir) dest = concat_path_file(argv[argc - 1], basename(argv[i])); 110 if (isdir)
111 dest = concat_path_file(argv[argc - 1], basename(argv[i]));
108 ret |= copy_file(argv[i], dest, copy_flags); 112 ret |= copy_file(argv[i], dest, copy_flags);
109 113
110 /* Set the file mode */ 114 /* Set the file mode */
111 if (chmod(dest, mode) == -1) { 115 if ((flags & OPT_MODE) && chmod(dest, mode) == -1) {
112 bb_perror_msg("cannot change permissions of %s", dest); 116 bb_perror_msg("cannot change permissions of %s", dest);
113 ret = EXIT_FAILURE; 117 ret = EXIT_FAILURE;
114 } 118 }
115 119
116 /* Set the user and group id */ 120 /* Set the user and group id */
117 if (lchown(dest, uid, gid) == -1) { 121 if ((flags & (OPT_OWNER|OPT_GROUP))
122 && lchown(dest, uid, gid) == -1
123 ) {
118 bb_perror_msg("cannot change ownership of %s", dest); 124 bb_perror_msg("cannot change ownership of %s", dest);
119 ret = EXIT_FAILURE; 125 ret = EXIT_FAILURE;
120 } 126 }
121 if (flags & INSTALL_OPT_STRIP) { 127 if (flags & OPT_STRIP) {
122 if (execlp("strip", "strip", dest, NULL) == -1) { 128 if (execlp("strip", "strip", dest, NULL) == -1) {
123 bb_error_msg("strip failed"); 129 bb_perror_msg("strip");
124 ret = EXIT_FAILURE; 130 ret = EXIT_FAILURE;
125 } 131 }
126 } 132 }
127 if(ENABLE_FEATURE_CLEAN_UP && isdir) free(dest); 133 if (ENABLE_FEATURE_CLEAN_UP && isdir) free(dest);
128 } 134 }
129 135
130 return ret; 136 return ret;
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c
index d1f5e94c0..521b43d04 100644
--- a/debianutils/start_stop_daemon.c
+++ b/debianutils/start_stop_daemon.c
@@ -274,7 +274,7 @@ int start_stop_daemon_main(int argc, char **argv)
274 if (userspec) { 274 if (userspec) {
275 user_id = bb_strtou(userspec, NULL, 10); 275 user_id = bb_strtou(userspec, NULL, 10);
276 if (errno) 276 if (errno)
277 user_id = bb_xgetpwnam(userspec); 277 user_id = xuname2uid(userspec);
278 } 278 }
279 279
280 if (opt & CTX_STOP) { 280 if (opt & CTX_STOP) {
@@ -305,7 +305,7 @@ int start_stop_daemon_main(int argc, char **argv)
305 if (chuid) { 305 if (chuid) {
306 user_id = bb_strtou(chuid, NULL, 10); 306 user_id = bb_strtou(chuid, NULL, 10);
307 if (errno) 307 if (errno)
308 user_id = bb_xgetpwnam(chuid); 308 user_id = xuname2uid(chuid);
309 xsetuid(user_id); 309 xsetuid(user_id);
310 } 310 }
311#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY 311#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
diff --git a/e2fsprogs/old_e2fsprogs/tune2fs.c b/e2fsprogs/old_e2fsprogs/tune2fs.c
index a2ca1ba09..c4e084ecd 100644
--- a/e2fsprogs/old_e2fsprogs/tune2fs.c
+++ b/e2fsprogs/old_e2fsprogs/tune2fs.c
@@ -441,7 +441,7 @@ static void parse_tune2fs_options(int argc, char **argv)
441 case 'g': 441 case 'g':
442 resgid = bb_strtoul(optarg, NULL, 10); 442 resgid = bb_strtoul(optarg, NULL, 10);
443 if (errno) 443 if (errno)
444 resgid = bb_xgetgrnam(optarg); 444 resgid = xgroup2gid(optarg);
445 g_flag = 1; 445 g_flag = 1;
446 open_flag = EXT2_FLAG_RW; 446 open_flag = EXT2_FLAG_RW;
447 break; 447 break;
@@ -535,7 +535,7 @@ static void parse_tune2fs_options(int argc, char **argv)
535 case 'u': 535 case 'u':
536 resuid = bb_strtoul(optarg, NULL, 10); 536 resuid = bb_strtoul(optarg, NULL, 10);
537 if (errno) 537 if (errno)
538 resuid = bb_xgetpwnam(optarg); 538 resuid = xuname2uid(optarg);
539 u_flag = 1; 539 u_flag = 1;
540 open_flag = EXT2_FLAG_RW; 540 open_flag = EXT2_FLAG_RW;
541 break; 541 break;
diff --git a/include/libbb.h b/include/libbb.h
index a2b9a82b2..ece1c9d91 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -338,17 +338,20 @@ uint16_t xatou16(const char *numstr);
338/* These parse entries in /etc/passwd and /etc/group. This is desirable 338/* These parse entries in /etc/passwd and /etc/group. This is desirable
339 * for BusyBox since we want to avoid using the glibc NSS stuff, which 339 * for BusyBox since we want to avoid using the glibc NSS stuff, which
340 * increases target size and is often not needed on embedded systems. */ 340 * increases target size and is often not needed on embedded systems. */
341extern long bb_xgetpwnam(const char *name); 341extern long xuname2uid(const char *name);
342extern long bb_xgetgrnam(const char *name); 342extern long xgroup2gid(const char *name);
343/*extern char *bb_getug(char *buffer, char *idname, long id, int bufsize, char prefix);*/ 343/* wrapper: allows string to contain numeric uid or gid */
344extern char *bb_getpwuid(char *name, long uid, int bufsize); 344extern unsigned long get_ug_id(const char *s, long (*xname2id)(const char *));
345extern char *bb_getgrgid(char *group, long gid, int bufsize); 345/* from chpst. Does not die, returns 0 on failure */
346/* from chpst */
347struct bb_uidgid_t { 346struct bb_uidgid_t {
348 uid_t uid; 347 uid_t uid;
349 gid_t gid; 348 gid_t gid;
350}; 349};
351extern unsigned uidgid_get(struct bb_uidgid_t*, const char* /*, unsigned*/); 350extern int get_uidgid(struct bb_uidgid_t*, const char*, int numeric_ok);
351/* what is this? */
352/*extern char *bb_getug(char *buffer, char *idname, long id, int bufsize, char prefix);*/
353extern char *bb_getpwuid(char *name, long uid, int bufsize);
354extern char *bb_getgrgid(char *group, long gid, int bufsize);
352 355
353 356
354enum { BB_GETOPT_ERROR = 0x80000000 }; 357enum { BB_GETOPT_ERROR = 0x80000000 };
@@ -484,7 +487,6 @@ extern void vfork_daemon_rexec(int nochdir, int noclose,
484 int argc, char **argv, char *foreground_opt); 487 int argc, char **argv, char *foreground_opt);
485#endif 488#endif
486extern int get_terminal_width_height(int fd, int *width, int *height); 489extern int get_terminal_width_height(int fd, int *width, int *height);
487extern unsigned long get_ug_id(const char *s, long (*__bb_getxxnam)(const char *));
488 490
489int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name); 491int is_in_ino_dev_hashtable(const struct stat *statbuf, char **name);
490void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name); 492void add_to_ino_dev_hashtable(const struct stat *statbuf, const char *name);
diff --git a/libbb/bb_pwd.c b/libbb/bb_pwd.c
index b5125b0f4..223a6b44c 100644
--- a/libbb/bb_pwd.c
+++ b/libbb/bb_pwd.c
@@ -7,31 +7,30 @@
7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. 7 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
8 */ 8 */
9 9
10#include <stdio.h>
11#include <string.h>
12#include <assert.h>
13#include "libbb.h" 10#include "libbb.h"
14 11
15 /* 12#define assert(x) ((void)0)
16 * if bufsize is > 0 char *buffer cannot be set to NULL. 13
17 * If idname is not NULL it is written on the static 14/*
18 * allocated buffer (and a pointer to it is returned). 15 * if bufsize is > 0 char *buffer cannot be set to NULL.
19 * if idname is NULL, id as string is written to the static 16 * If idname is not NULL it is written on the static
20 * allocated buffer and NULL is returned. 17 * allocated buffer (and a pointer to it is returned).
21 * if bufsize is = 0 char *buffer can be set to NULL. 18 * if idname is NULL, id as string is written to the static
22 * If idname exists a pointer to it is returned, 19 * allocated buffer and NULL is returned.
23 * else NULL is returned. 20 * if bufsize is = 0 char *buffer can be set to NULL.
24 * if bufsize is < 0 char *buffer can be set to NULL. 21 * If idname exists a pointer to it is returned,
25 * If idname exists a pointer to it is returned, 22 * else NULL is returned.
26 * else an error message is printed and the program exits. 23 * if bufsize is < 0 char *buffer can be set to NULL.
27 */ 24 * If idname exists a pointer to it is returned,
25 * else an error message is printed and the program exits.
26 */
28 27
29/* internal function for bb_getpwuid and bb_getgrgid */ 28/* internal function for bb_getpwuid and bb_getgrgid */
30static char * bb_getug(char *buffer, char *idname, long id, int bufsize, char prefix) 29static char* bb_getug(char *buffer, char *idname, long id, int bufsize, char prefix)
31{ 30{
32 if (bufsize > 0 ) { 31 if (bufsize > 0 ) {
33 assert(buffer!=NULL); 32 assert(buffer != NULL);
34 if(idname) { 33 if (idname) {
35 return safe_strncpy(buffer, idname, bufsize); 34 return safe_strncpy(buffer, idname, bufsize);
36 } 35 }
37 snprintf(buffer, bufsize, "%ld", id); 36 snprintf(buffer, bufsize, "%ld", id);
@@ -41,75 +40,76 @@ static char * bb_getug(char *buffer, char *idname, long id, int bufsize, char pr
41 return idname; 40 return idname;
42} 41}
43 42
44 /* Hacked by Tito Ragusa (c) 2004 <farmatito@tiscali.it> to make it more 43/* Hacked by Tito Ragusa (c) 2004 <farmatito@tiscali.it> to make it more
45 * flexible : 44 * flexible :
46 * 45 *
47 * if bufsize is > 0 char *group cannot be set to NULL. 46 * if bufsize is > 0 char *group cannot be set to NULL.
48 * On success groupname is written on static allocated buffer 47 * On success groupname is written on static allocated buffer
49 * group (and a pointer to it is returned). 48 * group (and a pointer to it is returned).
50 * On failure gid as string is written to static allocated 49 * On failure gid as string is written to static allocated
51 * buffer group and NULL is returned. 50 * buffer group and NULL is returned.
52 * if bufsize is = 0 char *group can be set to NULL. 51 * if bufsize is = 0 char *group can be set to NULL.
53 * On success groupname is returned. 52 * On success groupname is returned.
54 * On failure NULL is returned. 53 * On failure NULL is returned.
55 * if bufsize is < 0 char *group can be set to NULL. 54 * if bufsize is < 0 char *group can be set to NULL.
56 * On success groupname is returned. 55 * On success groupname is returned.
57 * On failure an error message is printed and 56 * On failure an error message is printed and
58 * the program exits. 57 * the program exits.
59 */ 58 */
60 59
61/* gets a groupname given a gid */ 60/* gets a groupname given a gid */
62char * bb_getgrgid(char *group, long gid, int bufsize) 61char* bb_getgrgid(char *group, long gid, int bufsize)
63{ 62{
64 struct group *mygroup = getgrgid(gid); 63 struct group *mygroup = getgrgid(gid);
65 64
66 return bb_getug(group, (mygroup) ? 65 return bb_getug(group,
67 mygroup->gr_name : (char *)mygroup, gid, bufsize, 'g'); 66 mygroup ? mygroup->gr_name : (char *)mygroup,
67 gid, bufsize, 'g');
68} 68}
69 69
70/* returns a gid given a group name */ 70/* returns a gid given a group name */
71long bb_xgetgrnam(const char *name) 71long xgroup2gid(const char *name)
72{ 72{
73 struct group *mygroup; 73 struct group *mygroup;
74 74
75 mygroup = getgrnam(name); 75 mygroup = getgrnam(name);
76 if (mygroup==NULL) 76 if (mygroup == NULL)
77 bb_error_msg_and_die("unknown group name: %s", name); 77 bb_error_msg_and_die("unknown group name: %s", name);
78 78
79 return mygroup->gr_gid; 79 return mygroup->gr_gid;
80} 80}
81 81
82/* returns a uid given a username */ 82/* returns a uid given a username */
83long bb_xgetpwnam(const char *name) 83long xuname2uid(const char *name)
84{ 84{
85 struct passwd *myuser; 85 struct passwd *myuser;
86 86
87 myuser = getpwnam(name); 87 myuser = getpwnam(name);
88 if (myuser==NULL) 88 if (myuser == NULL)
89 bb_error_msg_and_die("unknown user name: %s", name); 89 bb_error_msg_and_die("unknown user name: %s", name);
90 90
91 return myuser->pw_uid; 91 return myuser->pw_uid;
92} 92}
93 93
94 /* Hacked by Tito Ragusa (c) 2004 <farmatito@tiscali.it> to make it more 94/* Hacked by Tito Ragusa (c) 2004 <farmatito@tiscali.it> to make it more
95 * flexible : 95 * flexible :
96 * 96 *
97 * if bufsize is > 0 char *name cannot be set to NULL. 97 * if bufsize is > 0 char *name cannot be set to NULL.
98 * On success username is written on the static allocated 98 * On success username is written on the static allocated
99 * buffer name (and a pointer to it is returned). 99 * buffer name (and a pointer to it is returned).
100 * On failure uid as string is written to the static 100 * On failure uid as string is written to the static
101 * allocated buffer name and NULL is returned. 101 * allocated buffer name and NULL is returned.
102 * if bufsize is = 0 char *name can be set to NULL. 102 * if bufsize is = 0 char *name can be set to NULL.
103 * On success username is returned. 103 * On success username is returned.
104 * On failure NULL is returned. 104 * On failure NULL is returned.
105 * if bufsize is < 0 char *name can be set to NULL 105 * if bufsize is < 0 char *name can be set to NULL
106 * On success username is returned. 106 * On success username is returned.
107 * On failure an error message is printed and 107 * On failure an error message is printed and
108 * the program exits. 108 * the program exits.
109 */ 109 */
110 110
111/* gets a username given a uid */ 111/* gets a username given a uid */
112char * bb_getpwuid(char *name, long uid, int bufsize) 112char* bb_getpwuid(char *name, long uid, int bufsize)
113{ 113{
114 struct passwd *myuser = getpwuid(uid); 114 struct passwd *myuser = getpwuid(uid);
115 115
@@ -118,13 +118,12 @@ char * bb_getpwuid(char *name, long uid, int bufsize)
118} 118}
119 119
120unsigned long get_ug_id(const char *s, 120unsigned long get_ug_id(const char *s,
121 long (*__bb_getxxnam)(const char *)) 121 long (*xname2id)(const char *))
122{ 122{
123 unsigned long r; 123 unsigned long r;
124 124
125 r = bb_strtoul(s, NULL, 10); 125 r = bb_strtoul(s, NULL, 10);
126 if (errno) 126 if (errno)
127 r = __bb_getxxnam(s); 127 return xname2id(s);
128
129 return r; 128 return r;
130} 129}
diff --git a/libpwdgrp/uidgid_get.c b/libpwdgrp/uidgid_get.c
index a2d02a84f..32cbd21b9 100644
--- a/libpwdgrp/uidgid_get.c
+++ b/libpwdgrp/uidgid_get.c
@@ -1,26 +1,47 @@
1#include "busybox.h" 1#include "busybox.h"
2 2
3unsigned uidgid_get(struct bb_uidgid_t *u, const char *ug /*, unsigned dogrp */) 3int get_uidgid(struct bb_uidgid_t *u, const char *ug, int numeric_ok)
4{ 4{
5 struct passwd *pwd; 5 struct passwd *pwd;
6 struct group *gr; 6 struct group *gr;
7 const char *g; 7 char *user, *group;
8 unsigned n;
8 9
9 /* g = 0; if (dogrp) g = strchr(ug, ':'); */ 10 user = (char*)ug;
10 g = strchr(ug, ':'); 11 group = strchr(ug, ':');
11 if (g) { 12 if (group) {
12 int sz = (++g) - ug; 13 int sz = (++group) - ug;
13 char buf[sz]; 14 user = alloca(sz);
14 safe_strncpy(buf, ug, sz); 15 /* copies sz-1 bytes, stores terminating '\0' */
15 pwd = getpwnam(buf); 16 safe_strncpy(user, ug, sz);
16 } else 17 }
17 pwd = getpwnam(ug); 18 if (numeric_ok) {
19 n = bb_strtou(user, NULL, 10);
20 if (!errno) {
21 u->uid = n;
22 pwd = getpwuid(n);
23 /* If we have e.g. "500" string without user */
24 /* with uid 500 in /etc/passwd, we set gid == uid */
25 u->gid = pwd ? pwd->pw_gid : n;
26 goto skip;
27 }
28 }
29 pwd = getpwnam(user);
18 if (!pwd) 30 if (!pwd)
19 return 0; 31 return 0;
20 u->uid = pwd->pw_uid; 32 u->uid = pwd->pw_uid;
21 u->gid = pwd->pw_gid; 33 u->gid = pwd->pw_gid;
22 if (g) { 34
23 gr = getgrnam(g); 35 skip:
36 if (group) {
37 if (numeric_ok) {
38 n = bb_strtou(group, NULL, 10);
39 if (!errno) {
40 u->gid = n;
41 return 1;
42 }
43 }
44 gr = getgrnam(group);
24 if (!gr) return 0; 45 if (!gr) return 0;
25 u->gid = gr->gr_gid; 46 u->gid = gr->gr_gid;
26 } 47 }
@@ -33,16 +54,16 @@ int main()
33{ 54{
34 unsigned u; 55 unsigned u;
35 struct bb_uidgid_t ug; 56 struct bb_uidgid_t ug;
36 u = uidgid_get(&ug, "apache"); 57 u = get_uidgid(&ug, "apache", 0);
37 printf("%u = %u:%u\n", u, ug.uid, ug.gid); 58 printf("%u = %u:%u\n", u, ug.uid, ug.gid);
38 ug.uid = ug.gid = 1111; 59 ug.uid = ug.gid = 1111;
39 u = uidgid_get(&ug, "apache"); 60 u = get_uidgid(&ug, "apache", 0);
40 printf("%u = %u:%u\n", u, ug.uid, ug.gid); 61 printf("%u = %u:%u\n", u, ug.uid, ug.gid);
41 ug.uid = ug.gid = 1111; 62 ug.uid = ug.gid = 1111;
42 u = uidgid_get(&ug, "apache:users"); 63 u = get_uidgid(&ug, "apache:users", 0);
43 printf("%u = %u:%u\n", u, ug.uid, ug.gid); 64 printf("%u = %u:%u\n", u, ug.uid, ug.gid);
44 ug.uid = ug.gid = 1111; 65 ug.uid = ug.gid = 1111;
45 u = uidgid_get(&ug, "apache:users"); 66 u = get_uidgid(&ug, "apache:users", 0);
46 printf("%u = %u:%u\n", u, ug.uid, ug.gid); 67 printf("%u = %u:%u\n", u, ug.uid, ug.gid);
47 return 0; 68 return 0;
48} 69}
diff --git a/loginutils/adduser.c b/loginutils/adduser.c
index 418d4c785..5766e5de3 100644
--- a/loginutils/adduser.c
+++ b/loginutils/adduser.c
@@ -157,7 +157,7 @@ static int adduser(struct passwd *p, unsigned long flags)
157 * gecos 157 * gecos
158 * 158 *
159 * can be customized via command-line parameters. 159 * can be customized via command-line parameters.
160 * ________________________________________________________________________ */ 160 */
161int adduser_main(int argc, char **argv) 161int adduser_main(int argc, char **argv)
162{ 162{
163 struct passwd pw; 163 struct passwd pw;
@@ -187,7 +187,7 @@ int adduser_main(int argc, char **argv)
187 pw.pw_name = argv[optind]; 187 pw.pw_name = argv[optind];
188 pw.pw_passwd = "x"; 188 pw.pw_passwd = "x";
189 pw.pw_uid = 0; 189 pw.pw_uid = 0;
190 pw.pw_gid = (usegroup) ? bb_xgetgrnam(usegroup) : 0; /* exits on failure */ 190 pw.pw_gid = usegroup ? xgroup2gid(usegroup) : 0; /* exits on failure */
191 191
192 /* grand finale */ 192 /* grand finale */
193 return adduser(&pw, flags); 193 return adduser(&pw, flags);
diff --git a/miscutils/makedevs.c b/miscutils/makedevs.c
index 3bc1559c7..c25bdadc4 100644
--- a/miscutils/makedevs.c
+++ b/miscutils/makedevs.c
@@ -127,8 +127,8 @@ int makedevs_main(int argc, char **argv)
127 continue; 127 continue;
128 } 128 }
129 129
130 gid = (*group) ? get_ug_id(group, bb_xgetgrnam) : getgid(); 130 gid = (*group) ? get_ug_id(group, xgroup2gid) : getgid();
131 uid = (*user) ? get_ug_id(user, bb_xgetpwnam) : getuid(); 131 uid = (*user) ? get_ug_id(user, xuname2uid) : getuid();
132 full_name = concat_path_file(rootdir, name); 132 full_name = concat_path_file(rootdir, name);
133 133
134 if (type == 'd') { 134 if (type == 'd') {
diff --git a/runit/chpst.c b/runit/chpst.c
index f8e63031f..14b8b5a15 100644
--- a/runit/chpst.c
+++ b/runit/chpst.c
@@ -59,7 +59,7 @@ static void suidgid(char *user)
59{ 59{
60 struct bb_uidgid_t ugid; 60 struct bb_uidgid_t ugid;
61 61
62 if (!uidgid_get(&ugid, user)) { 62 if (!get_uidgid(&ugid, user, 1)) {
63 bb_error_msg_and_die("unknown user/group: %s", user); 63 bb_error_msg_and_die("unknown user/group: %s", user);
64 } 64 }
65 if (setgroups(1, &ugid.gid) == -1) 65 if (setgroups(1, &ugid.gid) == -1)
@@ -72,7 +72,7 @@ static void euidgid(char *user)
72{ 72{
73 struct bb_uidgid_t ugid; 73 struct bb_uidgid_t ugid;
74 74
75 if (!uidgid_get(&ugid, user)) { 75 if (!get_uidgid(&ugid, user, 1)) {
76 bb_error_msg_and_die("unknown user/group: %s", user); 76 bb_error_msg_and_die("unknown user/group: %s", user);
77 } 77 }
78 xsetenv("GID", utoa(ugid.gid)); 78 xsetenv("GID", utoa(ugid.gid));