What is the regex to validate Linux users?

When adding a new user, how is the string validated?

I suppose there is a regular expression. What is that regular expression?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Sorry for necrobumping this almost 4-year-old question, but it comes up pretty high on Internet search results and it warrants a little more attention.

A more accurate regex is (yes, I know, despite the man page):

^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}$)$

Hopefully that helps some of those searching.

To break it down:

  1. It should start (^) with only a lowercase letter or an
    underscore ([a-z_]). This occupies exactly 1 character.
  2. Then it should be one of either (( ... )):
    1. From 0 to 31 characters ({0,31}) of letters, numbers, underscores, and/or hyphens ([a-z0-9_-]),

    OR (|)

    1. From 0 to 30 characters of the above plus
      a US dollar sign symbol ($) at the end,

    and then

  3. No more characters past this pattern ($).

For those unfamiliar with regular expressions, you may ask why the dollar sign had a backslash in 2.2, but did not in 3. This is because in most (all?) regex variants, the dollar sign indicates the end of a string (or line, etc.). Depending on the engine being used, it will need to be escaped if it’s part of the actual string (I can’t think off the top of my head of a regex engine that doesn’t use backslash as an escape).

Note that Debian and Ubuntu remove some restrictions for a fully POSIX/shadow upstream compliant username (for instance, and I don’t know if this has been fixed, but they allow the username to start with a number –
which actually is what caused this bug). If you want to guarantee cross-platform, I’d recommend the above regex rather than what passes/fails the check in Debian, Ubuntu, and others.

Method 2

From the man page of useradd (8):

It is usually recommended to only use usernames that begin with a lower case letter or an underscore, followed by lower case letters, digits, underscores, or dashes. They can end with a dollar sign. In regular expression terms: [a-z_][a-z0-9_-]*[$]?

On Debian, the only constraints are that usernames must neither start with a dash (‘-‘) nor contain a colon (‘:’) or a whitespace (space: ‘ ‘, end of line: ‘n’, tabulation: ‘t’, etc.). Note that using a slash (‘/’) may break the default algorithm for the definition of the user’s home directory.

Usernames may only be up to 32 characters long.

So, there’s a general recommendation. The actual constraints depend on the specifics of your implementation / distribution. On Debian-based systems, apparently there are no very hard constraints. In fact, I just tried useradd '€' on my Ubuntu box, and it worked. Of course, this may break some applications that do not expect such unusual usernames. To avoid such problems, it is best to follow the general recommendation.

Method 3

The general rule for username is its length must less than 32 characters. It depend on your distribution to make what is valid username.

In Debian, shadow-utils 4.1, there is a is_valid_name function in chkname.c:

static bool is_valid_name (const char *name)
{
    /*
     * User/group names must match [a-z_][a-z0-9_-]*[$]
     */
    if (('' == *name) ||
        !((('a' <= *name) && ('z' >= *name)) || ('_' == *name))) {
        return false;
    }

    while ('' != *++name) {
        if (!(( ('a' <= *name) && ('z' >= *name) ) ||
              ( ('0' <= *name) && ('9' >= *name) ) ||
              ('_' == *name) ||
              ('-' == *name) ||
              ( ('$' == *name) && ('' == *(name + 1)) )
             )) {
            return false;
        }
    }

    return true;
}

And the length of username was checked before:

bool is_valid_user_name (const char *name)
{
    /*
     * User names are limited by whatever utmp can
     * handle.
     */
    if (strlen (name) > USER_NAME_MAX_LENGTH) {
        return false;
    }

    return is_valid_name (name);
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x