Quero encontrar arquivos que um usuário em particular não possa ler.
Suponha que o nome de usuário seja "user123" e eles estejam em um grupo chamado "user123". Quero encontrar arquivos que, se pertencem ao user123, têm u + r; falhando que, se o arquivo for do grupo user123, ele deve ter g + r ativado; falhando que ele pode ter o + r ligado.
Como o GNU find tem "-readable", eu poderia fazer isso:
sudo -u user123 find /start ! -readable -ls
No entanto, o processo precisa ser executado por um usuário que não possui acesso ao sudo. Portanto, eu tentei o seguinte: (não verifica o + r, mas isso não é importante neste momento)
find /start \( -user user123 ! -perm -u=r \) -o \( -group user123 ! -perm -g=r \) -ls
mas lista este arquivo:
272118 4 -rw------- 1 user123 user123 3243 Jul 3 19:50 /start/blah/blah/file.txt
Este arquivo é o único arquivo /start
pertencente ao user123 com g=r
desativado. É como se find estivesse interpretando o -u=r
as -g=r
.
Decidi tentar reverter a lógica e, em not ( truth )
vez disso, testar :
find /etc/puppet ! \( \( -user puppet -perm -u=r \) -o \( -group puppet -perm -g=r \) -o \( -perm -o=r \) \) -ls
Isso funciona!
Por que o original find
falhou? É um erro find
(improvável) ou a lógica está errada?
Atualização: eu estava com a lógica errada. Como apontado abaixo, desde! (A || B || C) == (! A &&! B &&! C) estas são as duas instruções equivalentes:
find /start ! \( \( -user user123 -perm -u=r \) -o \( -group user123 -perm -g=r \) -o \( ! \( -user user123 -o -group user123 \) -perm -o=r \) \) -ls
find /start ! \( -user user123 -perm -u=r \) ! \( -group user123 -perm -g=r \) ! \( ! \( -user user123 -o -group user123 \) -perm -o=r \) -ls
Meu objetivo não era ter que testar usuário / grupo duas vezes. O que eu realmente preciso é de uma estrutura se-então-mais mais complicada, que provavelmente só seria possível se houvesse um operador -xor. Eu poderia criar um xor a partir e / ou não, mas seria mais complexo do que as duas soluções acima.
puppet
tem acesso a um arquivo com--wxrwxrwx puppet puppet
.Respostas:
A lógica está errada. Você está pensando que esse arquivo não deveria ter sido listado porque pertence
user123
e tem or
bit do usuário definido. No entanto, ele é listado porque corresponde ao segundo critério (pertence ao grupouser123
e tem or
bit do grupo não definido).Sua segunda versão funciona devido a uma das leis de Morgan : negar o ORing lógico de um grupo de declarações é logicamente equivalente a ANDing a negação das declarações individuais. Em outras palavras:
Então, o trabalho
find
está procurando um arquivo queuser123
e legível pelo usuário) ANDuser123
e legível pelo referido grupo) ANDenquanto o primeiro
find
está procurando um arquivo queuser123
e não pode ser lido pelo referido usuário OUuser123
e não pode ser lido pelo referido grupo OU (se você o tiver concluído)Portanto, um arquivo que corresponda a QUALQUER dos três critérios acima (e não necessariamente a todos) será listado como você viu.
Editar
Aliás (depois de ver o seu perfil), sou um grande fã do seu livro O'Reilly :)
fonte
( !A && !B && !C )
mas mudei!
para o interior de cada parte, o que não é válido. Obrigado!Há muito mais coisas a serem levadas em consideração para verificar se um usuário tem acesso a um arquivo por um determinado caminho:
Antes de realmente mudar todos os uids e gids para os do usuário e verificar, é muito difícil implementar a mesma lógica que o sistema faz.
Com o zsh, você pode fazer (como root):
Ou com
perl
:Nos dois casos, desça a árvore de diretórios,
root
mas teste o acesso ao arquivo como o usuário correspondente.Executando
find -readable
comosome-user
não, nos casos em que não poderá passar pelos diretórios para os quais o usuário não tem acesso ou permissão de leitura (mas possivelmente acesso).Mesmo considerando apenas a permissão e a propriedade do próprio arquivo (e não ACLs ou componentes de caminho ...), você precisa de pelo menos (aqui sintaxe GNU):
A ideia é que, se o arquivo pertencer ao usuário, todas as outras permissões serão irrelevantes. Caso contrário, se o arquivo pertencer a um grupo de qualquer um dos grupos de usuários, a permissão "other" será irrelevante.
fonte
access()
que ela usa o mesmo código do kernel queopen()
. Assimsudo -u user123 find /start -readable
é a melhor solução sesudo
for uma opção.sudo -u user123 find -readable
, ele não reportará arquivos em diretórios que você não pode entrar ou em diretórios que você não pode ler (portanto, haverá falsos negativos e positivos). É por isso que eu sugiro usarzsh
para descer da árvore de diretórios como root e fazeraccess()
([ -r ... ]
) como o usuário real (ajuste$USERNAME
emzsh
mudanças todos os UIDs e GIDs comosudo
faria).