Se o UID máximo for 65535, não haverá nenhum valor para indicar um erro ou um UID desconhecido se o UID estiver armazenado em um valor não assinado de 16 bits.
Eu sei que não há um valor máximo compartilhado para uid (ou gid): alguns sistemas usam 99 (Slackware, ...), outros 65534 (Debian, ...).
Eu pergunto se existe uma motivação específica para usar 65534 e não 65535 (0xFFFF).
Obrigado.
Se o UID máximo for 65535, não haverá nenhum valor para indicar um erro ou um UID desconhecido se o UID estiver armazenado em um valor não assinado de 16 bits.
Isso não é na verdade um máximo. É um limite, onde os IDs das contas "do sistema" param e os IDs das contas "pessoa real" são iniciados. É bastante arbitrário e variável também. Não há razão real para que seja 99, exceto que 100 é um número redondo acessível.
É um número redondo acessível acordado pelas várias ferramentas de gerenciamento de banco de dados de senha e grupo para uma plataforma. No Debian versão 7, por exemplo, as ferramentas useradd
e groupadd
procuram /etc/login.defs
para os intervalos de UIDs e GIDs que contam como "sistema" e "usuário", e o último intervalo é de 1000 a 60000 para ambos UIDs e GIDs.
Primeiro, porque existem duas convenções generalizadas nas chamadas do sistema POSIX:
-1
(convertido para o tipo de retorno) indica um erro, com o número do erro disponível na macro errno
. -1
indica "não muda". Estas não são convenções universais . Observe que não há possibilidade de um erro retornar da chamada do sistema geteuid()
, por exemplo. (Processos sempre têm UIDs efetivos.) Portanto, não há static_cast<uid_t>(-1)
para se preocupar com isso. Mas pelo menos um deles se aplica a UIDs e GIDs. No sistema setreuid()
e setregid()
, um argumento de -1
significa "sem alteração". Portanto, static_cast<uid_t>(-1)
e static_cast<gid_t>(-1)
não são utilizáveis adequadamente como IDs reais.
Em segundo lugar, porque os UIDs e os GIDs no Linux costumavam ser de 16 bits.
Isso mudou para 32 bits na virada do século, mas seus ecos continuam vivos, e na verdade é mais sutil do que parece à primeira vista. -1
convertido para um inteiro não assinado de 16 bits, que é o que costumava ser uid_t
e gid_t
(na interface de chamada do sistema), é claro 65535 como você observou. Então, isso não era um UID ou um GID utilizável.
No entanto, para os benefícios dos programas que usavam a API de 16 bits nos kernels que tinham alternado para% de 32 bitsuid_t
e gid_t
, o Linux definiu um "UID de estouro" e um "GID de estouro". Isso ocorreu porque em vários pontos houve algumas interações bastante desagradáveis devido ao lançamento feito entre 16 bits e 32 bits. Os programas de 16 bits viam o UID 65536 como o superusuário quando o kernel não. Os kernels mais antigos viam o UID 131072 como o superusuário quando o código das aplicações não o fazia.
O "overflow UID" e "overflow GID" essencialmente mapearam todos os UIDs e GIDs de 32 bits maiores que 65535 para 65534 para o código de 16 bits. Isso significa que um valor segundo , 0xFFFE, agora estava inutilizável como um valor real de UID ou GID.
E, é claro, -1
convertido para o tipo de UID e GID de 32 bits também não pode ser usado.
Os sistemas normalmente reservam o valor inteiro mais alto sem sinal 0xffff (ou -1 se o valor for interpretado como um inteiro com sinal) para indicar "inválido" ou "não usado". (0xffff é de 16 bits, é claro. Alguns sistemas usam 0xffffffff de 32 bits.)
Zero não pode ser usado para isso, porque é reservado para uso raiz.
(Reservar 0 para root é, se bem me lembro, uma convenção POSIX que é observada por quase todos os outros sistemas operacionais também, por razões de compatibilidade).
Tags uid