Hello,

Here is a fix for PR 56138, in which it is observed that chpass(1) and friends should not allow breaking the passwd databases by editing the username.

The problem:
--
# grep 1005 /etc/passwd
testuser:*:1005:0:,,,:/home/testuser:/bin/sh

# chpass testuser

# grep 1005 /etc/passwd
testuser:*:1005:0:,,,:/home/testuser:/bin/sh
newuser:*:1005:0:,,,:/home/testuser:/bin/sh
--


A fix, which is also attached as "cvs.diff":
--
Index: field.c
===================================================================
RCS file: /cvsroot/src/usr.bin/chpass/field.c,v
retrieving revision 1.12
diff -u -r1.12 field.c
--- field.c    11 Apr 2009 12:10:02 -0000    1.12
+++ field.c    29 Jul 2024 13:32:56 -0000
@@ -33,7 +33,7 @@
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)field.c    8.4 (Berkeley) 4/2/94";
-#else
+#else
 __RCSID("$NetBSD: field.c,v 1.12 2009/04/11 12:10:02 lukem Exp $");
 #endif
 #endif /* not lint */
@@ -57,26 +57,11 @@
 int
 p_login(const char *p, struct passwd *pw, ENTRY *ep)
 {
-
-    if (!*p) {
-        warnx("empty login field");
-        return (1);
-    }
-    if (*p == '-') {
-        warnx("login names may not begin with a hyphen");
-        return (1);
-    }
-    if (!(pw->pw_name = strdup(p))) {
-        warnx("can't save entry");
+    if (strcmp(p, pw->pw_name) != 0) {
+        warnx("you may not change the %s field", ep->prompt);
         return (1);
     }
-    if (strchr(p, '.'))
-        warnx("\'.\' is dangerous in a login name");
-    for (; *p; ++p)
-        if (isupper((unsigned char)*p)) {
-            warnx("upper-case letters are dangerous in a login name");
-            break;
-        }
+
     return (0);
 }

@@ -89,7 +74,7 @@
         warnx("can't save password entry");
         return (1);
     }
-
+
     return (0);
 }

@@ -145,7 +130,7 @@
     errno = 0;
     id = strtoul(p, &np, 10);
     /*
-     * We don't need to check the return value of strtoul()
+     * We don't need to check the return value of strtoul()
      * since ULONG_MAX is greater than GID_MAX.
      */
     if (*np || id > GID_MAX) {
@@ -165,7 +150,7 @@
         warnx("can't save entry");
         return (1);
     }
-
+
     return (0);
 }

--

Some trailing spaces were caught in the crossfire.

Testing the fix:
--
# /usr/src/usr.bin/chpass/chpass testuser
chpass: you may not change the login field
re-edit the password file? [y]:
--

Thanks.
J
Index: field.c
===================================================================
RCS file: /cvsroot/src/usr.bin/chpass/field.c,v
retrieving revision 1.12
diff -u -r1.12 field.c
--- field.c     11 Apr 2009 12:10:02 -0000      1.12
+++ field.c     29 Jul 2024 13:32:56 -0000
@@ -33,7 +33,7 @@
 #ifndef lint
 #if 0
 static char sccsid[] = "@(#)field.c    8.4 (Berkeley) 4/2/94";
-#else 
+#else
 __RCSID("$NetBSD: field.c,v 1.12 2009/04/11 12:10:02 lukem Exp $");
 #endif
 #endif /* not lint */
@@ -57,26 +57,11 @@
 int
 p_login(const char *p, struct passwd *pw, ENTRY *ep)
 {
-
-       if (!*p) {
-               warnx("empty login field");
-               return (1);
-       }
-       if (*p == '-') {
-               warnx("login names may not begin with a hyphen");
-               return (1);
-       }
-       if (!(pw->pw_name = strdup(p))) {
-               warnx("can't save entry");
+       if (strcmp(p, pw->pw_name) != 0) {
+               warnx("you may not change the %s field", ep->prompt);
                return (1);
        }
-       if (strchr(p, '.'))
-               warnx("\'.\' is dangerous in a login name");
-       for (; *p; ++p)
-               if (isupper((unsigned char)*p)) {
-                       warnx("upper-case letters are dangerous in a login 
name");
-                       break;
-               }
+
        return (0);
 }
 
@@ -89,7 +74,7 @@
                warnx("can't save password entry");
                return (1);
        }
-       
+
        return (0);
 }
 
@@ -145,7 +130,7 @@
        errno = 0;
        id = strtoul(p, &np, 10);
        /*
-        * We don't need to check the return value of strtoul() 
+        * We don't need to check the return value of strtoul()
         * since ULONG_MAX is greater than GID_MAX.
         */
        if (*np || id > GID_MAX) {
@@ -165,7 +150,7 @@
                warnx("can't save entry");
                return (1);
        }
-       
+
        return (0);
 }
 

Reply via email to