-
Notifications
You must be signed in to change notification settings - Fork 0
/
nss_filter.c
154 lines (115 loc) · 3.58 KB
/
nss_filter.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <nss.h>
#include <pwd.h>
#include <grp.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h> /* sysconf() */
#include <ctype.h>
#include <stdarg.h>
#include <stdbool.h> /* bool type */
#include "debug.h"
#include "util.h"
static void *nssinfo;
/* This function is part of nss itself. It's available at runtime
* but no user-land header declares it (currently?). */
extern enum nss_status (*__nss_lookup_function(void *nssinfo, char *func))();
static enum nss_status (*backend_getpwnam_r) (const char *name,
struct passwd *pwd,
char *buffer, size_t buflen, int *errnop);
static enum nss_status (*backend_getpwuid_r) (uid_t uid,
struct passwd *pwd,
char *buffer, size_t buflen, int *errnop);
static enum nss_status (*backend_setpwent_r) (int stayopen);
static enum nss_status (*backend_endpwent_r) (void);
static enum nss_status (*backend_getpwent_r) (
struct passwd *pwd,
char *buffer, size_t buflen, int *errnop);
static void
init_wrapper (void)
{
if (__nss_database_lookup ("filter.backend.passwd", NULL, "files", &nssinfo) >= 0)
{
backend_getpwnam_r = (void *) __nss_lookup_function (nssinfo, "getpwnam_r");
backend_getpwuid_r = (void *) __nss_lookup_function (nssinfo, "getpwuid_r");
backend_setpwent_r = (void *) __nss_lookup_function (nssinfo, "setpwent_r");
backend_endpwent_r = (void *) __nss_lookup_function (nssinfo, "endpwent_r");
backend_getpwent_r = (void *) __nss_lookup_function (nssinfo, "getpwent_r");
}
}
enum nss_status
_nss_filter_getpwnam_r(const char *name, struct passwd *pwd,
char *buf, size_t buflen, int *errnop)
{
enum nss_status r;
printd("nss_filter_getpwuid_r\n");
if (nssinfo == NULL)
init_wrapper();
if (backend_getpwnam_r == NULL)
return NSS_STATUS_NOTFOUND;
/* Call into filter backend */
r = backend_getpwnam_r(name, pwd, buf, buflen, errnop);
if (r != NSS_STATUS_SUCCESS)
return r;
/* Perform filtering and return */
filter_passwd(pwd, buf, buflen);
return r;
}
enum nss_status
_nss_filter_getpwuid_r(uid_t uid, struct passwd *pwd,
char *buf, size_t buflen, int *errnop)
{
enum nss_status r;
printd("nss_filter_getpwuid_r\n");
if (nssinfo == NULL)
init_wrapper();
if (backend_getpwuid_r == NULL)
return NSS_STATUS_NOTFOUND;
/* Call into filter backend */
r = backend_getpwuid_r(uid, pwd, buf, buflen, errnop);
if (r != NSS_STATUS_SUCCESS)
return r;
/* Perform filtering and return */
filter_passwd(pwd, buf, buflen);
return r;
}
enum nss_status
_nss_filter_getpwent_r(struct passwd *pwd,
char *buf, size_t buflen, int *errnop)
{
enum nss_status r;
printd("nss_filter_getpwent_r\n");
if (nssinfo == NULL)
init_wrapper();
if (backend_getpwent_r == NULL)
return NSS_STATUS_NOTFOUND;
/* Call into filter backend */
r = backend_getpwent_r(pwd, buf, buflen, errnop);
if (r != NSS_STATUS_SUCCESS)
return r;
/* Perform filtering and return */
filter_passwd(pwd, buf, buflen);
return r;
}
enum nss_status
_nss_filter_setpwent_r(int stayopen)
{
enum nss_status r = NSS_STATUS_UNAVAIL;
printd("nss_filter_setpwent_r\n");
if (nssinfo == NULL)
init_wrapper();
if (backend_setpwent_r)
r = backend_setpwent_r(stayopen);
return r;
}
enum nss_status
_nss_filter_endpwent_r(void)
{
enum nss_status r = NSS_STATUS_SUCCESS;
printd("nss_filter_endpwent_r\n");
if (nssinfo == NULL)
init_wrapper();
if (backend_endpwent_r)
backend_endpwent_r();
return r;
}