From ab050f5522e843bf08994685134adaaac7ffd392 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Sat, 27 Jan 2001 06:01:43 +0000 Subject: [PATCH] Add in a patch to make busybox use the normal pwd.h and grp.h functions. Add in simple implementations of these functions, which can, optionally, be used instead of the system versions. -Erik --- Makefile | 28 +++++++++- chmod_chown_chgrp.c | 2 - cmdedit.c | 10 +--- coreutils/id.c | 2 - coreutils/uudecode.c | 1 - coreutils/uuencode.c | 1 - coreutils/whoami.c | 1 - id.c | 2 - include/grp.h | 47 ++++++++++++++++ include/pwd.h | 51 +++++++++++++++++ shell/cmdedit.c | 10 +--- utility.c | 129 +++++++++++++++---------------------------- uudecode.c | 1 - uuencode.c | 1 - whoami.c | 1 - 15 files changed, 174 insertions(+), 113 deletions(-) create mode 100644 include/grp.h create mode 100644 include/pwd.h diff --git a/Makefile b/Makefile index 285f3ab66..d5587ae4f 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,17 @@ DOSTATIC = false # Do not enable this for production builds... DODEBUG = false +# Setting this to `true' will cause busybox to directly use the system's +# password and group functions. Assuming you use GNU libc, when this is +# `true', you will need to install the /etc/nsswitch.conf configuration file +# and the required libnss_* libraries. This generally makes your embedded +# system quite a bit larger... If you leave this off, busybox will directly +# use the /etc/password, /etc/group files (and your system will be smaller, and +# I will get fewer emails asking about how glibc NSS works). Enabling this adds +# just 1.4k to the binary size (which is a _lot_ less then glibc NSS costs), +# Most people will want to leave this set to false. +USE_SYSTEM_PWD_GRP = false + # This enables compiling with dmalloc ( http://dmalloc.com/ ) # which is an excellent public domain mem leak and malloc problem # detector. To enable dmalloc, before running busybox you will @@ -158,10 +169,20 @@ ifdef BB_INIT_SCRIPT CFLAGS += -DINIT_SCRIPT='"$(BB_INIT_SCRIPT)"' endif +ifneq ($(USE_SYSTEM_PWD_GRP),true) + PWD_LIB = pwd_grp/libpwd.a + LIBRARIES += $(PWD_LIB) +else + CFLAGS += -DUSE_SYSTEM_PWD_GRP +endif + + # Put user-supplied flags at the end, where they # have a chance of winning. CFLAGS += $(CFLAGS_EXTRA) +.EXPORT_ALL_VARIABLES: + all: busybox busybox.links doc doc: olddoc @@ -220,15 +241,19 @@ docs/busybox/busyboxdocumentation.html: docs/busybox.sgml -busybox: $(OBJECTS) +busybox: $(PWD_LIB) $(OBJECTS) $(CC) $(LDFLAGS) -o $@ $^ $(LIBRARIES) $(STRIP) +$(PWD_LIB): + $(MAKE) -eC pwd_grp + busybox.links: Config.h applets.h - $(BB_SRC_DIR)/busybox.mkll $(CONFIG_H) $(BB_SRC_DIR)/applets.h >$@ nfsmount.o cmdedit.o: %.o: %.h $(OBJECTS): %.o: %.c Config.h busybox.h applets.h Makefile + $(CC) $(CFLAGS) -c $*.c -o $*.o utility.o: loop.h @@ -240,6 +265,7 @@ test tests: clean: - cd tests && $(MAKE) clean + - cd pwd_grp && $(MAKE) clean - rm -f docs/BusyBox.txt docs/BusyBox.1 docs/BusyBox.html \ docs/busybox.lineo.com/BusyBox.html - rm -f docs/busybox.txt docs/busybox.dvi docs/busybox.ps \ diff --git a/chmod_chown_chgrp.c b/chmod_chown_chgrp.c index 530c45658..f6ecfd6f8 100644 --- a/chmod_chown_chgrp.c +++ b/chmod_chown_chgrp.c @@ -29,8 +29,6 @@ #include "messages.c" #include -#include -#include static long uid = -1; diff --git a/cmdedit.c b/cmdedit.c index c2b4123db..e043d5f52 100644 --- a/cmdedit.c +++ b/cmdedit.c @@ -54,10 +54,6 @@ #include #endif -#ifdef BB_FEATURE_USERNAME_COMPLETION -#include -#endif - static const int MAX_HISTORY = 15; /* Maximum length of the linked list for the command line history */ enum { @@ -354,10 +350,10 @@ static char** username_tab_completion(char *ud, int *num_matches) char *temp; int nm = 0; - setpwent (); + bb_setpwent (); userlen = strlen (ud + 1); - while ((entry = getpwent ()) != NULL) { + while ((entry = bb_getpwent ()) != NULL) { /* Null usernames should result in all users as possible completions. */ if (!userlen || !strncmp (ud + 1, entry->pw_name, userlen)) { @@ -369,7 +365,7 @@ static char** username_tab_completion(char *ud, int *num_matches) } } - endpwent (); + bb_endpwent (); (*num_matches) = nm; return (matches); } diff --git a/coreutils/id.c b/coreutils/id.c index 59cfafa0a..d50de4775 100644 --- a/coreutils/id.c +++ b/coreutils/id.c @@ -23,8 +23,6 @@ #include "busybox.h" #include #include -#include -#include #include #include diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c index 279b9d6ce..7b26d2dad 100644 --- a/coreutils/uudecode.c +++ b/coreutils/uudecode.c @@ -27,7 +27,6 @@ #include #include #include -#include /*struct passwd *getpwnam();*/ diff --git a/coreutils/uuencode.c b/coreutils/uuencode.c index 36bc4970f..24aabd373 100644 --- a/coreutils/uuencode.c +++ b/coreutils/uuencode.c @@ -27,7 +27,6 @@ #include #include #include -#include #define RW (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) diff --git a/coreutils/whoami.c b/coreutils/whoami.c index 38a2b3078..d7f0a177c 100644 --- a/coreutils/whoami.c +++ b/coreutils/whoami.c @@ -22,7 +22,6 @@ #include "busybox.h" #include -#include extern int whoami_main(int argc, char **argv) { diff --git a/id.c b/id.c index 59cfafa0a..d50de4775 100644 --- a/id.c +++ b/id.c @@ -23,8 +23,6 @@ #include "busybox.h" #include #include -#include -#include #include #include diff --git a/include/grp.h b/include/grp.h new file mode 100644 index 000000000..f27c466fd --- /dev/null +++ b/include/grp.h @@ -0,0 +1,47 @@ +#ifndef __BB_GRP_H +#define __BB_GRP_H + +#if defined USE_SYSTEM_PWD_GRP +#include +#else + +#define bb_setgrent setgrent +#define bb_endgrent endgrent +#define bb_getgrent getgrent +#define bb_getgrgid getgrgid +#define bb_getgrnam getgrnam +#define bb_fgetgrent fgetgrent +#define bb_setgroups setgroups +#define bb_initgroups initgroups +#define __bb_getgrent __getgrent + +#include +#include +#include + +/* The group structure */ +struct group +{ + char *gr_name; /* Group name. */ + char *gr_passwd; /* Password. */ + gid_t gr_gid; /* Group ID. */ + char **gr_mem; /* Member list. */ +}; + +extern void bb_setgrent __P ((void)); +extern void bb_endgrent __P ((void)); +extern struct group * bb_getgrent __P ((void)); + +extern struct group * bb_getgrgid __P ((__const gid_t gid)); +extern struct group * bb_getgrnam __P ((__const char * name)); + +extern struct group * bb_fgetgrent __P ((FILE * file)); + +extern int bb_setgroups __P ((size_t n, __const gid_t * groups)); +extern int bb_initgroups __P ((__const char * user, gid_t gid)); + +extern struct group * __bb_getgrent __P ((int grp_fd)); + +#endif /* USE_SYSTEM_PWD_GRP */ +#endif /* __BB_GRP_H */ + diff --git a/include/pwd.h b/include/pwd.h new file mode 100644 index 000000000..82743f5ad --- /dev/null +++ b/include/pwd.h @@ -0,0 +1,51 @@ +#ifndef __BB_PWD_H +#define __BB_PWD_H + +#if defined USE_SYSTEM_PWD_GRP +#include +#else + +#define bb_setpwent setpwent +#define bb_endpwent endpwent +#define bb_getpwent getpwent +#define bb_putpwent putpwent +#define bb_getpw getpw +#define bb_fgetpwent fgetpwent +#define bb_getpwuid getpwuid +#define bb_getpwnam getpwnam +#define __bb_getpwent __bb_getpwent + + +#include +#include +#include + +/* The passwd structure. */ +struct passwd +{ + char *pw_name; /* Username. */ + char *pw_passwd; /* Password. */ + uid_t pw_uid; /* User ID. */ + gid_t pw_gid; /* Group ID. */ + char *pw_gecos; /* Real name. */ + char *pw_dir; /* Home directory. */ + char *pw_shell; /* Shell program. */ +}; + +extern void bb_setpwent __P ((void)); +extern void bb_endpwent __P ((void)); +extern struct passwd * bb_getpwent __P ((void)); + +extern int bb_putpwent __P ((__const struct passwd * __p, FILE * __f)); +extern int bb_getpw __P ((uid_t uid, char *buf)); + +extern struct passwd * bb_fgetpwent __P ((FILE * file)); + +extern struct passwd * bb_getpwuid __P ((__const uid_t)); +extern struct passwd * bb_getpwnam __P ((__const char *)); + +extern struct passwd * __bb_getpwent __P ((__const int passwd_fd)); + +#endif /* USE_SYSTEM_PWD_GRP */ +#endif /* __BB_PWD_H */ + diff --git a/shell/cmdedit.c b/shell/cmdedit.c index c2b4123db..e043d5f52 100644 --- a/shell/cmdedit.c +++ b/shell/cmdedit.c @@ -54,10 +54,6 @@ #include #endif -#ifdef BB_FEATURE_USERNAME_COMPLETION -#include -#endif - static const int MAX_HISTORY = 15; /* Maximum length of the linked list for the command line history */ enum { @@ -354,10 +350,10 @@ static char** username_tab_completion(char *ud, int *num_matches) char *temp; int nm = 0; - setpwent (); + bb_setpwent (); userlen = strlen (ud + 1); - while ((entry = getpwent ()) != NULL) { + while ((entry = bb_getpwent ()) != NULL) { /* Null usernames should result in all users as possible completions. */ if (!userlen || !strncmp (ud + 1, entry->pw_name, userlen)) { @@ -369,7 +365,7 @@ static char** username_tab_completion(char *ud, int *num_matches) } } - endpwent (); + bb_endpwent (); (*num_matches) = nm; return (matches); } diff --git a/utility.c b/utility.c index 81542e94f..13b8065d3 100644 --- a/utility.c +++ b/utility.c @@ -52,6 +52,8 @@ #include #include #include /* for uname(2) */ +#include "pwd_grp/pwd.h" +#include "pwd_grp/grp.h" /* Busybox mount uses either /proc/filesystems or /dev/mtab to get the * list of available filesystems used for the -t auto option */ @@ -856,117 +858,72 @@ extern int parse_mode(const char *s, mode_t * theMode) #if defined BB_CHMOD_CHOWN_CHGRP || defined BB_PS || defined BB_LS \ || defined BB_TAR || defined BB_ID || defined BB_LOGGER \ || defined BB_LOGNAME || defined BB_WHOAMI || defined BB_SH - -/* This parses entries in /etc/passwd and /etc/group. This is desirable - * for BusyBox, since we want to avoid using the glibc NSS stuff, which - * increases target size and is often not needed or wanted for embedded - * systems. - * - * /etc/passwd entries look like this: - * root:x:0:0:root:/root:/bin/bash - * and /etc/group entries look like this: - * root:x:0: - * - * This uses buf as storage to hold things. - * - */ -unsigned long my_getid(const char *filename, char *name, long id, long *gid) -{ - FILE *file; - char *rname, *start, *end, buf[128]; - long rid; - long rgid = 0; - - file = fopen(filename, "r"); - if (file == NULL) { - /* Do not complain. It is ok for /etc/passwd and - * friends to be missing... */ - return (-1); - } - - while (fgets(buf, 128, file) != NULL) { - if (buf[0] == '#') - continue; - - /* username/group name */ - start = buf; - end = strchr(start, ':'); - if (end == NULL) - continue; - *end = '\0'; - rname = start; - - /* password */ - start = end + 1; - end = strchr(start, ':'); - if (end == NULL) - continue; - - /* uid in passwd, gid in group */ - start = end + 1; - rid = (unsigned long) strtol(start, &end, 10); - if (end == start) - continue; - - /* gid in passwd */ - start = end + 1; - rgid = (unsigned long) strtol(start, &end, 10); - - if (name) { - if (0 == strcmp(rname, name)) { - if (gid) *gid = rgid; - fclose(file); - return (rid); - } - } - if (id != -1 && id == rid) { - strncpy(name, rname, 8); - name[8]='\0'; - if (gid) *gid = rgid; - fclose(file); - return (TRUE); - } - } - fclose(file); - return (-1); -} - /* returns a uid given a username */ long my_getpwnam(char *name) { - return my_getid("/etc/passwd", name, -1, NULL); + struct passwd *myuser; + + myuser = getpwnam(name); + if (myuser==NULL) + error_msg_and_die( "unknown username: %s\n", name); + + return myuser->pw_uid; } /* returns a gid given a group name */ long my_getgrnam(char *name) { - return my_getid("/etc/group", name, -1, NULL); + struct group *mygroup; + + mygroup = getgrnam(name); + if (mygroup==NULL) + error_msg_and_die( "unknown group: %s\n", name); + + return (mygroup->gr_gid); } /* gets a username given a uid */ void my_getpwuid(char *name, long uid) { - name[0] = '\0'; - my_getid("/etc/passwd", name, uid, NULL); + struct passwd *myuser; + + myuser = getpwuid(uid); + if (myuser==NULL) + error_msg_and_die( "unknown uid %ld\n", (long)uid); + + strcpy(name, myuser->pw_name); } /* gets a groupname given a gid */ void my_getgrgid(char *group, long gid) { - group[0] = '\0'; - my_getid("/etc/group", group, gid, NULL); + struct group *mygroup; + + mygroup = getgrgid(gid); + if (mygroup==NULL) + error_msg_and_die( "unknown gid %ld\n", (long)gid); + + strcpy(group, mygroup->gr_name); } #if defined BB_ID /* gets a gid given a user name */ long my_getpwnamegid(char *name) { - long gid; - my_getid("/etc/passwd", name, -1, &gid); - return gid; -} -#endif + struct group *mygroup; + struct passwd *myuser; + myuser=getpwnam(name); + if (myuser==NULL) + error_msg_and_die( "unknown user name: %s\n", name); + + mygroup = getgrgid(myuser->pw_gid); + if (mygroup==NULL) + error_msg_and_die( "unknown gid %ld\n", (long)myuser->pw_gid); + + return mygroup->gr_gid; +} +#endif /* BB_ID */ #endif /* BB_CHMOD_CHOWN_CHGRP || BB_PS || BB_LS || BB_TAR \ || BB_ID || BB_LOGGER || BB_LOGNAME || BB_WHOAMI */ diff --git a/uudecode.c b/uudecode.c index 279b9d6ce..7b26d2dad 100644 --- a/uudecode.c +++ b/uudecode.c @@ -27,7 +27,6 @@ #include #include #include -#include /*struct passwd *getpwnam();*/ diff --git a/uuencode.c b/uuencode.c index 36bc4970f..24aabd373 100644 --- a/uuencode.c +++ b/uuencode.c @@ -27,7 +27,6 @@ #include #include #include -#include #define RW (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) diff --git a/whoami.c b/whoami.c index 38a2b3078..d7f0a177c 100644 --- a/whoami.c +++ b/whoami.c @@ -22,7 +22,6 @@ #include "busybox.h" #include -#include extern int whoami_main(int argc, char **argv) {