A API do PAM oferece seis primitivas de autenticação diferentes agrupadas em quatro recursos, descritos abaixo.
auth
Autenticação. Este recurso se preocupa em autenticar o requerente e estabelecer as credenciais da conta. Ele fornece duas primitivas:
pam_authenticate(3) autentica o requerente, geralmente solicitando um token de autenticação e comparando-o com um valor armazenado em um banco de dados ou obtido de um servidor de autenticação.
pam_setcred(3) estabelece credenciais de conta, como ID de usuário, associação de grupo e limites de recursos.
account
Gerenciamento de contas. Esse recurso lida com problemas de disponibilidade de conta não relacionados à autenticação, como restrições de acesso com base na hora do dia ou na carga de trabalho do servidor. Ele fornece uma única primitiva:
pam_acct_mgmt(3) verifica se a conta solicitada está disponível.
session
Gerenciamento de sessão. Esse recurso lida com tarefas associadas à configuração e desmontagem da sessão, como a contabilização de login. Ele fornece duas primitivas:
pam_open_session(3) executa tarefas associadas à configuração da sessão: adiciona uma entrada nos bancos de dados utmp
e wtmp
, inicia um agente SSH, etc.
pam_close_session(3) executa tarefas associadas à desmontagem da sessão: adiciona uma entrada nos bancos de dados utmp
e wtmp
, pare o agente SSH, etc.
password
Gerenciamento de senhas. Esse recurso é usado para alterar o token de autenticação associado a uma conta, porque expirou ou porque o usuário deseja alterá-lo. Ele fornece uma única primitiva:
pam_chauthtok(3) altera o token de autenticação, opcionalmente, verificando se é suficientemente difícil de adivinhar, se não foi usado anteriormente etc.
Módulos são um conceito muito central no PAM; afinal, eles são os “M” no “PAM”. Um módulo PAM é um código de programa autocontido que implementa as primitivas em uma ou mais instalações para um mecanismo específico; possíveis mecanismos para o recurso de autenticação, por exemplo, incluem os bancos de dados de senhas UNIX®, NIS, LDAP e Radius.
O FreeBSD implementa cada mecanismo em um único módulo, chamado pam_
(por exemplo, mechanism
.sopam_unix.so
para o mecanismo UNIX®. Outras implementações às vezes possuem módulos separados para instalações separadas e incluem o nome do recurso, bem como o nome do mecanismo no nome do módulo. Para citar um exemplo, Solaris™ tem um módulo pam_dial_auth.so.1
que é comumente usado para autenticar usuários de conexões discadas.
A implementação original do PAM no FreeBSD, baseada no Linux-PAM, não utilizou números de versão para os módulos PAM. Isso normalmente causaria problemas com aplicativos legados, que poderiam estar vinculados a versões mais antigas das bibliotecas do sistema, pois não havia como carregar uma versão correspondente dos módulos necessários.
O OpenPAM, por outro lado, procura por módulos que possuam o mesmo número de versão que a biblioteca PAM (atualmente 2), e só retorna a um módulo não versionado se nenhum módulo versionado puder ser carregado. Assim, os módulos legados podem ser fornecidos para aplicativos legados, permitindo que novos aplicativos (ou recém-construídos) aproveitem os módulos mais recentes.
Embora os módulos PAM do Solaris™ normalmente tenham um número de versão, eles não são realmente versionados, porque o número é uma parte do nome do módulo e deve ser incluído na configuração.
Quando um servidor inicia uma transação PAM, a biblioteca PAM tenta carregar uma política para o serviço especificado na chamada pam_start(3). A política especifica como as solicitações de autenticação devem ser processadas e definidas em um arquivo de configuração. Este é o outro conceito central no PAM: a possibilidade de o administrador ajustar a política de segurança do sistema (no sentido mais amplo da palavra) simplesmente editando um arquivo de texto.
Uma política consiste em quatro cadeias, uma para cada uma dos quatro recursos do PAM. Cada chain é uma sequência de instruções de configuração, cada uma especificando um módulo para invocar, alguns parâmetros (opcionais) para passar para o módulo e um sinalizador de controle que descreve como interpretar o código de retorno do módulo.
Entender os sinalizadores de controle é essencial para entender os arquivos de configuração do PAM. Existem quatro diferentes flags de controle:
binding
Se o módulo tiver exito e nenhum módulo anterior na chain tiver falhado, a chain será encerrada imediatamente e a solicitação será concedida. Se o módulo falhar, o resto da chain é executado, mas a solicitação é negada no final.
Esta flag de controle foi introduzida pela Sun no Solaris™9 (SunOS™ 5.9), e também é suportado pelo OpenPAM.
required
Se o módulo tiver exito, o restante da chain será executada e a solicitação será concedida, a menos que algum outro módulo falhe. Se o módulo falhar, o restante da chain também será executado, mas a solicitação será negada no final.
requisite
Se o módulo for tiver exito, o restante da chain será executado e a solicitação será concedida, a menos que algum outro módulo falhe. Se o módulo falhar, a chain será encerrada imediatamente e a solicitação será negada.
sufficient
Se o módulo tiver exito e nenhum módulo anterior na chain tiver falhado, a chain será encerrada imediatamente e a solicitação será concedida. Se o módulo falhar, o módulo será ignorado e o resto da chain será executado.
Como a semântica dessa flag pode ser um pouco confusa, especialmente quando ela é usada para o último módulo em uma chain, é recomendado que a flag de controle binding
seja usada em seu lugar, se a implementação o suportar.
optional
O módulo é executado, mas seu resultado é ignorado. Se todos os módulos em uma chain estiverem marcados como optional
, todas as solicitações serão sempre concedidas.
Quando um servidor invoca uma das seis primitivas PAM, o PAM recupera a chain para o recurso ao qual a primitiva pertence, e invoca cada um dos módulos listados na chain, na ordem em que estão listados, até chegar ao fim ou determina que nenhum processamento adicional é necessário (porque um módulo binding
ou sufficient
teve exito, ou porque um módulo requisite
falhou.) O pedido é concedido se e somente se pelo menos um módulo foi chamado e todos os módulos não opcionais tiveram exito.
Note que é possível, embora não muito comum, ter o mesmo módulo listado várias vezes na mesma chain. Por exemplo, um módulo que procura nomes de usuário e senhas em um servidor de diretório pode ser chamado várias vezes com parâmetros diferentes, especificando diferentes servidores de diretórios para contato. O PAM trata diferentes ocorrências do mesmo módulo na mesma chain de módulos diferentes e não relacionados.
O ciclo de vida de uma transação típica do PAM é descrito abaixo. Observe que, se qualquer uma dessas etapas falhar, o servidor deverá informar uma mensagem de erro adequada ao cliente e anular a transação.
Se necessário, o servidor obtém as credenciais do mediador por meio de um mecanismo independente do PAM - mais comumente em virtude de ter sido iniciado por root
ou de ser setuid root
.
O servidor chama pam_start(3) para inicializar a biblioteca PAM, especificar seu nome de serviço e a conta de destino e registrar uma função de conversação adequada.
O servidor obtém várias informações relacionadas à transação (como o nome de usuário do requerente e o nome do host no qual o cliente é executado) e o envia ao PAM usando pam_set_item(3).
O servidor chama pam_authenticate(3) para autenticar o requerente.
O servidor chama pam_acct_mgmt(3) para verificar se a conta solicitada está disponível e é válida. Se a senha estiver correta mas expirar, pam_acct_mgmt(3) retornará PAM_NEW_AUTHTOK_REQD
em vez de PAM_SUCCESS
.
Se a etapa anterior retornasse PAM_NEW_AUTHTOK_REQD
, o servidor agora chamaria pam_chauthtok(3) para forçar o cliente a alterar o token de autenticação para a conta solicitada.
Agora que o requerente foi devidamente autenticado, o servidor chama pam_setcred(3) para estabelecer as credenciais da conta solicitada. É capaz de fazer isso porque age em nome do mediador e possui as credenciais do madiador.
Depois que as credenciais corretas forem estabelecidas, o servidor chamará pam_open_session(3) para configurar a sessão.
O servidor agora executa qualquer serviço solicitado pelo cliente - por exemplo, fornecer ao requerente um shell.
Quando o servidor terminar de atender ao cliente, ele chamará pam_close_session(3) para derrubar a sessão.
Finalmente, o servidor chama pam_end(3) para notificar a biblioteca PAM que ela esta pronta e que pode liberar quaisquer recursos alocados no curso da transação.
All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/
Questions that are not answered by the
documentation may be
sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.