summaryrefslogtreecommitdiffstats
path: root/pw
diff options
context:
space:
mode:
authorGarance A Drosehn <gad@FreeBSD.org>2003-01-28 01:21:57 +0000
committerGarance A Drosehn <gad@FreeBSD.org>2003-01-28 01:21:57 +0000
commit05629a18e9a053a748b4fe799031ac940a6758e7 (patch)
tree442596ba4f8aeae980edf6223f0f5e28ebdd0389 /pw
parentab19769c21029b9edfb079615d83f00ff64cbf85 (diff)
downloadpw-darwin-05629a18e9a053a748b4fe799031ac940a6758e7.tar.gz
pw-darwin-05629a18e9a053a748b4fe799031ac940a6758e7.tar.zst
pw-darwin-05629a18e9a053a748b4fe799031ac940a6758e7.zip
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.
Diffstat (limited to 'pw')
-rw-r--r--pw/pw_user.c65
1 files changed, 51 insertions, 14 deletions
diff --git a/pw/pw_user.c b/pw/pw_user.c
index 456c954..a2d5e78 100644
--- a/pw/pw_user.c
+++ b/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:+&#%$^()!@~*?<>=|\\/\"";
-
- 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;
}