]> granicus.if.org Git - shadow/commitdiff
* NEWS, src/usermod.c; man/usermod.8.xml: When the shadow file
authornekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Thu, 14 Jul 2011 13:29:37 +0000 (13:29 +0000)
committernekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Thu, 14 Jul 2011 13:29:37 +0000 (13:29 +0000)
exists but there are no shadow entries, an entry has to be created
if the password is changed and passwd requires a shadow entry, or
if aging features are used (-e or -f). Document this and also that
-e and -f require a shadow file.

ChangeLog
NEWS
man/usermod.8.xml
src/usermod.c

index a8ee0af09eca8a591d334f748a1b6713fddf640d..4fd204dfb3903157a3a8f4918a4510127cfa9074 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
        * src/usermod.c (update_group, update_gshadow): Reduce complexity
        and document checks. Some checks were always true/false within
        their call context.
+       * NEWS, src/usermod.c; man/usermod.8.xml: When the shadow file
+       exists but there are no shadow entries, an entry has to be created
+       if the password is changed and passwd requires a shadow entry, or
+       if aging features are used (-e or -f). Document this and also that
+       -e and -f require a shadow file.
 
 2011-07-08  Nicolas François  <nicolas.francois@centraliens.net>
 
diff --git a/NEWS b/NEWS
index f544a851426042cdc1517e39ee094dfb4d91332d..87ba9cb56835d057b7a1ab17a37b2fb3a7bcb403 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -61,6 +61,9 @@ shadow-4.1.4.3 -> shadow-4.1.5                                        UNRELEASED
     this group isn't the user's primary group.
 - usermod
   * Accept options in any order (username not necessarily at the end)
+  * When the shadow file exists but there are no shadow entries, an entry
+    is created if the password is changed and passwd requires a
+    shadow entry, or if aging features are used (-e or -f).
 
 *** translation
   * Updated Brazilian Portuguese translation.
index 43b183198cbc49c19c7e0c1b9bbe58c024bad4b8..e1317c7025d2d7f3d130c79e19945acc7f9bc1c9 100644 (file)
            The date on which the user account will be disabled. The date is
            specified in the format <emphasis remap='I'>YYYY-MM-DD</emphasis>.
          </para>
+         <para>
+           This option requires a <filename>/etc/shadow</filename> file.
+           A <filename>/etc/shadow</filename> entry will be created if
+           there were none.
+         </para>
        </listitem>
       </varlistentry>
       <varlistentry>
            as the password has expired, and a value of -1 disables the
            feature.
          </para>
+         <para>
+           This option requires a <filename>/etc/shadow</filename> file.
+           A <filename>/etc/shadow</filename> entry will be created if
+           there were none.
+         </para>
        </listitem>
       </varlistentry>
       <varlistentry>
index 504ac5838ef55fb3d36092e36f6fd637899c3702..d4bd5b160be970edd2368a44c7d683c9ef8484a4 100644 (file)
@@ -417,7 +417,13 @@ static void new_pwent (struct passwd *pwent)
                         pwent->pw_name, user_newname));
                pwent->pw_name = xstrdup (user_newname);
        }
-       if (!is_shadow_pwd) {
+       /* Update the password in passwd if there is no shadow file or if
+        * the password is currently in passwd (pw_passwd != "x").
+        * We do not force the usage of shadow passwords if they are not
+        * used for this account.
+        */
+       if (   (!is_shadow_pwd)
+           || (strcmp (pwent->pw_passwd, SHADOW_PASSWD_STRING) != 0)) {
                pwent->pw_passwd = new_pw_passwd (pwent->pw_passwd);
        }
 
@@ -522,12 +528,23 @@ static void new_spent (struct spwd *spent)
                         spent->sp_namp, old_exp, new_exp));
                spent->sp_expire = user_newexpire;
        }
+
+       /* Always update the shadowed password if there is a shadow entry
+        * (even if shadowed passwords might not be enabled for this
+        * account (pw_passwd != "x")).
+        * It seems better to update the password in both places in case a
+        * shadow and a non shadow entry exist.
+        * This might occur if:
+        *  + there were already both entries
+        *  + aging has been requested
+        */
        spent->sp_pwdp = new_pw_passwd (spent->sp_pwdp);
+
        if (pflg) {
                spent->sp_lstchg = (long) time ((time_t *) 0) / SCALE;
                if (0 == spent->sp_lstchg) {
                        /* Better disable aging than requiring a password
-                        * change */
+                        * change. */
                        spent->sp_lstchg = -1;
                }
        }
@@ -1380,13 +1397,46 @@ static void usr_update (void)
        new_pwent (&pwent);
 
 
-       /* 
-        * Locate the entry in /etc/shadow. It doesn't have to exist, and
-        * won't be created if it doesn't.
-        */
-       if (is_shadow_pwd && ((spwd = spw_locate (user_name)) != NULL)) {
-               spent = *spwd;
-               new_spent (&spent);
+       /* If the shadow file does not exist, it won't be created */
+       if (is_shadow_pwd) {
+               spwd = spw_locate (user_name);
+               if (NULL != spwd) {
+                       /* Update the shadow entry if it exists */
+                       spent = *spwd;
+                       new_spent (&spent);
+               } else if (   (    pflg
+                              && (strcmp (pwent.pw_passwd, SHADOW_PASSWD_STRING) == 0))
+                          || eflg || fflg) {
+                       /* In some cases, we force the creation of a
+                        * shadow entry:
+                        *  + new password requested and passwd indicates
+                        *    a shadowed password
+                        *  + aging information is requested
+                        */
+                       memset (&spent, 0, sizeof spent);
+                       spent.sp_namp   = user_name;
+
+                       /* The user explicitly asked for a shadow feature.
+                        * Enable shadowed passwords for this new account.
+                        */
+                       spent.sp_pwdp   = xstrdup (pwent.pw_passwd);
+                       pwent.pw_passwd = xstrdup (SHADOW_PASSWD_STRING);
+
+                       spent.sp_lstchg = (long) time ((time_t *) 0) / SCALE;
+                       if (0 == spent.sp_lstchg) {
+                               /* Better disable aging than
+                                * requiring a password change */
+                               spent.sp_lstchg = -1;
+                       }
+                       spent.sp_min    = getdef_num ("PASS_MIN_DAYS", -1);
+                       spent.sp_max    = getdef_num ("PASS_MAX_DAYS", -1);
+                       spent.sp_warn   = getdef_num ("PASS_WARN_AGE", -1);
+                       spent.sp_inact  = -1;
+                       spent.sp_expire = -1;
+                       spent.sp_flag   = SHADOW_SP_FLAG_UNSET;
+                       new_spent (&spent);
+                       spwd = &spent; /* entry needs to be committed */
+               }
        }
 
        if (lflg || uflg || gflg || cflg || dflg || sflg || pflg