On Tue, Sep 11, 2012 at 06:24:04PM +0200, Antoine Jacoutot wrote:
> On Tue, Sep 11, 2012 at 04:46:57PM +0200, Antoine Jacoutot wrote:
> > On Mon, Sep 10, 2012 at 05:01:13PM +0200, Antoine Jacoutot 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).
> > 
> > Ok new diff that does something slightly different.
> > Instead of putting a '!' in front of the password (which confused people), 
> > lock/unlock means appending/removing a dash to the user's login shell.
> > While this is non standard behavior (but as I mentionned in a previous 
> > mail, usermod(8) is already not standard accross unices) I think it is 
> > better because:
> > - account is locked, period (no local login, no remote login -- no surprise 
> > for tedu ;-) )
> > - no values are touched
> >   (e.g. one could disable an account by using 'usermod -e 1' but when he 
> > wants to re-enable the account he'll be forced to change the expiration 
> > time)
> 
> New diff which also put a '*' in front of the encrypted password; i.e. both 
> pre and post-auth become locked (req. by Theo).
> With some man page tweak from jmc.

Anyone?


> 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    11 Sep 2012 16:20:11 -0000
> @@ -100,7 +100,9 @@
>       F_UID           = 0x0400,
>       F_USERNAME      = 0x0800,
>       F_CLASS         = 0x1000,
> -     F_SETSECGROUP   = 0x4000
> +     F_SETSECGROUP   = 0x4000,
> +     F_ACCTLOCK      = 0x8000,
> +     F_ACCTUNLOCK    = 0x10000
>  };
>  
>  #define CONFFILE     "/etc/usermgmt.conf"
> @@ -1339,11 +1341,17 @@
>       struct group    *grp;
>       const char      *homedir;
>       char            buf[LINE_MAX];
> +     char            acctlock_str[] = "-";
> +     char            pwlock_str[] = "*";
> +     char            pw_len[PasswordLength + 1];
> +     char            shell_len[MaxShellNameLen];
>       size_t          colonc, loginc;
>       size_t          cc;
>       FILE            *master;
>       char            newdir[MaxFileNameLen];
>       char            *colon;
> +     char            *pw_tmp = NULL;
> +     char            *shell_tmp = NULL;
>       int             len;
>       int             masterfd;
>       int             ptmpfd;
> @@ -1359,6 +1367,10 @@
>       if (!is_local(login_name, _PATH_MASTERPASSWD)) {
>               errx(EXIT_FAILURE, "User `%s' must be a local user", 
> login_name);
>       }
> +     if (up != NULL) {
> +             if ((up->u_flags & (F_ACCTLOCK | F_ACCTUNLOCK)) && (pwp->pw_uid 
> == 0))
> +                     errx(EXIT_FAILURE, "(un)locking is not supported for 
> the `%s' account", pwp->pw_name);
> +     }
>       /* keep dir name in case we need it for '-m' */
>       homedir = pwp->pw_dir;
>  
> @@ -1410,6 +1422,48 @@
>                               pwp->pw_passwd = up->u_password;
>                       }
>               }
> +             if (up->u_flags & F_ACCTLOCK) {
> +                     /* lock the account */
> +                     if (strncmp(pwp->pw_shell+strlen(pwp->pw_shell) - 1, 
> acctlock_str+strlen(acctlock_str) - 1, sizeof(acctlock_str) - 1) != 0) {
> +                             shell_tmp = malloc(strlen(pwp->pw_shell) + 
> sizeof(acctlock_str));
> +                             if (shell_tmp == NULL) {
> +                                     (void) close(ptmpfd);
> +                                     pw_abort();
> +                                     errx(EXIT_FAILURE, "account lock: 
> cannot allocate memory");
> +                             }
> +                             strlcpy(shell_tmp, pwp->pw_shell, 
> sizeof(shell_len));
> +                             strlcat(shell_tmp, acctlock_str, 
> sizeof(shell_len));
> +                             pwp->pw_shell = shell_tmp;
> +                     }
> +                     /* lock the password */
> +                     if (strncmp(pwp->pw_passwd, pwlock_str, 
> sizeof(pwlock_str)-1) != 0) {
> +                             pw_tmp = malloc(strlen(pwp->pw_passwd) + 
> sizeof(pwlock_str));
> +                             if (pw_tmp == NULL) {
> +                                     (void) close(ptmpfd);
> +                                     pw_abort();
> +                                     errx(EXIT_FAILURE, "password lock: 
> cannot allocate memory");
> +                             }
> +                             strlcpy(pw_tmp, pwlock_str, sizeof(pw_len));
> +                             strlcat(pw_tmp, pwp->pw_passwd, sizeof(pw_len));
> +                             pwp->pw_passwd = pw_tmp;
> +                     }
> +             }
> +             if (up->u_flags & F_ACCTUNLOCK) {
> +                     /* unlock the password */
> +                     if (strncmp(pwp->pw_passwd, pwlock_str, 
> sizeof(pwlock_str)-1) == 0)
> +                             pwp->pw_passwd += sizeof(pwlock_str)-1;
> +                     /* unlock the account */
> +                     if (strncmp(pwp->pw_shell+strlen(pwp->pw_shell) - 1, 
> acctlock_str+strlen(acctlock_str) - 1, sizeof(acctlock_str) - 1) == 0) {
> +                             shell_tmp = malloc(strlen(pwp->pw_shell) - 
> sizeof(acctlock_str));
> +                             if (shell_tmp == NULL) {
> +                                     (void) close(ptmpfd);
> +                                     pw_abort();
> +                                     errx(EXIT_FAILURE, "unlock: cannot 
> allocate memory");
> +                             }
> +                             strlcpy(shell_tmp, pwp->pw_shell, 
> sizeof(shell_tmp) + 1);
> +                             pwp->pw_shell = shell_tmp;
> +                     }
> +             }
>               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) {
> @@ -1547,6 +1601,10 @@
>               }
>       }
>       (void) close(ptmpfd);
> +     if (pw_tmp)
> +             FREE(pw_tmp);
> +     if (shell_tmp)
> +             FREE(shell_tmp);
>       if (up != NULL && strcmp(login_name, newlogin) == 0)
>               rval = pw_mkdb(login_name, 0);
>       else
> @@ -1617,7 +1675,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 [-moUvZ] "
>                   "[-c comment] [-d home-directory] [-e expiry-time]\n"
>                   "               [-f inactive-time] "
>                   "[-G secondary-group[,group,...]]\n"
> @@ -1788,7 +1846,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 +1872,12 @@
>                       }
>                       u.u_flags |= F_SETSECGROUP;
>                       break;
> +             case 'U':
> +                     u.u_flags |= F_ACCTUNLOCK;
> +                     break;
> +             case 'Z':
> +                     u.u_flags |= F_ACCTLOCK;
> +                     break;
>               case 'c':
>                       memsave(&u.u_comment, optarg, strlen(optarg));
>                       u.u_flags |= F_COMMENT;
> @@ -1883,6 +1947,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_ACCTLOCK) && (u.u_flags & F_ACCTUNLOCK))
> +             errx(EXIT_FAILURE, "options 'U' and 'Z' are mutually 
> exclusive");
> +     if ((u.u_flags & F_PASSWORD) && (u.u_flags & (F_ACCTLOCK | 
> F_ACCTUNLOCK)))
> +             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 11 Sep 2012 16:20:11 -0000
> @@ -40,7 +40,7 @@
>  .Sh SYNOPSIS
>  .Nm usermod
>  .Bk -words
> -.Op Fl mov
> +.Op Fl moUvZ
>  .Op Fl c Ar comment
>  .Op Fl d Ar home-directory
>  .Op Fl e Ar expiry-time
> @@ -199,6 +199,17 @@
>  See
>  .Xr usermgmt.conf 5
>  for more details.
> +.It Fl U
> +Unlock the account by removing the trailing
> +.Ql \&-
> +from the user's shell and the
> +.Ql \&*
> +in front of his password.
> +.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 +223,17 @@
>  for more details.
>  .It Fl v
>  Enables verbose mode - explain the commands as they are executed.
> +.It Fl Z
> +Lock the account by appending a
> +.Ql \&-
> +to the user's shell and putting a
> +.Ql \&*
> +in front of his password.
> +.Fl Z
> +and
> +.Fl U
> +are mutually exclusive and cannot be used with
> +.Fl p .
>  .El
>  .Pp
>  Once the information has been verified,

-- 
Antoine

Reply via email to