I like the direction this is going.  I've implemented a shell
equivalent in the past for one scenario, but having it in the
tools directly definitely makes life easier.

1000 admins can implement it differently, but this at least
provides consistent behavior and provides a mechanism for
automation that is robust.

I look forward to the next version with '-' added/removed to/from
the users shell ;-)

Thanks,

Penned by Antoine Jacoutot on 20120910 10:01.13, we have:
| 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

-- 
Todd Fries .. t...@fries.net

 _____________________________________________
|                                             \  1.636.410.0632 (voice)
| Free Daemon Consulting, LLC                 \  1.405.227.9094 (voice)
| http://FreeDaemonConsulting.com             \  1.866.792.3418 (FAX)
| 2525 NW Expy #525, Oklahoma City, OK 73112  \  sip:freedae...@ekiga.net
| "..in support of free software solutions."  \  sip:4052279...@ekiga.net
 \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
                                                 
              37E7 D3EB 74D0 8D66 A68D  B866 0326 204E 3F42 004A
                        http://todd.fries.net/pgp.txt

Reply via email to