]> git.cameronkatri.com Git - pw-darwin.git/commitdiff
Changes so the 'pw' command will allow '$' as the last character in a userid
authorGarance A Drosehn <gad@FreeBSD.org>
Tue, 28 Jan 2003 01:21:57 +0000 (01:21 +0000)
committerGarance A Drosehn <gad@FreeBSD.org>
Tue, 28 Jan 2003 01:21:57 +0000 (01:21 +0000)
or group name (mainly for the benefit of samba).  This pretty much rewrites
he pw_checkname() routine, but should work exactly the same except for the
above change, and that error messages are somewhat more informative.

PR: 28733 46890
Inspired by: example patch written by Terry Lambert
Reviewed by: no objections on freebsd-arch and freebsd-current
MFC plans: no plans, but will do if people want it in stable.

pw/pw_user.c

index 456c954d21fe4c7345d2dc866b1afe24c86cbd42..a2d5e78dbbd5e33695ee67819b9a604106a50350 100644 (file)
@@ -1194,21 +1194,58 @@ print_user(struct passwd * pwd, int pretty, int v7)
 char    *
 pw_checkname(u_char *name, int gecos)
 {
-       int             l = 0;
-       char const     *notch = gecos ? ":!@" : " ,\t:+&#%$^()!@~*?<>=|\\/\"";
-
-       while (name[l]) {
-               if (strchr(notch, name[l]) != NULL || name[l] < ' ' || name[l] == 127 ||
-                       (!gecos && l==0 && name[l] == '-') ||   /* leading '-' */
-                       (!gecos && name[l] & 0x80))     /* 8-bit */
-                       errx(EX_DATAERR, (name[l] >= ' ' && name[l] < 127)
-                                           ? "invalid character `%c' in field"
-                                           : "invalid character 0x%02x in field",
-                                           name[l]);
-               ++l;
+       char showch[8];
+       u_char const *badchars, *ch, *showtype;
+       int reject;
+
+       ch = name;
+       reject = 0;
+       if (gecos) {
+               /* See if the name is valid as a gecos (comment) field. */
+               badchars = ":!@";
+               showtype = "gecos field";
+       } else {
+               /* See if the name is valid as a userid or group. */
+               badchars = " ,\t:+&#%$^()!@~*?<>=|\\/\"";
+               showtype = "userid/group name";
+               /* Userids and groups can not have a leading '-'. */
+               if (*ch == '-')
+                       reject = 1;
+       }
+       if (!reject) {
+               while (*ch) {
+                       if (strchr(badchars, *ch) != NULL || *ch < ' ' ||
+                           *ch == 127) {
+                               reject = 1;
+                               break;
+                       }
+                       /* 8-bit characters are only allowed in GECOS fields */
+                       if (!gecos && (*ch & 0x80)) {
+                               reject = 1;
+                               break;
+                       }
+                       ch++;
+               }
+       }
+       /*
+        * A `$' is allowed as the final character for userids and groups,
+        * mainly for the benefit of samba.
+        */
+       if (reject && !gecos) {
+               if (*ch == '$' && *(ch + 1) == '\0') {
+                       reject = 0;
+                       ch++;
+               }
+       }
+       if (reject) {
+               snprintf(showch, sizeof(showch), (*ch >= ' ' && *ch < 127)
+                   ? "`%c'" : "0x%02x", *ch);
+               errx(EX_DATAERR, "invalid character %s at position %d in %s",
+                   showch, (ch - name), showtype);
        }
-       if (!gecos && l > LOGNAMESIZE)
-               errx(EX_DATAERR, "name too long `%s'", name);
+       if (!gecos && (ch - name) > LOGNAMESIZE)
+               errx(EX_DATAERR, "name too long `%s' (max is %d)", name,
+                   LOGNAMESIZE);
        return (char *)name;
 }