Autenticar externamente o usuário na sessão PAM/sessão PAM na sessão PAM

Autenticar externamente o usuário na sessão PAM/sessão PAM na sessão PAM

Existe uma maneira de autenticar adequadamente um usuário em uma sessão PAM personalizada?

Atualmente estou escrevendo meu próprio módulo de autenticação PAM que permite ao usuário fazer login através de um token externo. Este token deve ser gerado antes que o usuário possa fazer login com meu módulo. Portanto, gostaria de voltar à autenticação PAM padrão quando não existir nenhum token e continuar com meu código assim que o usuário for autenticado.

Isso é possível de alguma forma? Em pseudocódigo, meu módulo fica assim:

pam_sm_authenticate() {
  if (first_login) {
    code_copied_from_pam_unix_to_authenticate_user();
    // do something else here?
  } else {
    custom_auth();
  }
}

Como solução rápida, copiei o código do módulo pam_unix do Linux para o meu e funcionou. No entanto, isso não é muito satisfatório, pois envolve muitas bibliotecas adicionais e também só funcionará enquanto o pam_unix não for alterado. Eu preferiria abrir outra sessão PAM dentro da minha sessão, mas não consegui fazê-la funcionar.

Responder1

Não deixe seu código executar toda a lógica: use primeiro o PAM e sua configuração para garantir que seu módulo funcione nas melhores condições (ou seja, não requer cópia pam_unixdo código).

Primeiro, deixe-me sugerir outro pseudocódigo para o seu módulo:

pam_sm_authenticate() {
    if (first_login) return PAM_CRED_INSUFFICIENT;
    else custom_auth();
}

Aqui, consideroprimeiro loginser um caso de insuficiência de credenciais. Estou dizendo ao PAM que o módulo está falhando porque não tem tudo o que precisa para autenticar totalmente o usuário. Agora, supondo que seu módulo seja chamado my_module, uma configuração possível seria:

auth [cred_insufficient=ok success=done default=2] my_module.so
auth [success=ok default=1]      pam_unix.so
auth sufficient                  my_module.so
auth requisite                   pam_deny.so

Aqui estão os detalhes:

  • Primeiro, a solicitação é processada my_module. Várias possibilidades aqui:

    1. Primeiro login: seu módulo retornou PAM_CRED_INSUFFICIENT. Este caso écapturadopelo PAM (através de cred_insufficient), caso em que é configurado para marcar a cadeia como bem-sucedida ( ok), mas paracontinue.
    2. Esse não foi o primeiro login, você realizou custom_auth()e foi um sucesso (devolveu PAM_SUCCESS). Neste caso, encerramos a cadeia ( done) :acesso concedido.
    3. Este não foi o primeiro login e custom_auth()não deu certo ( PAM_AUTH_ERRou outros tipos de erros internos). Neste caso, pule as próximas 2 linhas ( default=2). A cadeia vai direto para pam_deny, que sempre falha:acesso negado.
  • No primeiro cenário, a cadeia segue para pam_unix. Duas possibilidades aqui:

    1. A autenticação UNIX foi bem-sucedida. Isso marca a cadeia como bem-sucedida ( ok) esegue para o próximo módulo.
    2. A autenticação UNIX falha. O próximo módulo é ignorado ( default=1) e a cadeia termina em pam_deny:acesso negado.
  • Se você chegar à terceira linha, significa que my_moduleterminou na PAM_CRED_INSUFFICIENTprimeira vez e deu pam_unixcerto. Seu módulo é chamado novamente ( // do something else here?) como sufficient. Duas possibilidades novamente:

    1. Desta vez, seu módulo foi bem-sucedido:acesso concedido.
    2. O módulo falha novamente, mas por outro motivo que não a insuficiência de credenciais:acesso negado.

Você também pode querer executar código personalizadoapós autenticação UNIX, mesmo que tenha falhado. Para fazer isso, altere a segunda linha para:

auth [success=ok default=bad]    pam_unix.so

Isso fará com que a cadeia passe por my_moduleoutro momento, não importa o que aconteça, mas a cadeia será marcada comofracassado. Mesmo que o seu módulo tenha sucesso aqui, a cadeia falhará.

Você também pode deixar seu módulo ciente de quantas vezes o chamamos em uma cadeia: diferencie a primeira chamada my_moduleda segunda. Isso poderia ser feito facilmente com argumentos:

auth [cred_insufficient=ok success=done default=2] my_module.so
auth [success=ok default=1]      pam_unix.so
auth sufficient                  my_module.so second_time
auth requisite                   pam_deny.so

Aqui, a segunda chamada para pam_sm_authenticatereceberá um argumento (através de argve argc) que deve ajudá-lolocalizarseu módulo na cadeia em tempo de execução. É claro que sua firstLogincondição deveria ser suficiente para fazer tal distinção.

informação relacionada