converted to git
[tridge/junkcode.git] / nsslist.c
1 /* list users for a particular nss module
2  */
3
4 #include <stdio.h>
5 #include <nss.h>
6 #include <dlfcn.h>
7 #include <pwd.h>
8 #include <grp.h>
9
10 typedef enum nss_status NSS_STATUS;
11
12 static char *nss_name;
13 static int nss_errno;
14 static NSS_STATUS last_error;
15 static int total_errors;
16
17 static void *find_fn(const char *name)
18 {
19         char *so_path, *s;
20         static void *h;
21         void *res;
22
23         asprintf(&s, "_nss_%s_%s", nss_name, name);
24         asprintf(&so_path, "/lib/libnss_%s.so.2", nss_name);
25
26         if (!h) {
27                 h = dlopen(so_path, RTLD_LAZY);
28         }
29         if (!h) {
30                 printf("Can't open shared library %s\n", so_path);
31                 exit(1);
32         }
33         res = dlsym(h, s);
34         if (!res) {
35                 printf("Can't find function %s\n", s);
36                 return NULL;
37         }
38         free(so_path);
39         free(s);
40         return res;
41 }
42
43 static void report_nss_error(const char *who, NSS_STATUS status)
44 {
45         last_error = status;
46         total_errors++;
47         printf("ERROR %s: NSS_STATUS=%d  %d (nss_errno=%d)\n", 
48                who, status, NSS_STATUS_SUCCESS, nss_errno);
49 }
50
51 static struct passwd *nss_getpwent(void)
52 {
53         NSS_STATUS (*_nss_getpwent_r)(struct passwd *, char *, 
54                                       size_t , int *) = find_fn("getpwent_r");
55         static struct passwd pwd;
56         static char buf[1000];
57         NSS_STATUS status;
58
59         status = _nss_getpwent_r(&pwd, buf, sizeof(buf), &nss_errno);
60         if (status == NSS_STATUS_NOTFOUND) {
61                 return NULL;
62         }
63         if (status != NSS_STATUS_SUCCESS) {
64                 report_nss_error("getpwent", status);
65                 return NULL;
66         }
67         return &pwd;
68 }
69
70 static void nss_setpwent(void)
71 {
72         NSS_STATUS (*_nss_setpwent)(void) = find_fn("setpwent");
73         NSS_STATUS status;
74         status = _nss_setpwent();
75         if (status != NSS_STATUS_SUCCESS) {
76                 report_nss_error("setpwent", status);
77         }
78 }
79
80 static void nss_endpwent(void)
81 {
82         NSS_STATUS (*_nss_endpwent)(void) = find_fn("endpwent");
83         NSS_STATUS status;
84         status = _nss_endpwent();
85         if (status != NSS_STATUS_SUCCESS) {
86                 report_nss_error("endpwent", status);
87         }
88 }
89
90 static void list_users(void)
91 {
92         struct passwd *pwd;
93
94         nss_setpwent();
95         /* loop over all users */
96         while ((pwd = nss_getpwent())) {
97                 printf("%s\n", pwd->pw_name);
98         }
99         nss_endpwent();
100 }
101
102 static void usage(void)
103 {
104         printf("nsslist <nsstype>\n");
105 }
106
107 int main(int argc, char *argv[])
108 {       
109         if (argc < 2) {
110                 usage();
111                 exit(1);
112         }
113
114         nss_name = argv[1];
115
116         list_users();
117
118         return 0;
119 }