J'utilise pam_mount.so pour monter automatiquement un partage CIFS pour les utilisateurs sur un client Ubuntu 14.04.
pam_mount utilise une conf locale dans le répertoire de base de chaque utilisateur. J'exécute un script bash avec pam_exec qui met à jour le fichier de configuration avec le chemin d'accès au partage CIFS.
La fin de mon fichier /etc/pam.d/common-session ressemble à ceci:
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
Lorsque vous vous connectez avec SSH ou via l'interface graphique, cela fonctionne, le script est exécuté avant le montage, de sorte que le partage est accessible.
Cependant, lors de l'utilisation de su, le script échoue et la conf de l'utilisateur local n'est pas mise à jour. Le montage échoue également.
L'erreur que je reçois lorsque j'utilise su de [accountA] à [accountB] est la suivante:
/bin/sed: couldn't open temporary file /home/[accountB]/sednpoogQ: Permission denied
La ligne du script qui échoue est la suivante:
/bin/sed -i "s|\@S|${XSERVER}|g" /home/${PAM_USER}/.pam_mount.conf.xml
J'ai essayé d'exécuter le script à partir de ~/.profile et d'autres endroits, cela fonctionne parfaitement, mais n'est pas exécuté avant pam_mount.
Ma question est donc la suivante: comment puis-je obtenir que pam_exec remplace une chaîne dans un fichier texte résidant dans le répertoire de base d'un utilisateur lors de l'utilisation de su?
Mise à jour
D'après les commentaires, j'ai essayé 'Sudo -u [accountb] -i' (après avoir inclus @ common-session dans /etc/pam.d/Sudo) et cela ne renvoie pas la même erreur, cela fonctionne. Cependant, ce n'est pas une solution acceptable, car j'ai besoin de su pour fonctionner (et cela provoque une invite de mot de passe de pam_mount).
pdate2
Je me suis connecté avec ssh, j'ai envoyé un fichier env dans un fichier, puis je me suis connecté avec ssh à partir d'un autre compte, utilisé su et un fichier env avec env.
En comparant les deux (noms de compte remplacés par accounta et accountb comme dans la question:
$ 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
Mise à jour
Ajout du script complet exécuté par pam_exec (informations sensibles remplacées par des espaces réservés):
#!/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
pdate4
Placer un whoami dans le script indique que lors de l'utilisation de su de accounta à accountb, le script est exécuté par accounta.
Mise à jour 5
L'utilisation de l'option 'seteuid' avec pam_exec a résolu le problème. session optional pam_exec.so seteuid log=/var/log/pamexec /usr/local/bin/mdrive_add
whoami affiche maintenant 'root' lors du basculement de A à B et il n'y a pas de problème d'autorisation.
Je ne comprends pas les termes "ID utilisateur réel" et "ID utilisateur effectif" dans le manuel pour pam_exec, mais c'est une question pour un autre jour.
Par défaut, pam_exec.so exécutera la commande externe avec l'ID utilisateur réel du processus appelant. Spécifier cette option signifie que la commande est exécutée avec l'ID utilisateur effectif.
Le problème était que la connexion via su
pam_exec
exécutait le script en tant qu '"ancien" utilisateur, qui n'était pas autorisé à écrire dans le répertoire de base du "nouvel" utilisateur.
La définition de l'option seteuid
dans session optional pam_exec.so log=/var/log/pamexec /usr/local/bin/mdrive_add
a pour effet que pam_exec
exécute le script en tant que root, ce qui a résolu le problème:
session optional pam_exec.so seteuid log=/var/log/pamexec /usr/local/bin/mdrive_add
Cependant, la "vraie" solution consiste probablement à configurer /etc/pam.d/su
correctement, ce qui me préoccupe encore; Je mettrai à jour cette réponse dès que je comprendrai la bonne façon de configurer /etc/pam.d/su
.