login e su internals

9

Estou tentando entender como as permissões de usuário funcionam no Linux. O kernel inicializa e inicia init como root, certo? Em seguida, o Init executa os scripts de inicialização e executa getty ( agetty ), novamente como root. Agetty apenas lê o nome de usuário e executa login , ainda como root, eu acho. Nada de interessante ainda. Mas o que login faz? Não consegui encontrar nada melhor do que "ele tenta fazer login". Suponha que o login descubra que a senha corresponde (e estamos tentando fazer o login como usuário normal), como ela muda o ID do usuário? Eu pensei que deveria haver uma chamada de sistema para isso, mas eu não fui capaz de encontrá-lo (talvez eu esteja apenas cego?)

Além disso, cerca de su . su tem o bit 'setuid' definido, então quando o rodamos, ele sempre roda como root. Mas quando dizemos a ele para fazer o login como usuário normal, é necessário alterar novamente o ID do usuário. Eu entendi corretamente que a mesma "mágica" acontece em su e login quando eles precisam alterar o usuário? Em caso afirmativo, por que dois programas diferentes? Existe algum tipo adicional de negócios sérios acontecendo ao executar o login?

    
por Anton Barkovsky 22.06.2011 / 22:48

3 respostas

8

Existem várias partes para os programas de login. Os programas de login diferem em como eles interagem com o usuário que está tentando efetuar login. Veja alguns exemplos:

  • login : lê a entrada em um terminal de texto
  • su : invocado por um usuário já logado, obtém a maioria dos dados de seus argumentos de linha de comando, além de dados de autenticação (senha) de um terminal
  • gksu : semelhante a su , mas lê dados de autenticação em X
  • rlogind : obtém entrada através de uma conexão TCP através do protocolo rlogin
  • sshd : obtém entrada através de uma conexão TCP através do protocolo SSH
  • X gerenciadores de exibição (xdm, gdm, kdm,…): semelhante a login , mas lê entrada em um display X

Esses programas operam de maneira semelhante.

  1. A primeira parte é authentication : o programa lê algumas informações do usuário e decide se o usuário está autorizado a efetuar login. O método tradicional é ler um nome de usuário e senha, e verificar se o usuário é mencionado no banco de dados do usuário do sistema e se a senha digitada pelo usuário é a que está no banco de dados. Mas há muitas outras possibilidades (senhas únicas, autenticação biométrica, transferência de autorização,…).

  2. Uma vez estabelecido que o usuário está autorizado a efetuar login e em qual conta, o programa de login estabelece a autorização do usuário, por exemplo, a quais grupos o usuário pertencerá nesta sessão.

  3. O programa de login também pode verificar as restrições da conta. Por exemplo, pode impor um tempo de login ou um número máximo de usuários conectados ou recusar determinados usuários em determinadas conexões.

  4. Finalmente, o programa de login configura a sessão do usuário. Existem vários subetapas:

    1. Defina as permissões do processo para o que foi decidido na autorização: usuário, grupos, limites,… Você pode ver um exemplo simples desta sub-seção aqui (somente trata usuários e grupos). A idéia básica é que o programa de login ainda está rodando como root neste momento, então ele tem privilégios máximos; primeiro remove todos os privilégios além de ser o usuário root e, finalmente, chama setuid para eliminar esse último privilégio, mas não menos importante.
    2. Possivelmente monte o diretório pessoal do usuário, exiba uma mensagem "você tem e-mail", etc.
    3. Invoque algum programa como usuário, normalmente o shell do usuário (para login e su ou sshd se nenhum comando tiver sido especificado; um gerenciador de exibição X chama um gerenciador de sessão X ou gerenciador de janelas).

A maioria dos unices hoje em dia usa PAM (Pluggable Authentication Modules) para fornecer uma maneira uniforme de gerenciar o login Serviços. O PAM divide sua funcionalidade em 4 partes : “Auth” engloba tanto a autenticação (1 acima) quanto a autorização (2 acima); “Conta” e “sessão” são como 3 e 4 acima; e há também "senha", que não é usada para logins, mas para atualizar os tokens de autenticação (por exemplo, senhas).

    
por 23.06.2011 / 01:32
4

As chamadas do sistema que você está procurando são chamadas de coisas como setuid e seteuid , embora exista uma família inteira de bainhas, dependendo exatamente de quais variantes de identidade do usuário você está tentando alterar.

Também há chamadas paralelas como setgid para alterar o grupo que um processo é executado.

    
por 22.06.2011 / 23:28
4

login eliminará privilégios de root quando necessário. Muitos programas que precisam apenas de privilégios de root inicialmente começam como root, fazem o que precisam fazer e, em seguida, são baixados para uma conta de usuário normal para que não precisem se preocupar com alguém usando um bug no binário para obter acesso a um shell de raiz. login naturalmente mantém os privilégios por mais tempo, mas o princípio é o mesmo.

De fato, eliminar privilégios de root é bastante trivial. O POSIX define setuid() e setgid() functions, que alteram seus IDs de usuário e grupo, respectivamente (real e efetivo, se você estiver iniciando como root). login chama ambos, assim como initgroups() para configurar qualquer grupo suplementar que você possa ter (já que setgid é apenas para definir sua ID de grupo principal)

Naturalmente, é o kernel que realmente manipula a alteração do processo 'UID / GID. Como posso encontrar as implementações das chamadas do sistema kernel do Linux? explica muito sobre o syscalls; na minha fonte do kernel eu tenho:

#define __NR_setgid 144
__SYSCALL(__NR_setgid, sys_setgid)
#define __NR_setuid 146
__SYSCALL(__NR_setuid, sys_setuid)

então 144 e 146 são os números de chamada do sistema para essas funções na minha máquina

Eu não verifiquei o su source para ver o que ele faz, mas suspeito que ele também libera privilégios de root antes de exec() ing um shell, usando o mesmo método

    
por 22.06.2011 / 23:28