PAM 模块 mkhomedir 与已存在的主目录

PAM 模块 mkhomedir 与已存在的主目录

我确实针对 LDAP 设置了 PAM 身份验证。一切正常,但当我同时拥有同名但不同 UID 的本地用户和 ldap 用户时,我遇到了问题。

我正在 RH6 上工作,目前我的system-auth配置password-auth如下:

session   required      pam_mkhomedir.so skel=/etc/skel umask=0002

我的ssosers用户存在于ldap

[root@localhost pam.d]# getent -s ldap passwd ssosers
ssosers:x:20100:1000:ssosers:/home/ssosers:/usr/bin/sh

以及/etc/passwd

[root@localhost pam.d]# cat /etc/passwd | grep ssosers
ssosers:x:50025:50025::/home/ssosers:/bin/bash

ssosers可以使用本地密码和 LDAP 密码登录。请考虑他们有不同的 UID。问题是,当我删除本地用户以强制对 ldap 进行身份验证时,下次ssosers登录时会pam_mkhomedir.so失败,因为该用户/home/ssosers已经存在,并且由于缺乏权限,用户无法加入他的家:

Last login: Mon Feb 19 17:01:00 2018 from 10.212.148.18
Could not chdir to home directory /home/ssosers: Permission denied
-sh: /home/ssosers/.profile: Permission denied
-sh-4.1$

$PAM_USER如果 pam_mkhomedir 失败,有没有办法更改主目录的权限?我希望他加入他的老家。

更新

我想出了一个简单的解决方案。基本上运行此脚本是为了通过 LDAP 查找用户,如果找到它,我会删除该用户并更新主文件夹的 UID,如果没有找到它,我会删除用户和主目录。

#!/bin/bash
getent -s ldap passwd $1 > /dev/null

if [ $? -eq 0 ]; then
    userdel $1
    chown -R $1 /home/$1
else
    userdel -r $1
fi

但是,在积极的情况下,如何添加基于 OLD UID 的查找(查找具有 OLD uid 的其他文件)?当我执行userdel $1本地 UID(旧的)时,已不再解决。这是ssosers删除后 的用户主目录的权限:

drwx------   3    50025 oinstall   1024 Feb 19 18:30 ssosers

这就是为什么我必须用 chown 更新家庭的许可,因为首先指向passwd然后指向nsswitchfilesldap

答案1

在删除用户之前,您应该将用户的旧 UID 存储在变量中。

例如,这是脚本的改进版本:

  • 可以在命令行上使用多个用户名参数
  • 正确引用所有变量
  • 有两种不同的确定所有权的方法 - 仅选择 1。
  • 有一些非常原始的错误检查。需要更多。尝试考虑所有可能出错的事情,然后想出一种方法来测试它们,并error()在必要时使用该函数来中止。如果您有一位了解您环境的同事,您可以向他展示您的代码并询问“我缺少什么?”、“还有什么可能出错吗?”这将非常有用。

在我认为它可以安全地在我的系统上使用之前,它仍然需要工作,但作为一个例子已经足够了。

#!/bin/bash

error() {
  local ec="$1" ; shift # first arg is the exit code

  # if there are any more args, they are the error message. print to stderr
  [ -n "$*" ] && echo "$@" >&2

  # exit with $ec if $ec is non-zero
  [ "$ec" -ne 0 ] && exit "$ec"
}

for user in "$@" ; do 
  OLDUID=$(getent -s files passwd "$user" | cut -d : -f 3)
  [ -z "$OLDUID" ] && error 1 "user '$user' is not local"

  NEWUID=$(getent -s ldap passwd "$user" | cut -d : -f 3)

  if [ -z "$NEWUID" ] ; then
    # user exists locally but there is no corresponding LDAP user
    # so delete the user and their home dir.  This **definitely** needs
    # more sanity checking to make sure you're not deleting root or some
    # other important account.  Maybe check that [ "$OLDUID" -ge 1000 ]
    # (or 500 or whatever the lowest normal-user uid is on your system)

    userdel -r "$user"

  elif [ "$OLDUID" -ne "$NEWUID" ]; then
    # both local and LDAP user exist.  UIDs are different, so delete the local
    # user and change ownership of their files to the the LDAP uid.

    # Method 1:
    #homedir=$(getent -s files passwd "$user" | cut -d : -f 6)
    #userdel "$user"
    #chown -R "$user" "$homedir"
    #find /tmp /var/tmp -uid "$OLDUID" -exec chown "$NEWUID" {} +

    # Method 2:
    #userdel "$user"
    #find / -uid "$OLDUID" -exec chown "$NEWUID" {} +
  else
    # both exist, delete local user. UIDs are equal, no need to chown anything.

    userdel "$user"
  fi
done

顺便说一句,由于此脚本处理多个用户名参数,您可能想要使用error 0 ...而不是error 1 ...仅将问题记录到 stderr 而不中止,但如果 OLDUID 或 NEWUID 为空,则需要跳到下一个用户名。

例如

  OLDUID=$(getent -s files passwd "$user" | cut -d : -f3)
  [ -z "$OLDUID" ] && error 0 "user '$user' is not local" && continue

相关内容