[Pkg-shadow-devel] Bug#264879: passwd: useradd allows invalid characters as username

Nicolas François Nicolas François , 264879@bugs.debian.org
Thu, 31 Mar 2005 00:40:34 +0200


--/9DWx/yDrRhgMJTb
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

tags 264879 patch
retitle 264879 [POST-SARGE] useradd: Colon allowed as username
thanks

On Mon, Dec 20, 2004 at 04:04:52AM +0700, David Garamond wrote:
> Not only does it allow colon, but also characters like newline which
> will corrupt the /etc/passwd database. Characters like '/' can also be
> considered invalid, since it will be impossible for the user to have a
> home directory with its name.

It's even worse: good_name does not return 0 on error.  So no checking
is performed.

I'm quite uncomfortable with this bug.  It may be more severe than normal,
but I also fear that fixing it now may break something else.  So the fix
should probably be delayed post Sarge.
A discussion should happen on usernames (e.g. are non-ASCII usernames
allowed?)

Currently, adduser uses a very restrictive regex ("^[a-z][-a-z0-9]*\$";
which can be disabled with --force-badname) and useradd doesn't check
anything.


Attached are:
  * a patch to fix good_name with the proposal from David (no ':', '/' or
    '\n').  There is still a lot of questionable usernames allowed
    (names containing a space or tab, starting by a digit, etc.)
  * the implementation from RedHat, which seems reasonable to me.  (maybe
    we should not allow usernames starting with a '-').
    useradd will still be much more permissive than adduser, but some
    reasonable checks will be performed.
    The RedHat equivalent regex is "^[a-zA-Z_][a-zA-Z0-9_-.]*\$?$"


Just for the record: good_name is used to check username (in useradd,
groupmod and pwck), and groupnames (in groupadd, groupmod and grpck).

Best Regards,
-- 
Nekral

--/9DWx/yDrRhgMJTb
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=redhat-good_name

static int
good_name(const char *name)
{
	/*
	 * User/group names must match [a-zA-Z_][a-zA-Z0-9_-.]*
	 */
	if (!*name || !((*name >= 'a' && *name <= 'z')
                         || (*name >= 'A' && *name <= 'Z') || *name == '_'))
		return 0;

	while (*++name) {
		if (!((*name >= 'a' && *name <= 'z') ||
		    (*name >= 'A' && *name <= 'Z') ||
		    (*name >= '0' && *name <= '9') ||
		    *name == '_' || *name == '-' || *name == '.' ||
		    (*name == '$' && *(name+1) == NULL)))
			return 0;
	}

	return 1;
}

--/9DWx/yDrRhgMJTb
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="chkname.c.patch"

--- chkname.c.orig	2005-03-30 23:07:08.000000000 +0200
+++ chkname.c	2005-03-31 00:08:32.000000000 +0200
@@ -37,11 +37,14 @@
 	}
 #endif
 	/* seeing no sufficiently good reason for the above... */
-	if (*name == '-')
-		return 1;
-	while (*++name)
-		if (*name == ':')
-			return 1;
+	if (*name == '\0' || *name == '-')
+		return 0;
+	/*
+	 * ':' and '\n' will break /etc/passwd
+	 * with '/' the home directory will be an issue
+	 */
+	if (strcspn (name, ":\n/") != strlen (name))
+		return 0;
 
 	return 1;
 }

--/9DWx/yDrRhgMJTb--