Qual é a maneira correta de autenticar um usuário sem PAM?

Qual é a maneira correta de autenticar um usuário sem PAM?

como minha pergunta relacionada não parece receber muito amor, aqui está outra: Qual é a maneira correta de autenticar um usuário via prompt de nome de usuário/senha no Linux hoje em dia?

Em princípio, suponho que teria que obter nome de usuário e senha, ler salt e hash do usuário correspondente em /etc/shadow. Eu então calcularia o hash da senha fornecida e do salt armazenado e verificaria se o resultado corresponde ao hash armazenado em /etc/shadow.

Normalmente, eu poderia simplesmente autenticar via PAM (por exemplo pam_unix), que já faz tudo isso, mas meu aplicativo é um módulo PAM personalizado e não encontrei nenhum método para chamar um módulo PAM de outro. Se isso for possível de alguma forma, eu ficaria feliz em optar por esta solução.

A partir de agora, achei este tutorial realmente desatualizadohttp://www.tldp.org/HOWTO/Shadow-Password-HOWTO-8.htmldesde 1996, quando, aparentemente, o suporte shadow ainda não estava incorporado na libc. Menciona pw_authe validcomo funções auxiliares para autenticação. Tentei implantá-los em meu código e vinculá-los libshadow.aàs ferramentas de sombra, mas recebo erros de 'referência externa não resolvida' para pw_authe valid. O código é mais ou menos assim:

if ((pw->pw_passwd && pw->pw_passwd[0] == '@'
     && pw_auth (pw->pw_passwd+1, pw->pw_name, PW_LOGIN, NULL))
    || !valid (passwd, pw)) {
    return (UPAP_AUTHNAK);
}

Não verifiquei isso ainda mais, mas de qualquer forma, esta não é uma solução preferida, pois eu teria que atualizar meu código toda vez que os shadow-utils fossem atualizados.

Prefiro vincular a uma biblioteca (que não seja PAM) que forneça autenticação contra arquivos /etc/shadow. Existe tal coisa e eu ainda não encontrei? Ou alguma outra solução?

Responder1

Seu medo de uma atualização de shadow-utils é IMO injustificado. As rotinas descritas nesse HOWTO estão disponíveis em meus sistemas Ubuntu 12.04 e Mint 17 sem instalar nada de especial.

A estrutura para ler /etc/shadowinformações em um programa C pode ser encontrada em /usr/include/shadow.he com man 5 shadowe as funções que você precisaria encontrar, por exemplo, uma entrada de senha shadow por nome, conforme definido em /usr/include/shadow.his getspname que também fornecerá uma página de manual ( man getspnam) descrevendo isso e todas as funções relacionadas.

Com base nisso, você poderá obter a entrada de senha com hash para qualquer nome. A senha com hash deve ter vários tokens '$', cortar tudo depois e incluindo o último '$' da senha com hash e apresentar isso como salt para crypt(), a versão glibc (de acordo com man 3 crypt) deve ser capaz de lidar com os sais "estendidos" que indicam entradas SHA512 como são mais comuns hoje em dia.

informação relacionada