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_USERpam_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(以前のUID)を実行すると、この問題は解決されなくなります。ssosers削除後のユーザーホームディレクトリの権限は次のとおりです。

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

passwdそのため、まずchownを使用して家族の権限を更新する必要がありました。nsswitchfilesldap

答え1

ユーザーを削除する前に、ユーザーの古いUIDを変数に保存する必要があります。

たとえば、以下は拡張スクリプトのバージョンです。

  • コマンドラインで複数のユーザー名パラメータを使用できます。
  • すべての変数を正しく引用してください。
  • 所有権を決定する方法は2つあります。 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 ...ただし、このスクリプトは複数のユーザー名引数を処理するため、中断せずにstderrに問題を記録する代わりに使用したい場合がありますが、error 1 ...OLDUIDまたはNEWUIDが空の場合は、次のユーザー名に移動する必要があります。

例えば

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

関連情報