permiso sed denegado al usar pam_exec con su

permiso sed denegado al usar pam_exec con su

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_execse ejecutaba el script como el usuario "antiguo", que no tenía permiso para escribir en el directorio de inicio del "nuevo" usuario.

Configurar la seteuidopción session optional pam_exec.so log=/var/log/pamexec /usr/local/bin/mdrive_addhizo pam_execejecutar 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/suadecuadamente, 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.

información relacionada