From Gerhard.Sittig@gmx.net  Tue Nov 14 21:51:14 2000
Return-Path: <Gerhard.Sittig@gmx.net>
Received: from mail.gmx.net (pop.gmx.net [194.221.183.20])
	by hub.freebsd.org (Postfix) with SMTP id D73F537B4CF
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 14 Nov 2000 21:51:13 -0800 (PST)
Received: (qmail 15549 invoked by uid 0); 15 Nov 2000 05:51:11 -0000
Received: from p3ee2165e.dip.t-dialin.net (HELO speedy.gsinet) (62.226.22.94)
  by mail.gmx.net (mail06) with SMTP; 15 Nov 2000 05:51:11 -0000
Received: (from sittig@localhost)
	by speedy.gsinet (8.8.8/8.8.8) id WAA00991
	for FreeBSD-gnats-submit@freebsd.org; Tue, 14 Nov 2000 22:01:22 +0100
Message-Id: <20001114220122.N27042@speedy.gsinet>
Date: Tue, 14 Nov 2000 22:01:22 +0100
From: Gerhard Sittig <Gerhard.Sittig@gmx.net>
To: FreeBSD-gnats-submit@freebsd.org
In-Reply-To: <20001113124402.C21033@serv.gk-domain>; from GSittig@gk-soft.de on Mon, Nov 13, 2000 at 12:44:02PM +0100
Subject: [PATCH] adduser & friends with '$' in usernames
References: <20001113124402.C21033@serv.gk-domain>
X-Send-Pr-Version: 3.2

>Number:         22860
>Category:       bin
>Synopsis:       [PATCH] adduser & friends with '$' in usernames
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    gad
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Nov 14 22:00:01 PST 2000
>Closed-Date:    Mon Jan 27 18:38:11 PST 2003
>Last-Modified:  Mon Jan 27 18:38:11 PST 2003
>Originator:     Gerhard Sittig
>Release:        FreeBSD 4.1-STABLE i386
>Organization:
in private
>Environment:

adduser(8), rmuser(8), pw(8) administrative commands
and usernames with non-alphanumeric characters in them

>Description:

When dealing with NTdom functionality (in heterogenous networks
with NT machines in your LAN) the need arises to put dollar signs
into usernames.

Although they can be handled well when brought into the user
database manually, the "admin's frontend" tools mentioned above
deny to accept these names, since they don't fit a given pattern
the names are checked against.

>How-To-Repeat:

Just try to add or manipulate an account named "machine$" with
the given tools.  They will be claimed "invalid".

# adduser  (opens an interactive session,
            specify "machine$" as the username)
# rmuser machine\$
# pw useradd machine\$ -g machines -h -

>Fix:

The following patch extends the adduser(8) and rmuser(8) scripts
to accept dollar signs at the username's end.  It is drawn from
the command sequence

  cd /usr/src/usr.sbin/adduser
  cvs diff

Index: adduser.perl
===================================================================
RCS file: /home/ncvs/src/usr.sbin/adduser/adduser.perl,v
retrieving revision 1.44
diff -u -r1.44 adduser.perl
--- adduser.perl	1999/08/28 01:15:11	1.44
+++ adduser.perl	2000/11/13 08:51:00
@@ -304,7 +304,7 @@
     local($name);
 
     while(1) {
-	$name = &confirm_list("Enter username", 1, "a-z0-9_-", "");
+	$name = &confirm_list("Enter username", 1, "a-z0-9_-\$", "");
 	if (length($name) > 16) {
 	    warn "Username is longer than 16 chars\a\n";
 	    next;
@@ -317,9 +317,9 @@
 sub new_users_name_valid {
     local($name) = @_;
 
-    if ($name !~ /^[a-z0-9_][a-z0-9_\-]*$/ || $name eq "a-z0-9_-") {
+    if ($name !~ /^[a-z0-9_][a-z0-9_\-]*\$?$/ || $name eq "a-z0-9_-\$") {
 	warn "Wrong username. " .
-	    "Please use only lowercase characters or digits\a\n";
+	    "Please use only lowercase characters or digits and maybe a dollar sign at the end\a\n";
 	return 0;
     } elsif ($username{$name}) {
 	warn "Username ``$name'' already exists!\a\n"; return 0;
Index: rmuser.perl
===================================================================
RCS file: /home/ncvs/src/usr.sbin/adduser/rmuser.perl,v
retrieving revision 1.8.2.1
diff -u -r1.8.2.1 rmuser.perl
--- rmuser.perl	2000/03/20 13:00:36	1.8.2.1
+++ rmuser.perl	2000/11/13 08:50:01
@@ -107,8 +107,8 @@
 if ($#ARGV == 0) {
     # Username was given as a parameter
     $login_name = pop(@ARGV);
-    die "Sorry, login name must contain alphanumeric characters only.\n"
-	if ($login_name !~ /^[a-zA-Z0-9_]\w*$/);
+    die "Sorry, login name must contain alphanumeric characters only and may end with a dollar sign.\n"
+	if ($login_name !~ /^[a-zA-Z0-9_]\w*\$?$/);
 } else {
     if ($affirm) {
 	print STDERR "${whoami}: Error: -y option given without username!\n";
@@ -276,8 +276,8 @@
 	print "Enter login name for user to remove: ";
 	$login_name = <>;
 	chop $login_name;
-	if (!($login_name =~ /^[a-z0-9_][a-z0-9_\-]*$/)) {
-	    print STDERR "Sorry, login name must contain alphanumeric characters only.\n";
+	if (!($login_name =~ /^[a-z0-9_][a-z0-9_\-]*\$?$/)) {
+	    print STDERR "Sorry, login name must contain alphanumeric characters only and may end with a dollar sign.\n";
 	} elsif (length($login_name) > 16 || length($login_name) == 0) {
 	    print STDERR "Sorry, login name must be 16 characters or less.\n";
 	} else {

The following patch extends the pw(8) command to accept dollar
signs at the username's end.  It is drawn from the command
sequence

  cd /usr/src/usr.sbin/pw
  cvs diff

and has the "side effect" of making the pw_checkname() routine
easier to maintain when user names, group names, login classes
and gecos fields should differ in their handling in future.

Index: pw.h
===================================================================
RCS file: /home/ncvs/src/usr.sbin/pw/pw.h,v
retrieving revision 1.10.2.1
diff -u -r1.10.2.1 pw.h
--- pw.h	2000/06/28 19:19:04	1.10.2.1
+++ pw.h	2000/11/13 08:36:09
@@ -62,6 +62,15 @@
         W_NUM
 };
 
+enum _gecos
+{			/* pw_checkname() classes (plausi test) */
+	GEC_PWNAME,	/* user name field */
+	GEC_GROUP,	/* user group field */
+	GEC_CLASS,	/* default login class */
+	GEC_COMMENT,	/* gecos comment field */
+	GEC_MAXDIM	/* allowed patterns table dimensioning */
+};
+
 struct carg
 {
 	int		  ch;
@@ -105,7 +114,7 @@
 
 int pw_user(struct userconf * cnf, int mode, struct cargs * _args);
 int pw_group(struct userconf * cnf, int mode, struct cargs * _args);
-char    *pw_checkname(u_char *name, int gecos);
+char    *pw_checkname(u_char *name, enum _gecos gecos);
 
 int addpwent(struct passwd * pwd);
 int delpwent(struct passwd * pwd);
Index: pw_group.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/pw/pw_group.c,v
retrieving revision 1.12.2.1
diff -u -r1.12.2.1 pw_group.c
--- pw_group.c	2000/06/28 19:19:04	1.12.2.1
+++ pw_group.c	2000/11/13 08:36:58
@@ -135,7 +135,7 @@
 			grp->gr_gid = (gid_t) atoi(a_gid->val);
 
 		if ((arg = getarg(args, 'l')) != NULL)
-			grp->gr_name = pw_checkname((u_char *)arg->val, 0);
+			grp->gr_name = pw_checkname((u_char *)arg->val, GEC_GROUP);
 	} else {
 		if (a_name == NULL)	/* Required */
 			errx(EX_DATAERR, "group name required");
@@ -145,7 +145,7 @@
 		extendarray(&members, &grmembers, 200);
 		members[0] = NULL;
 		grp = &fakegroup;
-		grp->gr_name = pw_checkname((u_char *)a_name->val, 0);
+		grp->gr_name = pw_checkname((u_char *)a_name->val, GEC_GROUP);
 		grp->gr_passwd = "*";
 		grp->gr_gid = gr_gidpolicy(cnf, args);
 		grp->gr_mem = members;
Index: pw_user.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/pw/pw_user.c,v
retrieving revision 1.34.2.7
diff -u -r1.34.2.7 pw_user.c
--- pw_user.c	2000/09/20 11:19:55	1.34.2.7
+++ pw_user.c	2000/11/13 09:16:54
@@ -231,7 +231,7 @@
 		}
 	}
 	if ((arg = getarg(args, 'L')) != NULL)
-		cnf->default_class = pw_checkname((u_char *)arg->val, 0);
+		cnf->default_class = pw_checkname((u_char *)arg->val, GEC_CLASS);
 
 	if ((arg = getarg(args, 'G')) != NULL && arg->val) {
 		int i = 0;
@@ -293,7 +293,7 @@
 	}
 
 	if ((a_name = getarg(args, 'n')) != NULL)
-		pwd = GETPWNAM(pw_checkname((u_char *)a_name->val, 0));
+		pwd = GETPWNAM(pw_checkname((u_char *)a_name->val, GEC_PWNAME));
 	a_uid = getarg(args, 'u');
 
 	if (a_uid == NULL) {
@@ -455,7 +455,7 @@
 		if ((arg = getarg(args, 'l')) != NULL) {
 			if (strcmp(pwd->pw_name, "root") == 0)
 				errx(EX_DATAERR, "can't rename `root' account");
-			pwd->pw_name = pw_checkname((u_char *)arg->val, 0);
+			pwd->pw_name = pw_checkname((u_char *)arg->val, GEC_PWNAME);
 			edited = 1;
 		}
 
@@ -595,7 +595,7 @@
 	 * Shared add/edit code
 	 */
 	if ((arg = getarg(args, 'c')) != NULL) {
-		char	*gecos = pw_checkname((u_char *)arg->val, 1);
+		char	*gecos = pw_checkname((u_char *)arg->val, GEC_COMMENT);
 		if (strcmp(pwd->pw_gecos, gecos) != 0) {
 			pwd->pw_gecos = gecos;
 			edited = 1;
@@ -1208,22 +1208,29 @@
 }
 
 char    *
-pw_checkname(u_char *name, int gecos)
+pw_checkname(u_char *name, enum _gecos gecos)
 {
 	int             l = 0;
-	char const     *notch = gecos ? ":!@" : " ,\t:+&#%$^()!@~*?<>=|\\/\"";
+	static const char *notchtab[GEC_MAXDIM] = {
+		" ,\t:+&#%^()!@~*?<>=|\\/\"" , /* GEC_PWNAME */
+		" ,\t:+&#%$^()!@~*?<>=|\\/\"", /* GEC_GROUP */
+		" ,\t:+&#%$^()!@~*?<>=|\\/\"", /* GEC_CLASS */
+		":!@"                        , /* GEC_COMMENT */
+	};
+	char const     *notch = notchtab[gecos];
 
 	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 */
+			(gecos != GEC_COMMENT && l==0 && name[l] == '-') ||	/* leading '-' */
+			(gecos != GEC_COMMENT && name[l] == '$' && name[l+1]) ||	/* not a trailing '$' */
+			(gecos != GEC_COMMENT && 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;
 	}
-	if (!gecos && l > LOGNAMESIZE)
+	if (gecos != GEC_COMMENT && l > LOGNAMESIZE)
 		errx(EX_DATAERR, "name too long `%s'", name);
 	return (char *)name;
 }

Feel free to change the wording of printouts and to rearrange the
last check (LOGNAMESIZE length for anything that's not a gecos
field -- does it actually apply only to user names and group
names or maybe login classes, too?  I'm not sure of this.  As
well as I never tried dollar signs in anything that's not a user
name).


virtually yours   82D1 9B9C 01DC 4FB4 D7B4  61BE 3F49 4F77 72DE DA76
Gerhard Sittig   true | mail -s "get gpg key" Gerhard.Sittig@gmx.net
-- 
     If you don't understand or are scared by any of the above
             ask your parents or an adult to help you.

>Release-Note:
>Audit-Trail:

From: Sheldon Hearn <sheldonh@uunet.co.za>
To: freebsd-gnats-submit@freebsd.org
Cc:  
Subject: Re: bin/22860: [PATCH] adduser & friends with '$' in usernames 
Date: Thu, 23 Nov 2000 15:14:49 +0200

 There's been a lot of useless mumbling on this PR.
 
 Unless someone can come up with proof that the $ character is illegal in
 usernames, could everyone please stop arguing with the guy who keeps on
 bringing up Microsoft.  He's not listening and doesn't seem to be here
 to contribute.
 
 By the way, what I can dig out of my POSIX.1 book suggests that the $
 character, while not recommended, is legal.
 
 It's stupid not to support legal characters in usernames.  It may be
 stupid to use certain legal characters in usernames, but let's leave
 policy up to the administrator and provide tools that do the right
 thing.
 
 Ciao,
 Sheldon.
 

From: "Michael C . Wu" <keichii@iteration.net>
To: Gerhard Sittig <Gerhard.Sittig@gmx.net>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: bin/22860: [PATCH] adduser & friends with '$' in usernames
Date: Sat, 2 Dec 2000 08:47:54 -0600

 On Tue, Nov 14, 2000 at 10:01:22PM +0100, Gerhard Sittig scribbled:
 |
 | >Number:         22860
 | >Category:       bin
 | >Synopsis:       [PATCH] adduser & friends with '$' in usernames
 | >Confidential:   no
 | >Severity:       non-critical
 | >Priority:       low
 | >Responsible:    freebsd-bugs
 | >State:          open
 | >Quarter:
 | >Keywords:
 | >Date-Required:
 | >Class:          change-request
 | >Submitter-Id:   current-users
 | >Arrival-Date:   Tue Nov 14 22:00:01 PST 2000
 | >Closed-Date:
 | >Last-Modified:
 | >Originator:     Gerhard Sittig
 | >Release:        FreeBSD 4.1-STABLE i386
 | >Organization:
 | in private
 | >Environment:
 |
 | adduser(8), rmuser(8), pw(8) administrative commands
 | and usernames with non-alphanumeric characters in them
 
 Please commit this patch, we require this for I18N support.
 I have changes that are similiar to these changes.  Then we
 can do other stuff that I plan to change.
 
 --
 +------------------------------------------------------------------+
 | keichii@peorth.iteration.net         | keichii@bsdconspiracy.net |
 | http://peorth.iteration.net/~keichii | Yes, BSD is a conspiracy. |
 +------------------------------------------------------------------+
 

From: Gerhard Sittig <Gerhard.Sittig@gmx.net>
To: bug-followup@freebsd.org
Cc: yar@freebsd.org
Subject: Re: bin/22860: [PATCH] adduser & friends with '$' in usernames
Date: Thu, 3 Jan 2002 22:07:50 +0100

 To create some kind of "link" and to keep some kind of state or
 progress in the audit trail:  I understand this PR is heavily
 connected to bin/31049 (dots in usernames) and yar@freebsd.org
 tried to attack the issue in revs 1.51 and 1.52 of
 src/usr.sbin/adduser/adduser.perl as of 2002-01-02.
 
 Doug Barton fixed src/usr.sbin/adduser/rmuser.perl so it has
 been removing (well, "has been able to remove" might be better
 wording:) any existing user since rev 1.12 as of 2000-12-17.
 
 Yar Tikhi yesterday taught adduser.perl about an option to force
 the administrator's wish onto the system what the name should
 look like.  I have to state two points here:  I'm not completely
 sure about which characters are allowed in usernames while PR
 bin/31049 cites POSIX and talks about "characters from the
 portable filename character set".  So I cannot decide if the
 current implementation (short circuit *any* test except for
 "there must be a username" and "it must not contain a colon"
 because of the passwd(5) format) is going too far and would
 allow invalid usernames.  And I feel that the wording of the
 warn messages is too strong.  I would talk about "unexpected"
 or "not recommended" characters unless I'm sure they really
 _are_ invalid characters.  BTW:  Should there be a length check
 like in pw(8)?
 
 src/usr.sbin/pw/* hasn't been touched yet.  But I take it from
 the bin/31049 audit trail that yar is aware of this tool, too,
 and tries to sync both the Perl and the C version of the user
 database manipulating frontends -- once it's determined what a
 username is allowed to look like.
 
 
 virtually yours   82D1 9B9C 01DC 4FB4 D7B4  61BE 3F49 4F77 72DE DA76
 Gerhard Sittig   true | mail -s "get gpg key" Gerhard.Sittig@gmx.net
 -- 
      If you don't understand or are scared by any of the above
              ask your parents or an adult to help you.

From: Yar Tikhiy <yar@freebsd.org>
To: Gerhard Sittig <Gerhard.Sittig@gmx.net>
Cc: bug-followup@freebsd.org
Subject: Re: bin/22860: [PATCH] adduser & friends with '$' in usernames
Date: Sat, 5 Jan 2002 01:15:10 +0300

 On Thu, Jan 03, 2002 at 10:07:50PM +0100, Gerhard Sittig wrote:
 > 
 > Yar Tikhi yesterday taught adduser.perl about an option to force
 > the administrator's wish onto the system what the name should
 > look like.  I have to state two points here:  I'm not completely
 > sure about which characters are allowed in usernames while PR
 > bin/31049 cites POSIX and talks about "characters from the
 > portable filename character set".  So I cannot decide if the
 > current implementation (short circuit *any* test except for
 > "there must be a username" and "it must not contain a colon"
 > because of the passwd(5) format) is going too far and would
 > allow invalid usernames.  And I feel that the wording of the
 > warn messages is too strong.  I would talk about "unexpected"
 > or "not recommended" characters unless I'm sure they really
 > _are_ invalid characters.
 
 The problem is that there are no distinct grades of validity for
 characters to use in a username.  I did some simple tests that
 showed the base system could treat a number of weird characterd
 such as the whitespace, asterisk or dollar sign without any troubles.
 On the other hand, a poorly written program or (which is more
 likely) shell script may be tricked into doing illegitimate actions
 using such unusual usernames.  Someone would say even period is no
 good in usernames due to the NIS or Kerberos issues.
 
 As an alternative to the "allow anything the admin wants" solution,
 I would propose to make the regular expression usernames are checked
 against configurable and saved in /etc/adduser.conf.
 
 > BTW:  Should there be a length check like in pw(8)?
 
 There is one in adduser.perl; however, it's not in the obvious
 place: it's in "sub new_users_name" instead of "sub
 new_users_name_valid."
  
 > src/usr.sbin/pw/* hasn't been touched yet.  But I take it from
 > the bin/31049 audit trail that yar is aware of this tool, too,
 > and tries to sync both the Perl and the C version of the user
 > database manipulating frontends -- once it's determined what a
 > username is allowed to look like.
 
 pw has a maintainer: David Nugent (davidn.) I wrote him an email
 asking for help in this issue.  Honestly, adduser has a maintainer
 (wosch,) too, but its commit log lists so many FreeBSD folks
 modifying it without any sign of approval from wosch... :-)
 
 -- 
 Yar

From: Sheldon Hearn <sheldonh@starjuice.net>
To: Yar Tikhiy <yar@freebsd.org>
Cc: bug-followup@freebsd.org
Subject: Re: bin/22860: [PATCH] adduser & friends with '$' in usernames 
Date: Wed, 16 Jan 2002 17:08:23 +0200

 On Fri, 04 Jan 2002 15:10:01 PST, Yar Tikhiy wrote:
 
 >  As an alternative to the "allow anything the admin wants" solution,
 >  I would propose to make the regular expression usernames are checked
 >  against configurable and saved in /etc/adduser.conf.
 
 I like this idea.
 
 Either that, or do something like what passwd(1) does with weak new
 passwords root gives it. passwd(1) will warn against the offered
 password (e.g. "Please enter a password at least 6 characters in
 length") but will accept the new password if it is repeated.
 
 Ciao,
 Sheldon.

From: Yar Tikhiy <yar@freebsd.org>
To: Sheldon Hearn <sheldonh@starjuice.net>
Cc: bug-followup@freebsd.org
Subject: Re: bin/22860: [PATCH] adduser & friends with '$' in usernames
Date: Thu, 17 Jan 2002 03:34:58 +0300

 On Wed, Jan 16, 2002 at 05:08:23PM +0200, Sheldon Hearn wrote:
 > 
 > On Fri, 04 Jan 2002 15:10:01 PST, Yar Tikhiy wrote:
 > 
 > >  As an alternative to the "allow anything the admin wants" solution,
 > >  I would propose to make the regular expression usernames are checked
 > >  against configurable and saved in /etc/adduser.conf.
 > 
 > I like this idea.
 
 Ok, I've implemented that instead of the -force option.
 Would you mind trying the attached adduser.perl patch (it's against
 -current) and telling about your impression?
 
 -- 
 Yar
 
 Index: adduser.perl
 ===================================================================
 RCS file: /home/ncvs/src/usr.sbin/adduser/adduser.perl,v
 retrieving revision 1.53
 diff -u -r1.53 adduser.perl
 --- adduser.perl	4 Jan 2002 21:28:32 -0000	1.53
 +++ adduser.perl	17 Jan 2002 00:29:43 -0000
 @@ -30,7 +30,8 @@
  # read variables
  sub variables {
      $verbose = 1;		# verbose = [0-2]
 -    $force = 0;			# relax username validity check if true
 +    $usernameregexp = "^[a-z0-9_][a-z0-9_-]*\$"; # configurable
 +    $defaultusernameregexp = $usernameregexp; # remains constant
      $defaultusepassword = "yes";	# use password authentication for new users
      $defaultenableaccount = "yes"; # enable the account by default
      $defaultemptypassword = "no"; # don't create an empty password
 @@ -315,7 +316,7 @@
      local($name);
  
      while(1) {
 -	$name = &confirm_list("Enter username", 1, "a-z0-9_-", "");
 +	$name = &confirm_list("Enter username", 1, $usernameregexp, "");
  	if (length($name) > 16) {
  	    warn "Username is longer than 16 chars\a\n";
  	    next;
 @@ -328,29 +329,20 @@
  sub new_users_name_valid {
      local($name) = @_;
  
 -    if ($force) {
 -	if ($name eq "a-z0-9_-") {
 -	    warn "Please enter a username.\a\n";
 -	    return 0;
 -	}
 -	if ($name =~ /[:\n]/) {
 -	    warn "Illegal username, which would break your passwd file.\a\n";
 -	    return 0;
 +    if ($name eq $usernameregexp) {
 +	warn "Please enter a username\a\n";
 +	return 0;
 +    } elsif ($name !~ /$usernameregexp/) {
 +	if ($usernameregexp eq $defaultusernameregexp) {
 +	    warn "Illegal username.\n" .
 +		"Please use only lowercase Roman, decimal, underscore, " .
 +		"or hyphen characters.\n" .
 +		"Additionally, a username should not start with a hyphen.\a\n";
 +	} else {
 +	    warn "Username doesn't match the regexp /$usernameregexp/\a\n";
  	}
 -	if ($name !~ /^[a-z0-9_][a-z0-9_\-]*$/) {
 -	    warn "Caution: Username contains illegal characters.\n" .
 -		"Adding this user may cause utilities " .
 -		"or applications to malfunction,\n" .
 -		"or even impose a security risk on your system.\a\n";
 -	}
 -    } elsif ($name !~ /^[a-z0-9_][a-z0-9_\-]*$/ || $name eq "a-z0-9_-") {
 -	warn "Illegal username.\n" .
 -	    "Please use only lowercase Roman, decimal, underscore, " .
 -	    "or hyphen characters.\n" .
 -	    "Additionally, a username should not start with a hyphen.\a\n";
  	return 0;
 -    }
 -    if ($username{$name}) {
 +    } elsif ($username{$name}) {
  	warn "Username ``$name'' already exists!\a\n"; return 0;
      }
      return 1;
 @@ -878,7 +870,6 @@
      [-class login_class]
      [-config_create]
      [-dotdir dotdir]
 -    [-f|-force]
      [-group login_group]
      [-h|-help]
      [-home home]
 @@ -952,7 +943,6 @@
  	if    (/^--?(v|verbose)$/)	{ $verbose = 1 }
  	elsif (/^--?(s|silent|q|quiet)$/)  { $verbose = 0 }
  	elsif (/^--?(debug)$/)	    { $verbose = 2 }
 -	elsif (/^--?(f|force)$/)	{ $force = 1 }
  	elsif (/^--?(h|help|\?)$/)	{ &usage }
  	elsif (/^--?(home)$/)	 { $home = $argv[0]; shift @argv }
  	elsif (/^--?(shell)$/)	 { $defaultshell = $argv[0]; shift @argv }
 @@ -1223,6 +1213,21 @@
      return 0;
  }
  
 +# allow configuring usernameregexp
 +sub usernameregexp_default {
 +    local($r) = $usernameregexp;
 +
 +    while ($verbose) {
 +	$r = &confirm_list("Usernames must match regular expression:", 1,
 +	    $r, "");
 +	eval "'foo' =~ /$r/";
 +	last unless $@;
 +	warn "Invalid regular expression\a\n";
 +    }
 +    $changes++ if $r ne $usernameregexp;
 +    return $r;
 +}
 +
  # test if $dotdir exist
  # return "no" if $dotdir not exist or dotfiles should not copied
  sub dotdir_default {
 @@ -1438,6 +1443,10 @@
  # verbose = [0-2]
  verbose = $verbose
  
 +# regular expression usernames are checked against (see perlre(1))
 +# usernameregexp = 'regexp'
 +usernameregexp = '$usernameregexp'
 +
  # use password-based authentication for new users
  # defaultusepassword =  "yes" | "no"
  defaultusepassword = "$defaultusepassword"
 @@ -1522,6 +1531,7 @@
  
  # interactive
  # some questions
 +$usernameregexp = &usernameregexp_default; # regexp to check usernames against
  &shells_add;			# maybe add some new shells
  $defaultshell = &shell_default;	# enter default shell
  $home = &home_partition($home);	# find HOME partition

From: Sheldon Hearn <sheldonh@starjuice.net>
To: Yar Tikhiy <yar@freebsd.org>
Cc: bug-followup@freebsd.org
Subject: Re: bin/22860: [PATCH] adduser & friends with '$' in usernames 
Date: Thu, 24 Jan 2002 14:47:33 +0200

 On Thu, 17 Jan 2002 03:34:58 +0300, Yar Tikhiy wrote:
 
 > Ok, I've implemented that instead of the -force option.
 > Would you mind trying the attached adduser.perl patch (it's against
 > -current) and telling about your impression?
 
 Hi Yar,
 
 Sorry about the delay.  I don't have time to test this properly at the
 moment.  All I can tell you is that the patch looks okay, although
 adding a comment that explains the odd return values would be a good
 idea. :-)
 
 Ciao,
 Sheldon.
Responsible-Changed-From-To: freebsd-bugs->yar 
Responsible-Changed-By: sheldonh 
Responsible-Changed-When: Mon Jan 28 05:35:11 PST 2002 
Responsible-Changed-Why:  
Over to the guy with the patch. :-) 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=22860 

From: "Yar Tikhiy" <yar@comp.chem.msu.su>
To: <freebsd-gnats-submit@FreeBSD.org>, <Gerhard.Sittig@gmx.net>
Cc:  
Subject: Re: bin/22860: [PATCH] adduser 
Date: Fri, 15 Feb 2002 20:43:42 +0300

 Adduser in -current and -stable can be now configured to
 allow usernames matching a desirable regular expression.
 I hope I will be able to do something about pw(8) some day.
 If someone comes with a solution for pw(8) before that, I'll
 pass this PR to him happily.
 
State-Changed-From-To: open->closed 
State-Changed-By: gad 
State-Changed-When: Mon Jan 27 18:36:23 PST 2003 
State-Changed-Why:  
I have installed a change to pw/pw_user.c which should address 
the last piece of this PR.  The change is only in freebsd-current, 
but I assume that will be good enough. 


Responsible-Changed-From-To: yar->gad 
Responsible-Changed-By: gad 
Responsible-Changed-When: Mon Jan 27 18:36:23 PST 2003 
Responsible-Changed-Why:  
I have installed a change to pw/pw_user.c which should address 
the last piece of this PR.  The change is only in freebsd-current, 
but I assume that will be good enough. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=22860 
>Unformatted:
