|
| 1 | +--- |
| 2 | +title: User/Group Name Syntax |
| 3 | +category: Users, Groups and Home Directories |
| 4 | +layout: default |
| 5 | +SPDX-License-Identifier: LGPL-2.1-or-later |
| 6 | +--- |
| 7 | + |
| 8 | +# User/Group Name Syntax |
| 9 | + |
| 10 | +The precise set of allowed user and group names on Linux systems is weakly |
| 11 | +defined. Depending on the distribution a different set of requirements and |
| 12 | +restrictions on the syntax of user/group names are enforced — on some |
| 13 | +distributions the accepted syntax is even configurable by the administrator. In |
| 14 | +the interest of interoperability systemd enforces different rules when |
| 15 | +processing users/group defined by other subsystems and when defining users/groups |
| 16 | +itself, following the principle of "Be conservative in what you send, be |
| 17 | +liberal in what you accept". Also in the interest of interoperability systemd |
| 18 | +will enforce the same rules everywhere and not make them configurable or |
| 19 | +distribution dependent. The precise rules are described below. |
| 20 | + |
| 21 | +Generally, the same rules apply for user as for group names. |
| 22 | + |
| 23 | +## Other Systems |
| 24 | + |
| 25 | +* On POSIX the set of [valid user |
| 26 | + names](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_437) |
| 27 | + is defined as [lower and upper case ASCII letters, digits, period, |
| 28 | + underscore, and |
| 29 | + hyphen](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_282), |
| 30 | + with the restriction that hyphen is not allowed as first character of the |
| 31 | + user name. Interestingly no size limit is declared, i.e. in neither |
| 32 | + direction, meaning that strictly speaking according to POSIX both the empty |
| 33 | + string is a valid user name as well as a string of gigabytes in length. |
| 34 | + |
| 35 | +* Debian/Ubuntu based systems enforce the regular expression |
| 36 | + `^[a-z][-a-z0-9]*$`, i.e. only lower case ASCII letters, digits and |
| 37 | + hyphens. As first character only lowercase ASCII letters are allowed. This |
| 38 | + regular expression is configurable by the administrator at runtime |
| 39 | + though. This rule enforces a minimum length of one character but no maximum |
| 40 | + length. |
| 41 | + |
| 42 | +* Upstream shadow-utils enforces the regular expression |
| 43 | + `^[a-z_][a-z0-9_-]*[$]$`, i.e. is similar to the Debian/Ubuntu rule, but |
| 44 | + allows underscores and hyphens, but the latter not as first character. Also, |
| 45 | + an optional trailing dollar character is permitted. |
| 46 | + |
| 47 | +* Fedora/Red Hat based systems enforce the regular expression of |
| 48 | + `^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,30}[a-zA-Z0-9_.$-]?$`, i.e. a size limit of |
| 49 | + 32 characters, with upper and lower case letters, digits, underscores, |
| 50 | + hyphens and periods. No hyphen as first character though, and the last |
| 51 | + character may be a dollar character. On top of that, `.` and `..` are not |
| 52 | + allowed as user/group names. |
| 53 | + |
| 54 | +* sssd is known to generate user names with embedded `@` and white-space |
| 55 | + characters, as well as non-ASCII (i.e. UTF-8) user/group names. |
| 56 | + |
| 57 | +* winbindd is known to generate user/group names with embedded `\` and |
| 58 | + white-space characters, as well as non-ASCII (i.e. UTF-8) user/group names. |
| 59 | + |
| 60 | +Other operating systems enforce different rules; in this documentation we'll |
| 61 | +focus on Linux systems only however, hence those are out of scope. That said, |
| 62 | +software like Samba is frequently deployed on Linux for providing compatibility |
| 63 | +with Windows systems; on such systems it might be wise to stick to user/group |
| 64 | +names also valid according to Windows rules. |
| 65 | + |
| 66 | +## Rules systemd enforces |
| 67 | + |
| 68 | +Distilled from the above, below are the rules systemd enforces on user/group |
| 69 | +names. An additional, common rule between both modes listed below is that empty |
| 70 | +strings are not valid user/group names. |
| 71 | + |
| 72 | +Philosophically, the strict mode described below enforces an allow list of |
| 73 | +what's allowed and prohibits everything else, while the relaxed mode described |
| 74 | +below implements a deny list of what's not allowed and permits everything else. |
| 75 | + |
| 76 | +### Strict mode |
| 77 | + |
| 78 | +Strict user/group name syntax is enforced whenever a systemd component is used |
| 79 | +to register a user or group in the system, for example a system user/group |
| 80 | +using |
| 81 | +[`systemd-sysusers.service`](https://www.freedesktop.org/software/systemd/man/systemd-sysusers.html) |
| 82 | +or a regular user with |
| 83 | +[`systemd-homed.service`](https://www.freedesktop.org/software/systemd/man/systemd-homed.html). |
| 84 | + |
| 85 | +In strict mode, only uppercase and lowercase characters are allowed, as well as |
| 86 | +digits, underscores and hyphens. The first character may not be a digit or |
| 87 | +hyphen. A size limit is enforced: the minimum of `sysconf(_SC_LOGIN_NAME_MAX)` |
| 88 | +(typically 256 on Linux; rationale: this is how POSIX suggests to detect the |
| 89 | +limit), `UT_NAMESIZE-1` (typically 31 on Linux; rationale: names longer than |
| 90 | +this cannot correctly appear in `utmp`/`wtmp` and create ambiguity with login |
| 91 | +accounting) and `NAME_MAX` (255 on Linux; rationale: user names typically |
| 92 | +appear in directory names, i.e. the home directory), thus MIN(256, 31, 255) = |
| 93 | +31. |
| 94 | + |
| 95 | +Note that these rules are both more strict and more relaxed than all of the |
| 96 | +rules enforced by other systems listed above. A user/group name conforming to |
| 97 | +systemd's strict rules will not necessarily pass a test by the rules enforced |
| 98 | +by these other subsystems. |
| 99 | + |
| 100 | +Written as regular expression the above is: `^[a-zA-Z_][a-zA-Z0-9_-]{0,30}$` |
| 101 | + |
| 102 | +### Relaxed mode |
| 103 | + |
| 104 | +Relaxed user/group name syntax is enforced whenever a systemd component accepts |
| 105 | +and makes use of user/group names registered by other (non-systemd) |
| 106 | +components of the system, for example in |
| 107 | +[`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.html). |
| 108 | + |
| 109 | +Relaxed syntax is also enforced by the `User=` setting in service unit files, |
| 110 | +i.e. for system services used for running services. Since these users may be |
| 111 | +registered by a variety of tools relaxed mode is used, but since the primary |
| 112 | +purpose of these users is to run a system service and thus a job for systemd a |
| 113 | +warning is shown if the specified user name does not qualify by the strict |
| 114 | +rules above. |
| 115 | + |
| 116 | +* No embedded NUL bytes (rationale: handling in C must be possible and |
| 117 | + straightforward) |
| 118 | + |
| 119 | +* No names consisting fully of digits (rationale: avoid confusion with numeric |
| 120 | + UID/GID specifications) |
| 121 | + |
| 122 | +* Similar, no names consisting of an initial hyphen and otherwise entirely made |
| 123 | + up of digits (rationale: avoid confusion with negative, numeric UID/GID |
| 124 | + specifications, e.g. `-1`) |
| 125 | + |
| 126 | +* No strings that do not qualify as valid UTF-8 (rationale: we want to be able |
| 127 | + to embed these strings in JSON, with permits only valid UTF-8 in its strings; |
| 128 | + user names using other character sets, such as JIS/Shift-JIS will cause |
| 129 | + validation errors) |
| 130 | + |
| 131 | +* No control characters (i.e. characters in ASCII range 1…31; rationale: they |
| 132 | + tend to have special meaning when output on a terminal in other contexts, |
| 133 | + moreover the newline character — as a specific control character — is used as |
| 134 | + record separator in `/etc/passwd`, and hence it's crucial to avoid |
| 135 | + ambiguities here) |
| 136 | + |
| 137 | +* No colon characters (rationale: it is used as field separator in `/etc/passwd`) |
| 138 | + |
| 139 | +* The two strings `.` and `..` are not permitted, as these have special meaning |
| 140 | + in file system paths, and user names are frequently included in file system |
| 141 | + paths, in particular for the purpose of home directories. |
| 142 | + |
| 143 | +* Similar, no slashes, as these have special meaning in file system paths |
| 144 | + |
| 145 | +* No leading or trailing white-space is permitted; and hence no user/group names |
| 146 | + consisting of white-space only either (rationale: this typically indicates |
| 147 | + parsing errors, and creates confusion since not visible on screen) |
| 148 | + |
| 149 | +Note that these relaxed rules are implied by the strict rules above, i.e. all |
| 150 | +user/group names accepted by the strict rules are also accepted by the relaxed |
| 151 | +rules, but not vice versa. |
| 152 | + |
| 153 | +Note that this relaxed mode does not refuse a couple of very questionable |
| 154 | +syntaxes. For example it permits a leading or embedded period. A leading period |
| 155 | +is problematic because the matching home directory would typically be hidden |
| 156 | +from the user's/administrator's view. An embedded period is problematic since |
| 157 | +it creates ambiguity in traditional `chown` syntax (which is still accepted |
| 158 | +today) that uses it to separate user and group names in the command's |
| 159 | +parameter: without consulting the user/group databases it is not possible to |
| 160 | +determine if a `chown` invocation would change just the owning user or both the |
| 161 | +owning user and group. It also allows embedding `@` (which is confusing to |
| 162 | +MTAs). |
| 163 | + |
| 164 | +## Common Core |
| 165 | + |
| 166 | +Combining all rules listed above, user/group names that shall be considered |
| 167 | +valid in all systemd contexts and on all Linux systems should match the |
| 168 | +following regular expression (at least according to our understanding): |
| 169 | + |
| 170 | +`^[a-z][a-z0-9-]{0,30}$` |
0 commit comments