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.

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.

Regards,
Eugene

-- 
The best the little guy can do is what
the little guy does right

Reply via email to