Qual é o regex para validar usuários do Linux?

21

Ao adicionar um novo usuário, como a string é validada?

Suponho que exista uma expressão regular. O que é essa expressão regular?

Ionică Bizău
fonte

Respostas:

12

A regra geral para o nome de usuário é que seu comprimento deve ter menos de 32 caracteres. Depende da sua distribuição para criar o nome de usuário válido.

No Debian, shadow-utils 4.1existe uma is_valid_namefunção em chkname.c:

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

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

    return true;
}

E o tamanho do nome de usuário foi verificado antes:

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);
}
cuonglm
fonte
15

Na página de manual do useradd (8) :

Geralmente, é recomendável usar apenas nomes de usuários que começam com uma letra minúscula ou um sublinhado, seguidos por letras minúsculas, dígitos, sublinhados ou traços. Eles podem terminar com um cifrão. Em termos de expressão regular: [a-z _] [a-z0-9 _-] * [$]?

No Debian, as únicas restrições são que os nomes de usuário não devem começar com um hífen ('-') nem conter dois pontos (':') ou um espaço em branco (espaço: '', fim de linha: '\ n', tabulação: ' \ t 'etc.). Observe que o uso de uma barra ('/') pode interromper o algoritmo padrão para a definição do diretório inicial do usuário.

Os nomes de usuário podem ter apenas 32 caracteres.

Portanto, há uma recomendação geral. As restrições reais dependem das especificidades da sua implementação / distribuição. Em sistemas baseados no Debian, aparentemente não há restrições muito rígidas. Na verdade, eu apenas tentei useradd '€'na minha caixa do Ubuntu e funcionou. Obviamente, isso pode quebrar alguns aplicativos que não esperam nomes de usuário incomuns. Para evitar esses problemas, é melhor seguir a recomendação geral.

Malte Skoruppa
fonte
12

Sinto muito por não ter respondido a essa pergunta de quase 4 anos de idade, mas aparece bastante nos resultados de pesquisa na Internet e merece um pouco mais de atenção.

Uma regex mais precisa é (sim, eu sei, apesar da página de manual):

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

Espero que ajude alguns dos que pesquisam.

Para dividir:

  1. Ele deve começar ( ^) com apenas letras minúsculas ou um sublinhado ( [a-z_]). Ocupa exatamente 1 caractere.
  2. Então deve ser um dos dois ( ( ... )):
    1. De 0 a 31 caracteres ( {0,31}) de letras , números , sublinhados e / ou hífens ( [a-z0-9_-]), OR ( |)
    2. De 0 a 30 caracteres acima, mais um símbolo de USD ( \$) no final e, em seguida,
  3. Não há mais caracteres além desse padrão ( $).

Para aqueles que não estão familiarizados com os padrões regex, você pode perguntar por que o cifrão teve uma barra invertida no 2.2. mas não em 3. Isso ocorre porque na maioria das variantes de regex (todas?), o cifrão indica o final de uma sequência (ou linha etc.). Dependendo do mecanismo que está sendo usado, ele precisará ser escapado se fizer parte da sequência real (não consigo pensar em um mecanismo regex que não use barra invertida como escape para uma expressão pura) .

Observe que o Debian e o Ubuntu removem algumas restrições para um nome de usuário totalmente compatível com POSIX / shadow upstream (por exemplo, e eu não sei se isso foi corrigido, mas eles permitem que o nome de usuário comece com um número - o que realmente causou isso) bug ). Se você quiser garantir a plataforma cruzada, recomendo o padrão regex acima, em vez do que passa / falha na verificação no Debian, Ubuntu e outros.

Brent Saner
fonte
Ótima resposta. Pode ser facilmente aplicado também em Java usandojava.util.regex.Pattern.matches("^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\\$)$", user);
dokaspar
Deve ser em [abcdefghijklmnopqrstuvwxyz]vez de [a-z]. [a-z]em muitos mecanismos regexp, também corresponde a coisas como é, œou às vezes, elementos de intercalação de vários caracteres, como dsznos locais húngaros.
Stéphane Chazelas
Os nomes de usuário do Linux não aceitam Unicode (a menos que estejam explicitamente configurados para quebrar a conformidade com POSIX - 1 2 ). Essa verificação deve ser feita fora do regex, pois é uma validação de entrada / ambiente / localização, não uma validação de string. Além disso, eu adoraria ouvir um exemplo de um mecanismo de regex que faz isso. Todos os que eu conheço correspondem no ASCII e é preciso habilitar explicitamente o Unicode, se for compatível.
Brent saner