Se eu criar um arquivo como um usuário não privilegiado e alterar o modo de permissões para 400
, ele será visto como somente leitura, corretamente:
$ touch somefile
$ chmod 400 somefile
$ [ -w somefile ] && echo rw || echo ro
ro
Tudo está bem.
Mas então a raiz aparece:
# [ -w somefile ] && echo rw || echo ro
rw
Que diabos? Claro, o root pode gravar em arquivos somente leitura, mas não deve ter o hábito: as práticas recomendadas tendem a exigir que eu seja capaz de testar o bit de permissão de gravação e, se não for, foi definido dessa maneira por uma razão.
Acho que quero entender por que isso está acontecendo e como posso obter um código de retorno falso ao testar um arquivo que não possui o bit de gravação definido?
permissions
test
readonly
Rico
fonte
fonte
4.1.2(1)-release
) e RHEL7 (4.2.46(2)-release
)./etc/dhcp/dhcpd.conf
, que pertence à raiz. Estou usando o fornecido pelo fornecedordhcpd
. Desastre total, não é? O arquivo é verificado em RCS, estou automatizar uso dercsdiff
,ci
eco
porque temos operadores que precisam ... operar. A verificação de bits de permissão (-w
conforme detalhado portest(1)
) seria a primeira linha de falha, trabalhando com base no queci -u
deixa um arquivo somente leitura. Estou abandonando isso e indo direto pararcsdiff -q
e verificando$?
. Desastrosodhcpd
? Seria propriedade dedhcpd
.bash
etest
me levaram a acreditar que[ -w
é para isso.Respostas:
test -w
aka[ -w
não verifica o modo de arquivo. Ele verifica se é gravável. Para raiz, é.A maneira como eu testaria seria fazer uma comparação bit a bit com a saída de
stat(1)
("%a
Direitos de acesso em octal").Observe que o subshell
$(...)
precisa de um0
prefixo para que a saída destat
seja interpretada como octal por(( ... ))
.fonte
(( ... & ... ))
. Um erro de digitação corrigido :-)if
necessário, a saída de permissões octal%a
não é%d
e(( ... ))
precisa de um prefixo0
para interpretar a saídastat
como octal.man stat
diz "% d número do dispositivo em decimal", mas o que queremos são os "direitos de acesso", não? Seu ponto de vista sobre a necessidade do prefixo 0 é bem-feito, mas acho que só precisamos insistir nele :).stat -c 0%a
...Eu acho que você entendeu mal o que
-w
faz. Ele não verifica se o arquivo tem "Permissões de gravação", verifica se o arquivo é gravável pelo usuário que está chamando .Mais especificamente, chama
access(2)
ou similar.por exemplo, se um script tiver
if [ -w /etc/shadow ]
, se você executarstrace
o script, poderá ver uma linha semelhante aComo
root
pode gravar no arquivo, ele retorna 0.por exemplo, como um usuário normal:
Como raiz
Isso, apesar do fato de
/etc/shadow
ter permissão000
na minha máquina.Agora, o que você quer fazer fica interessante e não é tão simples.
Se você quiser verificar as permissões simples, verifique a
ls
saída ou liguestat
ou similar. Mas saiba que as ACLs podem substituir essas permissões. Só porque um arquivo tem permissão 400, não impede que ele seja gravável ...fonte
-w
:test(1)
é explícito: "FILE existe e a permissão de gravação é concedida", não "o arquivo pode ser gravado pelo usuário atual ". Nada sobre a substituição de permissões, nem ACLs.bash(1)
é cauteloso: "Verdadeiro se o arquivo existir e for gravável ."ksh(1)
faz uma dica sutil em relação às travessuras: "-w file // True, se o arquivo existir e for gravável pelo processo atual ".zsh(1)
adiatest(1)
,zshmisc(1)
é redigido comoksh(1)
ezshexpn(1)
detalha alguns globbing interessantes baseados em permissões.csh(1)
é hilariamente breve: "Acesso de gravação".O usuário root pode fazer o que bem entender, as permissões de arquivo "normais" não são uma limitação. Ele não executará diretamente um arquivo simples sem nenhuma permissão eXecute, apenas para um pouco de segurança contra a prática de tiro ao alvo.
fonte