O módulo pwd consulta a base de contas de usuário em sistemas Unix. Ele permite localizar um login pelo UID, obter UID e GID numéricos, descobrir diretório home, shell configurado e o campo descritivo da conta.
Apesar do nome histórico “password database”, o módulo não é uma API de autenticação. Em Unix moderno, senhas ficam normalmente no sistema shadow, PAM, LDAP ou outro serviço de identidade. O campo pw_passwd costuma conter apenas x, * ou marcador semelhante.
Disponibilidade
pwd está disponível em Unix, mas não em WASI nem iOS. Windows possui outro modelo de contas.
try:
import pwd
except ImportError:
pwd = None
Para software multiplataforma, use abstrações de alto nível para diretório home e usuário atual quando não precisa da base POSIX completa.
Estrutura de uma entrada
As funções retornam um objeto parecido com tupla com os campos:
pw_name, pw_passwd, pw_uid, pw_gid, pw_gecos, pw_dir, pw_shell
pw_uid e pw_gid são inteiros. Os outros valores são strings.
Consultar pelo UID
import os
import pwd
conta = pwd.getpwuid(os.getuid())
print(conta.pw_name)
print(conta.pw_dir)
print(conta.pw_shell)
getpwuid() gera KeyError quando o UID não existe na base acessível ao processo.
Consultar pelo nome
import pwd
try:
conta = pwd.getpwnam("deploy")
except KeyError:
print("Usuário inexistente")
else:
print(conta.pw_uid, conta.pw_gid)
Não use exceção como único controle em uma API pública sem converter o resultado para uma mensagem clara.
Usuário real e efetivo
os.getuid() retorna o UID real; os.geteuid() retorna o efetivo. Em programas setuid, containers ou processos que alteram privilégios, eles podem ser diferentes.
real = pwd.getpwuid(os.getuid())
efetivo = pwd.getpwuid(os.geteuid())
Ao verificar permissões, compreenda qual identidade o kernel usa para a operação.
Não confie em variáveis de ambiente
USER, LOGNAME e HOME podem estar ausentes ou ser manipuladas.
conta = pwd.getpwuid(os.geteuid())
home = conta.pw_dir
Para caminhos do usuário que iniciou uma sessão com sudo, a decisão pode ser diferente: o UID efetivo pode ser root, enquanto SUDO_UID aponta para o chamador. Trate isso como política explícita, não heurística silenciosa.
Diretório home
pw_dir contém o home registrado na base. Ele pode não existir, não estar montado ou não ser acessível.
from pathlib import Path
home = Path(conta.pw_dir)
if home.is_dir():
print(home)
Não crie arquivos automaticamente no home de outra conta sem verificar ownership e permissões.
Shell configurado
pw_shell indica o programa de login, como /bin/bash, /bin/zsh, /usr/sbin/nologin ou /bin/false.
Esse campo não prova que o usuário pode autenticar, nem autoriza executar o shell. Contas de serviço podem possuir valores vazios ou específicos da plataforma.
Campo GECOS
pw_gecos costuma armazenar nome completo ou comentário, mas seu formato não é padronizado para aplicação. Pode conter vírgulas e dados administrativos.
Não use GECOS como identificador único e minimize exposição por privacidade.
pw_passwd não autentica
Em sistemas shadow, pw_passwd normalmente contém x ou *. Mesmo quando existe um hash, compará-lo manualmente não é uma arquitetura adequada.
Use PAM, serviço de identidade corporativo, OAuth, SSH ou o mecanismo oficial do sistema. Nunca solicite senha e tente validá-la com dados de pwd.
Listar todas as contas
import pwd
for conta in pwd.getpwall():
print(conta.pw_uid, conta.pw_name, conta.pw_shell)
A ordem é arbitrária. Em máquinas conectadas a LDAP, NIS ou outros provedores NSS, a operação pode ser lenta e retornar muitas contas.
NSS e fontes remotas
As funções seguem a configuração Name Service Switch do sistema. A informação pode vir de /etc/passwd, LDAP, SSSD, NIS, containers ou plugins.
Uma consulta aparentemente local pode fazer rede e bloquear. Não execute repetidamente no hot path sem cache e timeout arquitetural.
Cache
Para consultas frequentes, mantenha cache com expiração curta.
from functools import lru_cache
import pwd
@lru_cache(maxsize=256)
def usuario_por_uid(uid):
return pwd.getpwuid(uid)
lru_cache não expira sozinho. Em serviços longos, mudanças de conta podem ficar invisíveis. Use TTL quando atualização importa.
Conversão de ownership
Ao exibir arquivos, pwd converte UID para nome.
import os
import pwd
stat = os.stat("arquivo.txt")
try:
dono = pwd.getpwuid(stat.st_uid).pw_name
except KeyError:
dono = str(stat.st_uid)
Preserve o UID numérico como fallback. Um arquivo pode pertencer a uma conta removida ou a um namespace diferente.
Containers e namespaces
Dentro de container, o UID pode não ter entrada em /etc/passwd. Isso é comum em imagens minimalistas e plataformas que executam com UID aleatório.
Não trate KeyError como falha fatal quando apenas precisa exibir identidade. Use o número ou configuração fornecida pela aplicação.
UID zero
UID 0 normalmente representa root, mas não use apenas nome root para verificar privilégio.
if os.geteuid() == 0:
print("Processo com UID efetivo zero")
Mesmo root pode estar limitado por namespaces, capabilities, SELinux, AppArmor ou container.
Drop de privilégios
Serviços iniciados como root podem obter UID/GID de uma conta e então reduzir privilégios.
import grp
import os
import pwd
conta = pwd.getpwnam("appuser")
os.initgroups(conta.pw_name, conta.pw_gid)
os.setgid(conta.pw_gid)
os.setuid(conta.pw_uid)
Essa sequência é sensível: configure diretórios, descriptors e grupos antes; nunca tente recuperar privilégio depois. Prefira iniciar o serviço diretamente com o usuário correto pelo supervisor.
Grupos suplementares
pw_gid informa apenas o grupo primário. Para grupos suplementares, use grp, os.getgroups() ou os.getgrouplist() quando disponível.
O próximo conjunto deste lote aborda o módulo grp.
Expansão de ~
os.path.expanduser("~nome") pode consultar a mesma base de usuários.
Quando precisa de controle e tratamento de erros, consultar pwd.getpwnam(nome).pw_dir é mais explícito.
Validação de nomes
Não construa caminhos concatenando nome de login fornecido pelo usuário. Consulte a conta e use o home retornado, ainda verificando se o caminho está dentro da raiz permitida.
Nomes podem variar em caracteres aceitos por plataforma e serviço de identidade.
Privacidade
getpwall() pode revelar nomes de contas, homes e shells. Não exponha a lista em API web ou logs sem necessidade e autorização.
Concorrência
As funções são simples, mas a implementação NSS subjacente pode usar rede e arquivos de configuração. Evite assumir latência constante.
Erros
KeyError significa entrada não encontrada. Erros de sistema e problemas do provedor podem aparecer de outras formas. Diferencie ausência conhecida de indisponibilidade do serviço de identidade quando isso importa.
Testes
Teste usuário existente e ausente, UID sem entrada, container com UID aleatório, LDAP lento, home inexistente, shell nologin, conta removida, root em namespace, cache desatualizado e execução multiplataforma.
Não faça testes unitários dependerem das contas da máquina. Encapsule consultas e use objetos fake.
Erros comuns
Os erros mais frequentes são usar pw_passwd para autenticação, confiar em $USER, tratar pw_gid como todos os grupos, presumir que home existe, listar contas em cada requisição, falhar quando UID não tem nome e expor a base inteira sem necessidade.
Conclusão
pwd é a interface padrão para consultar identidades Unix por UID ou login. Use-o para nomes, homes, shells e ownership, com fallback para IDs numéricos e consciência de NSS, containers e privacidade.
Não use o módulo para validar senhas e não confunda registro de conta com autorização. Consulte a documentação oficial de pwd e o manual passwd(5).







