Skip to content

Commit 235e72a

Browse files
lib/chkname.c, src/: Strictly disallow really bad names
Some names are bad, and some names are really bad. '--badname' should only allow the mildly bad ones, which we can handle. Some names are too bad, and it's not possible to deal with them. Reject them unconditionally. Acked-by: Chris Hofstaedtler <[email protected]> Acked-by: Tobias Stoeckmann <[email protected]> Cc: Marc 'Zugschlus' Haber <[email protected]> Cc: Iker Pedrosa <[email protected]> Cc: Serge Hallyn <[email protected]> Signed-off-by: Alejandro Colomar <[email protected]>
1 parent e562faf commit 235e72a

File tree

5 files changed

+24
-18
lines changed

5 files changed

+24
-18
lines changed

lib/chkname.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
* true - OK
1414
* false - bad name
1515
* errors:
16-
* EINVAL Invalid name characters or sequences
16+
* EINVAL Invalid name
17+
* EILSEQ Invalid name character sequence (acceptable with --badname)
1718
* EOVERFLOW Name longer than maximum size
1819
*/
1920

@@ -27,12 +28,15 @@
2728
#include <limits.h>
2829
#include <stdbool.h>
2930
#include <stddef.h>
31+
#include <string.h>
3032
#include <unistd.h>
3133

3234
#include "defines.h"
3335
#include "chkname.h"
36+
#include "string/ctype/strchrisascii/strchriscntrl.h"
3437
#include "string/ctype/strisascii/strisdigit.h"
3538
#include "string/strcmp/streq.h"
39+
#include "string/strcmp/strcaseeq.h"
3640

3741

3842
#ifndef LOGIN_NAME_MAX
@@ -59,6 +63,18 @@ login_name_max_size(void)
5963
static bool
6064
is_valid_name(const char *name)
6165
{
66+
if (streq(name, "")
67+
|| streq(name, ".")
68+
|| streq(name, "..")
69+
|| strspn(name, "-")
70+
|| strpbrk(name, " !\"#&*+,/:;@|~")
71+
|| strchriscntrl(name)
72+
|| strisdigit(name))
73+
{
74+
errno = EINVAL;
75+
return false;
76+
}
77+
6278
if (allow_bad_names) {
6379
return true;
6480
}
@@ -69,25 +85,15 @@ is_valid_name(const char *name)
6985
*
7086
* as a non-POSIX, extension, allow "$" as the last char for
7187
* sake of Samba 3.x "add machine script"
72-
*
73-
* Also do not allow fully numeric names or just "." or "..".
7488
*/
7589

76-
if (strisdigit(name)) {
77-
errno = EINVAL;
78-
return false;
79-
}
80-
81-
if (streq(name, "") ||
82-
streq(name, ".") ||
83-
streq(name, "..") ||
84-
!((*name >= 'a' && *name <= 'z') ||
90+
if (!((*name >= 'a' && *name <= 'z') ||
8591
(*name >= 'A' && *name <= 'Z') ||
8692
(*name >= '0' && *name <= '9') ||
8793
*name == '_' ||
8894
*name == '.'))
8995
{
90-
errno = EINVAL;
96+
errno = EILSEQ;
9197
return false;
9298
}
9399

@@ -101,7 +107,7 @@ is_valid_name(const char *name)
101107
streq(name, "$")
102108
))
103109
{
104-
errno = EINVAL;
110+
errno = EILSEQ;
105111
return false;
106112
}
107113
}

src/newusers.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ static int add_user (const char *name, uid_t uid, gid_t gid)
397397

398398
/* Check if this is a valid user name */
399399
if (!is_valid_user_name(name)) {
400-
if (errno == EINVAL) {
400+
if (errno == EILSEQ) {
401401
fprintf(stderr,
402402
_("%s: invalid user name '%s': use --badname to ignore\n"),
403403
Prog, name);

src/pwck.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ static void check_pw_file (bool *errors, bool *changed, struct option_flags *fla
492492
*/
493493

494494
if (!is_valid_user_name(pwd->pw_name)) {
495-
if (errno == EINVAL) {
495+
if (errno == EILSEQ) {
496496
printf(_("invalid user name '%s': use --badname to ignore\n"),
497497
pwd->pw_name);
498498
} else {

src/useradd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1498,7 +1498,7 @@ static void process_flags (int argc, char **argv, struct option_flags *flags)
14981498

14991499
user_name = argv[optind];
15001500
if (!is_valid_user_name(user_name)) {
1501-
if (errno == EINVAL) {
1501+
if (errno == EILSEQ) {
15021502
fprintf(stderr,
15031503
_("%s: invalid user name '%s': use --badname to ignore\n"),
15041504
Prog, user_name);

src/usermod.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,7 @@ process_flags(int argc, char **argv, struct option_flags *flags)
11371137
/*@notreached@*/break;
11381138
case 'l':
11391139
if (!is_valid_user_name(optarg)) {
1140-
if (errno == EINVAL) {
1140+
if (errno == EILSEQ) {
11411141
fprintf(stderr,
11421142
_("%s: invalid user name '%s': use --badname to ignore\n"),
11431143
Prog, optarg);

0 commit comments

Comments
 (0)