
Ubuntu 14.04 클라이언트의 사용자를 위해 CIFS 공유를 자동으로 마운트하기 위해 pam_mount.so를 사용하고 있습니다.
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로 대체하려면 어떻게 해야 합니까?
업데이트
의견에 따라 'sudo -u [accountb] -i'(/etc/pam.d/sudo에 @common-session을 포함시킨 후)를 시도했지만 동일한 오류가 반환되지 않고 작동합니다. 그러나 su가 작동하도록 요구하므로 이는 허용 가능한 솔루션이 아닙니다(그리고 pam_mount에서 비밀번호 프롬프트가 표시됩니다).
업데이트2
ssh로 로그인하고 env를 파일에 덤프한 다음 다른 계정에서 ssh로 로그인하고 su를 사용하고 env를 파일에 덤프했습니다.
두 가지 비교(질문에서와 같이 계정 이름이 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로 전환할 때 '루트'를 표시하며 권한 문제는 없습니다.
pam_exec 매뉴얼에 있는 '실제 사용자 ID'와 '유효 사용자 ID'라는 용어를 이해하지 못하는데, 그건 나중에 질문하겠습니다.
기본적으로 pam_exec.so는 호출 프로세스의 실제 사용자 ID를 사용하여 외부 명령을 실행합니다. 이 옵션을 지정하면 명령이 유효한 사용자 ID로 실행된다는 의미입니다.
답변1
문제는 로그인을 통해 su
pam_exec
"새" 사용자의 홈 디렉터리에 쓸 수 있는 권한이 없는 "이전" 사용자로 스크립트를 실행했다는 것입니다.
seteuid
옵션을 설정 하면 스크립트가 루트로 실행 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
적절하게 구성되어 있을 것입니다. 이는 제가 아직도 다루고 있는 부분입니다. .NET 구성의 올바른 방법을 이해하자마자 이 답변을 업데이트하겠습니다 /etc/pam.d/su
.