From: Alejandro Colomar Date: Sun, 12 Jul 2026 14:22:17 +0000 (+0200) Subject: lib/, src/, tests/: Pass the badname flag as a function parameter X-Git-Tag: 4.20.0-rc3~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4df3f783c4d936e6985590981a2ddaf0377a3785;p=thirdparty%2Fshadow.git lib/, src/, tests/: Pass the badname flag as a function parameter ... instead of an extern variable. This makes it easier to analyze which programs allow badnames and which don't. Signed-off-by: Alejandro Colomar --- diff --git a/lib/chkname.c b/lib/chkname.c index ee8ff9d10..2f80740db 100644 --- a/lib/chkname.c +++ b/lib/chkname.c @@ -20,8 +20,6 @@ #include "config.h" -#ident "$Id$" - #include #include #include @@ -45,11 +43,8 @@ #define LABEL_MAXLEN 63 -int allow_bad_names = false; - - static bool -is_valid_name(const char *name) +is_valid_name(const char *name, bool badnames) { if (streq(name, "") || streq(name, ".") @@ -63,9 +58,8 @@ is_valid_name(const char *name) return false; } - if (allow_bad_names) { + if (badnames) return true; - } /* * User/group names must match BRE regex: @@ -105,19 +99,19 @@ is_valid_name(const char *name) bool -is_valid_user_name(const char *name) +is_valid_user_name(const char *name, bool badnames) { if (strlen(name) >= LOGIN_NAME_MAX) { errno = EOVERFLOW; return false; } - return is_valid_name(name); + return is_valid_name(name, badnames); } bool -is_valid_group_name(const char *name) +is_valid_group_name(const char *name, bool badnames) { /* * Arbitrary limit for group names. @@ -130,7 +124,7 @@ is_valid_group_name(const char *name) return false; } - return is_valid_name (name); + return is_valid_name(name, badnames); } @@ -196,7 +190,7 @@ is_valid_domain_name(const char *domain) * in any authentication system. */ bool -is_valid_upn(const char *upn) +is_valid_upn(const char *upn, bool badnames) { char *u, *d; @@ -212,5 +206,5 @@ is_valid_upn(const char *upn) return false; } - return is_valid_user_name(u) && is_valid_domain_name(d); + return is_valid_user_name(u, badnames) && is_valid_domain_name(d); } diff --git a/lib/chkname.h b/lib/chkname.h index de93b8251..43766e66b 100644 --- a/lib/chkname.h +++ b/lib/chkname.h @@ -26,8 +26,8 @@ #include -extern bool is_valid_user_name (const char *name); -extern bool is_valid_group_name (const char *name); -extern bool is_valid_upn (const char *name); +extern bool is_valid_user_name(const char *name, bool badnames); +extern bool is_valid_group_name(const char *name, bool badnames); +extern bool is_valid_upn(const char *name, bool badnames); #endif diff --git a/src/chfn.c b/src/chfn.c index 71875253e..966919bc6 100644 --- a/src/chfn.c +++ b/src/chfn.c @@ -604,7 +604,7 @@ int main (int argc, char **argv) * name, or the name getlogin() returns. */ if (optind < argc) { - if (!is_valid_user_name (argv[optind])) { + if (!is_valid_user_name(argv[optind], false)) { fprintf (stderr, _("%s: Provided user name is not a valid name\n"), Prog); fail_exit (E_NOPERM, process_selinux); } diff --git a/src/chsh.c b/src/chsh.c index fafa9759d..0e3a6923f 100644 --- a/src/chsh.c +++ b/src/chsh.c @@ -493,7 +493,7 @@ int main (int argc, char **argv) * name, or the name getlogin() returns. */ if (optind < argc) { - if (!is_valid_user_name (argv[optind])) { + if (!is_valid_user_name(argv[optind], false)) { fprintf (stderr, _("%s: Provided user name is not a valid name\n"), Prog); fail_exit (1, process_selinux); } diff --git a/src/groupadd.c b/src/groupadd.c index 3c4ac8b13..275371727 100644 --- a/src/groupadd.c +++ b/src/groupadd.c @@ -260,7 +260,7 @@ grp_update(void) static void check_new_name(void) { - if (!is_valid_group_name(group_name)) { + if (!is_valid_group_name(group_name, false)) { fprintf(stderr, _("%s: '%s' is not a valid group name\n"), Prog, group_name); diff --git a/src/groupmod.c b/src/groupmod.c index 0ad7a3073..5056faffe 100644 --- a/src/groupmod.c +++ b/src/groupmod.c @@ -382,7 +382,7 @@ check_new_name(void) return; } - if (!is_valid_group_name(group_newname)) { + if (!is_valid_group_name(group_newname, false)) { fprintf(stderr, _("%s: invalid group name '%s'\n"), Prog, group_newname); diff --git a/src/grpck.c b/src/grpck.c index 385c105e8..76c191dd7 100644 --- a/src/grpck.c +++ b/src/grpck.c @@ -580,7 +580,7 @@ static void check_grp_file(bool *errors, bool *changed, const struct option_flag /* * Check for invalid group names. --marekm */ - if (!is_valid_group_name (grp->gr_name)) { + if (!is_valid_group_name(grp->gr_name, false)) { *errors = true; printf (_("invalid group name '%s'\n"), grp->gr_name); } diff --git a/src/newgrp.c b/src/newgrp.c index afe4d8518..f7671ae4f 100644 --- a/src/newgrp.c +++ b/src/newgrp.c @@ -480,7 +480,7 @@ int main (int argc, char **argv) * not "newgrp". */ if ((argc > 0) && (argv[0][0] != '-')) { - if (!is_valid_group_name (argv[0])) { + if (!is_valid_group_name(argv[0], false)) { fprintf ( stderr, _("%s: provided group is not a valid group name\n"), Prog); @@ -516,7 +516,7 @@ int main (int argc, char **argv) usage (); goto failure; } else if (argv[0] != NULL) { - if (!is_valid_group_name (argv[0])) { + if (!is_valid_group_name(argv[0], false)) { fprintf ( stderr, _("%s: provided group is not a valid group name\n"), Prog); diff --git a/src/newusers.c b/src/newusers.c index b316d8b5c..c66f7ee4d 100644 --- a/src/newusers.c +++ b/src/newusers.c @@ -70,6 +70,7 @@ struct option_flags { */ static const char Prog[] = "newusers"; +static bool bflg = false; static bool rflg = false; /* create a system account */ #ifndef USE_PAM static /*@null@*//*@observer@*/char *crypt_method = NULL; @@ -114,7 +115,6 @@ static void check_flags (void); static void open_files (bool process_selinux); static void close_files(const struct option_flags *flags); -extern int allow_bad_names; /* * usage - display usage message and exit @@ -288,7 +288,7 @@ static int add_group (const char *name, const char *gid, gid_t *ngid, uid_t uid) } /* Check if this is a valid group name */ - if (!is_valid_group_name (grent.gr_name)) { + if (!is_valid_group_name(grent.gr_name, bflg)) { fprintf (stderr, _("%s: invalid group name '%s'\n"), Prog, grent.gr_name); @@ -385,7 +385,7 @@ static int add_user (const char *name, uid_t uid, gid_t gid) struct passwd pwent; /* Check if this is a valid user name */ - if (!is_valid_user_name(name)) { + if (!is_valid_user_name(name, bflg)) { if (errno == EILSEQ) { fprintf(stderr, _("%s: invalid user name '%s': use --badname to ignore\n"), @@ -643,7 +643,7 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) long_options, NULL)) != -1) { switch (c) { case 'b': - allow_bad_names = true; + bflg = true; break; #ifndef USE_PAM case 'c': diff --git a/src/passwd.c b/src/passwd.c index 1873bf89f..83b45f63c 100644 --- a/src/passwd.c +++ b/src/passwd.c @@ -946,7 +946,7 @@ main(int argc, char **argv) } myname = xstrdup (pw->pw_name); if (optind < argc) { - if (!is_valid_user_name (argv[optind]) && !is_valid_upn (argv[optind])) { + if (!is_valid_user_name(argv[optind], false) && !is_valid_upn(argv[optind], false)) { fprintf (stderr, _("%s: Provided user name is not a valid name\n"), Prog); fail_exit (E_NOPERM, process_selinux); } diff --git a/src/pwck.c b/src/pwck.c index 0413f3f8e..954cf3a8a 100644 --- a/src/pwck.c +++ b/src/pwck.c @@ -68,6 +68,7 @@ static bool pw_locked = false; static bool spw_locked = false; /* Options */ +static bool bflg = false; static bool read_only = false; static bool sort_mode = false; static bool quiet = false; /* don't report warnings, only errors */ @@ -82,7 +83,6 @@ static void check_pw_file (bool *errors, bool *changed, const struct option_flags *flags); static void check_spw_file (bool *errors, bool *changed); -extern int allow_bad_names; /* * fail_exit - do some cleanup and exit with the given error code @@ -178,7 +178,7 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) long_options, NULL)) != -1) { switch (c) { case 'b': - allow_bad_names = true; + bflg = true; break; case 'h': usage (E_SUCCESS); @@ -486,7 +486,7 @@ static void check_pw_file(bool *errors, bool *changed, const struct option_flags * Check for invalid usernames. --marekm */ - if (!is_valid_user_name(pwd->pw_name)) { + if (!is_valid_user_name(pwd->pw_name, bflg)) { if (errno == EILSEQ) { printf(_("invalid user name '%s': use --badname to ignore\n"), pwd->pw_name); diff --git a/src/useradd.c b/src/useradd.c index 81798b6af..9b52c8fc8 100644 --- a/src/useradd.c +++ b/src/useradd.c @@ -160,9 +160,8 @@ static char **user_groups; /* NULL-terminated list */ static size_t sys_ngroups; static bool do_grp_update = false; /* group files need to be updated */ -extern int allow_bad_names; - static bool + badnameflg = false, bflg = false, /* new default root of home directory */ cflg = false, /* comment (GECOS) field for new account */ dflg = false, /* home directory for new account */ @@ -1215,7 +1214,7 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) subvolflg = true; break; case 201: - allow_bad_names = true; + badnameflg = true; break; case 'c': if (!VALID (optarg)) { @@ -1516,7 +1515,7 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) } user_name = argv[optind]; - if (!is_valid_user_name(user_name)) { + if (!is_valid_user_name(user_name, badnameflg)) { if (errno == EILSEQ) { fprintf(stderr, _("%s: invalid user name '%s': use --badname to ignore\n"), diff --git a/src/usermod.c b/src/usermod.c index 5a2222638..31addeb34 100644 --- a/src/usermod.c +++ b/src/usermod.c @@ -147,6 +147,7 @@ static char* prefix_user_newhome = NULL; static bool aflg = false, /* append to existing secondary group set */ + bflg = false, cflg = false, /* new comment (GECOS) field */ dflg = false, /* new home directory */ eflg = false, /* days since 1970-01-01 when account becomes expired */ @@ -225,7 +226,6 @@ static void update_faillog (void); static void move_mailbox (void); #endif -extern int allow_bad_names; /* * get_groups - convert a list of group names to an array of group IDs @@ -1084,7 +1084,7 @@ process_flags(int argc, char **argv, struct option_flags *flags) aflg = true; break; case 'b': - allow_bad_names = true; + bflg = true; break; case 'c': if (!VALID (optarg)) { @@ -1159,7 +1159,7 @@ process_flags(int argc, char **argv, struct option_flags *flags) usage (E_SUCCESS); /*@notreached@*/break; case 'l': - if (!is_valid_user_name(optarg)) { + if (!is_valid_user_name(optarg, bflg)) { if (errno == EILSEQ) { fprintf(stderr, _("%s: invalid user name '%s': use --badname to ignore\n"), diff --git a/tests/unit/test_chkname.c b/tests/unit/test_chkname.c index a211b9f59..56af7afa1 100644 --- a/tests/unit/test_chkname.c +++ b/tests/unit/test_chkname.c @@ -66,15 +66,15 @@ main(void) static void test_is_valid_user_name_ok(MAYBE_UNUSED void ** _1) { - assert_true(is_valid_user_name("alx")); - assert_true(is_valid_user_name("u-ser")); - assert_true(is_valid_user_name("u")); - assert_true(is_valid_user_name("I")); - assert_true(is_valid_user_name("_")); - assert_true(is_valid_user_name("_.-")); - assert_true(is_valid_user_name(".007")); - assert_true(is_valid_user_name("0_0")); - assert_true(is_valid_user_name("some_longish_user_name_sHould_also_be_valid.wHY_not")); + assert_true(is_valid_user_name("alx", false)); + assert_true(is_valid_user_name("u-ser", false)); + assert_true(is_valid_user_name("u", false)); + assert_true(is_valid_user_name("I", false)); + assert_true(is_valid_user_name("_", false)); + assert_true(is_valid_user_name("_.-", false)); + assert_true(is_valid_user_name(".007", false)); + assert_true(is_valid_user_name("0_0", false)); + assert_true(is_valid_user_name("some_longish_user_name_sHould_also_be_valid.wHY_not", false)); } @@ -82,61 +82,61 @@ static void test_is_valid_user_name_ok_dollar(MAYBE_UNUSED void ** _1) { // Non-POSIX extension for Samba 3.x "add machine script". - assert_true(is_valid_user_name("dollar$")); - assert_true(is_valid_user_name("SSS$")); + assert_true(is_valid_user_name("dollar$", false)); + assert_true(is_valid_user_name("SSS$", false)); } static void test_is_valid_user_name_nok_dash(MAYBE_UNUSED void ** _1) { - assert_true(false == is_valid_user_name("-")); - assert_true(false == is_valid_user_name("-not-valid")); - assert_true(false == is_valid_user_name("--C")); + assert_true(false == is_valid_user_name("-", false)); + assert_true(false == is_valid_user_name("-not-valid", false)); + assert_true(false == is_valid_user_name("--C", false)); } static void test_is_valid_user_name_nok_dir(MAYBE_UNUSED void ** _1) { - assert_true(false == is_valid_user_name(".")); - assert_true(false == is_valid_user_name("..")); + assert_true(false == is_valid_user_name(".", false)); + assert_true(false == is_valid_user_name("..", false)); } static void test_is_valid_user_name_nok_dollar(MAYBE_UNUSED void ** _1) { - assert_true(false == is_valid_user_name("$")); - assert_true(false == is_valid_user_name("$dollar")); - assert_true(false == is_valid_user_name("mo$ney")); - assert_true(false == is_valid_user_name("do$$ar")); - assert_true(false == is_valid_user_name("foo$bar$")); + assert_true(false == is_valid_user_name("$", false)); + assert_true(false == is_valid_user_name("$dollar", false)); + assert_true(false == is_valid_user_name("mo$ney", false)); + assert_true(false == is_valid_user_name("do$$ar", false)); + assert_true(false == is_valid_user_name("foo$bar$", false)); } static void test_is_valid_user_name_nok_empty(MAYBE_UNUSED void ** _1) { - assert_true(false == is_valid_user_name("")); + assert_true(false == is_valid_user_name("", false)); } static void test_is_valid_user_name_nok_numeric(MAYBE_UNUSED void ** _1) { - assert_true(false == is_valid_user_name("6")); - assert_true(false == is_valid_user_name("42")); + assert_true(false == is_valid_user_name("6", false)); + assert_true(false == is_valid_user_name("42", false)); } static void test_is_valid_user_name_nok_otherchars(MAYBE_UNUSED void ** _1) { - assert_true(false == is_valid_user_name("no spaces")); - assert_true(false == is_valid_user_name("no,")); - assert_true(false == is_valid_user_name("no;")); - assert_true(false == is_valid_user_name("no:")); + assert_true(false == is_valid_user_name("no spaces", false)); + assert_true(false == is_valid_user_name("no,", false)); + assert_true(false == is_valid_user_name("no;", false)); + assert_true(false == is_valid_user_name("no:", false)); } @@ -151,10 +151,10 @@ test_is_valid_user_name_long(MAYBE_UNUSED void ** _1) memset(name, '_', LOGIN_NAME_MAX); stpcpy(&name[LOGIN_NAME_MAX], ""); - assert_true(false == is_valid_user_name(name)); + assert_true(false == is_valid_user_name(name, false)); stpcpy(&name[LOGIN_NAME_MAX - 1], ""); - assert_true(is_valid_user_name(name)); + assert_true(is_valid_user_name(name, false)); free(name); } @@ -163,27 +163,27 @@ test_is_valid_user_name_long(MAYBE_UNUSED void ** _1) static void test_is_valid_upn_ok(MAYBE_UNUSED void ** _1) { - assert_true(is_valid_upn("user@example.com")); - assert_true(is_valid_upn("john.doe@corp.example.org")); - assert_true(is_valid_upn("test@sub.domain.net")); - assert_true(is_valid_upn("a@b.c")); - assert_true(is_valid_upn("user123@test123.example")); - assert_true(is_valid_upn("user_name@example-domain.com")); - assert_true(is_valid_upn("test.user@example.domain.org")); - assert_true(is_valid_upn("user@domain")); - assert_true(is_valid_upn("user@domain.com.")); - assert_true(is_valid_upn("user@sub.")); + assert_true(is_valid_upn("user@example.com", false)); + assert_true(is_valid_upn("john.doe@corp.example.org", false)); + assert_true(is_valid_upn("test@sub.domain.net", false)); + assert_true(is_valid_upn("a@b.c", false)); + assert_true(is_valid_upn("user123@test123.example", false)); + assert_true(is_valid_upn("user_name@example-domain.com", false)); + assert_true(is_valid_upn("test.user@example.domain.org", false)); + assert_true(is_valid_upn("user@domain", false)); + assert_true(is_valid_upn("user@domain.com.", false)); + assert_true(is_valid_upn("user@sub.", false)); } static void test_is_valid_upn_nok_not_upn(MAYBE_UNUSED void ** _1) { - assert_true(false == is_valid_upn("regularuser")); - assert_true(false == is_valid_upn("user.name")); - assert_true(false == is_valid_upn("user_name")); - assert_true(false == is_valid_upn("123user")); - assert_true(false == is_valid_upn("USER")); + assert_true(false == is_valid_upn("regularuser", false)); + assert_true(false == is_valid_upn("user.name", false)); + assert_true(false == is_valid_upn("user_name", false)); + assert_true(false == is_valid_upn("123user", false)); + assert_true(false == is_valid_upn("USER", false)); } @@ -191,22 +191,22 @@ static void test_is_valid_upn_nok_structure(MAYBE_UNUSED void ** _1) { // Empty parts - assert_true(false == is_valid_upn("@domain.com")); - assert_true(false == is_valid_upn("user@")); - assert_true(false == is_valid_upn("@")); + assert_true(false == is_valid_upn("@domain.com", false)); + assert_true(false == is_valid_upn("user@", false)); + assert_true(false == is_valid_upn("@", false)); // Multiple @ symbols - assert_true(false == is_valid_upn("user@domain@com")); - assert_true(false == is_valid_upn("@@domain.com")); - assert_true(false == is_valid_upn("user@@domain.com")); + assert_true(false == is_valid_upn("user@domain@com", false)); + assert_true(false == is_valid_upn("@@domain.com", false)); + assert_true(false == is_valid_upn("user@@domain.com", false)); // Empty string - assert_true(false == is_valid_upn("")); + assert_true(false == is_valid_upn("", false)); // Invalid prefix - assert_true(false == is_valid_upn("-user@domain.com")); - assert_true(false == is_valid_upn("123@domain.com")); - assert_true(false == is_valid_upn("user space@domain.com")); + assert_true(false == is_valid_upn("-user@domain.com", false)); + assert_true(false == is_valid_upn("123@domain.com", false)); + assert_true(false == is_valid_upn("user space@domain.com", false)); } @@ -214,12 +214,12 @@ static void test_is_valid_upn_nok_domain(MAYBE_UNUSED void ** _1) { // Invalid domain formats - assert_true(false == is_valid_upn("user@.domain.com")); - assert_true(false == is_valid_upn("user@domain..com")); + assert_true(false == is_valid_upn("user@.domain.com", false)); + assert_true(false == is_valid_upn("user@domain..com", false)); // Invalid domain characters - assert_true(false == is_valid_upn("user@domain_name.com")); - assert_true(false == is_valid_upn("user@domain name.com")); + assert_true(false == is_valid_upn("user@domain_name.com", false)); + assert_true(false == is_valid_upn("user@domain name.com", false)); } @@ -244,7 +244,7 @@ test_is_valid_upn_ok_limits(MAYBE_UNUSED void ** _1) assert_true(upn != NULL); strcpy(upn, "user@"); strcat(upn, domain); - assert_true(is_valid_upn(upn)); + assert_true(is_valid_upn(upn, false)); free(upn); free(domain); @@ -267,7 +267,7 @@ test_is_valid_upn_nok_limits(MAYBE_UNUSED void ** _1) assert_true(upn != NULL); strcpy(upn, "user@"); strcat(upn, domain); - assert_true(false == is_valid_upn(upn)); + assert_true(false == is_valid_upn(upn, false)); free(upn); free(domain); @@ -275,5 +275,5 @@ test_is_valid_upn_nok_limits(MAYBE_UNUSED void ** _1) // Domain label too long (>63 chars) assert_true(false == is_valid_upn("user@" "verylongdomainlabelthatexceedssixtythreecharacterslimitsetbyRFC1035" - ".com")); + ".com", false)); }