On Tue, Sep 11, 2012 at 09:33:56AM +0300, Eugene Yunak wrote: > On 10 September 2012 18:01, Antoine Jacoutot <ajacou...@bsdfrog.org> wrote: > > Hi. > > > > This diff adds 2 new options to usermod(8): > > -U to unlock a user's password > > -Z to lock a user's password > > > > In effect locking/unlocking the password means to add a '!' in front of > > the encrypted entry in master.passwd. > > Note that this disable the _password_ not the account of course (you > > could still connect using ssh+key for e.g.). > > > > That said, I have some use for it and would like to be able to have this > > if at all possible. > > Behavior is basically the same as Linux's usermod(8) except that I am > > using -Z for locking the password (-Z is for SElinux in Linux land and > > -L is used instead but we use it ourselves for the login class). > > > > Comments? > > > > > > > > > > > > Index: user.c > > =================================================================== > > RCS file: /cvs/src/usr.sbin/user/user.c,v > > retrieving revision 1.90 > > diff -u -r1.90 user.c > > --- user.c 29 Jan 2012 08:38:54 -0000 1.90 > > +++ user.c 10 Sep 2012 15:00:21 -0000 > > @@ -100,7 +100,9 @@ > > F_UID = 0x0400, > > F_USERNAME = 0x0800, > > F_CLASS = 0x1000, > > - F_SETSECGROUP = 0x4000 > > + F_SETSECGROUP = 0x4000, > > + F_PWLOCK = 0x8000, > > + F_PWUNLOCK = 0x10000 > > }; > > > > #define CONFFILE "/etc/usermgmt.conf" > > @@ -1339,11 +1341,14 @@ > > struct group *grp; > > const char *homedir; > > char buf[LINE_MAX]; > > + char locked_str[] = "!"; > > + char pw_len[PasswordLength + 1]; > > size_t colonc, loginc; > > size_t cc; > > FILE *master; > > char newdir[MaxFileNameLen]; > > char *colon; > > + char *pw_tmp; > > int len; > > int masterfd; > > int ptmpfd; > > @@ -1359,6 +1364,9 @@ > > if (!is_local(login_name, _PATH_MASTERPASSWD)) { > > errx(EXIT_FAILURE, "User `%s' must be a local user", > > login_name); > > } > > + if ((up->u_flags & (F_PWLOCK | F_PWUNLOCK)) && (pwp->pw_uid == 0)) { > > + errx(EXIT_FAILURE, "(un)locking is not supported for `%s'", > > pwp->pw_name); > > + } > > /* keep dir name in case we need it for '-m' */ > > homedir = pwp->pw_dir; > > > > @@ -1410,6 +1418,29 @@ > > pwp->pw_passwd = up->u_password; > > } > > } > > + if (up->u_flags & F_PWLOCK) { > > + if (strncmp(pwp->pw_passwd, locked_str, > > sizeof(locked_str)-1) == 0) { > > + warnx("user '%s' is already locked", > > pwp->pw_name); > > + } else { > > + pw_tmp = malloc(strlen(pwp->pw_passwd) + > > sizeof(locked_str)); > > + if (pw_tmp == NULL) { > > + (void) close(ptmpfd); > > + pw_abort(); > > + errx(EXIT_FAILURE, "cannot allocate > > memory"); > > + } > > + strlcpy(pw_tmp, locked_str, sizeof(pw_len)); > > + strlcat(pw_tmp, pwp->pw_passwd, > > sizeof(pw_len)); > > + pwp->pw_passwd = pw_tmp; > > + free (pw_tmp); > > + } > > + } > > + if (up->u_flags & F_PWUNLOCK) { > > + if (strncmp(pwp->pw_passwd, locked_str, > > sizeof(locked_str)-1) != 0) { > > + warnx("user '%s' is not locked", > > pwp->pw_name); > > + } else { > > + pwp->pw_passwd += sizeof(locked_str)-1; > > + } > > + } > > if (up->u_flags & F_UID) { > > /* check uid isn't already allocated */ > > if (!(up->u_flags & F_DUPUID) && > > getpwuid((uid_t)(up->u_uid)) != NULL) { > > @@ -1617,7 +1648,7 @@ > > "[-p password] [-r low..high]\n" > > " [-s shell] [-u uid] user\n", prog); > > } else if (strcmp(prog, "usermod") == 0) { > > - (void) fprintf(stderr, "usage: %s [-mov] " > > + (void) fprintf(stderr, "usage: %s [-UZmov] " > > "[-c comment] [-d home-directory] [-e expiry-time]\n" > > " [-f inactive-time] " > > "[-G secondary-group[,group,...]]\n" > > @@ -1788,7 +1819,7 @@ > > free(u.u_primgrp); > > u.u_primgrp = NULL; > > have_new_user = 0; > > - while ((c = getopt(argc, argv, "G:L:S:c:d:e:f:g:l:mop:s:u:v")) != > > -1) { > > + while ((c = getopt(argc, argv, "G:L:S:UZc:d:e:f:g:l:mop:s:u:v")) != > > -1) { > > switch(c) { > > case 'G': > > while ((u.u_groupv[u.u_groupc] = strsep(&optarg, > > ",")) != NULL && > > @@ -1814,6 +1845,12 @@ > > } > > u.u_flags |= F_SETSECGROUP; > > break; > > + case 'U': > > + u.u_flags |= F_PWUNLOCK; > > + break; > > + case 'Z': > > + u.u_flags |= F_PWLOCK; > > + break; > > case 'c': > > memsave(&u.u_comment, optarg, strlen(optarg)); > > u.u_flags |= F_COMMENT; > > @@ -1883,6 +1920,10 @@ > > } > > if ((u.u_flags & F_SECGROUP) && (u.u_flags & F_SETSECGROUP)) > > errx(EXIT_FAILURE, "options 'G' and 'S' are mutually > > exclusive"); > > + if ((u.u_flags & F_PWLOCK) && (u.u_flags & F_PWUNLOCK)) > > + errx(EXIT_FAILURE, "options 'U' and 'Z' are mutually > > exclusive"); > > + if ((u.u_flags & F_PASSWORD) && (u.u_flags & (F_PWLOCK | > > F_PWUNLOCK))) > > + errx(EXIT_FAILURE, "options 'U' or 'Z' with 'p' are > > mutually exclusive"); > > argc -= optind; > > argv += optind; > > if (argc != 1) { > > Index: usermod.8 > > =================================================================== > > RCS file: /cvs/src/usr.sbin/user/usermod.8,v > > retrieving revision 1.28 > > diff -u -r1.28 usermod.8 > > --- usermod.8 28 Jan 2012 14:25:45 -0000 1.28 > > +++ usermod.8 10 Sep 2012 15:00:21 -0000 > > @@ -40,7 +40,7 @@ > > .Sh SYNOPSIS > > .Nm usermod > > .Bk -words > > -.Op Fl mov > > +.Op Fl UZmov > > .Op Fl c Ar comment > > .Op Fl d Ar home-directory > > .Op Fl e Ar expiry-time > > @@ -176,6 +176,11 @@ > > See > > .Xr usermgmt.conf 5 > > for more details. > > +.Fl p > > +cannot be used with > > +.Fl U > > +or > > +.Fl Z . > > .It Fl S Ar secondary-group Ns Op , Ns Ar group , Ns ... > > Sets the secondary groups the user will be a member of in the > > .Pa /etc/group > > @@ -199,6 +204,15 @@ > > See > > .Xr usermgmt.conf 5 > > for more details. > > +.It Fl U > > +Unlock the user's local password by removing the > > +.Ql \&! > > +in front of it. > > +.Fl U > > +and > > +.Fl Z > > +are mutually exclusive and cannot be used with > > +.Fl p. > > .It Fl u Ar uid > > Specifies a new UID for the user. > > Boundaries for this value can be preset for all users > > @@ -212,6 +226,15 @@ > > for more details. > > .It Fl v > > Enables verbose mode - explain the commands as they are executed. > > +.It Fl Z > > +Lock the user's local password by putting a > > +.Ql \&! > > +in front of it. > > +.Fl Z > > +and > > +.Fl U > > +are mutually exclusive and cannot be used with > > +.Fl p. > > .El > > .Pp > > Once the information has been verified, > > > > > > -- > > Antoine > > > > Hi, > > Isn't think better placed in passwd? > At least Linux and Solaris (since 5.6 i believe) have this as -l and > -u in passwd(1), > so this might be a better option to keep it consistent with other > systems. HP-UX > only implements -l; I haven't checked others.
It is consistent; this is how usermod works in linux as well. > OpenBSD passwd already uses -l to restrict passwd to local files only though > so > you would still need to use a different letter (as you do with > usermod) but at least > passwd(1) is where most unix admins would look for this option first. This diff is for the usermod part, not passwd; both are different things. -- Antoine