Copyright © 2001 Conectiva S/A, (c) 2004 EPx
Esta seção é uma revisão do sistema de permissões comum a todos os sistemas operacionais compatíveis com Unix.
O Unix tem uma lista de usuários (em /etc/passwd) e uma lista de grupos (/etc/group). Cada usuário pertence a um grupo (este será seu grupo primario). Dentro de cada lista, não existe qualquer hierarquia entre usuários ou entre grupos. Não há grupos de grupos, nem usuários-líderes.
Normalmente, é criado um grupo primário para cada usuário Unix, portanto as duas tabelas podem ficar bastante parecidas entre si. Mas não é necessário haver um grupo primário para cada usuário.
Cada usuário ainda pode ser incluído em outros grupos, que serão seus grupos secundários.
Cada arquivo tem alguns parâmetros de permissão:
O usuário-dono do arquivo não precisa necessariamente pertencer ao grupo-dono do arquivo. As permissões do grupo-dono na verdade regulam o que os usuários pertencentes àquele grupo poderão fazer com o arquivo.
Para ter as permissões do grupo-dono sobre o arquivo, um usuário precisa pertencer ao tal grupo. Mas não importa se é como grupo primário ou secundário; estando no grupo, tem as permissões.
Os "outros" são todos os usuários fora o dono do arquivo e que não pertencem ao grupo-dono.
Os parâmetros de permissão possuem 3 bits cada um, com o seguinte significado:
r | permissão de leitura (Bit mais significativo) |
w | permissão de escrita |
x | permissão de execução (para programas e scripts) |
Para que, por exemplo, um usuário possa ler o arquivo, pelo menos uma das três condições a seguir deve ser atendida:
A manipulação das permissões em si é mais restrita; apenas o usuário-dono do arquivo pode mexer nas permissões do mesmo. (Isso também vale para os diretórios.)
As permissões especiais têm bits que potencializam a semântica dos anteriores:
Os bits acima têm propósito quase que totalmente restrito a binários.
os bits de permissão costumam ser representados por quatro números octais (visto que cada dígito octal corresponde exatamente a 3 bits).
Então, as permissões a seguir: SUID ativado, permissões do usuário "rwx", permissões do grupo "r-x", nenhuma permissão para outros, são representadas muito mais abreviadamente como 4750.
Os diretórios possuem exatamente os mesmos parâmetros de permissão dos arquivos, porém o significado dos bits de permissão muda um pouco:
r | permissão de ler o diretório e consultar os diversos nomes de arquivos |
w | permissão de gravar no diretório |
x | permissão de abrir um arquivo deste diretório, se já sabia o nome (porque pesquisar o nome exigiria a permissão 'r') |
O diretório contém o nome do arquivo e um ponteiro para o seu conteúdo no disco. Esse fato tem conseqüências sutis.
Para abrir e modificar um arquivo de nome conhecido, o usuário precisa ter permissão 'x' em cada um dos diretórios do caminho, além, é claro, das devidas permissões sobre o próprio arquivo (vide 1.2).
Para cada diretório do caminho, o usuário deve ser a) dono do diretório, b) pertencente ao grupo-dono, ou c) que o diretório tenha o bit 'x' setado para as permissões dos "outros" usuários. Por este motivo, muitos diretórios padrão do Unix têm as permissões (root,root,0755).
Para listar nomes de arquivos de um diretório (é o que o comando 'ls' faz) o usuário precisa ter a permissão 'r' no diretório consultado.
Como geralmente a manipulação de um arquivo é precedida por uma busca, via de regra o usuário precisa ter pelo menos as permissões 'r' e 'x' em cada diretório do caminho para poder abrir um arquivo. Não por outra razão a permissão 0755 é a mais comum para diretórios.
Para criar, renomear ou apagar um arquivo, o usuário precisa também ter permissão 'w' no diretório onde estiver o arquivo.
Isso traz um paradoxo: é possível que um usuário possa modificar um arquivo sem poder apagá-lo. Por outro lado, se o usuário tem apenas permissão de escrita sobre o diretório (e não sobre o arquivo), o usuário pode truncá-lo, visto que pode apagar o arquivo e criá-lo em seguida.
Para mudar as permissões de um arquivo, o usuário precisa apenas ser dono do arquivo, não precisa de permissões especiais no diretório. Isso porque elas são gravadas no inode do arquivo, não no diretório.
Em sistemas padrão POSIX, quando um usuário cria um novo arquivo em um diretório, o grupo-dono do mesmo é automaticamente setado para o grupo primário do usuário. (Eis o porquê da diferenciação entre grupo primário e secundários).
Já em sistemas BSD, o grupo-dono do novo arquivo será sempre o mesmo do diretório. Isso pode ser muito desejável para, por exemplo, garantir aos demais membros de um grupo o acesso ao novo arquivo.
Como essa característica do BSD é bastante desejável, o padrão POSIX também oferece esse recurso, como um opcional, basta setar o bit SGID para o diretório.
Por falar nisso, os bits de permissões especiais têm significado diferenciado para diretórios:
Um último recurso do sistema de permissões Unix é a máscara de bits denominada 'umask'. O objetivo do umask é impedir que o usuário, involuntariamente, crie arquivos com permissões excessivamente liberais.
O umask é um valor de 12 bits, que também costuma ser representado por três dígitos octais. Observe o seguinte exemplo, onde o usuário cria um arquivo com permissões bastante liberais (0666) porém seu umask é o padrão comumente adotado (0022):
Especiais Usuário Grupo Outros ------- ------- ------- ------- open - - - r w - r w - r w - (0666) umask 0 0 0 0 0 0 0 1 0 0 1 0 (0022) --------------------------------------------------------------- final - - - r w - r - - r - - (0644)
Como visto, os bits 1 do umask desligam incondicionalmente os respectivos bits da permissão final.
As permissões padrão Unix têm algumas limitações severas. Cada arquivo ou diretório pode pertencer a apenas um usuário e um grupo. E não existe um mecanismo suficientemente poderoso de herança de permissões.
As permissões Unix são eficientes (i.e. os processos de autenticação consomem o mínimo possível de CPU), e são suficientes para a configuração segura de um ambiente operacional.
Porém, as limitações supra citadas podem ser impeditivas na adoção do Unix como servidor de arquivos. Alguns dos "truques" das permissões Unix (SGID em diretórios, grupos secundários) aliviam as limitações em ambientes relativamente simples.
Num ambiente corporativo típico, temos pessoas organizadas em equipes. Também temos projetos ou tarefas. Normalmente, cada projeto terá um diretório ou pasta dentro de um servidor de arquivos. No mundo Unix, cada pessoa equivale a um usuário, e cada equipe equivale a um grupo.
Num mundo ideal, cada projeto seria manipulado unicamente por um usuário ou por um grupo, e nesse caso as permissões Unix seriam suficientes para controlar o acesso a cada projeto. Porém, é comum que cada projeto seja tocado concomitantemente por duas ou mais equipes, e eventualmente envolvendo funcionários avulsos de outras equipes. Também pode suceder de, por exemplo, a equipe A e B terem acesso de escrita aos arquivos do projeto, enquanto a equipe C teria apenas acesso de leitura (e obviamente acesso negado a quaisquer outros funcionários e grupos!).
Para tais situações, as permissões Unix são insuficientes pelo simples fato de que não se pode atribuir dois grupos-donos a um único diretório. Uma saída seria criar um grupo Unix por projeto, e incluir nesse grupo apenas os usuários que vão trabalhar no projeto. É uma saída possível, mas tem 3 desvantagens:
Ainda faltou mencionar a questão da herança de permissões. Supondo que o administrador consiga configurar permissões suficientemente boas para os diretórios, mas os arquivos ali criados terão permissões insuficientes.
É IMPORTANTE QUE O LEITOR ENTENDA PERFEITAMENTE COMO FUNCIONAM AS PERMISSÕES UNIX COMUNS, VISTO QUE AS ACLs POSIX INTERAGEM DE FORMA RAZOAVELMENTE COMPLEXA COM AS MESMAS !!!
A mais importante extensão das ACLs POSIX é a atribuição de usuários e grupos adicionais, com os respectivos bits de permissão (r, w e x). Observe os seguintes comandos:
setfacl -m u:joao:rwx arquivo
Este comando atribui um usuário-dono adicional ao arquivo, com permissões de leitura, escrita e execução.
setfacl -m g:admin:r-x diretorio
Este atribui um grupo-dono adicional, com permissões de leitura (lembrar que o significado do bit 'x' é diferente para diretórios). Com estes poucos exemplos, já podemos formar algumas conclusões sobre as ACLs POSIX:
Na implementação Linux das ACLs POSIX, o comando 'ls' mostra um caractere '+' junto aos bits das permissões tradicionais, para indicar que aquele arquivo ou diretório tem uma ACL associada a ele:
/acl # ls -lsa total 8 1 drwxr-xr-x 8 epx users 1024 Jun 8 21:49 . 1 drwxr-xr-x 35 root root 1024 Jun 7 23:13 .. 1 drwxrwx---+ 2 epx users 1024 Jun 8 00:46 alpha 1 drwxrwx---+ 2 epx users 1024 Jun 8 02:10 beta 1 drwxrwx---+ 2 epx users 1024 Jun 8 00:19 delta 1 drwxrwx---+ 2 epx users 1024 Jun 8 00:44 gama 1 drwxrwx---+ 2 root root 1024 Jun 8 00:45 omega 1 drwxrwx--- 2 epx users 1024 Jun 8 22:03 zeta
Da lista acima, apenas o subdiretório 'zeta' não tem ACLs. Para mostrar as ACLs em si, use o comando getfacl:
/acl # getfacl alpha # file: alpha # owner: epx # group: users user::rwx group::r-x group:admin:rwx mask:rwx other:---
O diretório 'alpha' tem uma ACL que garante ao grupo 'admin' acesso irrestrito ao diretório.
As linhas 'user::rwx' e 'group::r-x' referem-se ao usuário-dono e ao grupo-dono originais (epx:users).
No exemplo do comando 'getfacl', pode-se notar um registro denominado 'mask', que ainda não conhecíamos. Além disso, existe uma aparente discrepância. O comando 'ls' mostrou que os bits de permissão do grupo são 'rwx':
1 drwxrwx---+ 2 epx users 1024 Jun 8 00:46 alpha
porém o comando getfacl disse que eram apenas 'r-x':
group::r-x
Num arquivo ou diretório que utilize ACLs (que tenha o '+' anexado às permissões tradicionais), os bits de permissão do grupo-dono tradicional mudam de significado. Ele atua como uma máscara para todas as demais permissões estendidas ACL, de forma análoga ao umask.
Para ilustrar a funcionalidade da máscara:
/acl # chmod 740 alpha /acl # getfacl alpha # file: alpha # owner: epx # group: users user::rwx group::r-x #effective:r-- group:admin:rwx #effective:r-- mask:r-- other:---
O comando 'chmod' alterou os bits de permissão do grupo-dono para 'r--'. Porém, o getfacl nos mostra que as permissões do grupo-dono continuam sendo 'r-x', e que a máscara é que foi mudada.
Note a presença do comentário '#effective:r--' para o grupo-dono original e o grupo adicional. Como a máscara é 'r--', as permissões do grupo-dono e de quaisquer outros usuários e grupos estendidos será, no máximo, 'r--'. Essa mudança na semântica dos bits de permissão tradicionais é um pouco 'chata' de entender, mas tem sua razão de existir.
Visto que os bits da máscara podem ser manipulados por um simples 'chmod', o usuário-dono do arquivo pode limitar ou revogar, de forma simples e rápida, todas as permissões estendidas das ACLs sem alterá-las. Com um simples
chmod 700 arquivo
o usuário-dono pode desativar todas as ACLs, e ativá-las novamente quando quiser usando
chmod 770 arquivo
A máscara também pode ser alterada de forma mais elegante com o próprio setfacl:
setfacl -m m:rwx arquivo
Os bits de permissão do grupo-dono original não podem mais ser alterados via 'chmod', por força do exposto no tópico 3.3. Mas podemos usar o próprio setfacl para isso:
setfacl u::rwx arquivo # usuário-dono setfacl g::rwx arquivo # grupo-dono setfacl o::rwx arquivo # outros usuários quaisquer
A alteração do usuário-dono e do grupo-dono em si continua sendo feita pelos comandos tradicionais 'chmod' e 'chgrp'.
Uma das limitações do sistema de permissões tradicional Unix é a falta de um mecanismo de herança de permissões. Veremos agora como fazer isso usando ACLs POSIX:
/acl # getfacl delta # file: delta # owner: epx # group: users user::rwx group::r-x group:admin:r-x group:doc:rwx mask:rwx other:--- /acl # setfacl -m d:u::rwx delta /acl # setfacl -m d:g::r-x delta /acl # setfacl -m d:o:--- delta /acl # setfacl -m d:g:admin:r-x delta /acl # setfacl -m d:g:doc:rwx delta /acl # setfacl -m d:m:rwx delta /acl # getfacl delta # file: delta # owner: epx # group: users user::rwx group::r-x group:admin:r-x group:doc:rwx mask:rwx other:--- default:user::rwx default:group::r-x default:group:admin:r-x default:group:doc:rwx default:mask:rwx default:other:---
Usando o prefixo 'd:', atribuimos as permissões ACL 'default', ao invés das próprias permissões do arquivo/diretório. Essas permissões é que serão herdadas pelos arquivos criados dentro do diretório:
/acl # touch delta/arqv /acl # getfacl delta/arqv # file: delta/arqv # owner: root # group: root user::rw- group::r-x #effective:r-- group:admin:r-x #effective:r-- group:doc:rwx #effective:rw- mask:rw- other:---
A presença das ACLs 'default' mitiga a importância do umask, e de fato o umask é desconsiderado de todo, na criação de arquivos dentro de diretórios com ACLs default.
Também é oportuno lembrar que:
- As ACLs default não precisam de forma alguma coincidir com as ACLs do diretório em si. (Embora a suprema maioria das aplicações práticas imponha que umas e outras sejam iguais).
- Obviamente, apenas diretórios podem ter ACLs default.
- Os subdiretórios herdarão também as próprias ACLs default do diretório-pai, e com isso o mecanismo de herança fica completo.
- Note, no primeiro exemplo, que definimos a máscara default como d:m:rwx, mas o arquivo final 'delta/arqv' ficou com uma máscara 'rw'. O bit de execução é desligado incondicionalmente. Porém, os diretórios herdarão a máscara completa ('rwx'), visto que o bit 'x' tem significado diferente para diretórios (e via de regra é necessário que 'x' esteja sempre ativado nos mesmos).
Algumas das formas aceitas já foram vistas nos exemplos. Segue algumas dicas adicionais.
Podemos especificar as permissões usando uma forma mais extensa e elegante:
d:u::rwx -> default:user::rwx g:admin:r-x -> group:admin:r-x o:r-- -> other:r-- m:rwx -> mask:rwx
Ao invés de nomes de usuários e grupos, podemos usar os respectivos números.
Pode-se concatenar vários registros, com vírgulas, em um único comando:
setfacl -m u::rwx,g::r-x,o:---,u:joao:r-- arquivo
Se você quer alterar um registro da ACL de um arquivo, basta especificar um registro que coincida com o preexistente. Também, é possível usar os modificadores '+' (mais) e '^' (menos), para ligar e desligar determinados bits da permissão. O exemplo a seguir desliga o bit 'w' para o grupo 'doc':
/acl # setfacl -m group:doc:^w delta
Os bits de permissão também podem ser especificadas como um dígito octal.
-m Se o registro especificado já existir, os bits de permissão especificados serão atualizados. Se o registro ainda não existir, será adicionado à ACL. -s Configura a ACL. Quaisquer registros anteriores serão eliminados e substituídos pelos novos. Para a formação incremental da ACL, o parâmetro -m é mais indicado. Exemplo: setfacl -s u:epx:rwx,u:joao:r-x,g:admin:rx arquivo -x Elimina o registro especificado, como no exemplo: setfacl -x g:admin arquivo -M/S/X Com significado idêntico aos respectivos parâmetros de letra minúscula, porém os registros são lidos de um arquivo (especificado logo depois deste parâmetro). O formato exigido é exatamente o formato gerado pelo comando getfacl. Para ler da entrada padrão, use o traço ('-'). Exemplos: getfacl arquivo1 > /tmp/acltemp cat /tmp/acltemp | setfacl -S- arquivo2 # opção 1 setfacl -S /tmp/acltemp arquivo2 # opção 2
Note que setfacl não usou o nome de arquivo contido em /tmp/acltemp. Se isso for necessário, a opção '-B' é que deve ser usada.
-b Remove todos os registros ACL do arquivo. Exemplo: setfacl -b arquivo -k Remove apenas os registros ACL 'default' do diretório. -d Todas as operações com registros ACL referir-se-ão aos registros 'default'. -B Restaura uma cópia de segurança gerada pelo comando 'getfacl -R' ou similar. (Vide getfacl) -t Modo de teste. Apenas testa a sintaxe mas não faz nenhuma alteração 'quente'. -R Aplica a operação a todos os arquivos e subdiretórios recursivamente. (Esta opcão NÃO pode ser usada em conjunto com -B) -5 Idêntico a -R, mas processa os arquivos primeiro, antes dos respectivos subdiretórios.
Outros parâmetros menos usados podem ser encontrados na página 'man' do comando setfacl.
Além das formas óbvias de uso, que já foram abordadas nos exemplos, podem ser utilizados os seguintes parâmetros:
-A Mostra apenas os registros ACL do arquivo em si -d Oposto de '-d', mostra apenas os registros 'default', e não mostra o prefixo 'default:' na saída. -a Em listas recursivas, mostra também as ACLs de arquivos cujos nomes comecem com ponto (que normalmente são ocultados). -c Não mostra as linhas de comentário -e Mostra os comentários com as permissões efetivas, mesmo as que não foram prejudicadas pela máscara. -E Oposto de '-e', não mostra comentários sobre permissões efetivas mesmo que haja permissões prejudicadas pela máscara. -s Pula arquivos que não tenham registros ACL. -R Lista as ACLs de todos os arquivos e subdiretórios recursivamente. Exemplo: cd /acl getfacl -sR . > copia-de-seguranca # depois de uma reformatação... mkdir /acl cd /acl setfacl -B copia-de-segurança -Y Segue links simbólicos. (O padrão é não os seguir.) -5 Idem '-R', mas imprime primeiro as permissões dos arquivos. -P Imprime caminhos absolutos (precedidos com '/'). O padrão é suprimir a barra de prefixo, para que a lista de ACLs possa ser reaplicada facilmente em uma outra árvore de diretórios. - Lê a lista de arquivos a partir da entrada padrão. -- Fim dos parâmetros. Os parâmetros à direita deste serão interpretados como nomes de arquivo mesmo que comecem com traço.
As ACLs POSIX são suportadas nativamente no Linux no kernel 2.6. As distribuições mais novas, que já trazem essa versão de kernel, têm suporte direto a ACL.
Como outros programas, além do kernel, precisam ser atualizados para o suporte a ACLs, aconselha-se a usar distribuições com suporte a ACL ao invés de tentar incluir esse suporte manualmente.
Novell e Windows NT | POSIX baunilha | ACLs POSIX |
---|---|---|
As permissões são armazenadas "separadamente" do sistema de arquivos, e estão centradas nos usuários e grupos. | As permissões são centradas em arquivos e diretórios. Cada arquivo sabe que usuários/grupos podem acessá-lo. As ACLs são armazenadas no sistema de arquivos. | Idem POSIX. |
Um grupo pode herdar permissões de outro(s) grupo(s) e/ou de outro(s) usuário(s), além de é claro ter as suas próprias permissões. | Não é possível estabelecer hierarquia entre grupos em sistemas POSIX, muito menos grupos hierarquicamente dependentes de usuários. | Idem POSIX. |
Um usuário pode herdar permissões de outro(s) usuário(s), isso de forma concomitante à herança de permissões de um ou mais grupos. | Usuários podem pertencer a um ou mais grupos, e portanto ter as mesmas permissões deles. Mas não se pode, por exemplo, fazer com que 'usuário A é equivalente a B'. | Idem POSIX. |
Quaisquer permissões atribuídas a um diretório são automaticamente válidas para todos os arquivos e subdiretórios contidos nele. | Cada arquivo e diretório tem suas próprias permissões, com herança muito limitada. | Cada arquivo e diretório têm sua própria ACL. A transmissão de permissões é possível, mas tem de ser explicitamente solicitada, e atuará apenas sobre arquivos criados dali para diante. |
Em extensão ao item anterior, as permissões atribuídas a um subdiretório atuarão cumulativamente às permissões estabelecidas em diretórios de nível mais alto. | Cada arquivo e diretório têm sua própria ACL, que não se acumula de nenhuma forma com as ACLs dos diretórios do caminho. | Idem POSIX tradicional. |
As permissões de 'renomear' e 'apagar' são atribuíveis ao próprio arquivo, e independem das permissões que o usuário tenha no diretório. | O usuário precisa ter permissão de escrita no diretório do arquivo para poder renomear e apagar arquivos. | Idem POSIX tradicional. |
Uma modificação de permissão tem efeito imediato sobre os usuários. | A semântica UNIX verifica as permissões no momento de abertura do arquivo. Uma vez aberto o arquivo, o programa retém as permissões até fechá-lo, mesmo que o administrador do sistema torne a ACL mais restritiva nesse interim. | Idem POSIX tradicional. |
É possível criar diretórios 'write-only' ou 'ratoeiras', onde o usuário possa jogar arquivos mas nunca mais poderá lê-los ou apagá-los. (Dica do Andreas.) | Não é possível criar diretórios-ratoeiras perfeitos, visto que para criar um arquivo, o usuário precisa ter direitos de gravação e de varredura ('x'), e esta última permissão implica em que o usuário ainda possa abrir ou apagar o arquivo se souber seu nome completo. | Idem POSIX tradicional. |