
Ich verwende pam_mount.so, um automatisch eine CIFS-Freigabe für Benutzer auf einem Ubuntu 14.04-Client zu mounten.
pam_mount verwendet eine lokale Konfiguration im Home-Verzeichnis jedes Benutzers. Ich führe ein Bash-Skript mit pam_exec aus, das die Konfigurationsdatei mit dem Pfad zur CIFS-Freigabe aktualisiert.
Das Ende meiner Datei /etc/pam.d/common-session sieht folgendermaßen aus:
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
Beim Einloggen per SSH oder über die GUI funktioniert dies, das Skript wird vor dem Mounten ausgeführt, so dass auf die Freigabe zugegriffen werden kann.
Bei Verwendung von „su“ schlägt das Skript jedoch fehl und die lokale Benutzerkonfiguration wird nicht aktualisiert, sodass auch das Mounten fehlschlägt.
Der Fehler, den ich erhalte, wenn ich su von [KontoA] zu [KontoB] verwende, ist:
/bin/sed: couldn't open temporary file /home/[accountB]/sednpoogQ: Permission denied
Die Zeile im Skript, die fehlschlägt, ist diese:
/bin/sed -i "s|\@S|${XSERVER}|g" /home/${PAM_USER}/.pam_mount.conf.xml
Ich habe versucht, das Skript von ~/.profile und anderen Orten aus auszuführen. Das funktioniert einwandfrei, wird aber nicht vor pam_mount ausgeführt.
Meine Frage ist also: Wie kann ich pam_exec dazu bringen, bei Verwendung von su eine Zeichenfolge in einer Textdatei zu ersetzen, die sich im Home-Verzeichnis eines Benutzers befindet?
Aktualisieren
Gemäß den Kommentaren habe ich „sudo -u [accountb] -i“ ausprobiert (nachdem ich @common-session in /etc/pam.d/sudo eingefügt hatte) und dies gibt nicht denselben Fehler zurück, es funktioniert. Es ist jedoch keine akzeptable Lösung, da ich su benötige, damit es funktioniert (und es verursacht eine Kennwortabfrage von pam_mount).
Update 2:
Ich habe mich mit SSH angemeldet, die Umgebung in eine Datei geschrieben und mich dann von einem anderen Konto aus mit SSH angemeldet, SU verwendet und die Umgebung in eine Datei geschrieben.
Vergleich der beiden (Kontonamen ersetzt durch accounta und accountb wie in der Frage):
$ 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
Update 3:
Das vollständige, von pam_exec ausgeführte Skript wurde hinzugefügt (vertrauliche Informationen durch Platzhalter ersetzt):
#!/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
Update 4:
Durch Einfügen eines „Whoami“ in das Skript wird angezeigt, dass bei der Verwendung von „su“ von Kontoa zu Kontob das Skript von Kontoa ausgeführt wird.
Aktualisierung 5
Die Verwendung der Option „seteuid“ mit pam_exec hat das Problem gelöst.
session optional pam_exec.so seteuid log=/var/log/pamexec /usr/local/bin/mdrive_add
whoami zeigt jetzt beim Wechsel von A nach B „root“ an und es gibt keine Berechtigungsprobleme.
Ich verstehe die Begriffe „reale Benutzer-ID“ und „effektive Benutzer-ID“ im Handbuch für pam_exec nicht, aber das ist eine Frage für einen anderen Tag.
Standardmäßig führt pam_exec.so den externen Befehl mit der tatsächlichen Benutzer-ID des aufrufenden Prozesses aus. Wenn Sie diese Option angeben, wird der Befehl mit der tatsächlichen Benutzer-ID ausgeführt.
Antwort1
Das Problem bestand darin, dass beim Anmelden su
pam_exec
das Skript als „alter“ Benutzer ausgeführt wurde, der jedoch nicht die Berechtigung hatte, in das Home-Verzeichnis des „neuen“ Benutzers zu schreiben.
Durch das Festlegen der seteuid
Option wurde das Skript als Root ausgeführt, wodurch das Problem behoben wurde session optional pam_exec.so log=/var/log/pamexec /usr/local/bin/mdrive_add
:pam_exec
session optional pam_exec.so seteuid log=/var/log/pamexec /usr/local/bin/mdrive_add
Die „echte“ Lösung besteht jedoch wahrscheinlich in einer /etc/pam.d/su
angemessenen Konfiguration, woran ich noch herumtüftle. Ich werde diese Antwort aktualisieren, sobald ich die richtige Konfigurationsmethode verstanden habe /etc/pam.d/su
.