Skip to content

Commit 4be5a59

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]> 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 4eb2c50 commit 4be5a59

File tree

5 files changed

+28
-22
lines changed

5 files changed

+28
-22
lines changed

lib/chkname.c

Lines changed: 24 additions & 18 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

@@ -31,7 +32,11 @@
3132

3233
#include "defines.h"
3334
#include "chkname.h"
35+
#include "string/ctype/strchrisascii/strchriscntrl.h"
36+
#include "string/ctype/strisascii/strisdigit.h"
3437
#include "string/strcmp/streq.h"
38+
#include "string/strcmp/strcaseeq.h"
39+
#include "string/strcmp/strprefix.h"
3540

3641

3742
#ifndef LOGIN_NAME_MAX
@@ -58,6 +63,21 @@ login_name_max_size(void)
5863
static bool
5964
is_valid_name(const char *name)
6065
{
66+
if (streq(name, "")
67+
|| streq(name, ".")
68+
|| streq(name, "..")
69+
|| strcaseeq(name, "none")
70+
|| strcaseeq(name, "all")
71+
|| strcaseeq(name, "except")
72+
|| strprefix(name, "-")
73+
|| strpbrk(name, " !\"#&*+,/:;@|")
74+
|| strchriscntrl(name)
75+
|| strisdigit(name))
76+
{
77+
errno = EINVAL;
78+
return false;
79+
}
80+
6181
if (allow_bad_names) {
6282
return true;
6383
}
@@ -68,26 +88,18 @@ is_valid_name(const char *name)
6888
*
6989
* as a non-POSIX, extension, allow "$" as the last char for
7090
* sake of Samba 3.x "add machine script"
71-
*
72-
* Also do not allow fully numeric names or just "." or "..".
7391
*/
74-
int numeric;
7592

76-
if (streq(name, "") ||
77-
streq(name, ".") ||
78-
streq(name, "..") ||
79-
!((*name >= 'a' && *name <= 'z') ||
93+
if (!((*name >= 'a' && *name <= 'z') ||
8094
(*name >= 'A' && *name <= 'Z') ||
8195
(*name >= '0' && *name <= '9') ||
8296
*name == '_' ||
8397
*name == '.'))
8498
{
85-
errno = EINVAL;
99+
errno = EILSEQ;
86100
return false;
87101
}
88102

89-
numeric = isdigit(*name);
90-
91103
while (!streq(++name, "")) {
92104
if (!((*name >= 'a' && *name <= 'z') ||
93105
(*name >= 'A' && *name <= 'Z') ||
@@ -98,15 +110,9 @@ is_valid_name(const char *name)
98110
streq(name, "$")
99111
))
100112
{
101-
errno = EINVAL;
113+
errno = EILSEQ;
102114
return false;
103115
}
104-
numeric &= isdigit(*name);
105-
}
106-
107-
if (numeric) {
108-
errno = EINVAL;
109-
return false;
110116
}
111117

112118
return true;

src/newusers.c

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

391391
/* Check if this is a valid user name */
392392
if (!is_valid_user_name(name)) {
393-
if (errno == EINVAL) {
393+
if (errno == EILSEQ) {
394394
fprintf(stderr,
395395
_("%s: invalid user name '%s': use --badname to ignore\n"),
396396
Prog, name);

src/pwck.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ static void check_pw_file (bool *errors, bool *changed)
475475
*/
476476

477477
if (!is_valid_user_name(pwd->pw_name)) {
478-
if (errno == EINVAL) {
478+
if (errno == EILSEQ) {
479479
printf(_("invalid user name '%s': use --badname to ignore\n"),
480480
pwd->pw_name);
481481
} else {

src/useradd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1534,7 +1534,7 @@ static void process_flags (int argc, char **argv)
15341534

15351535
user_name = argv[optind];
15361536
if (!is_valid_user_name(user_name)) {
1537-
if (errno == EINVAL) {
1537+
if (errno == EILSEQ) {
15381538
fprintf(stderr,
15391539
_("%s: invalid user name '%s': use --badname to ignore\n"),
15401540
Prog, user_name);

src/usermod.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1118,7 +1118,7 @@ process_flags(int argc, char **argv)
11181118
/*@notreached@*/break;
11191119
case 'l':
11201120
if (!is_valid_user_name(optarg)) {
1121-
if (errno == EINVAL) {
1121+
if (errno == EILSEQ) {
11221122
fprintf(stderr,
11231123
_("%s: invalid user name '%s': use --badname to ignore\n"),
11241124
Prog, optarg);

0 commit comments

Comments
 (0)