Is there a technical reason why? Is this an artifact from the early days of Linux or Unix, and if so is there a reason why it persists?
6 Answers
Some commands (eg chown
) can accept either a username or a numeric user ID, so allowing all-numeric usernames would break that.
A rule to allow names that start with a number and contain some alpha was probably considered not worth the effort; instead there is just a requirement to start with an alpha character.
Edit:
It appears from the other responses that some distro's have subverted this limitation; in this case, according to the GNU Core Utils documentation:
POSIX requires that these commands first attempt to resolve the specified string as a name, and only once that fails, then try to interpret it as an ID.
$ useradd 1000 # on most systems this will fail with:
# useradd: invalid user name '1000'
$ mkdir /home/1000
$ chown -R 1000 /home/1000 # This will first try to map
# to username "1000", but this may easily be misinterpreted.
Adding a user named '0' would just be asking for trouble (UID 0 == root user). However, note that group/user ID arguments can be preceded by a '+' to force their interpretation as an integer.
-
13This is the only post that actually does answer the question. You should add an example to show people that on linux distros that don't have the habit to mutilate upstream code the result of running
useradd 253
isuseradd: invalid user name '253'
Jun 2, 2016 at 13:15 -
3For the record here is the source code if you want to add it to your post. Jun 2, 2016 at 19:42
-
5Can you imagine the opportunities for confusion if username 1000 has UID 253? Or, in general, for numeric usernames that do not match the UID? Simlarly with groups, of course. Jun 3, 2016 at 2:42
-
6I have an LDAP system where some users have their (numeric) employee code/registration number as the username. I quickly learned to canonicalize to user IDs (
chown -R $(id -u $username) ...
).– muruJun 3, 2016 at 7:50 -
2ideally a user name string, whether numbers or letters, would be mapped to a UID and names always looked up to determine the UID, as opposed to the lazy 'is this name made of numbers? then I shall treat it as an ID' Jun 3, 2016 at 17:44
here is a test on ubuntu 14.04 using numbers:
root@ubuntu:~# useradd 232
root@ubuntu:~# mkdir /home/232
root@ubuntu:~# chown 232.232 /home/232
root@ubuntu:~# passwd 232
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
root@ubuntu:~# login
c2 login: 232
Password:
Welcome to Ubuntu 14.04.4 LTS (GNU/Linux 4.4.0-22-generic x86_64)
* Documentation: https://help.ubuntu.com/
System information disabled due to load higher than 2.0
Get cloud support with Ubuntu Advantage Cloud Guest:
http://www.ubuntu.com/business/services/cloud
0 packages can be updated.
0 updates are security updates.
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
$
$ whoami
232
and one using unicode U+1F600 - 😀
root@c2:~# useradd 😀
root@c2:~# mkdir /home/😀
root@c2:~# chown 😀.😀 /home/😀
root@c2:~# passwd 😀
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
root@c2:~# login
c2 login: 😀
Password:
Welcome to Ubuntu 14.04.4 LTS (GNU/Linux 4.4.0-22-generic x86_64)
* Documentation: https://help.ubuntu.com/
System information disabled due to load higher than 2.0
Get cloud support with Ubuntu Advantage Cloud Guest:
http://www.ubuntu.com/business/services/cloud
0 packages can be updated.
0 updates are security updates.
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.
$ whoami
😀
This is probably the worst idea I had:
root@c2:~# useradd '&#%^()!@~*?<>=|'
root@c2:~# passwd '&#%^()!@~*?<>=|'
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
root@c2:~# mkdir '/home/&#%^()!@~*?<>=|'
root@c2:~# chown '&#%^()!@~*?<>=|.&#%^()!@~*?<>=|' '/home/&#%^()!@~*?<>=|'
root@c2:~# login
c2 login: &#%^()!@~*?<>=|
Password:
Welcome to Ubuntu 14.04.4 LTS (GNU/Linux 4.4.0-22-generic x86_64)
**** text removed ****
applicable law.
$ whoami
&#%^()!@~*?<>=|
Clearly you can add such a user, although I'm not sure this is a good idea in the long run.
-
2
useradd '*'
would be fun -cd /home/*/
wouldn't work as expected, and who knows how other utilities would react when using the value of$HOME
for that user. Jun 2, 2016 at 5:06 -
9wow ubuntu permits that? I wonder what happens if you try to
useradd 1000
(assuming you already have a user with UID 1000) Jun 2, 2016 at 6:30 -
10
-
3
-
4@IsmaelMiguel: A literal
\0
in /etc/passwd would probably break a lot of programs that parse it. But you probably couldn't get add a user with that name in the first place, using standard tools. System calls likemkdir(2)
also use 0-terminated implicit-length strings, so you can't create/home/\0/
, because that path is just/home
. Jun 2, 2016 at 23:04
A *Nix username is generally a 32 character long string created by the utility useradd
. This is, as you said, a direct result of early Unix (BSD technically) standards. According to the FreeBSD Man Page passwd(5)
:
The login name must not begin with a hyphen (`-'), and cannot contain 8-bit characters, tabs or spaces, or any of these symbols: `,:+&#%^()!@~*?<>=|/"'. The dollar symbol (`$') is allowed only as the last character for use with Samba. No field may contain a colon (`:') as this has been used historically to separate the fields in the user data- base.
Certain *Nix systems used to throw obscure errors when presented with special characters in usernames, so eventually, the special characters were banned. In most modern *Nix systems it would be relatively easy to change the passwd
/useradd
utilities to support special character usernames, but most people are hesitant to change such an unimportant thing, as it would have little effect and would cause backwards incompatibility.
EDIT:
As Adonis said, it is in fact possible to do this in a modern Linux distribution, however it is ill-advised (especially when encountering standardized or legacy programs).
-
5Sure but the question doesn't even mention special characters. It asks why user names can't start with digits (which aren't special characters). Jun 2, 2016 at 12:40
-
Sure @don_crissti, would you prefer me to re-ask why historically a username can't start with a space, then ask seperately why it historially an't start with each of the symbols, then ask &c historically end with a $ ? This "answer" doesn't fit as a comment, which it clearly is, yet contains useful information related to the question.– frumbertJun 3, 2016 at 11:26
-
What is meant by 8-bit character in that paragraph? IE: Surely any ascii chars are 8-bit? Jun 3, 2016 at 17:47
-
feh!
/etc/passwd
is a text file.useradd
? pish-tosh. Real sysadmins usevi
!– infixedJun 3, 2016 at 19:44 -
1
Is there a technical reason why? Is this an artifact from the early days of Linux or Unix, and if so is there a reason why it persists?
I cannot think of a technical reason - historically, it's just ASCII. How it is read in and then typed is in the hands of the coder.
unix-history-repo/usr/src/cmd/passwd.c
char *uname;
insist = 0;
if(argc < 2) {
if ((uname = getlogin()) == NULL) {
printf ("Usage: passwd user\n");
goto bex;
} else {
printf("Changing password for %s\n", uname);
}
} else {
uname = argv[1];
}
Since I've spent some time browsing archive man pages (for instance: 1BSD was Bill Joy's first Berkeley Software Distribution), I've seen nothing that specifies user names. That is not to say that it doesn't exist, but I haven't seen it.
So then we are left with historical human context. Back when I started in tech in 1980, we always used our real name for logins. Usually first initial and last full name unless there was some length limit. This was important as your login name was used as your email address. Nobody back then sent email that was anonymous. Of course there must of been some exceptions, I don't recall them. On the whole though, I believe this to be the case.
And according to the rfc5321#page-63, there isn't any restriction on having an email "name" start with a numeric. gmail will create all numeric user names. (get it now, they are going fast).
So if there is any code that rejects a user name beginning with [0-9], then it probably came into existence later with some programmer thinking "why would you have a number as a name?". Once again, I have to say that there may very well be historic unix code that rejected a user name starting with a number. I just haven't seen it. The early password tables were hand edited, I certainly remember frequently doing that, even in the beginning 90s.
As far as why does it persist, I will quote stroustrup, C++11FAQ, When will the new standard libraries be available?
To make the problem more difficult, remember that it is not feasible to eliminate older features, even if the committee agrees that they are bad: experience shows that users force every implementer to keep providing deprecated and banned features under compatibility switches (or by default) for decades.
As pointed out in the answers, Linux usernames can be all-numeric. However, this is a Bad Idea as it would confuse many software tools (and human sysadmins!).
For this reason, for instance, all-numeric usernames and groupnames are deprecated in RHEL 7 and forbidden in RHEL 8:
8.7.1.
shadow-utils
no longer allow all-numeric user and group namesThe
useradd
andgroupadd
commands disallow user and group names consisting purely of numeric characters. The reason for not allowing such names is that this can confuse potentially many tools that work with user and group names and user and group ids (which are numbers). Please note that the all-numeric user and group names are deprecated in Red Hat Enterprise Linux 7 and their support is completely removed in Red Hat Enterprise Linux 8.
-
Here is IMHO better description of the problem: Numeric usernames in Red Hat Enterprise Linux.– pevikJun 4, 2020 at 10:05
I'm not sure I would call it a technical reason, but the rule boils down to "the username must be a valid programming-language identifier". Identifiers have some nice properties due to their restricted syntax: They cannot be mistaken for numbers, even when reading characte by character, and they do not need to be quoted when going through a parser. In short, they are easily recognized as names, which reduces the programming work needed to work with them.
I doubt it was ever really necessary to disallow usernames that begin with a digit, but "a username must be an identifier" is a simple rule that would have been crystal clear to 100% of early Unix users.
If the only place you type your username is at the login prompt in a GUI, it probably makes no difference what characters it includes (exempting nulls and things like newlines, which would give even the login procedure the hiccups). But if you do a lot of work from the commandline, the convenience of having a username that's easy to work with.
useradd
(fromshadow-utils 4.2.1
) manual page (see CAVEATS ):Usernames must start with a lower case letter or an underscore [...] In regular expression terms: [a-z_][a-z0-9_-]*[$]?
linux
, notubuntu
. Try doing it on archlinux.