diff -Nru shadow-4.8.1/debian/changelog shadow-4.8.1/debian/changelog --- shadow-4.8.1/debian/changelog 2021-01-06 23:05:37.000000000 -0600 +++ shadow-4.8.1/debian/changelog 2021-06-17 14:35:15.000000000 -0500 @@ -1,3 +1,11 @@ +shadow (1:4.8.1-1ubuntu9) impish; urgency=medium + + * Disallow purely numeric usernames. This includes usernames + that are hexadecimal, octal, and floating point representations + of numbers (LP: #1927078) + + -- William 'jawn-smith' Wilson Thu, 17 Jun 2021 14:35:15 -0500 + shadow (1:4.8.1-1ubuntu8) hirsute; urgency=medium * Enable private home directories by default (LP: #48734) diff -Nru shadow-4.8.1/debian/patches/506_relaxed_usernames shadow-4.8.1/debian/patches/506_relaxed_usernames --- shadow-4.8.1/debian/patches/506_relaxed_usernames 2020-02-07 09:32:06.000000000 -0600 +++ shadow-4.8.1/debian/patches/506_relaxed_usernames 2021-06-17 14:35:15.000000000 -0500 @@ -25,7 +25,7 @@ /* * User/group names must match [a-z_][a-z0-9_-]*[$] */ -@@ -73,6 +74,26 @@ +@@ -73,7 +74,51 @@ return false; } } @@ -37,24 +37,49 @@ + * + * Allow more relaxed user/group names in Debian -- ^[^-~+:,\s][^:,\s]*$ + */ ++ bool is_numeric = true; ++ bool is_hex = true; ++ /* ++ * We skip the hex check for the first two characters in the loop, and ++ * inspect them individually before the loop starts. This checks for "0x" ++ * at the beginning of the username while still treating "x" as a ++ * non-numeric character in all other scenarios ++ */ ++ int chars_checked = 0; ++ + if ( ('\0' == *name) + || ('-' == *name) + || ('~' == *name) + || ('+' == *name)) { + return false; + } ++ /* if the username does not start with "0x" it is not hexadecimal */ ++ if (*name != '0' || *(name + 1) != 'x') { ++ is_hex = false; ++ } + do { + if ((':' == *name) || (',' == *name) || isspace(*name)) { + return false; + } ++ if ((*name < '0' || *name > '9') && *name != '.') { ++ is_numeric = false; ++ if ((*name < 'A' || *name > 'F') && chars_checked >= 2) { ++ is_hex = false; ++ } ++ } ++ chars_checked++; + name++; + } while ('\0' != *name); ++ if (is_numeric || is_hex) { ++ return false; ++ } return true; } + --- a/man/useradd.8.xml +++ b/man/useradd.8.xml -@@ -662,12 +662,20 @@ +@@ -662,12 +662,26 @@ @@ -73,12 +98,18 @@ + user's home directory. + + ++ On Ubuntu, the same constraints as Debian are in place, with the ++ additional constraint that the username cannot be fully numeric. ++ This includes octal, hexadecimal, and floating point representations ++ of numbers. ++ ++ Usernames may only be up to 32 characters long. --- a/man/groupadd.8.xml +++ b/man/groupadd.8.xml -@@ -273,12 +273,18 @@ +@@ -273,12 +273,24 @@ CAVEATS @@ -94,6 +125,12 @@ + colon (':'), a comma (','), or a whitespace (space:' ', + end of line: '\n', tabulation: '\t', etc.). + ++ ++ On Ubuntu, the same constraints as Debian are in place, with the ++ additional constraint that the groupname cannot be fully numeric. ++ This includes octal, hexadecimal, and floating point representations ++ of numbers. ++ + Groupnames may only be up to &GROUP_NAME_MAX_LENGTH; characters long. diff -Nru shadow-4.8.1/debian/tests/control shadow-4.8.1/debian/tests/control --- shadow-4.8.1/debian/tests/control 2020-03-09 04:33:50.000000000 -0500 +++ shadow-4.8.1/debian/tests/control 2021-06-17 14:35:15.000000000 -0500 @@ -1,2 +1,2 @@ -Tests: smoke +Tests: smoke, numeric-username Restrictions: needs-root, allow-stderr diff -Nru shadow-4.8.1/debian/tests/numeric-username shadow-4.8.1/debian/tests/numeric-username --- shadow-4.8.1/debian/tests/numeric-username 1969-12-31 18:00:00.000000000 -0600 +++ shadow-4.8.1/debian/tests/numeric-username 2021-06-17 14:35:15.000000000 -0500 @@ -0,0 +1,25 @@ +#!/bin/sh + +set -ux + +# purely numeric usernames are considered invalid +for invalidUsername in "0" "00" "0123456789" "0x0" "0x0123456789" "0.0" "12345.06789" +do + useradd $invalidUsername + ret=$? + if [ $ret -eq 0 ] + then + exit 1 + fi +done + +# usernames that start with a digit and contain other valid characters should not fail +for validUsername in "0root" "0123456789root" "0-0" "0_0" "0.o" "0xo" "0-o" "0_o" "0x0x0x0" +do + useradd $validUsername + ret=$? + if [ $ret -ne 0 ] + then + exit 1 + fi +done