login e su internals


10

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


Além disso, sobre su. sutem o bit 'setuid' definido; portanto, quando o executamos, ele sempre é executado como root. Mas quando dizemos a ele para fazer login como usuário habitual, ele novamente precisa alterar a identificação do usuário. Entendo corretamente que a mesma "mágica" acontece sue loginquando eles precisam mudar de usuário? Se sim, por que ter dois programas diferentes? Há algum tipo de negócio sério acontecendo ao executar o login?

Respostas:


9

Existem várias partes no que os programas de login fazem. Os programas de login diferem em como eles interagem com o usuário que está tentando fazer login. Aqui estão alguns exemplos:

  • login: lê a entrada em um terminal de texto
  • su: invocado por usuários já logados, 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
  • Gerenciadores de exibição X (xdm, gdm, kdm,…): semelhante a login, mas lê a entrada em uma exibição X

Esses programas funcionam de maneira semelhante.

  1. A primeira parte é a autenticação : 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 e no sistema. que a senha digitada pelo usuário é a do banco de dados. Mas existem 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 certos usuários em determinadas conexões.

  4. Finalmente, o programa de login configura a sessão do usuário. Existem várias 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 subetapa aqui (ele trata apenas de usuários e grupos). A idéia básica é que o programa de login ainda esteja sendo executado como raiz nesse momento, portanto, ele tem privilégios máximos; primeiro, remove todos os privilégios que não sejam o usuário root e, finalmente, chama setuidpara eliminar esse último mas não menos importante privilégio.
    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 logine su, ou sshdse nenhum comando foi especificado; um gerenciador de exibição do X chama um gerenciador de sessões X ou gerenciador de janelas).

Hoje em dia, a maioria das organizações usa o PAM (Pluggable Authentication Modules) para fornecer uma maneira uniforme de gerenciar serviços de login. O PAM divide sua funcionalidade em 4 partes : "auth" engloba autenticação (1 acima) e autorização (2 acima); "Conta" e "sessão" são os itens 3 e 4 acima; e também há "senha", que não é usada para logins, mas para atualizar tokens de autenticação (por exemplo, senhas).


4

As chamadas do sistema que você está procurando são chamadas de coisas do tipo setuide, seteuidembora exista realmente uma família inteira de bainhas, dependendo exatamente de quais variantes da identidade do usuário você está tentando alterar.

Também existem chamadas paralelas, como setgidpara alterar o grupo em que um processo é executado.


4

logineliminará privilégios de root quando necessário. Muitos programas que precisam apenas de privilégios de root inicialmente serão iniciados como root, farão o que precisam e depois cairão 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 raiz. loginnaturalmente mantém os privilégios por mais tempo, mas o princípio é o mesmo.

Na verdade, eliminar privilégios de root é bastante trivial. O POSIX define setuid()e setgid()funciona, que altera seus IDs de usuário e grupo, respectivamente (reais e efetivos, se você estiver iniciando como root). loginchama ambos, além initgroups()de configurar qualquer grupo suplementar que você possa ter (já que setgidé apenas para definir seu ID de grupo principal)

Naturalmente, é o kernel que realmente lida com a alteração do UID / GID do processo. Como posso encontrar as implementações de chamadas do sistema do kernel Linux? explica muito sobre 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 telefone do sistema para essas funções na minha máquina


Não verifiquei a sufonte para ver o que ela faz, mas suspeito que ela também retira os privilégios de root antes de exec()usar um shell, usando o mesmo método

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.