X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=loginutils%2Fadduser.c;h=41dc9f0193202d3ce1e29e61aea5ed31e60007e0;hb=b79db92a21aee4c003f49eb21f1447b79e0e0c1e;hp=3485611cc690f651f5b316f2697eb1e1abf1b895;hpb=c38678d14b87f8e2d4f0d610d0aa61c656f17539;p=oweals%2Fbusybox.git diff --git a/loginutils/adduser.c b/loginutils/adduser.c index 3485611cc..41dc9f019 100644 --- a/loginutils/adduser.c +++ b/loginutils/adduser.c @@ -21,6 +21,9 @@ * */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include #include #include @@ -29,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -66,7 +70,7 @@ static int passwd_study(const char *filename, struct passwd *p) const int min = 500; const int max = 65000; - passwd = wfopen(filename, "r"); + passwd = bb_wfopen(filename, "r"); if (!passwd) return 4; @@ -89,21 +93,23 @@ static int passwd_study(const char *filename, struct passwd *p) } } - /* EDR check for an already existing gid */ - while (getgrgid(p->pw_uid) != NULL) - p->pw_uid++; + if (p->pw_gid == 0) { + /* EDR check for an already existing gid */ + while (getgrgid(p->pw_uid) != NULL) + p->pw_uid++; + + /* EDR also check for an existing group definition */ + if (getgrnam(p->pw_name) != NULL) + return 3; - /* EDR also check for an existing group definition */ - if (getgrnam(p->pw_name) != NULL) - return 3; + /* EDR create new gid always = uid */ + p->pw_gid = p->pw_uid; + } /* EDR bounds check */ if ((p->pw_uid > max) || (p->pw_uid < min)) return 2; - /* EDR create new gid always = uid */ - p->pw_gid = p->pw_uid; - /* return 1; */ return 0; } @@ -112,7 +118,7 @@ static void addgroup_wrapper(const char *login, gid_t gid) { char *cmd; - bb_asprintf(&cmd, "addgroup -g %d %s", gid, login); + bb_xasprintf(&cmd, "addgroup -g %d %s", gid, login); system(cmd); free(cmd); } @@ -123,11 +129,11 @@ static void passwd_wrapper(const char *login) { static const char prog[] = "passwd"; execlp(prog, prog, login, NULL); - error_msg_and_die("Failed to execute '%s', you must set the password for '%s' manually", prog, login); + bb_error_msg_and_die("Failed to execute '%s', you must set the password for '%s' manually", prog, login); } /* putpwent(3) remix */ -static int adduser(const char *filename, struct passwd *p) +static int adduser(const char *filename, struct passwd *p, int makehome, int setpass) { FILE *passwd; int r; @@ -135,9 +141,14 @@ static int adduser(const char *filename, struct passwd *p) FILE *shadow; struct spwd *sp; #endif + int new_group = 1; + + /* if using a pre-existing group, don't create one */ + if (p->pw_gid != 0) + new_group = 0; /* make sure everything is kosher and setup uid && gid */ - passwd = wfopen(filename, "a"); + passwd = bb_wfopen(filename, "a"); if (passwd == NULL) { return 1; } @@ -147,13 +158,13 @@ static int adduser(const char *filename, struct passwd *p) r = passwd_study(filename, p); if (r) { if (r == 1) - error_msg("%s: login already in use", p->pw_name); + bb_error_msg("%s: login already in use", p->pw_name); else if (r == 2) - error_msg("illegal uid or no uids left"); + bb_error_msg("illegal uid or no uids left"); else if (r == 3) - error_msg("group name %s already in use", p->pw_name); + bb_error_msg("group name %s already in use", p->pw_name); else - error_msg("generic error."); + bb_error_msg("generic error."); return 1; } @@ -166,7 +177,7 @@ static int adduser(const char *filename, struct passwd *p) #ifdef CONFIG_FEATURE_SHADOWPASSWDS /* add to shadow if necessary */ if (shadow_enabled) { - shadow = wfopen(shadow_file, "a"); + shadow = bb_wfopen(bb_path_shadow_file, "a"); if (shadow == NULL) { return 1; } @@ -181,38 +192,56 @@ static int adduser(const char *filename, struct passwd *p) } #endif - /* add to group */ - /* addgroup should be responsible for dealing w/ gshadow */ - addgroup_wrapper(p->pw_name, p->pw_gid); + if (new_group) { + /* add to group */ + /* addgroup should be responsible for dealing w/ gshadow */ + addgroup_wrapper(p->pw_name, p->pw_gid); + } /* Clear the umask for this process so it doesn't * * screw up the permissions on the mkdir and chown. */ umask(0); - /* mkdir */ - if (mkdir(p->pw_dir, 0755)) { - perror_msg("%s", p->pw_dir); - } - /* Set the owner and group so it is owned by the new user. */ - if (chown(p->pw_dir, p->pw_uid, p->pw_gid)) { - perror_msg("%s", p->pw_dir); + if (makehome) { + /* mkdir */ + if (mkdir(p->pw_dir, 0755)) { + bb_perror_msg("%s", p->pw_dir); + } + /* Set the owner and group so it is owned by the new user. */ + if (chown(p->pw_dir, p->pw_uid, p->pw_gid)) { + bb_perror_msg("%s", p->pw_dir); + } + /* Now fix up the permissions to 2755. Can't do it before now + * since chown will clear the setgid bit */ + if (chmod(p->pw_dir, 02755)) { + bb_perror_msg("%s", p->pw_dir); + } } - /* Now fix up the permissions to 2755. Can't do it before now - * since chown will clear the setgid bit */ - if (chmod(p->pw_dir, 02755)) { - perror_msg("%s", p->pw_dir); + + if (setpass) { + /* interactively set passwd */ + passwd_wrapper(p->pw_name); } - /* interactively set passwd */ - passwd_wrapper(p->pw_name); + + return 0; } /* return current uid (root is always uid == 0, right?) */ -static inline uid_t i_am_not_root(void) +#ifndef CONFIG_ADDGROUP +static inline void if_i_am_not_root(void) +#else +void if_i_am_not_root(void) +#endif { - return geteuid(); + if (geteuid()) { + bb_error_msg_and_die( "Only root may add a user or group to the system."); + } } +#define SETPASS 1 +#define MAKEHOME 4 + /* * adduser will take a login_name as its first parameter. * @@ -224,46 +253,36 @@ static inline uid_t i_am_not_root(void) * ________________________________________________________________________ */ int adduser_main(int argc, char **argv) { - int opt; + struct passwd pw; const char *login; - const char *gecos; + const char *gecos = default_gecos; const char *home = NULL; - const char *shell; - - struct passwd pw; + const char *shell = default_shell; + const char *usegroup = NULL; + int flags; + int setpass = 1; + int makehome = 1; /* init */ if (argc < 2) { - show_usage(); + bb_show_usage(); } - gecos = default_gecos; - shell = default_shell; - /* get args */ - while ((opt = getopt (argc, argv, "h:g:s:")) != -1) - switch (opt) { - case 'h': - home = optarg; - break; - case 'g': - gecos = optarg; - break; - case 's': - shell = optarg; - break; - default: - show_usage (); - break; - } + flags = bb_getopt_ulflags(argc, argv, "h:g:s:G:DSH", &home, &gecos, &shell, &usegroup); - /* got root? */ - if (i_am_not_root()) { - error_msg_and_die( "Only root may add a user or group to the system."); + if (flags & SETPASS) { + setpass = 0; + } + if (flags & MAKEHOME) { + makehome = 0; } + /* got root? */ + if_i_am_not_root(); + /* get login */ if (optind >= argc) { - error_msg_and_die( "no user specified"); + bb_error_msg_and_die( "no user specified"); } login = argv[optind]; @@ -273,7 +292,7 @@ int adduser_main(int argc, char **argv) } #ifdef CONFIG_FEATURE_SHADOWPASSWDS /* is /etc/shadow in use? */ - shadow_enabled = (0 == access(shadow_file, F_OK)); + shadow_enabled = (0 == access(bb_path_shadow_file, F_OK)); #endif /* create a passwd struct */ @@ -285,8 +304,17 @@ int adduser_main(int argc, char **argv) pw.pw_dir = (char *)home; pw.pw_shell = (char *)shell; + if (usegroup) { + /* Add user to a group that already exists */ + struct group *g; + + g = getgrnam(usegroup); + if (g == NULL) + bb_error_msg_and_die("group %s does not exist", usegroup); + + pw.pw_gid = g->gr_gid; + } + /* grand finale */ - return adduser(passwd_file, &pw); + return adduser(bb_path_passwd_file, &pw, makehome, setpass); } - -/* $Id: adduser.c,v 1.4 2002/09/16 06:22:24 andersen Exp $ */