c - 将服务添加到名称服务开关

标签 c gnu libc passwd nss

所以我正在尝试向 NSS(名称服务交换机)添加服务。请注意有关操作方法的 GNU 指南 here .我一直在遵循该指南。我需要实现一个与 passwd 数据库一起工作的服务。

我遇到的问题是我的模块没有被某些功能调用。让我在这里重现我的一些代码...

enum nss_status
_nss_myservice_setpwent (void) {
 printf( "@ %s\n", __FUNCTION__ ) ;
 return NSS_STATUS_SUCCESS ;
} ;

enum nss_status
_nss_myservice_endpwent (void) {
 printf( "@ %s\n", __FUNCTION__ ) ;
 return NSS_STATUS_SUCCESS ;
} ;

enum nss_status
_nss_myservice_getpwent_r (struct passwd *result, char *buffer,
   size_t buflen, int *errnop) {

 static int i = 0 ;

 if( i++ == 0 ) {
   printf( "@ %s\n", __FUNCTION__ ) ;
   return init_result( result, buffer, buflen, errnop ) ;
 } else {
   i = 0 ;
   return NSS_STATUS_NOTFOUND ;
 }
} ;

enum nss_status
_nss_myservice_getpwbynam (const char *nam, struct passwd *result, char *buffer,
   size_t buflen, int *errnop) {
 printf( "@ %s with name %s\n", __FUNCTION__, nam ) ;
 return init_result( result, buffer, buflen, errnop ) ;
} ;

enum nss_status
_nss_myservice_getpwbynam_r (const char *nam, struct passwd *result, char *buffer,
   size_t buflen, int *errnop) {
 printf( "@ %s with name_r %s\n", __FUNCTION__, nam ) ;
 return init_result( result, buffer, buflen, errnop ) ;
} ;

Init_result 是一个内联函数,无论 PARAMS 是什么,它都会简单地用虚拟用户填充结果。

现在我的/etc/nsswitch.conf 设置如下:

passwd:         myservice compat

为了完整起见,这里是我的 Makefile。

all:
       gcc -fPIC -shared -o libnss_myservice.so.2 -Wl,-soname,libnss_myservice.so.2 myservice.c
install:
       sudo install -m 0644 libnss_myservice.so.2 /lib
       sudo /sbin/ldconfig -n /lib /usr/lib
clean:
       /bin/rf -rf libnss_myservice.so.2

现在,在安装这个 nss 模块后,我在命令行上运行 getent,这是我的输出:

username@host:~/nss$ getent passwd
@ _nss_myservice_setpwent
@ _nss_myservice_getpwent_r
myuser:mypass:1:1:realname::
root:x:0:0:root:/root:/bin/bash
...
@ _nss_myservice_endpwent

如您所见,它正在按我的预期工作。进行迭代调用,返回用户,然后调用 compat 服务,返回/etc/passwd 中的所有用户。

问题是当我调用“getent passwd myuser”时,我得到返回值 2,“在数据库中找不到 key ”。这表明我的 _nss_myservice_getpwbynam_r 函数没有被调用。任何想法为什么?如果有帮助,我可以提供完整的代码。

最佳答案

您需要调用函数 _nss_myservice_getpwnam_r 而不是 _nss_myservice_getpwbynam_r

看了ftp://ftp.acer-euro.com/gpl/Utility/glibc/glibc-2.2.5.tar/include/pwd.h之后:

#define DECLARE_NSS_PROTOTYPES(service)                 \
extern enum nss_status _nss_ ## service ## _setpwent (int);     \
extern enum nss_status _nss_ ## service ## _endpwent (void);        \
extern enum nss_status _nss_ ## service ## _getpwnam_r          \        <<< this line
                       (const char *name, struct passwd *pwd,       \
            char *buffer, size_t buflen, int *errnop);  \
extern enum nss_status _nss_ ## service ## _getpwuid_r          \
                       (uid_t uid, struct passwd *pwd,          \
            char *buffer, size_t buflen, int *errnop);  \
extern enum nss_status _nss_ ## service ##_getpwent_r           \
                       (struct passwd *result, char *buffer,        \
            size_t buflen, int *errnop);

关于c - 将服务添加到名称服务开关,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16366571/

相关文章:

c - 将单词列表扫描到数组中的槽中

c++ - h.264字节流解析

macos - 如何在 macOS 中链接到 GNU readline 库而不是 libedit?

c - linux函数获取挂载点

汇编将指针传递给函数

c - 如何检查数组指针中的元素?

c++ - C/C++,否定运算符的挫败感

c - Gcc 编译器命令和选项

linux - 如何以编程方式访问 iptables?

c - 如何在 Linux 上重新实现(或包装)系统调用函数?