2013-05-03 18 views
9

Próbuję dodać usługę do NSS (Name Service Switch). Zwróć uwagę na przewodnik GNU, jak to zrobić: here. Śledziłem ten przewodnik. Potrzebuję wdrożyć usługę, która działa z bazą danych passwd.Dodawanie usługi do usługi Name Name Switch

Problem, który mam, to mój moduł nie jest wywoływany dla niektórych funkcji. Pozwól mi odtworzyć niektóre z moich kodu tutaj ...

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 jest funkcją inline, który po prostu wypełnia wyniku z manekina użytkownika bez względu na to, jakie są PARAMS.

Teraz mam setup /etc/nsswitch.conf następująco:

passwd:   myservice compat 

A dla kompletności tutaj jest mój 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 

Teraz po zainstalowaniu tego modułu NSS biegnę getent w wierszu poleceń i tu jest moje wyjście:

[email protected]:~/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 

Więc jak widać, że działa jak bym się spodziewał. Wywoływane jest wywołanie iteracyjne, które zwraca użytkownika, a następnie wywoływana jest usługa compat, która zwraca użytkownika z/etc/passwd.

Problem polega na tym, że gdy wykonuję to połączenie, "getent passwd myuser", otrzymuję wartość zwracaną 2, "Klucz nie został znaleziony w bazie danych". To pokazuje, że moja funkcja _nss_myservice_getpwbynam_r nie jest wywoływana. Jakieś pomysły, dlaczego? Mogę podać pełny kod, jeśli to pomogłoby.

+1

Co jeśli nazwać '_nss_myservice_getpwnam_r' zamiast? Zgadnij, ale widzę, że istnieje funkcja 'pwd.h' o nazwie' getpwnam_r' –

Odpowiedz

6

Musisz wywołać funkcję _nss_myservice_getpwnam_r zamiast _nss_myservice_getpwbynam_r.

Po obejrzeniu 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); 
+1

Dzięki, że działa. Co mnie zastanawia, dlaczego dokumentacja GNU jest sformułowana tak jak jest. (enum nss_status _nss_DATABASE_getdbbyXX_r (PARAMS, STRUKTURA * wynik, char * bufor, size_t buflen, int * errnop)) Czy brakuje mi czegoś? Jeśli nie, wyślę im notatkę ... –

+0

Oto bezpośredni link do tego kodu w repozytorium źródeł glibc: http://repo.or.cz/w/glibc.git/blob/HEAD:/include/pwd .h # l35 –