diff --git a/lib/Makefile.am b/lib/Makefile.am index c402ff02a3..30a210885d 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -67,6 +67,8 @@ libshadow_la_SOURCES = \ console.c \ copydir.c \ csrand.c \ + ctype/ispfchar.c \ + ctype/ispfchar.h \ defines.h \ encrypt.c \ env.c \ diff --git a/lib/chkname.c b/lib/chkname.c index 0abee4d294..591a306c53 100644 --- a/lib/chkname.c +++ b/lib/chkname.c @@ -14,7 +14,7 @@ * false - bad name * errors: * EINVAL Invalid name - * EILSEQ Invalid name character sequence (acceptable with --badname) + * EILSEQ Invalid name character sequence * EOVERFLOW Name longer than maximum size */ @@ -33,6 +33,7 @@ #include "defines.h" #include "chkname.h" +#include "ctype/ispfchar.h" #include "string/ctype/strchrisascii/strchriscntrl.h" #include "string/ctype/strisascii/strisdigit.h" #include "string/strcmp/streq.h" @@ -44,9 +45,6 @@ #endif -int allow_bad_names = false; - - size_t login_name_max_size(void) { @@ -66,19 +64,16 @@ is_valid_name(const char *name) if (streq(name, "") || streq(name, ".") || streq(name, "..") + || strcaseeq(name, "all") // access.conf(5) + || strcaseeq(name, "except") // access.conf(5) + || strcaseeq(name, "none") // access.conf(5) || strspn(name, "-") - || strpbrk(name, " \"#',/:;") - || strchriscntrl(name) || strisdigit(name)) { errno = EINVAL; return false; } - if (allow_bad_names) { - return true; - } - /* * User/group names must match BRE regex: * [a-zA-Z0-9_.][a-zA-Z0-9_.-]*$\? @@ -87,26 +82,16 @@ is_valid_name(const char *name) * sake of Samba 3.x "add machine script" */ - if (!((*name >= 'a' && *name <= 'z') || - (*name >= 'A' && *name <= 'Z') || - (*name >= '0' && *name <= '9') || - *name == '_' || - *name == '.')) - { + if (!ispfchar(*name)) { errno = EILSEQ; return false; } while (!streq(++name, "")) { - if (!((*name >= 'a' && *name <= 'z') || - (*name >= 'A' && *name <= 'Z') || - (*name >= '0' && *name <= '9') || - *name == '_' || - *name == '.' || - *name == '-' || - streq(name, "$") - )) - { + if (streq(name, "$")) // Samba + return true; + + if (!ispfchar(*name)) { errno = EILSEQ; return false; } diff --git a/lib/ctype/ispfchar.c b/lib/ctype/ispfchar.c new file mode 100644 index 0000000000..bb6868131d --- /dev/null +++ b/lib/ctype/ispfchar.c @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar +// SPDX-License-Identifier: BSD-3-Clause + + +#include + +#include "ctype/ispfchar.h" + +#include + + +extern inline bool ispfchar(unsigned char c); diff --git a/lib/ctype/ispfchar.h b/lib/ctype/ispfchar.h new file mode 100644 index 0000000000..68ff2c09dd --- /dev/null +++ b/lib/ctype/ispfchar.h @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: 2024, Alejandro Colomar +// SPDX-License-Identifier: BSD-3-Clause + + +#ifndef SHADOW_INCLUDE_LIB_CTYPE_ISPFCHAR_H_ +#define SHADOW_INCLUDE_LIB_CTYPE_ISPFCHAR_H_ + + +#include + +#include +#include + + +inline bool ispfchar(unsigned char c); + + +// is portable filename character +// Return true if 'c' is a character from the Portable Filename Character Set. +inline bool +ispfchar(unsigned char c) +{ + return isalnum(c) || c == '.' || c == '_' || c == '-'; +} + + +#endif // include guard diff --git a/man/newusers.8.xml b/man/newusers.8.xml index 7fff1a8c1f..2da4b43c92 100644 --- a/man/newusers.8.xml +++ b/man/newusers.8.xml @@ -254,18 +254,6 @@ The options which apply to the newusers command are: - - - -   - - - - Allow names that do not conform to standards. - - - - , diff --git a/man/pwck.8.xml b/man/pwck.8.xml index 46bb59df0d..0f24fd5c4a 100644 --- a/man/pwck.8.xml +++ b/man/pwck.8.xml @@ -159,16 +159,6 @@ The options which apply to the pwck command are: - - -   - - - - Allow names that do not conform to standards. - - - , diff --git a/man/useradd.8.xml b/man/useradd.8.xml index e6db7f6d7f..55676d0f9d 100644 --- a/man/useradd.8.xml +++ b/man/useradd.8.xml @@ -103,16 +103,6 @@ The options which apply to the useradd command are: - - -   - - - - Allow names that do not conform to standards. - - - ,  BASE_DIR diff --git a/man/usermod.8.xml b/man/usermod.8.xml index 2c704ab5b2..a5dc1ee502 100644 --- a/man/usermod.8.xml +++ b/man/usermod.8.xml @@ -84,16 +84,6 @@ - - - , - - - - Allow names that do not conform to standards. - - - ,  COMMENT diff --git a/src/chfn.c b/src/chfn.c index 81e2a31bb8..4106c01755 100644 --- a/src/chfn.c +++ b/src/chfn.c @@ -9,8 +9,6 @@ #include "config.h" -#ident "$Id$" - #include #include #include @@ -39,6 +37,8 @@ #include "string/strcmp/streq.h" #include "string/strcpy/strtcpy.h" #include "string/strdup/strdup.h" +#include "string/strerrno.h" + struct option_flags { bool chroot; @@ -605,7 +605,7 @@ int main (int argc, char **argv) */ if (optind < argc) { if (!is_valid_user_name (argv[optind])) { - fprintf (stderr, _("%s: Provided user name is not a valid name\n"), Prog); + fprintf(stderr, _("%s: user: %s\n"), Prog, strerrno()); fail_exit (E_NOPERM, process_selinux); } user = argv[optind]; diff --git a/src/chsh.c b/src/chsh.c index 0cfe26ee87..600c76a8fa 100644 --- a/src/chsh.c +++ b/src/chsh.c @@ -9,8 +9,6 @@ #include "config.h" -#ident "$Id$" - #include #include #include @@ -35,6 +33,7 @@ #include "string/strcmp/streq.h" #include "string/strcpy/strtcpy.h" #include "string/strdup/strdup.h" +#include "string/strerrno.h" #ifndef SHELLS_FILE @@ -494,7 +493,7 @@ int main (int argc, char **argv) */ if (optind < argc) { if (!is_valid_user_name (argv[optind])) { - fprintf (stderr, _("%s: Provided user name is not a valid name\n"), Prog); + fprintf(stderr, _("%s: user: %s\n"), Prog, strerrno()); fail_exit (1, process_selinux); } user = argv[optind]; diff --git a/src/groupadd.c b/src/groupadd.c index fab8111b4a..459aed97b1 100644 --- a/src/groupadd.c +++ b/src/groupadd.c @@ -268,9 +268,7 @@ static void check_new_name(void) { if (!is_valid_group_name(group_name)) { - fprintf(stderr, _("%s: '%s' is not a valid group name\n"), - Prog, group_name); - + fprintf(stderr, _("%s: group: %s\n"), Prog, strerrno()); fail_exit (E_BAD_ARG); } diff --git a/src/groupmod.c b/src/groupmod.c index c29f905088..c709c1e376 100644 --- a/src/groupmod.c +++ b/src/groupmod.c @@ -9,8 +9,6 @@ #include "config.h" -#ident "$Id$" - #include #include #include @@ -45,6 +43,7 @@ #include "string/strcmp/streq.h" #include "string/strcpy/stpecpy.h" #include "string/strdup/strdup.h" +#include "string/strerrno.h" /* @@ -389,9 +388,7 @@ check_new_name(void) } if (!is_valid_group_name(group_newname)) { - fprintf(stderr, - _("%s: invalid group name '%s'\n"), - Prog, group_newname); + fprintf(stderr, _("%s: group: %s\n"), Prog, strerrno()); exit(E_BAD_ARG); } diff --git a/src/grpck.c b/src/grpck.c index 90c724c9b4..58e6aca9a7 100644 --- a/src/grpck.c +++ b/src/grpck.c @@ -11,11 +11,11 @@ #include "config.h" #include +#include #include #include #include #include -#include #include "chkname.h" #include "commonio.h" @@ -29,6 +29,7 @@ #include "sssd.h" #include "string/strcmp/streq.h" #include "string/strcmp/strprefix.h" +#include "string/strerrno.h" #ifdef SHADOWGRP #include "sgroupio.h" @@ -583,7 +584,7 @@ static void check_grp_file(bool *errors, bool *changed, const struct option_flag */ if (!is_valid_group_name (grp->gr_name)) { *errors = true; - printf (_("invalid group name '%s'\n"), grp->gr_name); + printf(_("group: %s\n"), strerrno()); } /* diff --git a/src/newgrp.c b/src/newgrp.c index 5c4cc07b15..740b3898a8 100644 --- a/src/newgrp.c +++ b/src/newgrp.c @@ -482,9 +482,8 @@ int main (int argc, char **argv) */ if ((argc > 0) && (argv[0][0] != '-')) { if (!is_valid_group_name (argv[0])) { - fprintf ( - stderr, _("%s: provided group is not a valid group name\n"), - Prog); + fprintf(stderr, _("%s: group: %s\n"), + Prog, strerrno()); goto failure; } group = argv[0]; @@ -518,9 +517,8 @@ int main (int argc, char **argv) goto failure; } else if (argv[0] != NULL) { if (!is_valid_group_name (argv[0])) { - fprintf ( - stderr, _("%s: provided group is not a valid group name\n"), - Prog); + fprintf(stderr, _("%s: group: %s\n"), + Prog, strerrno()); goto failure; } group = argv[0]; diff --git a/src/newusers.c b/src/newusers.c index e9353fdc0a..60bab57ccc 100644 --- a/src/newusers.c +++ b/src/newusers.c @@ -122,7 +122,6 @@ static void check_perms(const struct option_flags *flags); 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 @@ -135,7 +134,6 @@ static void usage (int status) "\n" "Options:\n"), Prog); - (void) fputs (_(" -b, --badname allow bad names\n"), usageout); #ifndef USE_PAM (void) fprintf (usageout, _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), @@ -301,9 +299,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)) { - fprintf (stderr, - _("%s: invalid group name '%s'\n"), - Prog, grent.gr_name); + fprintf(stderr, _("%s: group: %s\n"), Prog, strerrno()); free (grent.gr_name); return -1; } @@ -396,17 +392,8 @@ 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 (errno == EILSEQ) { - fprintf(stderr, - _("%s: invalid user name '%s': use --badname to ignore\n"), - Prog, name); - } else { - fprintf(stderr, - _("%s: invalid user name '%s'\n"), - Prog, name); - } + fprintf(stderr, _("%s: user: %s\n"), Prog, strerrno()); return -1; } @@ -639,7 +626,6 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ #endif /* !USE_PAM */ static struct option long_options[] = { - {"badname", no_argument, NULL, 'b'}, #ifndef USE_PAM {"crypt-method", required_argument, NULL, 'c'}, #endif /* !USE_PAM */ @@ -666,9 +652,6 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) #endif long_options, NULL)) != -1) { switch (c) { - case 'b': - allow_bad_names = true; - break; #ifndef USE_PAM case 'c': crypt_method = optarg; diff --git a/src/passwd.c b/src/passwd.c index 0afae4d7be..1bb45bcae3 100644 --- a/src/passwd.c +++ b/src/passwd.c @@ -921,7 +921,7 @@ main(int argc, char **argv) myname = xstrdup (pw->pw_name); if (optind < argc) { if (!is_valid_user_name (argv[optind])) { - fprintf (stderr, _("%s: Provided user name is not a valid name\n"), Prog); + fprintf(stderr, _("%s: user: %s\n"), Prog, strerrno()); fail_exit (E_NOPERM, process_selinux); } name = argv[optind]; diff --git a/src/pwck.c b/src/pwck.c index c35f03e695..327dba72d3 100644 --- a/src/pwck.c +++ b/src/pwck.c @@ -10,8 +10,6 @@ #include "config.h" -#ident "$Id$" - #include #include #include @@ -30,6 +28,8 @@ #include "sssd.h" #include "string/strcmp/streq.h" #include "string/strcmp/strprefix.h" +#include "string/strerror.h" + #ifdef WITH_TCB #include "tcbfuncs.h" #endif /* WITH_TCB */ @@ -82,7 +82,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 @@ -139,7 +138,6 @@ usage (int status) "Options:\n"), Prog); } - (void) fputs (_(" -b, --badname allow bad names\n"), usageout); (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); (void) fputs (_(" -q, --quiet report errors only\n"), usageout); (void) fputs (_(" -r, --read-only display errors and warnings\n" @@ -164,7 +162,6 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) { int c; static struct option long_options[] = { - {"badname", no_argument, NULL, 'b'}, {"help", no_argument, NULL, 'h'}, {"quiet", no_argument, NULL, 'q'}, {"read-only", no_argument, NULL, 'r'}, @@ -179,9 +176,6 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) while ((c = getopt_long (argc, argv, "behqrR:s", long_options, NULL)) != -1) { switch (c) { - case 'b': - allow_bad_names = true; - break; case 'h': usage (E_SUCCESS); /*@notreached@*/break; @@ -487,18 +481,8 @@ 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 (errno == EILSEQ) { - printf(_("invalid user name '%s': use --badname to ignore\n"), - pwd->pw_name); - } else { - printf(_("invalid user name '%s'\n"), - pwd->pw_name); - } + printf(_("user: %s\n"), strerrno()); *errors = true; } diff --git a/src/useradd.c b/src/useradd.c index 899efe3c84..0c9b98471d 100644 --- a/src/useradd.c +++ b/src/useradd.c @@ -160,7 +160,6 @@ static char **user_groups; /* NULL-terminated list */ static long sys_ngroups; static bool do_grp_update = false; /* group files need to be updated */ -extern int allow_bad_names; static bool bflg = false, /* new default root of home directory */ @@ -877,7 +876,6 @@ static void usage (int status) "\n" "Options:\n"), Prog, Prog, Prog); - (void) fputs (_(" --badname do not check for bad names\n"), usageout); (void) fputs (_(" -b, --base-dir BASE_DIR base directory for the home directory of the\n" " new account\n"), usageout); #ifdef WITH_BTRFS @@ -1141,7 +1139,6 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) #ifdef WITH_BTRFS {"btrfs-subvolume-home", no_argument, NULL, 200}, #endif - {"badname", no_argument, NULL, 201}, {"comment", required_argument, NULL, 'c'}, {"home-dir", required_argument, NULL, 'd'}, {"defaults", no_argument, NULL, 'D'}, @@ -1198,9 +1195,6 @@ static void process_flags (int argc, char **argv, struct option_flags *flags) case 200: subvolflg = true; break; - case 201: - allow_bad_names = true; - break; case 'c': if (!VALID (optarg)) { fprintf (stderr, @@ -1498,15 +1492,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 (errno == EILSEQ) { - fprintf(stderr, - _("%s: invalid user name '%s': use --badname to ignore\n"), - Prog, user_name); - } else { - fprintf(stderr, - _("%s: invalid user name '%s'\n"), - Prog, user_name); - } + fprintf(stderr, _("%s: user: %s\n"), Prog, strerrno()); #ifdef WITH_AUDIT audit_logger (AUDIT_ADD_USER, "add-user", diff --git a/src/usermod.c b/src/usermod.c index e8c9da6687..3180009215 100644 --- a/src/usermod.c +++ b/src/usermod.c @@ -220,7 +220,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 @@ -396,7 +395,6 @@ usage (int status) (void) fputs (_(" -a, --append append the user to the supplemental GROUPS\n" " mentioned by the -G option without removing\n" " the user from other groups\n"), usageout); - (void) fputs (_(" -b, --badname allow bad names\n"), usageout); (void) fputs (_(" -c, --comment COMMENT new value of the GECOS field\n"), usageout); (void) fputs (_(" -d, --home HOME_DIR new home directory for the user account\n"), usageout); (void) fputs (_(" -e, --expiredate EXPIRE_DATE set account expiration date to EXPIRE_DATE\n"), usageout); @@ -1015,8 +1013,6 @@ process_flags(int argc, char **argv, struct option_flags *flags) int c; static struct option long_options[] = { {"append", no_argument, NULL, 'a'}, - {"badname", no_argument, NULL, 'b'}, - {"badnames", no_argument, NULL, 'b'}, {"comment", required_argument, NULL, 'c'}, {"home", required_argument, NULL, 'd'}, {"expiredate", required_argument, NULL, 'e'}, @@ -1060,9 +1056,6 @@ process_flags(int argc, char **argv, struct option_flags *flags) case 'a': aflg = true; break; - case 'b': - allow_bad_names = true; - break; case 'c': if (!VALID (optarg)) { fprintf (stderr, @@ -1137,15 +1130,8 @@ process_flags(int argc, char **argv, struct option_flags *flags) /*@notreached@*/break; case 'l': if (!is_valid_user_name(optarg)) { - if (errno == EILSEQ) { - fprintf(stderr, - _("%s: invalid user name '%s': use --badname to ignore\n"), - Prog, optarg); - } else { - fprintf(stderr, - _("%s: invalid user name '%s'\n"), - Prog, optarg); - } + fprintf(stderr, _("%s: user: %s\n"), + Prog, strerrno()); exit (E_BAD_ARG); } lflg = true;