permissão sed negada ao usar pam_exec com su

permissão sed negada ao usar pam_exec com su

Estou usando pam_mount.so para montar automaticamente um compartilhamento CIFS para usuários em um cliente Ubuntu 14.04.

pam_mount usa uma configuração local no diretório inicial de cada usuário. Estou executando um script bash com pam_exec que atualiza o arquivo de configuração com o caminho para o compartilhamento CIFS.

O final do meu arquivo /etc/pam.d/common-session é assim:

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

Ao fazer login com SSH ou através da GUI, isso funciona, o script é executado antes da montagem, para que o compartilhamento fique acessível.

No entanto, ao usar su, o script falha e o conf do usuário local não é atualizado, portanto a montagem também falha.

O erro que recebo ao usar su de [accountA] para [accountB] é:

/bin/sed: couldn't open temporary file /home/[accountB]/sednpoogQ: Permission denied

A linha no script que falha é esta:

/bin/sed -i "s|\@S|${XSERVER}|g" /home/${PAM_USER}/.pam_mount.conf.xml

Tentei executar o script em ~/.profile e em outros lugares, funciona perfeitamente, mas não é executado antes do pam_mount.

Então, minha pergunta é: como posso fazer com que pam_exec substitua uma string em um arquivo de texto que reside no diretório inicial de um usuário ao usar su?

Atualizar

Pelos comentários, tentei 'sudo -u [accountb] -i' (depois de incluir @common-session em /etc/pam.d/sudo) e isso não retorna o mesmo erro, funciona. No entanto, não é uma solução aceitável, pois preciso que o su funcione (e isso causa uma solicitação de senha do pam_mount).

Atualização2

Efetuei login com ssh, despejei env em um arquivo e, em seguida, efetuei login com ssh de outra conta, usei su e despejei env em um arquivo.

Comparando os dois (nomes de contas substituídos por accounta e accountb como na pergunta:

$ 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

Atualização3

Adicionado o script completo executado por pam_exec (informações confidenciais substituídas por espaços reservados):

#!/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

Atualização4

Colocar um whoami no script mostra que ao usar su de accounta para accountb, o script é executado por accounta.

Atualização5

Usar a opção 'seteuid' com pam_exec resolveu o problema. session optional pam_exec.so seteuid log=/var/log/pamexec /usr/local/bin/mdrive_add

whoami agora mostra 'root' ao mudar de A para B e não há problemas de permissão.

Não entendo os termos 'ID de usuário real' e 'ID de usuário efetivo' no manual do pam_exec, mas isso é uma questão para outro dia.

Por padrão, pam_exec.so executará o comando externo com o ID de usuário real do processo de chamada. Especificar esta opção significa que o comando será executado com o ID do usuário efetivo.

Responder1

O problema era que o login su pam_execexecutava o script como o usuário "antigo", que não tinha permissão para gravar no diretório inicial do "novo" usuário.

Definir a seteuidopção session optional pam_exec.so log=/var/log/pamexec /usr/local/bin/mdrive_addfez pam_execexecutar o script como root, o que resolveu o problema:

session optional pam_exec.so seteuid log=/var/log/pamexec /usr/local/bin/mdrive_add

No entanto, a solução "real" provavelmente está sendo configurada /etc/pam.d/suadequadamente, algo que ainda estou mexendo; Atualizarei esta resposta assim que entender a maneira correta de configurar o /etc/pam.d/su.

informação relacionada