5

ユーザーが LDAP ユーザーである Red Hat Enterprise 6 の現在のユーザー情報を取得する際に問題がありますか?

ユーザー名、ホーム ディレクトリ、およびその他の詳細を取得する必要があるコード (実際にはインストール ツールの一部) があります。ユーザー ID に基づいてこれを行うために、getpwuid() 呼び出しを使用しています。簡単な内訳:

uid_t uid = getuid();
printf("UID = %d\n", uid);

errno = 0;
struct passwd* udetails = getpwuid(uid);

if (udetails != NULL)
{
    printf("User name = %s\n", udetails->pw_name);
}
else
{
    printf("getpwuid returns NULL, errno=%d\n", errno);
}

これは、ユーザーがローカル ユーザー (そのシステムの /etc/passwd 内) である場合に問題なく機能します。

ユーザーが LDAP 認証済みユーザーの場合、getuid を呼び出すとユーザー ID または現在のユーザーが返されますが、getpwuid を呼び出すと 0 が返され、エラー コードは errno に設定されません。ドキュメントによると、これはユーザーが存在しないことを意味します。

これは機能するはずですか?getpwuid マンページによると:

getpwnam() 関数は、ユーザー名に一致するパスワード データベース (ローカル パスワード ファイル /etc/passwd、NIS、および LDAP など) 内のレコードの分割フィールドを含む構造体へのポインタを返します。

getpwuid() 関数は、ユーザー ID uid に一致するパスワード データベース内のレコードの分割されたフィールドを含む構造体へのポインターを返します。

現在のユーザーが LDAP によって認証された場合、詳細を取得するために別の呼び出しが必要ですか? アプリケーションで LDAP データベースを開く必要がありますか、それともシステム コールで処理する必要がありますか?

追加: 同じ LDAP ディレクトリに対して認証する RHEL 5 ボックスでもこれを試しました。これは RHEL 6 ボックスの構成の問題でしょうか? それともより広い RHEL 6 の問題ですか?

追加: Basile Starynkevitch の要求による /etc/nsswitch.conf (コメント行は削除されています):

passwd:     files sss
shadow:     files sss
group:      files sss

hosts:      files dns

bootparams: nisplus [NOTFOUND=return] files

ethers:     files
netmasks:   files
networks:   files
protocols:  files
rpc:        files
services:   files sss

netgroup:   files sss

publickey:  nisplus

automount:  files ldap
aliases:    files nisplus

これらのいくつかは、ある時点でldapに言及する必要があると思いますか? 実際、これはLDAPをまったく使用していないことを示唆しています....

4

3 に答える 3

3

問題は、32 ビット用のnss_sssライブラリーが欠落しているようです (私の場合)。Redhat の場合は rpm パッケージだと思います: sssd-client.i686.rpm

次のメイクファイルを使用しました。

all: getpwuid_bug-32bit getpwuid_bug-64bit

getpwuid_bug-32bit: getpwuid_bug.c makefile
        $(CC) -Wall -m32 -o $@ $<

getpwuid_bug-64bit: getpwuid_bug.c makefile
        $(CC) -Wall -m64 -o $@ $<

および次の getpwuid_bug.c

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>

int main(argc, argv)
     int argc; char **argv;
{
  uid_t uid;
  struct passwd *udetails;

  uid = getuid();
  printf("UID = %d\n", uid);

  errno = 0;
  udetails = getpwuid(uid);

  if (udetails != NULL) {
    printf("User name = %s\n", udetails->pw_name);
  } else {
    printf("getpwuid returns NULL, errno=%d\n", errno);
    return 1;
  }
  return 0;
}

次にmakeと入力します...

次に、両方を実行します

$ ./getpwuid_bug-32bit
UID = 1234
getpwuid returns NULL, errno=0
$ ./getpwuid_bug-64bit
UID = 1234
User name = krico
$

次に、プログラムの両方のバージョンを strace すると、64 ビット バージョンが nss_sss をすぐに検出することがわかります。

open("/lib64/libnss_sss.so.2", O_RDONLY) = 3

32ビットのものは、これらの多くを通過した後、惨めに失敗します:

open("/lib/tls/i686/sse2/libnss_sss.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/i686/sse2", 0xfffef338) = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/libnss_sss.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)

したがって、私の結論は、その 32 ビット バージョンのライブラリを含む rpm をインストールする必要があるということです (たとえば、sssd-client.i686.rpm など)。

于 2013-11-19T12:55:28.803 に答える