grp no Python: consulte grupos Unix

Publicado em: 26/08/2026
Tempo de leitura: 6 minutos
Detailed close-up of a reticulated python showcasing intricate scales and piercing eyes.

O módulo grp consulta a base de grupos em sistemas Unix. Ele permite encontrar um grupo pelo GID numérico ou nome, listar membros explicitamente registrados e converter ownership de arquivos para nomes legíveis.

Grupos Unix participam do controle de acesso a arquivos, dispositivos, serviços e recursos do sistema. Porém, a base de grupos não é uma autorização completa: permissões efetivas também dependem do usuário, grupo primário, grupos suplementares, ACLs, capabilities, namespaces, SELinux, AppArmor e outras políticas.

Disponibilidade

grp está disponível em Unix, mas não em WASI, Android nem iOS. Windows usa outro modelo de grupos.

try:
    import grp
except ImportError:
    grp = None

Aplicações multiplataforma devem isolar esse código e oferecer fallback quando o nome do grupo não for essencial.

Campos de uma entrada

As funções retornam um objeto parecido com tupla:

gr_name, gr_passwd, gr_gid, gr_mem

gr_name é o nome, gr_gid o ID numérico e gr_mem uma lista de logins explicitamente associados. gr_passwd é histórico e normalmente vazio ou inútil.

Consultar pelo GID

import grp

try:
    grupo = grp.getgrgid(1000)
except KeyError:
    print("GID sem entrada")
else:
    print(grupo.gr_name, grupo.gr_mem)

Desde Python 3.10, argumentos não inteiros, como string ou float, geram TypeError. Valide e converta entradas de CLI ou API antes da chamada.

Consultar pelo nome

import grp

try:
    grupo = grp.getgrnam("developers")
except KeyError:
    print("Grupo inexistente")
else:
    print(grupo.gr_gid)

Não use um nome fornecido pelo usuário para tomar decisões privilegiadas sem consultar a base e verificar a identidade efetiva do processo.

Grupo primário e grupos suplementares

O grupo primário de uma conta está em pw_gid no módulo pwd no Python. Já gr_mem contém membros explicitamente listados na base de grupos.

A documentação alerta que muitos usuários não aparecem em gr_mem do próprio grupo primário. Portanto, pesquisar somente essa lista produz uma visão incompleta.

Encontrar todos os grupos de um usuário

import grp
import pwd


def grupos_do_usuario(nome):
    conta = pwd.getpwnam(nome)
    gids = {conta.pw_gid}

    for grupo in grp.getgrall():
        if nome in grupo.gr_mem:
            gids.add(grupo.gr_gid)

    return [grp.getgrgid(gid) for gid in sorted(gids)]

Em sistemas com LDAP ou muitos grupos, getgrall() pode ser caro. Quando disponível, prefira os.getgrouplist(nome, gid_primario), que consulta o sistema de forma mais direta.

Grupos do processo atual

os.getgid() retorna o GID real, os.getegid() o efetivo e os.getgroups() a lista suplementar.

import os

print("Real:", os.getgid())
print("Efetivo:", os.getegid())
print("Suplementares:", os.getgroups())

As permissões de uma operação normalmente consideram o GID efetivo e os grupos suplementares do processo, não apenas a base estática.

Converter ownership de arquivos

import grp
import os

info = os.stat("arquivo.txt")
try:
    nome_grupo = grp.getgrgid(info.st_gid).gr_name
except KeyError:
    nome_grupo = str(info.st_gid)

print(nome_grupo)

Mantenha o GID numérico como fallback. Arquivos podem pertencer a grupos removidos, namespaces diferentes ou volumes externos.

gr_passwd não autentica

Senhas de grupo são um recurso histórico e raramente usado. gr_passwd costuma estar vazio, conter x ou outro marcador.

Não tente validar credenciais com esse campo. Autenticação e autorização devem usar PAM, políticas do serviço, ACLs ou mecanismos oficiais.

Listar grupos

import grp

for grupo in grp.getgrall():
    print(grupo.gr_gid, grupo.gr_name, grupo.gr_mem)

A ordem é arbitrária. A operação pode consultar NSS, LDAP, SSSD, NIS ou outras fontes remotas e ser lenta.

NSS e provedores remotos

Assim como pwd, grp segue a configuração Name Service Switch. A entrada pode vir de /etc/group, LDAP, SSSD, NIS ou plugins.

Uma chamada aparentemente local pode bloquear em rede. Evite executar getgrall() em cada requisição web ou operação de arquivo.

Referências NIS

Nomes iniciados com + ou - podem representar referências YP/NIS e nem sempre são acessíveis por getgrnam() ou getgrgid().

Não trate essas entradas como grupos locais comuns sem conhecer a configuração da máquina.

Cache com expiração

Consultas frequentes podem usar cache, mas mudanças de grupo precisam aparecer dentro de um prazo razoável.

import time

_cache = {}

def grupo_por_gid(gid, ttl=60):
    agora = time.monotonic()
    item = _cache.get(gid)
    if item and agora - item[0] < ttl:
        return item[1]

    valor = grp.getgrgid(gid)
    _cache[gid] = (agora, valor)
    return valor

Use relógio monotônico para TTL. Não armazene falhas indefinidamente.

Containers e namespaces

Em containers, um GID pode não ter entrada em /etc/group. Kubernetes e outras plataformas também podem adicionar grupos suplementares sem criar nomes correspondentes.

Não falhe ao exibir ownership: mostre o GID numérico. Para autorização, use os IDs efetivos fornecidos pelo kernel.

Grupos em volumes compartilhados

O mesmo GID pode representar nomes diferentes em hosts distintos. Em NFS ou volumes compartilhados, a consistência numérica entre sistemas é mais importante que o nome.

Planeje UID/GID entre hosts, containers e serviços antes de depender de permissões POSIX.

Verificar membresia

import os


def processo_esta_no_grupo(gid):
    return gid == os.getegid() or gid in os.getgroups()

Essa função responde sobre o processo atual. Ela é mais relevante para uma operação imediata do que reconstruir a membresia a partir de arquivos.

Não antecipe a decisão do kernel

Mesmo estando em um grupo, o acesso pode falhar por mode bits, ACL, mount options, SELinux, AppArmor, read-only filesystem ou capabilities.

Tente a operação e trate PermissionError. A consulta de grupo ajuda no diagnóstico, não substitui a syscall.

Alterar grupo de arquivo

import grp
import os

alvo = grp.getgrnam("developers")
os.chown("arquivo.txt", -1, alvo.gr_gid)

A operação exige permissão. Valide o caminho e evite seguir symlinks não confiáveis. Em código sensível, use APIs com dir_fd e flags apropriadas.

Alterar o grupo efetivo

Processos privilegiados podem usar os.setgid() ou os.setegid(). Essas operações são sensíveis e podem ser irreversíveis.

Prefira que o supervisor inicie o serviço com o usuário e grupo corretos, em vez de fazer mudanças dentro da aplicação.

initgroups()

os.initgroups(usuario, gid_primario) inicializa a lista suplementar com base na configuração do sistema.

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)

Chame initgroups() antes de perder privilégios. A ordem errada pode impedir a configuração ou manter grupos privilegiados.

Limpar grupos suplementares

Ao reduzir privilégios, não basta trocar UID e GID primário. Grupos suplementares herdados podem manter acesso indevido.

Use initgroups() para a conta alvo ou os.setgroups([]) quando a política exigir ausência de grupos adicionais.

Race conditions

A membresia pode mudar entre consulta e operação. Para segurança, confie na autorização da syscall e trate o resultado.

Não implemente “check then use” como única proteção.

Privacidade

Listas de membros revelam estrutura organizacional e nomes de contas. Não exponha getgrall() em APIs ou logs sem necessidade.

Logs

Ao registrar falhas em syslog no Python, prefira GID numérico e nome sanitizado. Não despeje a lista inteira de membros.

Limites de recursos

Grupos e contas sem privilégio complementam as cotas de resource no Python, mas nenhuma dessas medidas forma uma sandbox completa.

Testes

Teste grupo existente e ausente, argumento não inteiro, usuário no grupo primário mas fora de gr_mem, grupos suplementares, container sem nomes, LDAP lento, NIS, volume compartilhado, permissões reais e drop de privilégios.

Testes unitários não devem depender da base real do host. Encapsule chamadas e use registros fake.

Erros comuns

Os erros mais frequentes são tratar gr_mem como lista completa, usar gr_passwd para autenticação, presumir que nome existe para todo GID, chamar getgrall() em hot path, esquecer grupos suplementares ao reduzir privilégios e considerar membresia suficiente para garantir acesso.

Conclusão

grp resolve grupos Unix por nome ou GID e ajuda a interpretar ownership e membresia. Combine-o com pwd e com os grupos efetivos do processo para obter uma visão correta.

Preserve IDs numéricos, trate NSS e containers, não use a base para autenticação e deixe o kernel decidir o acesso final. Consulte a documentação oficial de grp e o manual group(5).

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    A person typing on a laptop with a Python programming book visible, capturing technology and learning.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pwd no Python: consulte usuários Unix

    Aprenda pwd no Python para consultar usuários Unix por UID ou login, obter home, shell e ownership sem usar a

    Ler mais

    Tempo de leitura: 6 minutos
    26/08/2026
    Close-up view of freshly cut log slices stacked for wood storage, showing natural texture.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    syslog no Python: envie logs ao sistema

    Aprenda syslog no Python para enviar logs Unix com prioridades, facilities, máscaras, conteúdo estruturado e proteção contra log injection.

    Ler mais

    Tempo de leitura: 6 minutos
    26/08/2026
    A CPU and RAM sticks displayed on a white surface, showcasing computer hardware components.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    resource no Python: limites de CPU e memória

    Aprenda resource no Python para medir CPU, memória e page faults, definir limites de arquivos, processos e descriptors em Unix.

    Ler mais

    Tempo de leitura: 7 minutos
    26/08/2026
    Close-up of a parking payment terminal in an indoor garage in Almere, Netherlands.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pty no Python: automatize terminais Unix

    Aprenda pty no Python para executar e testar programas interativos, controlar pseudo-terminais, tratar EOF, resize, sinais e timeouts.

    Ler mais

    Tempo de leitura: 6 minutos
    25/08/2026
    A close-up shot showcasing the intricate scales of a snake, highlighting texture and color.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    tty no Python: modos raw e cbreak

    Aprenda tty no Python para usar raw e cbreak, ler teclas, tratar sequências, Unicode e restaurar o terminal Unix com

    Ler mais

    Tempo de leitura: 6 minutos
    25/08/2026
    Multiple padlocks securing a green chain link fence, symbolizing safety and protection.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    termios no Python: controle seguro do terminal

    Aprenda termios no Python para modo canônico, echo, leitura por tecla, baud rate, filas e restauração segura do terminal POSIX.

    Ler mais

    Tempo de leitura: 6 minutos
    25/08/2026