From c6995b5046530b585a6eaf9fe4307a7b2a00fa1b Mon Sep 17 00:00:00 2001 From: bapt Date: Wed, 3 Jun 2015 19:08:25 +0000 Subject: New pw -R rootdir option This allows to set an alternate root directory in which the users/groups will be manipulated Requested by: gjb, ian Tested by: gjb --- usr.sbin/pw/pw_user.c | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index 48eb934..cb4c3de 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -63,6 +63,28 @@ static char *shell_path(char const * path, char *shells[], char *sh); static void rmat(uid_t uid); static void rmopie(char const * name); +static void +create_and_populate_homedir(int mode, struct cargs *args, struct passwd *pwd, + struct userconf *cnf) +{ + char *homedir, *dotdir; + struct carg *arg; + + homedir = dotdir = NULL; + + if ((arg = getarg(args, 'R'))) { + asprintf(&homedir, "%s/%s", arg->val, pwd->pw_dir); + if (homedir == NULL) + errx(EX_OSERR, "out of memory"); + asprintf(&dotdir, "%s/%s", arg->val, cnf->dotdir); + } + + copymkdir(homedir ? homedir : pwd->pw_dir, dotdir ? dotdir: cnf->dotdir, + cnf->homemode, pwd->pw_uid, pwd->pw_gid); + pw_log(cnf, mode, W_USER, "%s(%u) home %s made", pwd->pw_name, + pwd->pw_uid, pwd->pw_dir); +} + /*- * -C config configuration file * -q quiet operation @@ -108,6 +130,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) struct group *grp; struct stat st; char line[_PASSWORD_LEN+1]; + char path[MAXPATHLEN]; FILE *fp; char *dmode_c; void *set = NULL; @@ -451,7 +474,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) pw_log(cnf, mode, W_USER, "%s(%u) account removed", a_name->val, uid); - if (!PWALTDIR()) { + if (PWALTDIR()) { /* * Remove mail file */ @@ -800,11 +823,13 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) * doesn't hurt anything to create the empty mailfile */ if (mode == M_ADD) { - if (!PWALTDIR()) { - snprintf(line, sizeof(line), "%s/%s", _PATH_MAILDIR, pwd->pw_name); - close(open(line, O_RDWR | O_CREAT, 0600)); /* Preserve contents & + if (PWALTDIR() != PWF_ALT) { + arg = getarg(args, 'R'); + snprintf(path, sizeof(path), "%s%s/%s", + arg ? arg->val : "", _PATH_MAILDIR, pwd->pw_name); + close(open(path, O_RDWR | O_CREAT, 0600)); /* Preserve contents & * mtime */ - chown(line, pwd->pw_uid, pwd->pw_gid); + chown(path, pwd->pw_uid, pwd->pw_gid); } } @@ -813,12 +838,9 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) * that this also `works' for editing users if -m is used, but * existing files will *not* be overwritten. */ - if (!PWALTDIR() && getarg(args, 'm') != NULL && pwd->pw_dir && *pwd->pw_dir == '/' && pwd->pw_dir[1]) { - copymkdir(pwd->pw_dir, cnf->dotdir, cnf->homemode, pwd->pw_uid, pwd->pw_gid); - pw_log(cnf, mode, W_USER, "%s(%u) home %s made", - pwd->pw_name, pwd->pw_uid, pwd->pw_dir); - } - + if (PWALTDIR() != PWF_ALT && getarg(args, 'm') != NULL && pwd->pw_dir && + *pwd->pw_dir == '/' && pwd->pw_dir[1]) + create_and_populate_homedir(mode, args, pwd, cnf); /* * Finally, send mail to the new user as well, if we are asked to -- cgit v1.1 From 3b86c3ab1d2b77a2e9623b90b424e554d8728c21 Mon Sep 17 00:00:00 2001 From: bapt Date: Sun, 7 Jun 2015 10:57:02 +0000 Subject: Instead of always casting the pw_checkname input to u_char * and casting it back to char *, change pw_checkname to directly take char * in input --- usr.sbin/pw/pw_user.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index cb4c3de..3880c42 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -263,7 +263,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) } } if ((arg = getarg(args, 'L')) != NULL) - cnf->default_class = pw_checkname((u_char *)arg->val, 0); + cnf->default_class = pw_checkname(arg->val, 0); if ((arg = getarg(args, 'G')) != NULL && arg->val) { int i = 0; @@ -323,7 +323,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) } if ((a_name = getarg(args, 'n')) != NULL) - pwd = GETPWNAM(pw_checkname((u_char *)a_name->val, 0)); + pwd = GETPWNAM(pw_checkname(a_name->val, 0)); a_uid = getarg(args, 'u'); if (a_uid == NULL) { @@ -510,7 +510,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) if ((arg = getarg(args, 'l')) != NULL) { if (strcmp(pwd->pw_name, "root") == 0) errx(EX_DATAERR, "can't rename `root' account"); - pwd->pw_name = pw_checkname((u_char *)arg->val, 0); + pwd->pw_name = pw_checkname(arg->val, 0); edited = 1; } @@ -648,7 +648,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) * Shared add/edit code */ if ((arg = getarg(args, 'c')) != NULL) { - char *gecos = pw_checkname((u_char *)arg->val, 1); + char *gecos = pw_checkname(arg->val, 1); if (strcmp(pwd->pw_gecos, gecos) != 0) { pwd->pw_gecos = gecos; edited = 1; @@ -1239,11 +1239,11 @@ print_user(struct passwd * pwd, int pretty, int v7) return EXIT_SUCCESS; } -char * -pw_checkname(u_char *name, int gecos) +char * +pw_checkname(char *name, int gecos) { char showch[8]; - u_char const *badchars, *ch, *showtype; + const char *badchars, *ch, *showtype; int reject; ch = name; @@ -1294,7 +1294,8 @@ pw_checkname(u_char *name, int gecos) if (!gecos && (ch - name) > LOGNAMESIZE) errx(EX_DATAERR, "name too long `%s' (max is %d)", name, LOGNAMESIZE); - return (char *)name; + + return (name); } -- cgit v1.1 From 036d73e0105272af13a62ac6b74e0287ca114f50 Mon Sep 17 00:00:00 2001 From: bapt Date: Sun, 7 Jun 2015 11:26:28 +0000 Subject: Move user deletion code into a separate function to improve readability --- usr.sbin/pw/pw_user.c | 221 ++++++++++++++++++++++++++------------------------ 1 file changed, 115 insertions(+), 106 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index 3880c42..ad02450 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -51,6 +51,8 @@ static const char rcsid[] = static char locked_str[] = "*LOCKED*"; +static int delete_user(struct userconf *cnf, struct passwd *pwd, + struct carg *a_name, int delete, int mode); static int print_user(struct passwd * pwd, int pretty, int v7); static uid_t pw_uidpolicy(struct userconf * cnf, struct cargs * args); static uid_t pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer); @@ -394,112 +396,10 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) errx(EX_DATAERR, "user '%s' is not locked", pwd->pw_name); pwd->pw_passwd += sizeof(locked_str)-1; edited = 1; - } else if (mode == M_DELETE) { - /* - * Handle deletions now - */ - char file[MAXPATHLEN]; - char home[MAXPATHLEN]; - uid_t uid = pwd->pw_uid; - struct group *gr; - char grname[LOGNAMESIZE]; - - if (strcmp(pwd->pw_name, "root") == 0) - errx(EX_DATAERR, "cannot remove user 'root'"); - - if (!PWALTDIR()) { - /* - * Remove opie record from /etc/opiekeys - */ - - rmopie(pwd->pw_name); - - /* - * Remove crontabs - */ - snprintf(file, sizeof(file), "/var/cron/tabs/%s", pwd->pw_name); - if (access(file, F_OK) == 0) { - snprintf(file, sizeof(file), "crontab -u %s -r", pwd->pw_name); - system(file); - } - } - /* - * Save these for later, since contents of pwd may be - * invalidated by deletion - */ - snprintf(file, sizeof(file), "%s/%s", _PATH_MAILDIR, pwd->pw_name); - strlcpy(home, pwd->pw_dir, sizeof(home)); - gr = GETGRGID(pwd->pw_gid); - if (gr != NULL) - strlcpy(grname, gr->gr_name, LOGNAMESIZE); - else - grname[0] = '\0'; - - rc = delpwent(pwd); - if (rc == -1) - err(EX_IOERR, "user '%s' does not exist", pwd->pw_name); - else if (rc != 0) - err(EX_IOERR, "passwd update"); - - if (cnf->nispasswd && *cnf->nispasswd=='/') { - rc = delnispwent(cnf->nispasswd, a_name->val); - if (rc == -1) - warnx("WARNING: user '%s' does not exist in NIS passwd", pwd->pw_name); - else if (rc != 0) - warn("WARNING: NIS passwd update"); - /* non-fatal */ - } - - grp = GETGRNAM(a_name->val); - if (grp != NULL && - (grp->gr_mem == NULL || *grp->gr_mem == NULL) && - strcmp(a_name->val, grname) == 0) - delgrent(GETGRNAM(a_name->val)); - SETGRENT(); - while ((grp = GETGRENT()) != NULL) { - int i, j; - char group[MAXLOGNAME]; - if (grp->gr_mem != NULL) { - for (i = 0; grp->gr_mem[i] != NULL; i++) { - if (!strcmp(grp->gr_mem[i], a_name->val)) { - for (j = i; grp->gr_mem[j] != NULL; j++) - grp->gr_mem[j] = grp->gr_mem[j+1]; - strlcpy(group, grp->gr_name, MAXLOGNAME); - chggrent(group, grp); - } - } - } - } - ENDGRENT(); - - pw_log(cnf, mode, W_USER, "%s(%u) account removed", a_name->val, uid); - - if (PWALTDIR()) { - /* - * Remove mail file - */ - remove(file); - - /* - * Remove at jobs - */ - if (getpwuid(uid) == NULL) - rmat(uid); - - /* - * Remove home directory and contents - */ - if (getarg(args, 'r') != NULL && *home == '/' && getpwuid(uid) == NULL) { - if (stat(home, &st) != -1) { - rm_r(home, uid); - pw_log(cnf, mode, W_USER, "%s(%u) home '%s' %sremoved", - a_name->val, uid, home, - stat(home, &st) == -1 ? "" : "not completely "); - } - } - } - return EXIT_SUCCESS; - } else if (mode == M_PRINT) + } else if (mode == M_DELETE) + return (delete_user(cnf, pwd, a_name, + getarg(args, 'r') != NULL, mode)); + else if (mode == M_PRINT) return print_user(pwd, getarg(args, 'P') != NULL, getarg(args, '7') != NULL); @@ -1155,6 +1055,115 @@ pw_password(struct userconf * cnf, struct cargs * args, char const * user) return pw_pwcrypt(pwbuf); } +static int +delete_user(struct userconf *cnf, struct passwd *pwd, struct carg *a_name, + int delete, int mode) +{ + char file[MAXPATHLEN]; + char home[MAXPATHLEN]; + uid_t uid = pwd->pw_uid; + struct group *gr, *grp; + char grname[LOGNAMESIZE]; + int rc; + struct stat st; + + if (strcmp(pwd->pw_name, "root") == 0) + errx(EX_DATAERR, "cannot remove user 'root'"); + + if (!PWALTDIR()) { + /* + * Remove opie record from /etc/opiekeys + */ + + rmopie(pwd->pw_name); + + /* + * Remove crontabs + */ + snprintf(file, sizeof(file), "/var/cron/tabs/%s", pwd->pw_name); + if (access(file, F_OK) == 0) { + snprintf(file, sizeof(file), "crontab -u %s -r", pwd->pw_name); + system(file); + } + } + /* + * Save these for later, since contents of pwd may be + * invalidated by deletion + */ + snprintf(file, sizeof(file), "%s/%s", _PATH_MAILDIR, pwd->pw_name); + strlcpy(home, pwd->pw_dir, sizeof(home)); + gr = GETGRGID(pwd->pw_gid); + if (gr != NULL) + strlcpy(grname, gr->gr_name, LOGNAMESIZE); + else + grname[0] = '\0'; + + rc = delpwent(pwd); + if (rc == -1) + err(EX_IOERR, "user '%s' does not exist", pwd->pw_name); + else if (rc != 0) + err(EX_IOERR, "passwd update"); + + if (cnf->nispasswd && *cnf->nispasswd=='/') { + rc = delnispwent(cnf->nispasswd, a_name->val); + if (rc == -1) + warnx("WARNING: user '%s' does not exist in NIS passwd", pwd->pw_name); + else if (rc != 0) + warn("WARNING: NIS passwd update"); + /* non-fatal */ + } + + grp = GETGRNAM(a_name->val); + if (grp != NULL && + (grp->gr_mem == NULL || *grp->gr_mem == NULL) && + strcmp(a_name->val, grname) == 0) + delgrent(GETGRNAM(a_name->val)); + SETGRENT(); + while ((grp = GETGRENT()) != NULL) { + int i, j; + char group[MAXLOGNAME]; + if (grp->gr_mem != NULL) { + for (i = 0; grp->gr_mem[i] != NULL; i++) { + if (!strcmp(grp->gr_mem[i], a_name->val)) { + for (j = i; grp->gr_mem[j] != NULL; j++) + grp->gr_mem[j] = grp->gr_mem[j+1]; + strlcpy(group, grp->gr_name, MAXLOGNAME); + chggrent(group, grp); + } + } + } + } + ENDGRENT(); + + pw_log(cnf, mode, W_USER, "%s(%u) account removed", a_name->val, uid); + + if (PWALTDIR()) { + /* + * Remove mail file + */ + remove(file); + + /* + * Remove at jobs + */ + if (getpwuid(uid) == NULL) + rmat(uid); + + /* + * Remove home directory and contents + */ + if (delete && *home == '/' && getpwuid(uid) == NULL) { + if (stat(home, &st) != -1) { + rm_r(home, uid); + pw_log(cnf, mode, W_USER, "%s(%u) home '%s' %sremoved", + a_name->val, uid, home, + stat(home, &st) == -1 ? "" : "not completely "); + } + } + } + + return (EXIT_SUCCESS); +} static int print_user(struct passwd * pwd, int pretty, int v7) -- cgit v1.1 From bb815be56e819e3c76fd340b20f021eb714b71aa Mon Sep 17 00:00:00 2001 From: bapt Date: Sun, 7 Jun 2015 11:30:33 +0000 Subject: Remove one level of indentation --- usr.sbin/pw/pw_user.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index ad02450..8a07a0e 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -1152,13 +1152,12 @@ delete_user(struct userconf *cnf, struct passwd *pwd, struct carg *a_name, /* * Remove home directory and contents */ - if (delete && *home == '/' && getpwuid(uid) == NULL) { - if (stat(home, &st) != -1) { - rm_r(home, uid); - pw_log(cnf, mode, W_USER, "%s(%u) home '%s' %sremoved", - a_name->val, uid, home, - stat(home, &st) == -1 ? "" : "not completely "); - } + if (delete && *home == '/' && getpwuid(uid) == NULL && + stat(home, &st) != -1) { + rm_r(home, uid); + pw_log(cnf, mode, W_USER, "%s(%u) home '%s' %sremoved", + a_name->val, uid, home, + stat(home, &st) == -1 ? "" : "not completely "); } } -- cgit v1.1 From 0aa79fb06de52166dc7940bc933c3333c777d8bf Mon Sep 17 00:00:00 2001 From: bapt Date: Sun, 7 Jun 2015 11:35:34 +0000 Subject: Improve readability by reducing indentations levels --- usr.sbin/pw/pw_user.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index 8a07a0e..dc33272 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -1122,15 +1122,17 @@ delete_user(struct userconf *cnf, struct passwd *pwd, struct carg *a_name, while ((grp = GETGRENT()) != NULL) { int i, j; char group[MAXLOGNAME]; - if (grp->gr_mem != NULL) { - for (i = 0; grp->gr_mem[i] != NULL; i++) { - if (!strcmp(grp->gr_mem[i], a_name->val)) { - for (j = i; grp->gr_mem[j] != NULL; j++) - grp->gr_mem[j] = grp->gr_mem[j+1]; - strlcpy(group, grp->gr_name, MAXLOGNAME); - chggrent(group, grp); - } - } + if (grp->gr_mem == NULL) + continue; + + for (i = 0; grp->gr_mem[i] != NULL; i++) { + if (strcmp(grp->gr_mem[i], a_name->val)) + continue; + + for (j = i; grp->gr_mem[j] != NULL; j++) + grp->gr_mem[j] = grp->gr_mem[j+1]; + strlcpy(group, grp->gr_name, MAXLOGNAME); + chggrent(group, grp); } } ENDGRENT(); -- cgit v1.1 From 1844f29e51c70e0a895a5983963b095dafbc2382 Mon Sep 17 00:00:00 2001 From: bapt Date: Sun, 7 Jun 2015 11:38:26 +0000 Subject: Test explicitly the result of strcmp to be consistent with the rest of the code --- usr.sbin/pw/pw_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index dc33272..5f65129 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -1126,7 +1126,7 @@ delete_user(struct userconf *cnf, struct passwd *pwd, struct carg *a_name, continue; for (i = 0; grp->gr_mem[i] != NULL; i++) { - if (strcmp(grp->gr_mem[i], a_name->val)) + if (strcmp(grp->gr_mem[i], a_name->val) != 0) continue; for (j = i; grp->gr_mem[j] != NULL; j++) -- cgit v1.1 From c31a38b994d9eeac6b476cf034ab84479d78acff Mon Sep 17 00:00:00 2001 From: bapt Date: Sun, 7 Jun 2015 14:32:52 +0000 Subject: Fix pw userdel -r not deleting homedir --- usr.sbin/pw/pw_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index 5f65129..f5305f9 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -1139,7 +1139,7 @@ delete_user(struct userconf *cnf, struct passwd *pwd, struct carg *a_name, pw_log(cnf, mode, W_USER, "%s(%u) account removed", a_name->val, uid); - if (PWALTDIR()) { + if (!PWALTDIR()) { /* * Remove mail file */ -- cgit v1.1 From c6afeed630caacfd5c4b23de8544bf606a30af8f Mon Sep 17 00:00:00 2001 From: bapt Date: Sun, 7 Jun 2015 14:34:38 +0000 Subject: Add a new global struct pwconf to store etcpath, rootdir and struct userconf Do not add anymore -R and -V to arglist Add an error message if both -V and -R are set in arguments --- usr.sbin/pw/pw_user.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index f5305f9..d69f56b 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -55,7 +55,7 @@ static int delete_user(struct userconf *cnf, struct passwd *pwd, struct carg *a_name, int delete, int mode); static int print_user(struct passwd * pwd, int pretty, int v7); static uid_t pw_uidpolicy(struct userconf * cnf, struct cargs * args); -static uid_t pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer); +static uid_t pw_gidpolicy(struct cargs * args, char *nam, gid_t prefer); static time_t pw_pwdpolicy(struct userconf * cnf, struct cargs * args); static time_t pw_exppolicy(struct userconf * cnf, struct cargs * args); static char *pw_homepolicy(struct userconf * cnf, struct cargs * args, char const * user); @@ -66,19 +66,18 @@ static void rmat(uid_t uid); static void rmopie(char const * name); static void -create_and_populate_homedir(int mode, struct cargs *args, struct passwd *pwd, - struct userconf *cnf) +create_and_populate_homedir(int mode, struct passwd *pwd) { char *homedir, *dotdir; - struct carg *arg; + struct userconf *cnf = conf.userconf; homedir = dotdir = NULL; - if ((arg = getarg(args, 'R'))) { - asprintf(&homedir, "%s/%s", arg->val, pwd->pw_dir); + if (conf.rootdir[0] != '\0') { + asprintf(&homedir, "%s/%s", conf.rootdir, pwd->pw_dir); if (homedir == NULL) errx(EX_OSERR, "out of memory"); - asprintf(&dotdir, "%s/%s", arg->val, cnf->dotdir); + asprintf(&dotdir, "%s/%s", conf.rootdir, cnf->dotdir); } copymkdir(homedir ? homedir : pwd->pw_dir, dotdir ? dotdir: cnf->dotdir, @@ -120,7 +119,7 @@ create_and_populate_homedir(int mode, struct cargs *args, struct passwd *pwd, */ int -pw_user(struct userconf * cnf, int mode, struct cargs * args) +pw_user(int mode, struct cargs * args) { int rc, edited = 0; char *p = NULL; @@ -131,6 +130,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) struct passwd *pwd = NULL; struct group *grp; struct stat st; + struct userconf *cnf; char line[_PASSWORD_LEN+1]; char path[MAXPATHLEN]; FILE *fp; @@ -154,6 +154,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) #endif }; + cnf = conf.userconf; /* * With M_NEXT, we only need to return the @@ -165,7 +166,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) if (getarg(args, 'q')) return next; printf("%u:", next); - pw_group(cnf, mode, args); + pw_group(mode, args); return EXIT_SUCCESS; } @@ -528,7 +529,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) pwd->pw_name = a_name->val; pwd->pw_class = cnf->default_class ? cnf->default_class : ""; pwd->pw_uid = pw_uidpolicy(cnf, args); - pwd->pw_gid = pw_gidpolicy(cnf, args, pwd->pw_name, (gid_t) pwd->pw_uid); + pwd->pw_gid = pw_gidpolicy(args, pwd->pw_name, (gid_t) pwd->pw_uid); pwd->pw_change = pw_pwdpolicy(cnf, args); pwd->pw_expire = pw_exppolicy(cnf, args); pwd->pw_dir = pw_homepolicy(cnf, args, pwd->pw_name); @@ -740,7 +741,7 @@ pw_user(struct userconf * cnf, int mode, struct cargs * args) */ if (PWALTDIR() != PWF_ALT && getarg(args, 'm') != NULL && pwd->pw_dir && *pwd->pw_dir == '/' && pwd->pw_dir[1]) - create_and_populate_homedir(mode, args, pwd, cnf); + create_and_populate_homedir(mode, pwd); /* * Finally, send mail to the new user as well, if we are asked to @@ -824,11 +825,12 @@ pw_uidpolicy(struct userconf * cnf, struct cargs * args) static uid_t -pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer) +pw_gidpolicy(struct cargs * args, char *nam, gid_t prefer) { struct group *grp; gid_t gid = (uid_t) - 1; struct carg *a_gid = getarg(args, 'g'); + struct userconf *cnf = conf.userconf; /* * If no arg given, see if default can help out @@ -874,11 +876,11 @@ pw_gidpolicy(struct userconf * cnf, struct cargs * args, char *nam, gid_t prefer { addarg(&grpargs, 'N', NULL); addarg(&grpargs, 'q', NULL); - gid = pw_group(cnf, M_NEXT, &grpargs); + gid = pw_group(M_NEXT, &grpargs); } else { - pw_group(cnf, M_ADD, &grpargs); + pw_group(M_ADD, &grpargs); if ((grp = GETGRNAM(nam)) != NULL) gid = grp->gr_gid; } -- cgit v1.1 From 720254061f1395ebda3e3e2d6ebd2cf0d58f7249 Mon Sep 17 00:00:00 2001 From: bapt Date: Sun, 7 Jun 2015 15:09:53 +0000 Subject: Handle dryrun (-N) via global pwconf --- usr.sbin/pw/pw_user.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index d69f56b..fac4d25 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -620,7 +620,7 @@ pw_user(int mode, struct cargs * args) /* * Special case: -N only displays & exits */ - if (getarg(args, 'N') != NULL) + if (conf.dryrun) return print_user(pwd, getarg(args, 'P') != NULL, getarg(args, '7') != NULL); @@ -872,9 +872,7 @@ pw_gidpolicy(struct cargs * args, char *nam, gid_t prefer) snprintf(tmp, sizeof(tmp), "%u", prefer); addarg(&grpargs, 'g', tmp); } - if (getarg(args, 'N')) - { - addarg(&grpargs, 'N', NULL); + if (conf.dryrun) { addarg(&grpargs, 'q', NULL); gid = pw_group(M_NEXT, &grpargs); } @@ -1035,7 +1033,7 @@ pw_password(struct userconf * cnf, struct cargs * args, char const * user) * We give this information back to the user */ if (getarg(args, 'h') == NULL && getarg(args, 'H') == NULL && - getarg(args, 'N') == NULL) { + !conf.dryrun) { if (isatty(STDOUT_FILENO)) printf("Password for '%s' is: ", user); printf("%s\n", pwbuf); -- cgit v1.1 From 4ca3925ed28f1d1406eb93c5852f1b8bffd9d6cc Mon Sep 17 00:00:00 2001 From: bapt Date: Sun, 7 Jun 2015 15:27:17 +0000 Subject: Handle pretty print (-P) via global pwconf --- usr.sbin/pw/pw_user.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index fac4d25..bfbde78 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -53,7 +53,7 @@ static char locked_str[] = "*LOCKED*"; static int delete_user(struct userconf *cnf, struct passwd *pwd, struct carg *a_name, int delete, int mode); -static int print_user(struct passwd * pwd, int pretty, int v7); +static int print_user(struct passwd * pwd, int v7); static uid_t pw_uidpolicy(struct userconf * cnf, struct cargs * args); static uid_t pw_gidpolicy(struct cargs * args, char *nam, gid_t prefer); static time_t pw_pwdpolicy(struct userconf * cnf, struct cargs * args); @@ -316,11 +316,10 @@ pw_user(int mode, struct cargs * args) } if (mode == M_PRINT && getarg(args, 'a')) { - int pretty = getarg(args, 'P') != NULL; int v7 = getarg(args, '7') != NULL; SETPWENT(); while ((pwd = GETPWENT()) != NULL) - print_user(pwd, pretty, v7); + print_user(pwd, v7); ENDPWENT(); return EXIT_SUCCESS; } @@ -363,7 +362,6 @@ pw_user(int mode, struct cargs * args) fakeuser.pw_name = a_name ? a_name->val : "nouser"; fakeuser.pw_uid = a_uid ? (uid_t) atol(a_uid->val) : (uid_t) -1; return print_user(&fakeuser, - getarg(args, 'P') != NULL, getarg(args, '7') != NULL); } if (a_name == NULL) @@ -401,9 +399,7 @@ pw_user(int mode, struct cargs * args) return (delete_user(cnf, pwd, a_name, getarg(args, 'r') != NULL, mode)); else if (mode == M_PRINT) - return print_user(pwd, - getarg(args, 'P') != NULL, - getarg(args, '7') != NULL); + return print_user(pwd, getarg(args, '7') != NULL); /* * The rest is edit code @@ -621,9 +617,7 @@ pw_user(int mode, struct cargs * args) * Special case: -N only displays & exits */ if (conf.dryrun) - return print_user(pwd, - getarg(args, 'P') != NULL, - getarg(args, '7') != NULL); + return print_user(pwd, getarg(args, '7') != NULL); if (mode == M_ADD) { edited = 1; /* Always */ @@ -1167,9 +1161,9 @@ delete_user(struct userconf *cnf, struct passwd *pwd, struct carg *a_name, } static int -print_user(struct passwd * pwd, int pretty, int v7) +print_user(struct passwd * pwd, int v7) { - if (!pretty) { + if (!conf.pretty) { char *buf; if (!v7) -- cgit v1.1 From 87cd2261fe983ebe7709e2a10526322a407ca901 Mon Sep 17 00:00:00 2001 From: bapt Date: Sun, 7 Jun 2015 15:33:08 +0000 Subject: Handle -7 via gloval pwconf --- usr.sbin/pw/pw_user.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index bfbde78..0fc7272 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -53,7 +53,7 @@ static char locked_str[] = "*LOCKED*"; static int delete_user(struct userconf *cnf, struct passwd *pwd, struct carg *a_name, int delete, int mode); -static int print_user(struct passwd * pwd, int v7); +static int print_user(struct passwd * pwd); static uid_t pw_uidpolicy(struct userconf * cnf, struct cargs * args); static uid_t pw_gidpolicy(struct cargs * args, char *nam, gid_t prefer); static time_t pw_pwdpolicy(struct userconf * cnf, struct cargs * args); @@ -316,10 +316,9 @@ pw_user(int mode, struct cargs * args) } if (mode == M_PRINT && getarg(args, 'a')) { - int v7 = getarg(args, '7') != NULL; SETPWENT(); while ((pwd = GETPWENT()) != NULL) - print_user(pwd, v7); + print_user(pwd); ENDPWENT(); return EXIT_SUCCESS; } @@ -1161,15 +1160,15 @@ delete_user(struct userconf *cnf, struct passwd *pwd, struct carg *a_name, } static int -print_user(struct passwd * pwd, int v7) +print_user(struct passwd * pwd) { if (!conf.pretty) { char *buf; - if (!v7) + if (!conf.v7) pwd->pw_passwd = (pwd->pw_passwd == NULL) ? "" : "*"; - buf = v7 ? pw_make_v7(pwd) : pw_make(pwd); + buf = conf.v7 ? pw_make_v7(pwd) : pw_make(pwd); printf("%s\n", buf); free(buf); } else { -- cgit v1.1 From 28b61e032c63beebeadd5138f2f4c967cd25d6a8 Mon Sep 17 00:00:00 2001 From: bapt Date: Sun, 7 Jun 2015 15:54:57 +0000 Subject: Finish converting -7 to pwconf --- usr.sbin/pw/pw_user.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index 0fc7272..0b15c77 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -360,8 +360,7 @@ pw_user(int mode, struct cargs * args) if (mode == M_PRINT && getarg(args, 'F')) { fakeuser.pw_name = a_name ? a_name->val : "nouser"; fakeuser.pw_uid = a_uid ? (uid_t) atol(a_uid->val) : (uid_t) -1; - return print_user(&fakeuser, - getarg(args, '7') != NULL); + return print_user(&fakeuser); } if (a_name == NULL) errx(EX_NOUSER, "no such uid `%s'", a_uid->val); @@ -398,7 +397,7 @@ pw_user(int mode, struct cargs * args) return (delete_user(cnf, pwd, a_name, getarg(args, 'r') != NULL, mode)); else if (mode == M_PRINT) - return print_user(pwd, getarg(args, '7') != NULL); + return print_user(pwd); /* * The rest is edit code @@ -616,7 +615,7 @@ pw_user(int mode, struct cargs * args) * Special case: -N only displays & exits */ if (conf.dryrun) - return print_user(pwd, getarg(args, '7') != NULL); + return print_user(pwd); if (mode == M_ADD) { edited = 1; /* Always */ -- cgit v1.1 From 3be2bba5d71e59e56e7e8ba65e3c4efe3e59380f Mon Sep 17 00:00:00 2001 From: bapt Date: Sun, 7 Jun 2015 19:03:41 +0000 Subject: Refactor input validation Mutualize code to validate inputs of both 'user' and 'group' command Test that the input name fits into MAXLOGNAME --- usr.sbin/pw/pw_user.c | 95 ++++++++++++++++++++------------------------------- 1 file changed, 37 insertions(+), 58 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index 0b15c77..c9093bb 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -52,7 +52,7 @@ static const char rcsid[] = static char locked_str[] = "*LOCKED*"; static int delete_user(struct userconf *cnf, struct passwd *pwd, - struct carg *a_name, int delete, int mode); + char *name, int delete, int mode); static int print_user(struct passwd * pwd); static uid_t pw_uidpolicy(struct userconf * cnf, struct cargs * args); static uid_t pw_gidpolicy(struct cargs * args, char *nam, gid_t prefer); @@ -119,13 +119,11 @@ create_and_populate_homedir(int mode, struct passwd *pwd) */ int -pw_user(int mode, struct cargs * args) +pw_user(int mode, char *name, long id, struct cargs * args) { int rc, edited = 0; char *p = NULL; char *passtmp; - struct carg *a_name; - struct carg *a_uid; struct carg *arg; struct passwd *pwd = NULL; struct group *grp; @@ -166,7 +164,7 @@ pw_user(int mode, struct cargs * args) if (getarg(args, 'q')) return next; printf("%u:", next); - pw_group(mode, args); + pw_group(mode, name, -1, args); return EXIT_SUCCESS; } @@ -323,29 +321,11 @@ pw_user(int mode, struct cargs * args) return EXIT_SUCCESS; } - if ((a_name = getarg(args, 'n')) != NULL) - pwd = GETPWNAM(pw_checkname(a_name->val, 0)); - a_uid = getarg(args, 'u'); + if (name != NULL) + pwd = GETPWNAM(pw_checkname(name, 0)); - if (a_uid == NULL) { - if (a_name == NULL) - errx(EX_DATAERR, "user name or id required"); - - /* - * Determine whether 'n' switch is name or uid - we don't - * really don't really care which we have, but we need to - * know. - */ - if (mode != M_ADD && pwd == NULL - && strspn(a_name->val, "0123456789") == strlen(a_name->val) - && *a_name->val) { - (a_uid = a_name)->ch = 'u'; - a_name = NULL; - } - } else { - if (strspn(a_uid->val, "0123456789") != strlen(a_uid->val)) - errx(EX_USAGE, "-u expects a number"); - } + if (id < 0 && name == NULL) + errx(EX_DATAERR, "user name or id required"); /* * Update, delete & print require that the user exists @@ -353,22 +333,22 @@ pw_user(int mode, struct cargs * args) if (mode == M_UPDATE || mode == M_DELETE || mode == M_PRINT || mode == M_LOCK || mode == M_UNLOCK) { - if (a_name == NULL && pwd == NULL) /* Try harder */ - pwd = GETPWUID(atoi(a_uid->val)); + if (name == NULL && pwd == NULL) /* Try harder */ + pwd = GETPWUID(id); if (pwd == NULL) { if (mode == M_PRINT && getarg(args, 'F')) { - fakeuser.pw_name = a_name ? a_name->val : "nouser"; - fakeuser.pw_uid = a_uid ? (uid_t) atol(a_uid->val) : (uid_t) -1; + fakeuser.pw_name = name ? name : "nouser"; + fakeuser.pw_uid = (uid_t) id; return print_user(&fakeuser); } - if (a_name == NULL) - errx(EX_NOUSER, "no such uid `%s'", a_uid->val); - errx(EX_NOUSER, "no such user `%s'", a_name->val); + if (name == NULL) + errx(EX_NOUSER, "no such uid `%ld'", id); + errx(EX_NOUSER, "no such user `%s'", name); } - if (a_name == NULL) /* May be needed later */ - a_name = addarg(args, 'n', newstr(pwd->pw_name)); + if (name == NULL) + name = pwd->pw_name; /* * The M_LOCK and M_UNLOCK functions simply add or remove @@ -394,7 +374,7 @@ pw_user(int mode, struct cargs * args) pwd->pw_passwd += sizeof(locked_str)-1; edited = 1; } else if (mode == M_DELETE) - return (delete_user(cnf, pwd, a_name, + return (delete_user(cnf, pwd, name, getarg(args, 'r') != NULL, mode)); else if (mode == M_PRINT) return print_user(pwd); @@ -511,16 +491,16 @@ pw_user(int mode, struct cargs * args) * Add code */ - if (a_name == NULL) /* Required */ + if (name == NULL) /* Required */ errx(EX_DATAERR, "login name required"); - else if ((pwd = GETPWNAM(a_name->val)) != NULL) /* Exists */ - errx(EX_DATAERR, "login name `%s' already exists", a_name->val); + else if ((pwd = GETPWNAM(name)) != NULL) /* Exists */ + errx(EX_DATAERR, "login name `%s' already exists", name); /* * Now, set up defaults for a new user */ pwd = &fakeuser; - pwd->pw_name = a_name->val; + pwd->pw_name = name; pwd->pw_class = cnf->default_class ? cnf->default_class : ""; pwd->pw_uid = pw_uidpolicy(cnf, args); pwd->pw_gid = pw_gidpolicy(args, pwd->pw_name, (gid_t) pwd->pw_uid); @@ -635,13 +615,13 @@ pw_user(int mode, struct cargs * args) } } else if (mode == M_UPDATE || mode == M_LOCK || mode == M_UNLOCK) { if (edited) { /* Only updated this if required */ - rc = chgpwent(a_name->val, pwd); + rc = chgpwent(name, pwd); if (rc == -1) errx(EX_IOERR, "user '%s' does not exist (NIS?)", pwd->pw_name); else if (rc != 0) err(EX_IOERR, "passwd file update"); if ( cnf->nispasswd && *cnf->nispasswd=='/') { - rc = chgnispwent(cnf->nispasswd, a_name->val, pwd); + rc = chgnispwent(cnf->nispasswd, name, pwd); if (rc == -1) warn("User '%s' not found in NIS passwd", pwd->pw_name); else @@ -693,16 +673,16 @@ pw_user(int mode, struct cargs * args) /* go get a current version of pwd */ - pwd = GETPWNAM(a_name->val); + pwd = GETPWNAM(name); if (pwd == NULL) { /* This will fail when we rename, so special case that */ if (mode == M_UPDATE && (arg = getarg(args, 'l')) != NULL) { - a_name->val = arg->val; /* update new name */ - pwd = GETPWNAM(a_name->val); /* refetch renamed rec */ + name = arg->val; /* update new name */ + pwd = GETPWNAM(name); /* refetch renamed rec */ } } if (pwd == NULL) /* can't go on without this */ - errx(EX_NOUSER, "user '%s' disappeared during update", a_name->val); + errx(EX_NOUSER, "user '%s' disappeared during update", name); grp = GETGRGID(pwd->pw_gid); pw_log(cnf, mode, W_USER, "%s(%u):%s(%u):%s:%s:%s", @@ -849,7 +829,6 @@ pw_gidpolicy(struct cargs * args, char *nam, gid_t prefer) char tmp[32]; LIST_INIT(&grpargs); - addarg(&grpargs, 'n', nam); /* * We need to auto-create a group with the user's name. We @@ -866,11 +845,11 @@ pw_gidpolicy(struct cargs * args, char *nam, gid_t prefer) } if (conf.dryrun) { addarg(&grpargs, 'q', NULL); - gid = pw_group(M_NEXT, &grpargs); + gid = pw_group(M_NEXT, nam, -1, &grpargs); } else { - pw_group(M_ADD, &grpargs); + pw_group(M_ADD, nam, -1, &grpargs); if ((grp = GETGRNAM(nam)) != NULL) gid = grp->gr_gid; } @@ -1048,7 +1027,7 @@ pw_password(struct userconf * cnf, struct cargs * args, char const * user) } static int -delete_user(struct userconf *cnf, struct passwd *pwd, struct carg *a_name, +delete_user(struct userconf *cnf, struct passwd *pwd, char *name, int delete, int mode) { char file[MAXPATHLEN]; @@ -1097,7 +1076,7 @@ delete_user(struct userconf *cnf, struct passwd *pwd, struct carg *a_name, err(EX_IOERR, "passwd update"); if (cnf->nispasswd && *cnf->nispasswd=='/') { - rc = delnispwent(cnf->nispasswd, a_name->val); + rc = delnispwent(cnf->nispasswd, name); if (rc == -1) warnx("WARNING: user '%s' does not exist in NIS passwd", pwd->pw_name); else if (rc != 0) @@ -1105,11 +1084,11 @@ delete_user(struct userconf *cnf, struct passwd *pwd, struct carg *a_name, /* non-fatal */ } - grp = GETGRNAM(a_name->val); + grp = GETGRNAM(name); if (grp != NULL && (grp->gr_mem == NULL || *grp->gr_mem == NULL) && - strcmp(a_name->val, grname) == 0) - delgrent(GETGRNAM(a_name->val)); + strcmp(name, grname) == 0) + delgrent(GETGRNAM(name)); SETGRENT(); while ((grp = GETGRENT()) != NULL) { int i, j; @@ -1118,7 +1097,7 @@ delete_user(struct userconf *cnf, struct passwd *pwd, struct carg *a_name, continue; for (i = 0; grp->gr_mem[i] != NULL; i++) { - if (strcmp(grp->gr_mem[i], a_name->val) != 0) + if (strcmp(grp->gr_mem[i], name) != 0) continue; for (j = i; grp->gr_mem[j] != NULL; j++) @@ -1129,7 +1108,7 @@ delete_user(struct userconf *cnf, struct passwd *pwd, struct carg *a_name, } ENDGRENT(); - pw_log(cnf, mode, W_USER, "%s(%u) account removed", a_name->val, uid); + pw_log(cnf, mode, W_USER, "%s(%u) account removed", name, uid); if (!PWALTDIR()) { /* @@ -1150,7 +1129,7 @@ delete_user(struct userconf *cnf, struct passwd *pwd, struct carg *a_name, stat(home, &st) != -1) { rm_r(home, uid); pw_log(cnf, mode, W_USER, "%s(%u) home '%s' %sremoved", - a_name->val, uid, home, + name, uid, home, stat(home, &st) == -1 ? "" : "not completely "); } } -- cgit v1.1 From 4a60f5b2aa32e78ca47b6bda0c8df390f7116df0 Mon Sep 17 00:00:00 2001 From: bapt Date: Sun, 7 Jun 2015 19:33:25 +0000 Subject: In case of rename validate the length of the new name Check early that the new name fits MAXLOGNAME and store it in pwconf --- usr.sbin/pw/pw_user.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index c9093bb..6b3a266 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -382,10 +382,10 @@ pw_user(int mode, char *name, long id, struct cargs * args) /* * The rest is edit code */ - if ((arg = getarg(args, 'l')) != NULL) { + if (conf.newname != NULL) { if (strcmp(pwd->pw_name, "root") == 0) errx(EX_DATAERR, "can't rename `root' account"); - pwd->pw_name = pw_checkname(arg->val, 0); + pwd->pw_name = pw_checkname(conf.newname, 0); edited = 1; } @@ -676,8 +676,8 @@ pw_user(int mode, char *name, long id, struct cargs * args) pwd = GETPWNAM(name); if (pwd == NULL) { /* This will fail when we rename, so special case that */ - if (mode == M_UPDATE && (arg = getarg(args, 'l')) != NULL) { - name = arg->val; /* update new name */ + if (mode == M_UPDATE && conf.newname != NULL) { + name = conf.newname; /* update new name */ pwd = GETPWNAM(name); /* refetch renamed rec */ } } -- cgit v1.1 From c6688979243ff91c6c4816ff12594baba6c5c1ac Mon Sep 17 00:00:00 2001 From: bapt Date: Sun, 7 Jun 2015 19:39:06 +0000 Subject: Remove uneeded code (already done by pw_make_v7) --- usr.sbin/pw/pw_user.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index 6b3a266..99d8129 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -1143,9 +1143,6 @@ print_user(struct passwd * pwd) if (!conf.pretty) { char *buf; - if (!conf.v7) - pwd->pw_passwd = (pwd->pw_passwd == NULL) ? "" : "*"; - buf = conf.v7 ? pw_make_v7(pwd) : pw_make(pwd); printf("%s\n", buf); free(buf); -- cgit v1.1 From 302d4b4363132d1d7c08566d2a7bc7af78101d09 Mon Sep 17 00:00:00 2001 From: bapt Date: Sun, 7 Jun 2015 19:59:01 +0000 Subject: Fix duplicate checking --- usr.sbin/pw/pw_user.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index 99d8129..c567e68c 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -54,7 +54,7 @@ static char locked_str[] = "*LOCKED*"; static int delete_user(struct userconf *cnf, struct passwd *pwd, char *name, int delete, int mode); static int print_user(struct passwd * pwd); -static uid_t pw_uidpolicy(struct userconf * cnf, struct cargs * args); +static uid_t pw_uidpolicy(struct userconf * cnf, long id); static uid_t pw_gidpolicy(struct cargs * args, char *nam, gid_t prefer); static time_t pw_pwdpolicy(struct userconf * cnf, struct cargs * args); static time_t pw_exppolicy(struct userconf * cnf, struct cargs * args); @@ -160,7 +160,7 @@ pw_user(int mode, char *name, long id, struct cargs * args) */ if (mode == M_NEXT) { - uid_t next = pw_uidpolicy(cnf, args); + uid_t next = pw_uidpolicy(cnf, id); if (getarg(args, 'q')) return next; printf("%u:", next); @@ -389,8 +389,8 @@ pw_user(int mode, char *name, long id, struct cargs * args) edited = 1; } - if ((arg = getarg(args, 'u')) != NULL && isdigit((unsigned char)*arg->val)) { - pwd->pw_uid = (uid_t) atol(arg->val); + if (id > 0 && isdigit((unsigned char)*arg->val)) { + pwd->pw_uid = (uid_t)id; edited = 1; if (pwd->pw_uid != 0 && strcmp(pwd->pw_name, "root") == 0) errx(EX_DATAERR, "can't change uid of `root' account"); @@ -502,7 +502,7 @@ pw_user(int mode, char *name, long id, struct cargs * args) pwd = &fakeuser; pwd->pw_name = name; pwd->pw_class = cnf->default_class ? cnf->default_class : ""; - pwd->pw_uid = pw_uidpolicy(cnf, args); + pwd->pw_uid = pw_uidpolicy(cnf, id); pwd->pw_gid = pw_gidpolicy(args, pwd->pw_name, (gid_t) pwd->pw_uid); pwd->pw_change = pw_pwdpolicy(cnf, args); pwd->pw_expire = pw_exppolicy(cnf, args); @@ -741,19 +741,18 @@ pw_user(int mode, char *name, long id, struct cargs * args) static uid_t -pw_uidpolicy(struct userconf * cnf, struct cargs * args) +pw_uidpolicy(struct userconf * cnf, long id) { struct passwd *pwd; uid_t uid = (uid_t) - 1; - struct carg *a_uid = getarg(args, 'u'); /* * Check the given uid, if any */ - if (a_uid != NULL) { - uid = (uid_t) atol(a_uid->val); + if (id > 0) { + uid = (uid_t) id; - if ((pwd = GETPWUID(uid)) != NULL && getarg(args, 'o') == NULL) + if ((pwd = GETPWUID(uid)) != NULL && conf.checkduplicate) errx(EX_DATAERR, "uid `%u' has already been allocated", pwd->pw_uid); } else { struct bitmap bm; -- cgit v1.1 From fc781f489d6d2f9918c9ecdeea749b37a453cdd9 Mon Sep 17 00:00:00 2001 From: bapt Date: Sun, 7 Jun 2015 20:44:06 +0000 Subject: Fix generating configuration file --- usr.sbin/pw/pw_user.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index c567e68c..c3b2751 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -292,7 +292,7 @@ pw_user(int mode, char *name, long id, struct cargs * args) if ((arg = getarg(args, 'w')) != NULL) cnf->default_password = boolean_val(arg->val, cnf->default_password); if (mode == M_ADD && getarg(args, 'D')) { - if (getarg(args, 'n') != NULL) + if (name != NULL) errx(EX_DATAERR, "can't combine `-D' with `-n name'"); if ((arg = getarg(args, 'u')) != NULL && (p = strtok(arg->val, ", \t")) != NULL) { if ((cnf->min_uid = (uid_t) atoi(p)) == 0) @@ -307,9 +307,8 @@ pw_user(int mode, char *name, long id, struct cargs * args) cnf->max_gid = 32000; } - arg = getarg(args, 'C'); - if (write_userconfig(arg ? arg->val : NULL)) - return EXIT_SUCCESS; + if (write_userconfig(conf.config)) + return (EXIT_SUCCESS); err(EX_IOERR, "config udpate"); } -- cgit v1.1 From 65b30fab70c3b273f9797608833f522b5a12f43d Mon Sep 17 00:00:00 2001 From: bapt Date: Sun, 7 Jun 2015 21:57:20 +0000 Subject: Remove '-q' support for pw [user|group] next the intent of -q in this command is to return as exit status the value of the next group/user id, which does not make sense given exit status are limited to values between 0 and 255. --- usr.sbin/pw/pw_user.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index c3b2751..ea3cb3d 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -158,14 +158,10 @@ pw_user(int mode, char *name, long id, struct cargs * args) * With M_NEXT, we only need to return the * next uid to stdout */ - if (mode == M_NEXT) - { - uid_t next = pw_uidpolicy(cnf, id); - if (getarg(args, 'q')) - return next; - printf("%u:", next); + if (mode == M_NEXT) { + printf("%u:", pw_uidpolicy(cnf, id)); pw_group(mode, name, -1, args); - return EXIT_SUCCESS; + return (EXIT_SUCCESS); } /* -- cgit v1.1 From ec480fe320d4aa3e3de9a2d528d9c3a8bf4ec4cc Mon Sep 17 00:00:00 2001 From: bapt Date: Mon, 8 Jun 2015 05:27:34 +0000 Subject: backout remove of -q option for pw [user|group] next While the return code is broken, some corner case usage depends on the functionnality, so backout until we get better regression tests covering those corner case usage. --- usr.sbin/pw/pw_user.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'usr.sbin/pw/pw_user.c') diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index ea3cb3d..c3b2751 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -158,10 +158,14 @@ pw_user(int mode, char *name, long id, struct cargs * args) * With M_NEXT, we only need to return the * next uid to stdout */ - if (mode == M_NEXT) { - printf("%u:", pw_uidpolicy(cnf, id)); + if (mode == M_NEXT) + { + uid_t next = pw_uidpolicy(cnf, id); + if (getarg(args, 'q')) + return next; + printf("%u:", next); pw_group(mode, name, -1, args); - return (EXIT_SUCCESS); + return EXIT_SUCCESS; } /* -- cgit v1.1