[Pkg-shadow-devel] [Git][debian/adduser][master] 11 commits: define and export default regexes

Marc Haber (@zugschlus) gitlab at salsa.debian.org
Wed Feb 19 06:57:09 GMT 2025



Marc Haber pushed to branch master at Debian / adduser


Commits:
4dfc3772 by Marc Haber at 2025-02-19T07:28:33+01:00
define and export default regexes

Git-Dch: ignore

- - - - -
448c6aa7 by Marc Haber at 2025-02-19T07:29:07+01:00
use default regexes to preseed config

Git-Dch: ignore

- - - - -
6bf4c41f by Marc Haber at 2025-02-19T07:29:39+01:00
adapt name regexes to new useradd behavior

- - - - -
71a96eb1 by Marc Haber at 2025-02-19T07:30:09+01:00
remove Unicode reference from length error message

Git-Dch: ignore

- - - - -
845ad67c by Marc Haber at 2025-02-19T07:30:57+01:00
explicitly check for single and double period user names

- - - - -
dead1f44 by Marc Haber at 2025-02-19T07:33:06+01:00
use qr for all digits regexp

Git-Dch: ignore

- - - - -
0083b162 by Marc Haber at 2025-02-19T07:33:24+01:00
improve all digits error message

Git-Dch: ignore

- - - - -
4bc22ab4 by Marc Haber at 2025-02-19T07:34:16+01:00
use ieee_regexp and min_regexp constants from AdduserCommon

Git-Dch: ignore

- - - - -
3be6fa35 by Marc Haber at 2025-02-19T07:34:46+01:00
synchronize regexps with main program

Git-Dch: ignore

- - - - -
6e92a695 by Marc Haber at 2025-02-19T07:35:15+01:00
test for negative digits and period user names

Git-Dch: ignore

- - - - -
7bbb7604 by Marc Haber at 2025-02-19T07:35:42+01:00
test for ascii special names

Git-Dch: ignore

- - - - -


4 changed files:

- AdduserCommon.pm
- adduser
- adduser.conf
- debian/tests/f/valid_username.t


Changes:

=====================================
AdduserCommon.pm
=====================================
@@ -67,6 +67,10 @@ use constant {
     numberre => qr/[0-9]+/,
     namere => qr/^([^-+~:,\s\/][^:,\s\/]*)$/aa,
     anynamere => qr/^([^-+~:,\s\/][^:,\s\/]*)$/aa,
+    def_name_regex => qr/^[a-zA-Z][a-zA-Z0-9_-]*\$?$/aa,
+    def_sys_name_regex => qr/^[a-zA-Z_][a-zA-Z0-9_-]*\$?$/aa,
+    def_ieee_name_regex => qr/^[a-zA-Z0-9_.][a-zA-Z0-9_.-]*\$?$/aa,
+    def_min_regex => qr(^[^-+~:,\s/][^:,\s/]*$)aa,
 };
 
 @EXPORT = (
@@ -84,14 +88,18 @@ use constant {
     'egetpwnam',
     'preseed_config',
     'which',
-    'namere',
-    'anynamere',
     "filenamere",
     "simplefilenamere",
     "pathre",
     "simplepathre",
     "commentre",
     "numberre",
+    'namere',
+    'anynamere',
+    'def_name_regex',
+    'def_sys_name_regex',
+    'def_ieee_name_regex',
+    'def_min_regex',
 );
 
 sub sanitize_string {
@@ -402,8 +410,8 @@ sub preseed_config {
         sys_dir_mode => "0755",
         setgid_home => "no",
         no_del_paths => "^/bin\$ ^/boot\$ ^/dev\$ ^/etc\$ ^/initrd ^/lib ^/lost+found\$ ^/media\$ ^/mnt\$ ^/opt\$ ^/proc\$ ^/root\$ ^/run\$ ^/sbin\$ ^/srv\$ ^/sys\$ ^/tmp\$ ^/usr\$ ^/var\$ ^/vmlinu",
-        name_regex     => "^[a-z][a-z0-9_-]*\\\$?\$",
-        sys_name_regex => "^[a-z_][a-z0-9_-]*\\\$?\$",
+        name_regex     => def_name_regex,
+        sys_name_regex => def_sys_name_regex,
         exclude_fstypes => "(proc|sysfs|usbfs|devpts|devtmpfs|devfs|afs)",
         skel_ignore_regex => "\.(dpkg|ucf)-(old|new|dist)\$",
         extra_groups => "users",


=====================================
adduser
=====================================
@@ -1273,30 +1273,33 @@ sub copy_to_dir {
 sub sanitize_name {
     my ($name) = @_;
 
-    my $ieee_regex = qr(^[_.A-Za-z0-9][-\@_.A-Za-z0-9]*\$?$);
-    my $min_regex = qr{^[^-+~:,\s/][^:,\s/]*$};
     my $name_regex_var = $found_sys_opt ? 'SYS_NAME_REGEX' : 'NAME_REGEX';
     my $name_regex = $config{lc $name_regex_var};
 
     log_trace("sanitize name %s called. name_regex_var %s, name_regex %s, Now testing all numeric. ", $name, $name_regex_var, $name_regex);
-    if ($name =~ /^[\d]+$/) {
+    if ($name =~ qr/^-?[\d]+$/) {
         # this check cannot be turned off
         log_err( mtx("To avoid ambiguity with numerical UIDs, usernames which
-            consist of only digits are not allowed.") );
+            resemble numbers or negative numbers are not allowed.") );
+        exit( RET_INVALID_CHARS_IN_NAME );
+    }
+
+    log_trace("sanitize_name testing single or double period");
+    if ( $name =~ qr/^\.\.?$/ ) {
+        # this check cannot be turned off
+        log_err( mtx("Usernames must not be a single or a double period.") );
         exit( RET_INVALID_CHARS_IN_NAME );
     }
 
     log_trace("sanitize_name testing > 32 chars");
     if (length( encode($charset, $name) ) > 32) {
         # this check cannot be turned off
-        log_err( mtx("Usernames must be no more than 32 bytes in length;
-            note that if you are using Unicode characters, the character
-            limit will be less than 32.") );
+        log_err( mtx("Usernames must be no more than 32 bytes in length.") );
         exit( RET_INVALID_CHARS_IN_NAME );
     }
 
-    log_trace("sanitize_name testing insane chars");
-    if ($name !~ $min_regex) {
+    log_trace("sanitize_name testing %s against insane chars %s", $name, def_min_regex);
+    if ($name !~ def_min_regex) {
         # this check cannot be turned off
         log_err( mtx("To avoid problems, the username must not start with a
             dash, plus sign, or tilde, and it must not contain any of the
@@ -1311,8 +1314,8 @@ sub sanitize_name {
         return $1;
     };
 
-    log_trace("sanitize_name testing ieee_regex %s", $ieee_regex);
-    if ($name !~ $ieee_regex && $name_check_level < 2) {
+    log_trace("sanitize_name checking %s ieee_regex %s", $name, def_ieee_name_regex);
+    if ($name !~ def_ieee_name_regex && $name_check_level < 2) {
         log_err( mtx("To avoid problems, the username should consist only of
             letters, digits, underscores, periods, at signs and dashes, and
             not start with a dash (as defined by IEEE Std 1003.1-2001). For


=====================================
adduser.conf
=====================================
@@ -82,14 +82,21 @@
 #QUOTAUSER=""
 
 # Non-system user- and groupnames are checked against this regular
-# expression.
-# Default: NAME_REGEX="^[a-z][-a-z0-9_]*\$?$"
-#NAME_REGEX="^[a-z][-a-z0-9_]*\$?$"
+# expression. RFC8265 would allow all codepoints U+0021 through U+007E
+# meaning: !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ plus digits, lower case and
+# capital letters. ., / and : clash with special file names, path separator
+# and /etc/passwd format, many other characters might cause issues in shell
+# scripts. Therefore, the default is more restrictive than RFC8265 would
+# allow. Local administrators might relax this regexp as far as useradd
+# will allow.
+# Default: NAME_REGEX="^[a-zA-Z][a-zA-Z0-9_-]*\$?$"
+#NAME_REGEX="^[a-zA-Z][a-zA-Z0-9_-]*\$?$"
 
 # System user- and groupnames are checked against this regular
-# expression.
-# Default: SYS_NAME_REGEX="^[a-z_][-a-z0-9_]*\$?$"
-#SYS_NAME_REGEX="^[a-z_][-a-z0-9_]*\$?$"
+# expression. Comments from above apply as well, but changes here may
+# affect package installation.
+# Default: SYS_NAME_REGEX="^[a-zA-Z_][a-zA-Z0-9_-]*\$?$"
+#SYS_NAME_REGEX="^[a-zA-Z_][a-zA-Z0-9_-]*\$?$"
 
 # When populating the newly created home directory of a non-system user,
 # files in SKEL matching this regex are not copied.


=====================================
debian/tests/f/valid_username.t
=====================================
@@ -39,20 +39,97 @@ use constant ABAD => 32;
 my %pat = (
     # these need to be in sync with the defaults in AdduserCommon.pm
     # Traditional Debian username patterns
-    deb     => qr{^[a-z][a-z0-9_-]*\$?$},
-    deb_sys => qr{^[a-z_][a-z0-9_-]*\$?$},
+    deb     => qr{^[a-zA-Z][a-zA-Z0-9_-]*\$?$},
+    deb_sys => qr{^[a-zA-Z_][a-zA-Z0-9_-]*\$?$},
     # Bare minimum restrictions supported by useradd
     min     => qr{^[^-+~:,\s/][^:,\s/]*$},
     # Don't check anything!
     all     => qr{^.+$},
     # this needs to be in sync with sanitize_name in adduser
     # Debian minimum (adduser v3.122) IEEE Std 1003.1-2001
-    ieee    => qr{^[_.A-Za-z0-9][-\@_.A-Za-z0-9]*\$?$},
+    ieee    => qr{^[a-zA-Z0-9_.][a-zA-Z0-9_.-]*\$?$},
     caps    => qr{^[A-Za-z0-9_.]+$}
 );
 
+# all digits, positive and negative
 test_name('12345', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
             $pat{min}, FAIL, FAIL|ALL);
+test_name('-12345', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+
+# single or double period
+test_name('.', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('..', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+
+# ASCII special characters
+test_name('abc!123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc"123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc#123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc$123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc%123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc&123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name("abc'123", FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc(123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc)123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc*123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc+123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc,123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc-123', PASS, PASS|BAD, PASS|FBAD, PASS|ABAD, PASS|ALL,
+            $pat{min}, PASS, PASS|ALL);
+test_name('abc.123', FAIL, PASS|BAD, PASS|FBAD, PASS|ABAD, PASS|ALL,
+            $pat{min}, PASS, PASS|ALL);
+test_name('abc/123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc:123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc;123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc<123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc=123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc>123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc>123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc?123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc at 123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc[123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc\123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc]123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc^123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc_123', PASS, PASS|BAD, PASS|FBAD, PASS|ABAD, PASS|ALL,
+            $pat{min}, PASS, PASS|ALL);
+test_name('abc`123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc{123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc|123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc}123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
+test_name('abc~123', FAIL, FAIL|BAD, FAIL|FBAD, FAIL|ABAD, FAIL|ALL,
+            $pat{min}, FAIL, FAIL|ALL);
 test_name('1abc33', FAIL, PASS|BAD);
 test_name('1abc33', FAIL, PASS|ABAD);
 test_name('1abc33', FAIL, PASS|FBAD);



View it on GitLab: https://salsa.debian.org/debian/adduser/-/compare/28f610f9f2ed243992fedfcf21ff9ce6ee76c5fd...7bbb7604d72dcc51e201904a14b21983ef487034

-- 
View it on GitLab: https://salsa.debian.org/debian/adduser/-/compare/28f610f9f2ed243992fedfcf21ff9ce6ee76c5fd...7bbb7604d72dcc51e201904a14b21983ef487034
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-shadow-devel/attachments/20250219/ec5d7bb2/attachment-0001.htm>


More information about the Pkg-shadow-devel mailing list