As permissões dos ficheiros e directorias são algo tão básico na administração de sistemas linux/unix que muitas vezes não são adequadamente discutidas e estudas. Sem querer escrever um tratado sobre o assunto, vou da forma mais sucinta e completa possível descrever os usos comuns do sistema de permissões e ownership.
Se listarmos o conteúdo de uma directoria pode-nos aparecer qualquer coisa como:
$ ls -l total 12 -rw-r--r-- 1 helder users 0 2007-09-20 19:31 a -rw-r--r-- 1 helder users 0 2007-09-20 19:31 b -rw-r--r-- 1 helder users 0 2007-09-20 19:31 c drwxr-xr-x 2 helder users 4096 2007-09-20 19:31 C drwxr-xr-x 2 helder users 4096 2007-09-20 19:31 D drwxr-xr-x 2 helder users 4096 2007-09-20 19:31 E
Temos em cada coluna:
Permissões | Links | Utilizador | Grupo | Tamanho | Data Modificação | Nome do ficheiro |
---|---|---|---|---|---|---|
-rw-r--r-- | 1 | helder | users | 0 | 2007-09-20 19:31 | a |
-rw-r--r-- | 1 | helder | users | 0 | 2007-09-20 19:31 | b |
O campo das permissões é composto por 10 flags:
Grupo directoria | Utilizador | Grupo | Outros | ||||||
- | r | w | - | r | - | - | r | - | - |
O campo da directoria pode ter vários valores:
Uma directoria aparece:
drwxr-xr-x 2 helder users 4096 2007-09-20 19:31 E
E um ficheiro:
-rw-r--r-- 1 helder users 0 2007-09-20 19:31 c
Para este artigo apenas nos interessam os primeiros dois valores, isto é, sabermos quando temos uma directoria ou ficheiro.
Os bits do Utilizador são as permissões que se aplicam apenas ao utilizador dono do ficheiro e apenas a ele, neste caso as permissões são aplicadas ao utilizador "helder".
Os bits do Grupo são as permissões que se aplicam a todos os utilizadores que pertençam ao grupo do ficheiro, neste caso "users".
Finalmente o grupo de bits dos Outros identifica as permissões que se aplicam a todos os utilizadores que: i) não são o utilizador dono do ficheiro e ii) não pertencem ao grupo do ficheiro (dai "outros").
As permissões de cada grupo de links podem ser:
Leitura | Escrita | Execução |
---|---|---|
r | w | x |
read | write | execute |
Notar que se se tratar de uma directoria o bit de execução indica se o utilizador pode mudar para essa directoria.
Para além destes três grupos de bits, existe um quarto que não é representado da mesma forma, trata-se de um campo também de três bits:
Apesar de ser uma prática muito desanconselhável, ainda aparecem alguns programas que têm de ser corridos com o SUID root, isto é, mesmo que seja um utilizador normal a correr o programa, este corre com todos os direitos de root.
Na listagem do ls, este campo é mostrado com um 's' no lugar do bit de execução do utilizador dono do ficheiro se o ficheiro for executável, por exemplo '-rwsr-xr-x'. Se o ficheiro não for executável, então este bit é identificado, no mesmo sítio, por um 'S', por exemplo '-rwSr--r--'.
Reforço que se deve evitar ao máximo usar esta funcionalidade por motivos de segurança.
No entanto, este bit tem uma funcionalidade adicional, quando aplicado a directorias, que é bastante útil, um utilizador pode pertencer a vários grupos, mas todos os ficheiros e directorias que criar farão sempre parte, por omissão, do grupo principal do utilizador. Se mudarmos o grupo a uma directoria e ligarmos o SGID bit, os ficheiros e directorias criados por baixo dessa directoria farão parte, por omissão, do grupo da directoria mãe.
Podemos ver quais os grupos a que um utilizador pertence com o comando id:
$ id helder uid=1000(helder) gid=1000(helder) groups=1000(helder),20(dialout),24(cdrom),25(floppy),29(audio),44(video),46(plugdev),1006(teste)
Neste caso o utilizador tem como grupo principal 'helder' e depois pertence a uma colecção de grupos.
Se quisermos que todos os ficheiros e directorias criados por baixo de uma determinada directoria pertençam a outro grupo que não o principal, então temos de:
Esta funcionalidade é bastante útil quando temos grupos de trabalho que partilham uma directoria para trabalhar. Permite-nos por exemplo criarmos um grupo 'contabilidade', criar num local apropriado uma directoria para o projecto de contabilidade, dar permissões de escrita ao grupo, ligar o SGID bit, retirar todas as permissões aos 'outros' e finalmente acrescentar ao grupo 'contabilidade' todos os utilizadores que façam parte do projecto. O resultado final é que apenas os utilizadores que façam parte do grupo 'contabilidade' conseguem ver e editar os ficheiros destas directorias.
Eu utilizo com frequência esta técnica para criar áreas isoladas para os vários departamentos das empresas, quando utilizamos o servidor samba.
Na listagem do ls, este campo é mostrado com um 's' no lugar do bit de execução do grupo do ficheiro se o ficheiro for executável, por exemplo '-rwxr-sr-x'. Se o ficheiro não for executável, então este bit é identificado, no mesmo sítio, por um 'S', por exemplo '-rw-r-Sr--'.
Em vez disso, quando aplicado a directorias, serve para indicar que os ficheiros e directorias criados por baixo da directoria com o Sticky Bit ligado apenas podem ser modificados ou apagados pelos donos desses ficheiros e directorias. A aplicação clássica desta funcionalidade é marcar a directoria '/tmp' com este bit. Como a directoria '/tmp' tem permissões de leitura, escrita e execução para todos os utilizadores, estes poderiam apagar ficheiros alheios por baixo desta directoria se não se ligasse o Sticky Bit.
Na listagem do ls, este campo é mostrado com um 't' no lugar do bit de execução dos outros se o ficheiro for executável, por exemplo '-rwxr-xr-t'. Se o ficheiro não for executável, então este bit é identificado, no mesmo sítio, por um 'T', por exemplo '-rw-r--r-T'.
Para encontrarmos os ficheiros que estão SUID ou SGID, pode-se usar o comando:
# find / -type f \( -perm -04000 -o -perm -02000 \) \-exec ls -lg {} \;
As permissões mudam-se com o comando chmod. A sintaxe do ficheiro na sua forma mais simples é:
chmod [OPÇÕES] [MODO] [FICHEIRO(S)]
O modo pode ser indicado da seguinte forma: [ugoa...][[+-=][rwxXstugo...]...][,...]. Trocando isto por miúdos temos que:
Quando usamos '-' ou '+' vamos mudar apenas os bits indicados. Por exemplo se tivermos para as permissões do utilizador 'rwx' e com o chmod aplicarmos o modo 'u-x' o resultado final será 'rw-'. Se usarmos o '=' por exemplo com 'u=w', então se as permissões iniciais do utilizador fossem 'rwx' como no exemplo anterior, iriamos obter '-w-'.
Podemos ainda separar por virgulas vários modos.
Se tivermos o seguinte ficheiro:
$ ls -l -rw-r--r-- 1 helder teste 7 2007-09-20 20:57 TESTE
E considerando sempre que as permissões iniciais são as mostradas podemos:
$ chmod o-r TESTE
$ chmod g+w,o-r TESTE
$ chmod g=u TESTE
$ chmod a+x TESTEou
$ chmod +x TESTE
Se omitirmos a primeira letra, então o comando assume que estamos a usar o modificador 'a' (all == todos).
Para mudar permissões recursivamente em várias directorias, pode-se usar a opção '-R', por exemplo:
$ chmod -R g+X ~/public_html
O modo das permissões também pode ser indicado utilizando três ou quatros digitos em octal.
Para os grupos de bits do utilizador, grupo e outros o mapeamento é feito da seguinte forma:
Read Ler |
Write Escrever |
eXecute eXecutar |
Octal |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 |
0 | 1 | 0 | 2 |
0 | 1 | 1 | 3 |
1 | 0 | 0 | 4 |
1 | 0 | 1 | 5 |
1 | 1 | 0 | 6 |
1 | 1 | 1 | 7 |
Notar que o número '1' corresponde apenas a termos ligado o bit de execução, o '2' o bit de escrita e o '4' de leitura. Se fixarmos isto é fácil de ver que para termos um grupo com 'rw-' basta somar 4 + 2 = 6, ou se for 'r-x' então temos 4 + 1 = 5, ou 'rwx' 4 + 2 + 1 = 7!
Para o grupo do SUID, SGID e do sticky bit temos:
SUID | SGID | Sticky bit | Octal |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 |
0 | 1 | 0 | 2 |
0 | 1 | 1 | 3 |
1 | 0 | 0 | 4 |
1 | 0 | 1 | 5 |
1 | 1 | 0 | 6 |
1 | 1 | 1 | 7 |
Para aplicar os modos usando esta notação temos de compor o número da seguinte forma:
SUID SGID Sticky bit |
Utilizador | Grupo | Outros |
Notar que este é um número em octal, assim se usarmos apenas um dígito, estamos a assumir que os outros três são nulos (zeros às esquerda...)
Exemplos:
chmod u+rw,go-rwx TESTEÉ equivalente a:
chmod 600 TESTE
chmod u+rw,u-x,g+r,g-wx,o-rwx TESTEÉ equivalente a:
chmod u=rw,g=r,o= TESTEE é também equivalente a:
chmod 640 TESTE
Podemos dizer que este método é absoluto, enquanto que o anterior apenas muda os bits que indicarmos (se não utilizarmos a opção '='). Por outro lado, este método é seguramente mais compacto e fácil de compreender se as modificações que estamos a fazer nas permissões forem complicadas. Julgo que no fim de contas, utilizar uma forma ou outra depende da preferência de cada um...
A opção de recursividade '-R' continua válida usando esta forma de expressar o modo.
Não esquecer de consultar a página de documentação do 'chmod' com:
$ man chmod
Para ver todas as opções disponíveis.
A shell que o utilizador está a usar define as permissões por omissão usadas em novos ficheiros e directorias.
Se estivermos a utilizar a 'Bourne-Again SHell' (bash), que é a usada por omissão na maior parte dos linuxes, podemos usar o comando interno 'umask' da shell para consultar as permissões por omissão:
$ umask -S u=rwx,g=rx,o=rx
Notar que o bit executável apenas é aplicado a directorias.
Se, por exemplo, não quisermos que os 'outros' tenham acesso a ficheiros criados por nós, basta fazer a umask:
$ umask u=rwx,g=rx,o= $ touch T2 $ ls -l T2 -rw-r----- 1 helder helder 0 2007-09-20 23:46 T2
Este comando, deve ser incluído nos ficheiros de inicialização da shell (por exemplo no ~/.bashrc, ou ~/.profile, etc...), caso contrário a modificação da máscara perde-se quando fizermos logout da shell.
Como o nome do comando indica, o valor é uma máscara. Se invocarmos o comando, sem nenhum parâmetro, obtemos o valor da máscara em octal:
$ umask 0022
Para obtermos o modo dado por 'umask -S', temos de fazer um ou exclusivo binário. Por exemplo para um valor de 2 para a máscara, temos:
2 = 010 010 XOR 111 = 101 => rx (leitura e execução)
A posse de um ficheiro é muito mais simples do que as permissões. Todos os ficheiros e directorias num sistema unix são possuídos por um dado utilizador e pertencem a um dado grupo. Já vimos como podemos determinar o utilizador e o grupo de um ficheiro ou directoria usando o comando 'ls -l'.
A cada utilizador está associado um UID (identificação de utilizador) e a cada grupo um GID, os UIDs e GIDs são simplesmente números definidos nos ficheiros /etc/passwd e /etc/group, respectivamente.
Por exemplo se fizermos:
$ grep sysadm /etc/passwd sysadm:x:1001:1001:Administrador de Sistemas,,,:/home/sysadm:/bin/bash
Temos que o utilizador 'sysadm' tem como UID 1001, e como GID também 1001.
Este utilizador pertence aos grupos:
$ grep sysadm /etc/group www-data:x:33:sysadm sysadm:x:1001: admin:x:1002:sysadm,director ntadmin:x:1003:root,sysadm secretariado:x:1004:sysadm,director,secretaria tmp:x:1005:sysadm,director,secretaria
É claro que podemos obter toda esta informação fazendo simplesmente:
$ id sysadm uid=1001(sysadm) gid=1001(sysadm) groups=1001(sysadm),33(www-data),1002(admin),1003(ntadmin),1004(secretariado),1005(tmp)
O utilizador 'sysadm' pode mudar o GID dos seus ficheiros para qualquer grupo de que faça parte, não pode no entanto, mudar nunca o UID. Apenas o utilizador 'root' o pode fazer.
Para mudar a ownership de ficheiros e directorias, usa-se o comando 'chown' com a sintaxe seguinte:
chown [OPÇÕES] [DONO][:[GRUPO]] FICHEIRO(S)...
Se indicarmos apenas o dono do ficheiro, o grupo mantém-se o mesmo. A opção a usar se quisermos mudar recursivamente é '-R'.
Se quisermos mudar apenas o grupo do ficheiro, deve-se usar o comando 'chgrp' com sintaxe idêntica à do 'chmod':
chgrp [OPÇÕES] [GRUPO] FICHEIRO(S)...
$ chgrp secretariado carta.odt
$ chown abcd:secretariado carta.odt
$ chown abcd carta.odt
Podemos consultar toda a informação sobre um dado ficheiro usando o comando 'stat', por exemplo:
$ stat TESTE File: `TESTE' Size: 7 Blocks: 8 IO Block: 4096 regular file Device: 309h/777d Inode: 32663 Links: 1 Access: (0640/-rw-r-----) Uid: ( 1000/ helder) Gid: ( 1006/ teste) Access: 2007-09-20 20:57:09.000000000 +0100 Modify: 2007-09-20 20:57:09.000000000 +0100 Change: 2007-09-20 22:54:09.000000000 +0100
O esquema de permissões dos unixes, apesar de simples, permite um grau de flexibilidade bastante grande. Podemos criar a partir destas primitivas esquemas de grande complexidade.
É claro que, sendo os unixes sistemas muito flexíveis, podemos, se disso tivermos necessidade, usar ainda esquemas de listas de controlo de acesso (ACLs), que permitem sistemas ainda mais refinados de permissões. No entanto, em regra, conseguimos implementar as políticas de acesso que quisermos usando apenas as permissões tradicionais.