Bump to version 1.22.1
[platform/upstream/busybox.git] / libbb / die_if_bad_username.c
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 }