Vuelva a cargar las asignaciones de grupo de un usuario de Linux sin cerrar sesión

348

Al asignar la lista de grupos secundarios de un usuario usando:

# usermod -G <grouplist> <user>

¿Es posible forzar que esta asignación de grupo surta efecto sin cerrar todas las sesiones en ejecución?

Esto sería muy útil en la situación en la que existe una sesión de Screen con muchos shells en ejecución, ya que es necesario destruir toda la sesión para que la asignación del grupo surta efecto.

Creo que puedo cambiar el grupo primario del usuario en un shell en ejecución usando el newgrpcomando: ¿hay alguna alternativa que funcione para grupos secundarios?

Idealmente, quisiera algo que surta efecto en cada shell sin ejecutarse manualmente en cada uno, pero en su defecto, tal vez alguna forma de forzar a Screen a ejecutar el mismo comando en cada uno.

Simon
fuente
Sé que al menos para algunos administradores de ventanas / sesiones es posible hacer esto de modo que la sesión elija el nuevo grupo y esté disponible para cualquier proceso nuevo que se inicie desde los menús, botones del panel o lo que sea. Vine aquí ahora mismo para buscar eso nuevamente, así que no puedo decir cómo hacerlo, y probablemente sea específico del administrador de ventanas.
mc0e

Respuestas:

205

Horriblemente hacky, pero podrías usar dos capas newgrppara lograr esto para un grupo en particular:

id -g

... le dará la identificación actual del grupo primario. Llamaremos a esto orig_grouppara los propósitos de este ejemplo. Entonces:

newgrp <new group name>

... lo cambiará a ese grupo como principal y lo agregará a la lista de grupos devueltos por groupso id -G. Ahora, un más:

newgrp <orig_group>

... obtendrá un shell en el que puede ver el nuevo grupo y el primario es el original.

Esto es horrible y solo conseguirá que se agregue un grupo a la vez, pero me ha ayudado un par de veces a agregar grupos sin cerrar sesión / en toda mi sesión X (por ejemplo, para agregar fusibles como grupo a un usuario para que sshfs funcione).

Editar: Esto tampoco requiere que escriba su contraseña, lo que susí lo hará.

Legooolas
fuente
66
Buen truco, me gusta
Simon
1
En Fedora tuve que hacer en newgrp $USERlugar de newgrp <orig_group>. Eso significa que no tuve que encontrar mi ID de grupo primario original, por lo que es aún más fácil que esta solución.
Richard Turner
2
Encontré que era suficiente newgrp <new group name>. Esto fue Ubuntu 14.04
Edward Falk
44
@EdwardFalk bien, pero no quieres (puede que no) quieras dejar ese grupo como tu principal ...
mimoralea
44
Tenga en cuenta que cada uno newgrpcrea un nuevo shell, por lo que cuando necesita salir completamente de su sesión, debe hacer "salir salir salir" para salir ((
jwd
371

Desde dentro de un shell, puede emitir el siguiente comando

su - $USER

id ahora mostrará el nuevo grupo:

id
stivlo
fuente
3
Creo que este es el mejor enfoque en muchos casos, pero el póster original quería actualizar varios shells dentro de una sesión de pantalla. Esta solución debería hacerse desde cada shell.
Adrian Ratnapala
3
Buen truco, funciona muy bien!
genpfault
44
La solución original también solo arreglaría una única sesión de shell en la pantalla. Acabo de probar eso. La razón por la que esta solución funciona es porque está generando una nueva sesión completa en lugar de heredar del entorno original.
Dror
44
Esta realmente debería ser la respuesta aceptada. Buen truco, gracias!
dotancohen
2
Sin embargo, esto requiere que escriba una contraseña, lo que puede ser incómodo / no deseado si está intentando hacerlo en muchas sesiones.
Legooolas
156

¡Este ingenioso truco de este enlace funciona muy bien!

exec su -l $USER

Pensé que lo publicaría aquí, ya que cada vez que olvido cómo hacer esto, este es el primer enlace que aparece en Google.

jhaagsma
fuente
14
+1 por no poner al usuario en una subshell; puede cerrar sesión / salir como de costumbre con esto. Además, si NOPASSWD: está configurado en / etc / sudoers, puede usarlo exec sudo su -l $USERpara evitar que se le solicite la contraseña.
Ivan X
21
Tenga en cuenta: se le pedirá una contraseña de sudo. Si te equivocas, tu terminal se cerrará.
Tyler Collier
1
@TylerCollier Ivan hizo menciónNOPASSWD:
pepoluan
32

1. Obtener un shell con el nuevo grupo sin cerrar sesión y volver a iniciarla

Si solo agrega un grupo, utilicé lo siguiente:

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

Esta es una variación del truco newgrp de dos capas de Legooolas, pero está en una línea y no requiere que ingreses manualmente a tu grupo principal.

sges newgrp pero acepta un comando para ejecutar con la nueva ID de grupo. Esto execsignifica que el nuevo shell reemplaza al shell existente, por lo que no necesita "cerrar sesión" dos veces.

A diferencia de usar su, no necesita escribir su contraseña. Tampoco actualiza su entorno (aparte de agregar el grupo), por lo que conserva su directorio de trabajo actual, etc.

2. Ejecutar el comando en todas las ventanas de pantalla en una sesión

El atcomando en pantalla ejecuta un comando en cualquier ventana que especifique (tenga en cuenta que este es un comando de pantalla, no un comando de shell).

Puede usar el siguiente comando para enviar el comando a todas las sesiones de pantalla existentes:

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

Tenga en cuenta la necesidad de escapar de los backticks para poder idejecutar la sesión de la pantalla, y la ^ M para que la pantalla presione 'enter' al final de su comando.

Tenga en cuenta también que el stuffcomando de la pantalla simplemente escribe el texto del comando en su nombre. Por lo tanto, puede suceder algo extraño si una de las ventanas de la pantalla tiene un comando medio escrito en un símbolo del sistema o está ejecutando una aplicación que no sea un shell (por ejemplo, emacs, top). Si esto es un problema, tengo algunas ideas:

  • Para deshacerse de cualquier comando medio escrito, puede agregar "^ C" al inicio del comando.
  • Para evitar ejecutar el comando en una ventana de emacs, etc., puede pedirle a 'at' que filtre el título de la ventana, etc. (en el ejemplo anterior, uso "#", que coincide con todas las ventanas, pero puede filtrar por título de ventana, usuario , etc.)

Para ejecutar el comando en una ventana específica (identificada por el número de ventana), use lo siguiente:

screen -S <session_name> -p 0 -X stuff "exec sg <new_group_name> newgrp \`id -gn\`^M"
Patrick Conheady
fuente
Impresionante un revestimiento, que no parece tener otros efectos secundarios, ¡gracias!
Cyril Duchon-Doris
17

Usar el newgrpcomando resolvió el problema para mí:

newgrp <GroupName>

Esta publicación de blog tiene una explicación detallada.

Pavan Vegirouthu
fuente
12

Por lo general, los grupos se enumeran al iniciar sesión, no sé cómo forzarlo a volver a hacer la enumeración de grupo sin cerrar sesión y volver a iniciarla.

Muchas de las respuestas votadas aquí parecen utilizar una solución alternativa que invoca un nuevo shell con un entorno nuevo (igual que iniciar sesión de nuevo). el shell principal y todos los demás programas en ejecución continua generalmente no recibirán la nueva membresía de grupo hasta que se vuelva a invocar desde un shell nuevo, generalmente después de un cierre de sesión y un inicio de sesión limpios.

Mister_Tom
fuente
A decir verdad, estoy bastante seguro de que esto no es cierto: había encontrado una forma de hacerlo antes en una caja de Linux. Sin embargo, por mi vida, no puedo recordar cuál era el comando. Si lo encuentro, lo publicaré. Editar: Acabo de encontrarlo, lo estoy publicando como respuesta.
lunchmeat317
1
Gracias por señalar esto, este es también mi entendimiento. Cualquier otra respuesta aquí simplemente abre un nuevo shell, sin importar si reemplaza un shell abierto o reinicia la pantalla o lo que sea. No existe una panacea mágica para emitir un comando o script y hacer que cada sesión en ejecución, incluida su sesión X, refleje las nuevas membresías de grupo.
Scravy
12

Puedes hacerlo.

Agregue tantos grupos como desee usando usermod -G. Luego, como usuario con una sesión en ejecución, ejecute newgrp -solo con el argumento '-'.

Esto reinicializa la identificación del grupo al valor predeterminado, pero también establecerá los grupos secundarios también. Puede verificar esto ejecutando groupsdesde la sesión actual, antes y después de usermody el newgrp.

Esto debe ejecutarse desde cada sesión abierta: no sé mucho sobre la pantalla. Sin embargo, si es posible iterar sobre todas las sesiones abiertas y ejecutarse newgrp, debería ser bueno. No tendrá que preocuparse por conocer los grupos o las ID de grupo.

La mejor de las suertes para ti.

almuerzo317
fuente
11
probé un xterm dentro de una sesión X pero no funcionó
dwery
3
intentado en una sesión en tmux y tampoco funcionó allí
Michael
2
Probado en Amazon Linux 2, no funcionó
Cyril Duchon-Doris
1
newgrp -comienza un nuevo proceso de shell
Piotr Findeisen
A la luz de su comentario sobre la respuesta de Mister_Tom, esta es, como todas las otras respuestas, una solución alternativa. La respuesta de Mister_Tom sigue siendo correcta.
Scravy
4

Para resumir:

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

Usar 'exec' significa reemplazar el shell existente con el nuevo shell iniciado por el comando newgrp (por lo que salir del nuevo shell cierra la sesión).

La final newgrp -es necesaria para restaurar su grupo primario normal, por lo que los archivos que cree más adelante tendrán eso como propietario del grupo.

Nota: La pregunta del póster original era cómo hacer visibles los grupos recién agregados en los procesos existentes. Los comandos gpasswdy usermodno afectan los procesos existentes; los grupos recién agregados (¡o eliminados!) aparecen en (desaparecen) de su cuenta, es decir, en los archivos / etc / group y / etc / gshadow, pero los permisos para los procesos existentes no cambian. Para eliminar los permisos, debe eliminar todos los procesos en ejecución; newgrp -no volverá a leer / etc / group y restablecerá la lista de grupos; en cambio, parece usar solo los grupos previamente asociados con el proceso.

jimav
fuente
Por cierto, exec su - <username>se puede usar para obtener un nuevo shell de inicio de sesión con grupos configurados, pero eso no funcionará en los scripts porque un nuevo shell leerá comandos desde el terminal. Puede usar su -c "command ..." <myusername>para reiniciar su script, pero el proceso resultante no tiene un terminal de control, por lo que se producirá un error si se intenta un editor de pantalla u otro comando interactivo.
jimav
¿Por qué se rechazó esto? ¿Alguien puede explicar qué tiene de malo, porque fue lo que se me ocurrió y creo que me gusta más?
jasonmp85
Gah, lo voté antes de probar. newgrp -no no reemplazar el "grupo primario". La respuesta de Patrick Conheady es la mejor aquí, ya que no se bifurca ni cambia el grupo primario.
jasonmp85
1

Tuve un problema similar pero también para los usuarios que no han iniciado sesión. Reinicio de nscd no ayudó, pero lo hizo ejecutar este comando: nscd -i group. Eso debería indicar a nscd (demonio de almacenamiento en caché) que vuelva a cargar el archivo de grupos.

Marki555
fuente
1

No pude hacer que el comando newgrp funcione. No estoy seguro de si esto depende de / etc / sudoers, pero normalmente tengo que escribir mi contraseña para sudo, y esto funcionó sin requerir mi contraseña:

[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
fuente
0

Esto es suficiente si lo tiene sudoy puede evitar que ingrese su contraseña una vez más en algunos casos:

sudo su $USER
guaka
fuente