Temos imagens Linux baseadas em RH; nos quais tenho que "aplicar" algum "arquivo especial" para atualizá-los para a versão de desenvolvimento mais recente do nosso produto.
A pessoa que criou o arquivo percebeu que em nossa imagem base algumas permissões estão erradas; então nos disseram para correr
sudo chgrp -R nobody /whatever
Nós fizemos isso; e mais tarde, quando nosso aplicativo estava em execução, surgiram problemas obscuros.
O que descobri mais tarde: o chamado parachgrpvaiclaroas informações do bit setuid em nossos binários em /whatever.
E o verdadeiro problema é: alguns dos nossos bináriosdevetenha esse bit setuid definido para funcionar corretamente.
Resumindo: existe uma maneira de executar o comando "chgrp"semmatando meus bits setuid?
Acabei de executar o seguinte no meu Ubuntu local; levando ao mesmo resultado:
mkdir sticky
cd sticky/
touch blub
chmod 4755 blub
ls -al blub
-> mostra o nome do arquivo com fundo vermelho -> então, sim, setuid
chgrp -R myuser .
ls -al blub
-> mostra o nome do arquivo sem fundo vermelho -> setuid desapareceu
Responder1
Se você deseja implementar o seu chgrp -R nobody /whatever
enquanto retém o bit setuid, você pode usar estes dois find
comandos
find /whatever ! -type l -perm -04000 -exec chgrp nobody {} + \
-exec chmod u+s {} +
find /whatever ! -type l ! -perm -04000 -exec chgrp nobody {} +
A find ... -perm 04000
opção seleciona arquivos com o bit setuid definido. O primeiro comando então aplica o chgrp
e depois a chmod
para restabelecer o bit setuid que foi eliminado. O segundo se aplica chgrp
a todos os arquivos que não possuem um bit setuid.
Em qualquer caso, você não deseja chamar chgrp
ou chmod
usar links simbólicos, pois isso afetaria seus alvos, daí o ! -type l
.
Responder2
Limpar os bits SUID e SGID em chgrp
(ou chown
) é perfeitamente razoável. É uma medida de segurança para evitar problemas de segurança. Para SGID (em executáveis, presumo) significaexecute este programa com o grupo efetivo do proprietário do grupo.
Se você mudar o proprietário do grupo, então em termos de segurança e controle de acesso isso será algo totalmente diferente, ou seja, em vez de rodar com grupo efetivo uvw
o programa agora roda com grupo efetivo xyz
.
Portanto, você deve restaurar explicitamente o bit SUID ou SGID na mudança de propriedade.
Adendo: Na alegação de que chgrp (ou chown) deve apenas limpar SGID (ou SUID, respectivamente)
Ao chown
ing ou chgrp
ing você altera a configuração de segurança de um executável e isso é motivo suficiente para limpar quaisquer atributos de elevação de privilégio. O poder do Unix vem da simplicidade conceitual, e a segurança do Unix já é bastante complicada. Para este fim, remover SUID e SGID em qualquer mudança de propriedade é simplesmente uma rede de segurança - afinal, na história do Unix/Linux houve algumas vulnerabilidades devido a configurações equivocadas de SUID ou SGID.
Portanto, não há nenhuma razão mais profunda para o Unix se comportar dessa maneira, é apenas uma decisão conservadora de design.
Responder3
A limpeza do bit setuid
, setgid
(pelo menos no Linux) em não-diretórios é feita pelo kernel na chown()
chamada do sistema feita por chgrp
, e não por chgrp
si só. Então a única maneira é restaurá-lo depois.
Também limpa os recursos de segurança.
Então, no GNU Linux:
chown_preserve_sec() (
newowner=${1?}; shift
for file do
perms=$(stat -Lc %a -- "$file") || continue
cap=$(getfattr -m '^security\.capability$' --dump -- "$file") || continue
chown -- "$newowner" "$file" || continue
[ -z "$cap" ] || printf '%s\n' "$cap" | setfattr --restore=-
chmod -- "$perms" "$file"
done
)
E execute (como root
):
chown_preseve_sec :newgroup file1 file2...
para alterar o grupo enquanto tenta preservar as permissões.
Recursivamente, você poderia fazer:
# save permissions (and ACLs). Remove the "# owner" and "# group" lines
# to prevent them being restored!
perms=$(getfacl -RPn . | grep -vE '^# (owner|group): ')
# save capabilities
cap=$(getfattr -Rhm '^security\.capability$' --dump .)
chgrp -RP nobody .
# restore permissions, ACLs and capabilities
printf '%s\n' "$perms" | setfacl --restore=-
[ -z "$cap" ] || printf '%s\n' "$cap" | setfattr -h --restore=-
(isso tudo presumindo que nada esteja atrapalhando os arquivos ao mesmo tempo).
Responder4
Como de costume na administração, há muitos caminhos a seguir.
A solução que coloquei é assim:
cd /home/me
getfacl -R /whatever > whatever-permissions.org 2> /dev/null
# A) change lines starting with # group: root
# to # group: whatineed
sed 's/^# group: root/# group: whatineed/g' whatever-permissions.org > whatever-permissions.new
# B) change lines with group::x.y
# to group::xwy
# (where x, y mean: whatever was there before)
sed 's/^group::\(.\).\(.\)/group::\1w\2/g' whatever-permissions.new > whatever-permissions.new
cd /
setfacl --restore /home/me/whatever-permissions.new