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

Reply via email to