
私は pam_mount.so を使用して、Ubuntu 14.04 クライアント上のユーザーの CIFS 共有を自動的にマウントしています。
pam_mount は、各ユーザーのホーム ディレクトリにあるローカル conf を使用します。私は、CIFS 共有へのパスを使用して構成ファイルを更新する pam_exec を使用した bash スクリプトを実行しています。
/etc/pam.d/common-session ファイルの最後は次のようになります。
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
SSH または GUI 経由でログインする場合、これは機能し、マウント前にスクリプトが実行されるため、共有にアクセスできるようになります。
ただし、su を使用するとスクリプトが失敗し、ローカル ユーザー conf が更新されないため、マウントも失敗します。
[accountA] から [accountB] に su を使用するときに表示されるエラーは次のとおりです。
/bin/sed: couldn't open temporary file /home/[accountB]/sednpoogQ: Permission denied
スクリプト内で失敗する行は次の行です。
/bin/sed -i "s|\@S|${XSERVER}|g" /home/${PAM_USER}/.pam_mount.conf.xml
~/.profile や他の場所からスクリプトを実行してみましたが、問題なく動作しますが、pam_mount の前に実行されません。
そこで質問なのですが、su を使用しているときに、pam_exec でユーザーのホーム ディレクトリにあるテキスト ファイル内の文字列を置き換えるにはどうすればよいのでしょうか。
アップデート
コメントに従って、(/etc/pam.d/sudo に @common-session を含めた後で) 'sudo -u [accountb] -i' を試しましたが、同じエラーは返されず、正常に動作します。ただし、su が動作する必要があるため (pam_mount からパスワード プロンプトが表示されるため)、これは許容できる解決策ではありません。
アップデート2
私は ssh でログインし、env をファイルにダンプし、次に別のアカウントから ssh でログインし、su を使用して env をファイルにダンプしました。
2つを比較します(質問のようにアカウント名をaccountaとaccountbに置き換えます)。
$ 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
アップデート3
pam_exec によって実行される完全なスクリプトを追加しました (機密情報はプレースホルダーに置き換えられました):
#!/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
アップデート4
スクリプトに whoami を配置すると、accounta から accountb に su を使用するときに、スクリプトが accounta によって実行されることが示されます。
アップデート5
pam_exec で 'seteuid' オプションを使用すると、問題は解決しました。
session optional pam_exec.so seteuid log=/var/log/pamexec /usr/local/bin/mdrive_add
whoami は、A から B に切り替えるときに「root」と表示され、権限の問題は発生しません。
pam_exec のマニュアルにある「実ユーザー ID」と「実効ユーザー ID」という用語が理解できませんが、これは別の日に質問します。
デフォルトでは、pam_exec.so は呼び出しプロセスの実ユーザー ID を使用して外部コマンドを実行します。このオプションを指定すると、コマンドは実効ユーザー ID を使用して実行されます。
答え1
問題は、ログインするとsu
pam_exec
「古い」ユーザーとしてスクリプトが実行され、そのユーザーには「新しい」ユーザーのホーム ディレクトリに書き込む権限がなかったことです。
オプションを設定するseteuid
と、スクリプトが root として実行され、問題が解決しました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
しかし、「本当の」解決策はおそらく/etc/pam.d/su
適切に構成することであり、これは私がまだ試行錯誤しているところです。正しい構成方法がわかったらすぐにこの回答を更新します/etc/pam.d/su
。