Добавление сервиса к сервису именования
Поэтому я пытаюсь добавить службу в NSS (Name Service Switch). Пожалуйста, обратите внимание на руководство GNU о том, как это сделать здесь. Я следовал этому руководству. Мне нужно реализовать сервис, который работает с базой данных 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 "Ключ не найден в базе данных". Это показывает, что моя функция _nss_myservice_getpwbynam_r не вызывается. Есть идеи почему? Я могу предоставить полный код, если это поможет.
1 ответ
Вам нужно вызвать функцию _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);