Recarregar as atribuições de grupo de um usuário Linux sem fazer logout

348

Ao atribuir a lista de grupos secundários de um usuário usando:

# usermod -G <grouplist> <user>

é possível forçar essa atribuição de grupo a entrar em vigor sem sair de todas as sessões em execução?

Isso seria muito útil na situação em que existe uma sessão de tela com muitos shells em execução, pois a sessão inteira precisa ser essencialmente destruída para que a atribuição do grupo entre em vigor.

Eu acho que posso alterar o grupo principal do usuário em um shell em execução usando o newgrpcomando - existe alguma alternativa que funcione para grupos secundários?

Idealmente, eu gostaria de algo que entraria em vigor em cada shell sem ser executado manualmente em cada um, mas na falta disso, talvez alguma maneira de forçar a Screen a executar o mesmo comando em cada um.

Simon
fonte
Sei que pelo menos para alguns gerenciadores de janelas / sessões é possível fazer isso de forma que a sessão escolha o novo grupo e esteja disponível para qualquer novo processo iniciado nos menus, botões do painel ou o que for. Eu vim aqui agora procurando encontrá-lo novamente, então não posso dizer agora como fazê-lo, e provavelmente é específico para o gerenciador de janelas.
Mc0e

Respostas:

205

Horrivelmente hacky, mas você pode usar duas camadas newgrppara conseguir isso em um grupo específico:

id -g

... fornecerá o ID do grupo principal atual. Chamaremos isso orig_grouppara os fins deste exemplo. Então:

newgrp <new group name>

... alternará você para esse grupo como principal e o adicionará à lista de grupos retornados por groupsou id -G. Agora, mais:

newgrp <orig_group>

... você receberá um shell no qual poderá ver o novo grupo e o principal é o original.

Isso é horrível e você só adiciona um grupo de cada vez, mas me ajudou algumas vezes a adicionar grupos sem fazer logout / em toda a minha sessão X (por exemplo, para adicionar um fusível como um grupo a um usuário para que o sshfs funcione).

Editar: Isso também não exige que você digite sua senha su.

Legooolas
fonte
6
Bom truque, eu gosto
Simon
1
No Fedora eu tive que fazer em newgrp $USERvez de newgrp <orig_group>. Isso significa que não precisei encontrar meu ID de grupo primário original, por isso é ainda mais fácil do que esta solução.
Richard Turner
2
Eu achei que era o suficiente para fazer newgrp <new group name>. Este foi Ubuntu 14.04
Edward Falk
4
@EdwardFalk direito, mas você não (não) quer deixar esse grupo como o seu principal ...
mimoralea
4
Observe que cada newgrpum deles cria um novo shell; portanto, quando você precisa sair totalmente da sua sessão, é necessário "exit exit exit" para obter todo o caminho (:
jwd 4/17/17
371

De dentro de um shell, você pode emitir o seguinte comando

su - $USER

id agora listará o novo grupo:

id
Stivlo
fonte
3
Eu acho que essa é a melhor abordagem em muitos casos, mas o pôster original queria atualizar várias conchas em uma sessão de tela. Essa solução teria que ser feita a partir de cada shell.
Adrian Ratnapala
3
Bom truque, funciona muito bem!
Genpfault #
4
A solução original também corrigia apenas uma única sessão de shell na tela. Acabei de testar isso. A razão pela qual essa solução funciona é porque você está gerando uma nova sessão completa, em vez de herdar do ambiente original.
Dror
4
Esta realmente deve ser a resposta aceita. Bom truque, obrigado!
dotancohen
2
Isso exige que você digite uma senha, o que pode ser estranho / indesejado se você estiver tentando fazer isso em várias sessões.
Legooolas
156

Este truque bacana deste link funciona muito bem!

exec su -l $USER

Eu pensei em publicá-lo aqui, pois sempre que esqueço como fazer isso, esse é o primeiro link que aparece no google.

jhaagsma
fonte
14
+1 por não colocar o usuário em um subshell; você pode sair / sair como de costume com isso. Além disso, se NOPASSWD: estiver definido em / etc / sudoers, você poderá usar exec sudo su -l $USERpara evitar a solicitação de senha.
Ivan X
21
Esteja ciente: você será solicitado a fornecer uma senha do sudo. Se você errar, seu terminal será fechado.
Tyler Collier
1
@TylerCollier Ivan fez mençãoNOPASSWD:
pepoluan
32

1. Obtendo um shell com o novo grupo sem sair e entrar novamente

Se você estiver adicionando apenas um grupo, usei o seguinte:

exec sg <new group name> newgrp `id -gn`

Essa é uma variação do truque newgrp de duas camadas do Legooolas, mas está em uma linha e não exige que você insira manualmente seu grupo principal.

sgé newgrp, mas aceita um comando para executar com o novo ID do grupo. Os execmeios que o novo shell substitui o shell existente, para que você não precisa "logout" duas vezes.

Ao contrário de usar su, você não precisa digitar sua senha. Ele também não atualiza seu ambiente (exceto a adição do grupo); portanto, você mantém seu diretório de trabalho atual etc.

2. Executando o comando em todas as janelas da tela em uma sessão

O atcomando Screen executa um comando em qualquer janela que você especificar (observe que este é um comando Screen, não um comando shell).

Você pode usar o seguinte comando para enviar o comando para todas as sessões de tela existentes:

screen -S <session_name> -X at \# stuff "exec sg <new_group_name> newgrp \`id -gn\`^M"

Observe a necessidade de escapar dos backticks para idexecutar na sessão Screen e o ^ M para fazer com que a tela pressione 'enter' no final do seu comando.

Observe também que o stuffcomando da tela simplesmente digita o texto do comando em seu nome. Portanto, algo estranho pode acontecer se uma das janelas da tela tiver um comando semi-escrito em um prompt de comando ou estiver executando um aplicativo que não seja um shell (por exemplo, emacs, top). Se este for um problema, tenho algumas idéias:

  • Para se livrar de qualquer comando semi-escrito, você pode adicionar "^ C" ao início do comando.
  • Para evitar a execução do comando em uma janela do emacs, etc, você pode pedir ao at para filtrar o título da janela, etc (no exemplo acima, eu uso "#", que corresponde a todas as janelas, mas você pode filtrar por título da janela, usuário etc).

Para executar o comando em uma janela específica (identificada pelo número da janela), use o seguinte:

screen -S <session_name> -p 0 -X stuff "exec sg <new_group_name> newgrp \`id -gn\`^M"
Patrick Conheady
fonte
Um forro impressionante, que parece não ter outros efeitos colaterais, obrigado!
Cyril Duchon-Doris
17

Usando o newgrpcomando resolvido problema para mim:

newgrp <GroupName>

Esta postagem do blog tem explicação detalhada.

Pavan Vegirouthu
fonte
12

Os grupos geralmente são enumerados no login, não há como eu forçá-lo a refazer a enumeração de grupos sem fazer logoff e logon novamente.

Muitas respostas votadas aqui parecem usar uma solução alternativa que chama um novo shell com ambiente novo (o mesmo que fazer login novamente). o shell pai e todos os outros programas em execução contínua geralmente não receberão a nova associação do grupo até serem reinvocados de um shell novo, geralmente após o logout e o logon limpos.

Mister_Tom
fonte
Na verdade, tenho certeza de que isso não é verdade - eu havia encontrado uma maneira de fazer isso antes em uma caixa Linux. No entanto, para a minha vida, não me lembro qual era o comando. Se eu o encontrar, eu o publicarei. Edit: Acabei de encontrar, estou postando como resposta.
lunchmeat317
1
Obrigado por apontar isso, este também é meu entendimento. Todas as outras respostas aqui simplesmente abrem um novo shell, não importa se ele substitui um shell aberto ou reinicia a tela ou o que for. Não há panacéia mágica para emitir um comando ou script e todas as sessões em execução, incluindo a sua sessão X, refletem as novas participações no grupo.
scravy
12

Você consegue fazer isso.

Adicione quantos grupos você quiser usar usermod -G. Então, como usuário com uma sessão em execução, execute newgrp -apenas o argumento '-'.

Isso reinicializa o ID do grupo para o padrão, mas também define os grupos secundários. Você pode verificar isso executando a groupspartir da sessão atual, antes e depois do usermode do newgrp.

Isso deve ser executado em cada sessão aberta - não sei muito sobre tela. No entanto, se for possível iterar em todas as sessões abertas e executar newgrp, você deve ser bom. Você não precisará se preocupar em conhecer os grupos ou os IDs do grupo.

Boa sorte para você.

lunchmeat317
fonte
11
tentou em um xterm dentro de uma sessão X, mas não funcionou
dwery
3
tentou em uma sessão em tmux e não funcionou lá também
Michael
2
Tentou na Amazon linux 2, não funcionou
Cyril Duchon-Doris
1
newgrp -inicia um novo processo de shell
Piotr Findeisen
À luz do seu comentário sobre a resposta de Mister_Tom, esta é, como todas as outras respostas, uma solução alternativa. A resposta de Mister_Tom ainda está correta.
scravy 13/09
4

Para resumir:

exec newgrp <newlyaddedgroupname1>
exec newgrp <newlyaddedgroupname2>
...
exec newgrp -

Usar 'exec' significa substituir o shell existente pelo novo shell iniciado pelo comando newgrp (sair do novo shell faz o logout).

A final newgrp -é necessária para restaurar seu grupo principal normal, para que os arquivos criados posteriormente tenham esse nome como proprietário do grupo.

Nota: A pergunta do pôster original era como tornar os grupos adicionados recentemente visíveis nos processos existentes. Os comandos gpasswde usermodnão afetam os processos existentes; grupos adicionados recentemente (ou excluídos!) aparecem na sua conta (desaparecem da), ou seja, nos arquivos / etc / group e / etc / gshadow, mas as permissões dos processos existentes não são alteradas. Para remover permissões, você precisa eliminar todos os processos em execução; newgrp -não relerá o arquivo / etc / group e redefinirá a lista de grupos; em vez disso, parece usar apenas os grupos anteriormente associados ao processo.

jimav
fonte
A propósito, exec su - <username>pode ser usado para obter um novo shell de login com grupos configurados, mas isso não funcionará em scripts, porque um novo shell lerá comandos do terminal. Você pode usar su -c "command ..." <myusername>para reiniciar o script, mas o processo resultante não possui terminal de controle e, portanto, ocorrerá um erro se tentar um editor de tela ou outro comando interativo.
jimav
Por que isso foi prejudicado? Alguém pode explicar o que há de ruim nisso, porque foi o que me ocorreu e acho que gosto mais?
precisa saber é o seguinte
Gah, eu votei antes dos testes. newgrp -se não substituir o "grupo principal". A resposta de Patrick Conheady é a melhor aqui, pois não bifurca nem altera o grupo principal.
precisa saber é o seguinte
1

Eu tive um problema semelhante, mas também para usuários não logados. Reinício do nscd não ajudou, mas executar este comando fiz: nscd -i group. Isso deve instruir o nscd (daemon de cache) a recarregar o arquivo de grupos.

Marki555
fonte
1

Não consegui que o comando newgrp funcionasse. Não tenho certeza se isso depende de / etc / sudoers, mas normalmente tenho que digitar minha senha para sudo, e isso funcionou sem exigir minha senha:

[leo60228@leonix:~]$ groups
users wheel

[leo60228@leonix:~]$ sudo echo hi
[sudo] password for leo60228:
hi

[leo60228@leonix:~]$ sudo -k # reset sudo timeout

[leo60228@leonix:~]$ exec sudo -i -u $(whoami) # no password necessary

[leo60228@leonix:~]$ groups
users wheel docker
snuggles08
fonte
0

Isso funciona, se você tiver, sudoe pode evitar que você digite sua senha mais uma vez em alguns casos:

sudo su $USER
guaka
fonte