
Estoy usando pam_mount.so para montar automáticamente un recurso compartido CIFS para usuarios en un cliente Ubuntu 14.04.
pam_mount usa una configuración local en el directorio de inicio de cada usuario. Estoy ejecutando un script bash con pam_exec que actualiza el archivo de configuración con la ruta al recurso compartido CIFS.
El final de mi archivo /etc/pam.d/common-session se ve así:
session required pam_unix.so
session optional pam_exec.so log=/var/log/pamexec /usr/local/bin/mdrive_add
session optional pam_mount.so
session optional pam_ldap.so
session optional pam_systemd.so
Al iniciar sesión con SSH o mediante la GUI, esto funciona, el script se ejecuta antes del montaje, por lo que se puede acceder al recurso compartido.
Sin embargo, cuando se usa su, el script falla y la configuración del usuario local no se actualiza, por lo que el montaje también falla.
El error que recibo cuando uso su de [cuentaA] a [cuentaB] es:
/bin/sed: couldn't open temporary file /home/[accountB]/sednpoogQ: Permission denied
La línea del script que falla es esta:
/bin/sed -i "s|\@S|${XSERVER}|g" /home/${PAM_USER}/.pam_mount.conf.xml
Intenté ejecutar el script desde ~/.profile y otros lugares, esto funciona perfectamente, pero no se ejecuta antes de pam_mount.
Entonces mi pregunta es, ¿cómo puedo hacer que pam_exec reemplace una cadena en un archivo de texto que reside en el directorio de inicio de un usuario cuando uso su?
Actualizar
Según los comentarios, probé 'sudo -u [accountb] -i' (después de incluir @common-session en /etc/pam.d/sudo) y esto no devuelve el mismo error, funciona. Sin embargo, no es una solución aceptable, ya que necesito que su funcione (y provoca que pam_mount solicite una contraseña).
Actualización2
Inicié sesión con ssh, vertí env en un archivo y luego inicié sesión con ssh desde otra cuenta, usé su y vertí env en un archivo.
Comparando los dos (nombres de cuentas reemplazados por accounta y accountb como en la pregunta:
$ comm -3 <(sort ssh_list.txt ) <(sort su_list.txt)
PASSWD_FD=0
_PMT_DEBUG_LEVEL=0
PWD=/home/[accounta]
PWD=/home/[accountb]
SHLVL=1
SHLVL=2
SSH_CLIENT=10.112.9.87 58090 22
SSH_CLIENT=10.112.9.87 58695 22
SSH_CONNECTION=10.112.9.87 58090 10.80.0.68 22
SSH_CONNECTION=10.112.9.87 58695 10.80.0.68 22
SSH_TTY=/dev/pts/13
SSH_TTY=/dev/pts/14
XDG_RUNTIME_DIR=/run/user/1000
XDG_RUNTIME_DIR=/run/user/10006
XDG_SESSION_ID=6
XDG_SESSION_ID=7
Actualización3
Se agregó el script completo ejecutado por pam_exec (la información confidencial se reemplazó con marcadores de posición):
#!/bin/bash
USERN=$PAM_USER
if grep -q @S /home/${USERN}/.pam_mount.conf.xml || grep -q @P /home/${USERN}/.pam_mount.conf.xml; then
BASEDIR=`ldapsearch -LLL -H ldaps://dc.example.org:3269 -D "[email protected]" -b "DC=c,DC=sdu,DC=dk" -w [secretpw] "sAMAccountName=${USERN}" dn`;
PREFIX="dn:: "
BASEDIR=${BASEDIR#$PREFIX}
PREFIX="dn: "
BASEDIR=${BASEDIR#$PREFIX}
BASEDIR=`echo $BASEDIR | tr -d ' '`
if [[ $BASEDIR != *","* ]]
then
BASEDIR=`echo $BASEDIR | base64 --decode`
fi
BASEDIR=`echo $BASEDIR | tr -d ' \n' | awk -F "DC=" '{ st = index($0,"DC=");print substr($0,st+0)}'`;
DOMAIN=`echo $BASEDIR | sed 's/,DC=/./g' | sed 's/DC=//'`;
OUTPUT=`ping -c 1 -t 10 $DOMAIN | grep icmp`
HOMEDIR='\\fallbackserver\share'
if [[ -n "$OUTPUT" ]]
then
DC=`echo $OUTPUT| cut -d' ' -f 4`
HOMEDIR=`ldapsearch -LLL -H ldaps://$DC:636 -D "[email protected]" -b "${BASEDIR}" -w [secretpw] "sAMAccountName=${USERN}" homeDirectory | grep homeDirectory | awk '{print $2}'`;
fi
CHOMEDIR=$(echo ${HOMEDIR} | sed 's/\\/\//g')
XSERVER=`echo $CHOMEDIR | cut -f3 -d/`
XPATH=`echo $CHOMEDIR | cut -f4- -d/`
/bin/sed -i "s|\@S|${XSERVER}|g" /home/${USERN}/.pam_mount.conf.xml
/bin/sed -i "s|\@P|${XPATH}|g" /home/${USERN}/.pam_mount.conf.xml
fi
Actualización4
Al colocar un whoami en el script, se muestra que cuando se usa su de cuenta a cuentab, el script se ejecuta mediante accounta.
Actualización5
El uso de la opción 'seteuid' con pam_exec resolvió el problema.
session optional pam_exec.so seteuid log=/var/log/pamexec /usr/local/bin/mdrive_add
whoami ahora muestra 'root' al cambiar de A a B y no hay problemas de permisos.
No entiendo los términos 'ID de usuario real' e 'ID de usuario efectivo' en el manual de pam_exec, pero esa es una pregunta para otro día.
De forma predeterminada, pam_exec.so ejecutará el comando externo con el ID de usuario real del proceso de llamada. Especificar esta opción significa que el comando se ejecuta con el ID de usuario efectivo.
Respuesta1
El problema era que al iniciar sesión su
pam_exec
se ejecutaba el script como el usuario "antiguo", que no tenía permiso para escribir en el directorio de inicio del "nuevo" usuario.
Configurar la seteuid
opción session optional pam_exec.so log=/var/log/pamexec /usr/local/bin/mdrive_add
hizo pam_exec
ejecutar el script como root, lo que solucionó el problema:
session optional pam_exec.so seteuid log=/var/log/pamexec /usr/local/bin/mdrive_add
Sin embargo, la solución "real" probablemente sea configurarla /etc/pam.d/su
adecuadamente, que es algo con lo que todavía estoy jugando; Actualizaré esta respuesta tan pronto como comprenda la forma correcta de configurar /etc/pam.d/su
.