From 84a0950aeafd4a17e8dc8b5b04e0c82f88eb08ae Mon Sep 17 00:00:00 2001 From: Garance A Drosehn Date: Tue, 28 Jan 2003 01:21:57 +0000 Subject: [PATCH] Changes so the 'pw' command will allow '$' as the last character in a userid 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. --- usr.sbin/pw/pw_user.c | 63 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/usr.sbin/pw/pw_user.c b/usr.sbin/pw/pw_user.c index 456c954d21fe..a2d5e78dbbd5 100644 --- a/usr.sbin/pw/pw_user.c +++ b/usr.sbin/pw/pw_user.c @@ -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:+&#%$^()!@~*?<>=|\\/\""; + char showch[8]; + u_char const *badchars, *ch, *showtype; + int reject; - 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; + 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 (!gecos && l > LOGNAMESIZE) - errx(EX_DATAERR, "name too long `%s'", name); + 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 && (ch - name) > LOGNAMESIZE) + errx(EX_DATAERR, "name too long `%s' (max is %d)", name, + LOGNAMESIZE); return (char *)name; }