使用 pam_exec 与 su 时 sed 权限被拒绝

使用 pam_exec 与 su 时 sed 权限被拒绝

我正在使用 pam_mount.so 为 Ubuntu 14.04 客户端上的用户自动挂载 CIFS 共享。

pam_mount 在每个用户主目录中使用本地 conf。我正在使用 pam_exec 运行 bash 脚本,该脚本使用 CIFS 共享的路径更新配置文件。

我的 /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 时,脚本失败,并且本地用户配置未更新,因此挂载也会失败。

使用 su 从 [accountA] 到 [accountB] 时收到的错误是:

/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,表明当使用 su 从 accounta 到 accountb 时,该脚本由 accounta 运行。

更新5

使用 pam_exec 的“seteuid”选项解决了该问题。 session optional pam_exec.so seteuid log=/var/log/pamexec /usr/local/bin/mdrive_add

当从 A 切换到 B 时,whoami 现在显示“root”,并且没有权限问题。

我不明白 pam_exec 手册中的术语“真实用户 ID”和“有效用户 ID”,但这是另一天的问题。

默认情况下,pam_exec.so 将使用调用进程的真实用户 ID 执行外部命令。指定此选项意味着使用有效用户 ID 运行命令。

答案1

问题是,通过su pam_exec以“旧”用户身份登录时执行脚本,而该用户没有写入“新”用户主目录的权限。

设置seteuid选项以 rootsession 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

相关内容