首页 > 解决方案 > nsswitch.conf 中的多个源是否为 getpwent 合并?

问题描述

假设我创建了一个名为的自定义 nss 模块foo,它定义了所需的 API:

#include <nss.h>

enum nss_status _nss_foo_getpwnam(const char *name, struct passwd *result, char *buf, size_t buflen, int *errnop);
enum nss_status _nss_foo_getpwuid(uid_t uid, struct passwd *result, char *buf, size_t buflen, int *errnop);
enum nss_status _nss_foo_setpwent(void);
enum nss_status _nss_foo_getpwent(struct passwd *result, char *buf, size_t buflen, int *errnop);
enum nss_status _nss_foo_endpwent(void);

假设我的 nsswitch.conf 设置如下:

passwd: foo files

从标准中可以清楚地看出getpwnam(),用户bar首先会调用 my _nss_foo_getpwnam(),然后如果返回NSS_STATUS_NOTFOUND,请检查/etc/passwd. 但是,对于我来说,标准和行为[set|get|end]pwent()不太清楚。如果我理解man 5 nsswitch.conf正确,听起来这会首先调用 my _nss_foo_setpwent(),如果返回,NSS_STATUS_SUCCESS那么它只会从我的模块中枚举用户(因为默认情况下,成功的操作是根据手册页“立即返回”)。这种解释正确吗?

理想情况下,我希望首先使用我的模块和getpwnam/的后备方法getpwuid,但是对于枚举用户,我真的需要合并所有源之间的枚举。有没有一种方法可以做到这一点,而不是完全破解(我能想到的最好的方法是手动读取和解析/etc/passwd自己,因为我显然不能使用setpwent(),因为这会递归调用我的foo模块)?

深入研究 libc 源代码,我发现,这似乎可以为我和朋友们ACTION=merge做我想做的事。setpwent()但是,从 glibc >=2.24 的 nsswitch.conf 手册页看来,这是不支持的getgrent()。这是否意味着我被困在一个针对组的 hacky 解决方案(比如解析/etc/groups自己)?

标签: cposixglibclibcnss

解决方案


推荐阅读