From 38cb603c1f169febdffcf5c2fbe041c276f47d08 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Tue, 16 Sep 2014 07:21:56 -0500 Subject: Cleanup pass on useradd. --- toys/pending/useradd.c | 204 +++++++++++++++++-------------------------------- 1 file changed, 70 insertions(+), 134 deletions(-) diff --git a/toys/pending/useradd.c b/toys/pending/useradd.c index 1d2bf301..9f1fa4c5 100644 --- a/toys/pending/useradd.c +++ b/toys/pending/useradd.c @@ -5,24 +5,24 @@ * * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/useradd.html -USE_USERADD(NEWTOY(useradd, "<1>2u#<0G:s:g:h:SDH", TOYFLAG_NEEDROOT|TOYFLAG_SBIN)) -USE_USERADD(OLDTOY(adduser, useradd, OPTSTR_useradd, TOYFLAG_NEEDROOT|TOYFLAG_SBIN)) +USE_USERADD(NEWTOY(useradd, "<1>2u#<0G:s:g:h:SDH", TOYFLAG_NEEDROOT|TOYFLAG_UMASK|TOYFLAG_SBIN)) +USE_USERADD(OLDTOY(adduser, useradd, OPTSTR_useradd, TOYFLAG_NEEDROOT|TOYFLAG_UMASK|TOYFLAG_SBIN)) config USERADD bool "useradd" default n help - usage: useradd [-SDH] [-hDIR] [-sSHELL] [-G GRP] [-gGECOS] [-uUID] USER [GROUP] + usage: useradd [-SDH] [-h DIR] [-s SHELL] [-G GRP] [-g NAME] [-u UID] USER [GROUP] Create new user, or add USER to GROUP - + + -D Don't assign a password + -g NAME Real name + -G GRP Add user to existing group -h DIR Home directory - -g GECOS GECOS field + -H Don't create home directory -s SHELL Login shell - -G GRP Add user to existing group -S Create a system user - -D Don't assign a password - -H Don't create home directory -u UID User id */ @@ -35,89 +35,51 @@ GLOBALS( char *shell; char *u_grp; long uid; + long gid; ) -static char* get_shell(void) -{ - char *shell = getenv("SHELL"); - - if (!shell) { - struct passwd *pw; - pw = getpwuid(getuid()); - if (pw && pw->pw_shell && pw->pw_shell[0]) - shell = pw->pw_shell; - else shell = "/bin/sh"; - } - return xstrdup(shell); -} - -/* exec_wait() function does a fork(), and exec the command, - * waits for the child to exit and return the status to parent - */ -static int exec_wait(char **args) +void useradd_main(void) { - int status = 0; - pid_t pid = xfork(); + char *s = *toys.optargs, *entry; + struct passwd pwd; - if (!pid) xexec(args); - else waitpid(pid, &status, 0); + // Act like groupadd? + if (toys.optc == 2) { + if (toys.optflags) { + toys.exithelp = 1; + error_exit("options with USER GROUP"); + } + xexec((char *[]){"groupadd", toys.optargs[0], toys.optargs[1], 0}); + } - return WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status)+127; -} + // Sanity check user to add + if (strchr(s, ':') || strchr(s, '/') || strlen(s) > LOGIN_NAME_MAX) + error_exit("bad name"); + // race condition: two adds at same time? + if (getpwnam(s)) error_exit("'%s' in use", s); -/* create_copy_skel(), This function will create the home directory of the - * user, by copying /etc/skel/ contents to /home/. - * Then change the ownership of home dir to the UID and GID of new user, - * and Mode to 0700, i.e. rwx------ for user. - */ -static void create_copy_skel(char *skel, char *hdir) -{ - char *args[5]; - struct stat sb; - - if (toys.optflags & FLAG_H) return; - - umask(0); - args[4] = NULL; - if (stat(hdir, &sb)) { - args[0] = "cp"; - args[1] = "-R"; - args[2] = skel; - args[3] = hdir; - // Copy /etc/skel to home dir - toys.exitval = exec_wait(args); - - args[0] = "chown"; - args[1] = "-R"; - args[2] = xmprintf("%u:%u", TT.uid, TT.gid); - args[3] = hdir; - //Change ownership to that of UID and GID of new user - toys.exitval = exec_wait(args); - - } else xprintf("Warning: home directory for the user already exists\n" - "Not copying any file from skel directory into it.\n"); - - if (chown(hdir, TT.uid, TT.gid) || chmod(hdir, 0700)) - perror_exit("chown/chmod failed for '%s'", hdir); -} + // Add a new group to the system, if UID is given then that is validated + // to be free, else a free UID is choosen by self. + // SYSTEM IDs are considered in the range 100 ... 999 + // add_user(), add a new entry in /etc/passwd, /etc/shadow files -/* Add a new group to the system, if UID is given then that is validated - * to be free, else a free UID is choosen by self. - * SYSTEM IDs are considered in the range 100 ... 999 - * add_user(), add a new entry in /etc/passwd, /etc/shadow files - */ -static void new_user() -{ - struct passwd pwd; - char *entry, *args[4]; - - pwd.pw_name = *toys.optargs; + pwd.pw_name = s; pwd.pw_passwd = "x"; - pwd.pw_gecos = (toys.optflags & FLAG_g) ? TT.gecos : "Linux User,"; - pwd.pw_dir = (toys.optflags & FLAG_h) ? TT.dir - : xmprintf("/home/%s", *toys.optargs); - pwd.pw_shell = (toys.optflags & FLAG_s) ? TT.shell : get_shell(); + pwd.pw_gecos = TT.gecos ? TT.gecos : "Linux User,"; + pwd.pw_dir = TT.dir ? TT.dir : xmprintf("/home/%s", *toys.optargs); + + if (!TT.shell) { + TT.shell = getenv("SHELL"); + + if (!TT.shell) { + struct passwd *pw = getpwuid(getuid()); + + if (pw && pw->pw_shell && *pw->pw_shell) TT.shell = xstrdup(pw->pw_shell); + else TT.shell = "/bin/sh"; + } + } + pwd.pw_shell = TT.shell; if (toys.optflags & FLAG_u) { if (TT.uid > INT_MAX) error_exit("bad uid"); @@ -141,14 +103,13 @@ static void new_user() } pwd.pw_gid = TT.gid; + // Create a new group for user if (!(toys.optflags & FLAG_G)) { - // Create a new group for user - //add group, invoke addgroup command - args[0] = "groupadd"; - args[1] = toys.optargs[0]; - args[2] = xmprintf("-g%ld", pwd.pw_gid); - args[3] = NULL; - if (exec_wait(args)) error_msg("addgroup fail"); + char *s = xmprintf("-g%ld", pwd.pw_gid); + + if (xrun((char *[]){"groupadd", *toys.optargs, s, 0})) + error_msg("addgroup -g%ld fail", pwd.pw_gid); + free(s); } /*add user to system @@ -171,54 +132,29 @@ static void new_user() update_password("/etc/shadow", pwd.pw_name, entry); free(entry); - //2. craete home dir & copy skel dir to home - if (!(toys.optflags & FLAG_S)) create_copy_skel("/etc/skel", pwd.pw_dir); + // create home dir & copy skel dir to home + if (!(toys.optflags & (FLAG_S|FLAG_H))) { + char *skel = "/etc/skel", *p = pwd.pw_dir; + + // Copy and change ownership + if (access(p, F_OK)) { + if (!access(skel, R_OK)) + toys.exitval = xrun((char *[]){"cp", "-R", skel, p, 0}); + else toys.exitval = xrun((char *[]){"mkdir", "-p", p, 0}); + if (!toys.exitval) + toys.exitval |= xrun((char *[]){"chown", "-R", + xmprintf("%u:%u", TT.uid, TT.gid), p, 0}); + wfchmodat(AT_FDCWD, p, 0700); + } else fprintf(stderr, "'%s' exists, not copying '%s'", p, skel); + } //3. update the user passwd by running 'passwd' utility - if (!(toys.optflags & FLAG_D)) { - args[0] = "passwd"; - args[1] = pwd.pw_name; - args[2] = NULL; - if (exec_wait(args)) error_exit("changing user passwd failed"); - } + if (!(toys.optflags & FLAG_D)) + if (xrun((char *[]){"passwd", pwd.pw_name, 0})) error_exit("passwd"); + if (toys.optflags & FLAG_G) { /*add user to the existing group, invoke addgroup command */ - args[0] = "groupadd"; - args[1] = toys.optargs[0]; - args[2] = TT.u_grp; - args[3] = NULL; - if (exec_wait(args)) error_exit("adding user to group Failed"); - } -} - -/* Entry point for useradd feature - * Specifying options and User, Group at cmdline is treated as error. - * If only 2 parameters (Non-Option) are given, then User is added to the - * Group - */ -void useradd_main(void) -{ - struct passwd *pwd = NULL; - - if (toys.optflags && toys.optc == 2) { - toys.exithelp = 1; - error_exit("options, user and group can't be together"); - } - - if (toys.optc == 2) { - //add user to group - //toys.optargs[0]- user, toys.optargs[1] - group - char *args[4]; - args[0] = "groupadd"; - args[1] = toys.optargs[0]; - args[2] = toys.optargs[1]; - args[3] = NULL; - toys.exitval = exec_wait(args); - } else { //new user to be created - // investigate the user to be created - if ((pwd = getpwnam(*toys.optargs))) - error_exit("user '%s' is in use", *toys.optargs); - is_valid_username(*toys.optargs); //validate the user name - new_user(); + if (xrun((char *[]){"groupadd", *toys.optargs, TT.u_grp, 0})) + error_exit("groupadd"); } } -- cgit v1.2.3