blob: cf1297bd6a9d344deec392cb97a8775f49fa7ace
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * Check user and group names for illegal characters |
4 | * |
5 | * Copyright (C) 2008 Tito Ragusa <farmatito@tiscali.it> |
6 | * |
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
8 | */ |
9 | |
10 | #include "libbb.h" |
11 | |
12 | /* To avoid problems, the username should consist only of |
13 | * letters, digits, underscores, periods, at signs and dashes, |
14 | * and not start with a dash (as defined by IEEE Std 1003.1-2001). |
15 | * For compatibility with Samba machine accounts $ is also supported |
16 | * at the end of the username. |
17 | */ |
18 | |
19 | void FAST_FUNC die_if_bad_username(const char *name) |
20 | { |
21 | const char *start = name; |
22 | |
23 | /* 1st char being dash or dot isn't valid: |
24 | * for example, name like ".." can make adduser |
25 | * chown "/home/.." recursively - NOT GOOD. |
26 | * Name of just a single "$" is also rejected. |
27 | */ |
28 | goto skip; |
29 | |
30 | do { |
31 | unsigned char ch; |
32 | |
33 | /* These chars are valid unless they are at the 1st pos: */ |
34 | if (*name == '-' |
35 | || *name == '.' |
36 | /* $ is allowed if it's the last char: */ |
37 | || (*name == '$' && !name[1]) |
38 | ) { |
39 | continue; |
40 | } |
41 | skip: |
42 | ch = *name; |
43 | if (ch == '_' |
44 | /* || ch == '@' -- we disallow this too. Think about "user@host" */ |
45 | /* open-coded isalnum: */ |
46 | || (ch >= '0' && ch <= '9') |
47 | || ((ch|0x20) >= 'a' && (ch|0x20) <= 'z') |
48 | ) { |
49 | continue; |
50 | } |
51 | bb_error_msg_and_die("illegal character with code %u at position %u", |
52 | (unsigned)ch, (unsigned)(name - start)); |
53 | } while (*++name); |
54 | |
55 | /* The minimum size of the login name is one char or two if |
56 | * last char is the '$'. Violations of this are caught above. |
57 | * The maximum size of the login name is LOGIN_NAME_MAX |
58 | * including the terminating null byte. |
59 | */ |
60 | if (name - start >= LOGIN_NAME_MAX) |
61 | bb_error_msg_and_die("name is too long"); |
62 | } |
63 |