2 nss sample code for extended winbindd functionality
4 Copyright (C) Andrew Tridgell (tridge@samba.org)
6 you are free to use this code in any way you see fit, including
7 without restriction, using this code in your own products. You do
8 not need to give any attribution.
19 #include <sys/types.h>
21 #include "nss_winbind.h"
24 find a function in the nss library
26 static void *find_fn(struct nss_state *nss, const char *name)
31 asprintf(&s, "_nss_%s_%s", nss->nss_name, name);
36 res = dlsym(nss->dl_handle, s);
46 establish a link to the nss library
47 Return 0 on success and -1 on error
49 int nss_open(struct nss_state *nss, const char *nss_path)
52 p = strrchr(nss_path, '_');
58 nss->nss_name = strdup(p+1);
59 p = strchr(nss->nss_name, '.');
62 nss->dl_handle = dlopen(nss_path, RTLD_LAZY);
63 if (!nss->dl_handle) {
72 close and cleanup a nss state
74 void nss_close(struct nss_state *nss)
77 dlclose(nss->dl_handle);
82 Return 0 on success and -1 on error
84 int nss_getpwent(struct nss_state *nss, struct passwd *pwd)
86 enum nss_status (*_nss_getpwent_r)(struct passwd *, char *,
88 enum nss_status status;
91 _nss_getpwent_r = find_fn(nss, "getpwent_r");
93 if (!_nss_getpwent_r) {
97 status = _nss_getpwent_r(pwd, nss->pwnam_buf, sizeof(nss->pwnam_buf),
99 if (status == NSS_STATUS_NOTFOUND) {
103 if (status != NSS_STATUS_SUCCESS) {
112 make a setpwent call.
113 Return 0 on success and -1 on error
115 int nss_setpwent(struct nss_state *nss)
117 enum nss_status (*_nss_setpwent)(void) = find_fn(nss, "setpwent");
118 enum nss_status status;
119 if (!_nss_setpwent) {
122 status = _nss_setpwent();
123 if (status != NSS_STATUS_SUCCESS) {
131 make a endpwent call.
132 Return 0 on success and -1 on error
134 int nss_endpwent(struct nss_state *nss)
136 enum nss_status (*_nss_endpwent)(void) = find_fn(nss, "endpwent");
137 enum nss_status status;
138 if (!_nss_endpwent) {
141 status = _nss_endpwent();
142 if (status != NSS_STATUS_SUCCESS) {
151 convert a name to a SID
153 Return 0 on success and -1 on error
155 int nss_nametosid(struct nss_state *nss, const char *name, char **sid)
157 enum nss_status (*_nss_nametosid)(const char *, char **, char *,
159 enum nss_status status;
163 _nss_nametosid = find_fn(nss, "nametosid");
165 if (!_nss_nametosid) {
169 status = _nss_nametosid(name, sid, buf, sizeof(buf), &nss_errno);
170 if (status == NSS_STATUS_NOTFOUND) {
174 if (status != NSS_STATUS_SUCCESS) {
185 convert a SID to a name
187 Return 0 on success and -1 on error
189 int nss_sidtoname(struct nss_state *nss, const char *sid, char **name)
191 enum nss_status (*_nss_sidtoname)(const char *, char **, char *,
193 enum nss_status status;
197 _nss_sidtoname = find_fn(nss, "sidtoname");
199 if (!_nss_sidtoname) {
203 status = _nss_sidtoname(sid, name, buf, sizeof(buf), &nss_errno);
204 if (status == NSS_STATUS_NOTFOUND) {
208 if (status != NSS_STATUS_SUCCESS) {
213 *name = strdup(*name);
219 return a list of group SIDs for a user SID
220 the returned list is NULL terminated
221 Return 0 on success and -1 on error
223 int nss_getusersids(struct nss_state *nss, const char *user_sid, char ***sids)
225 enum nss_status (*_nss_getusersids)(const char *, char **, int *,
226 char *, size_t, int *);
227 enum nss_status status;
230 int i, num_groups = 0;
231 unsigned bufsize = 10;
234 _nss_getusersids = find_fn(nss, "getusersids");
236 if (!_nss_getusersids) {
241 buf = malloc(bufsize);
247 status = _nss_getusersids(user_sid, &s, &num_groups, buf, bufsize,
250 if (status == NSS_STATUS_NOTFOUND) {
256 if (status == NSS_STATUS_TRYAGAIN) {
262 if (status != NSS_STATUS_SUCCESS) {
268 if (num_groups == 0) {
273 *sids = (char **)malloc(sizeof(char *) * (num_groups+1));
280 for (i=0;i<num_groups;i++) {
281 (*sids)[i] = strdup(s);
292 convert a sid to a uid
293 Return 0 on success and -1 on error
295 int nss_sidtouid(struct nss_state *nss, const char *sid, uid_t *uid)
297 enum nss_status (*_nss_sidtouid)(const char*, uid_t *, int*);
299 enum nss_status status;
302 _nss_sidtouid = find_fn(nss, "sidtouid");
304 if (!_nss_sidtouid) {
308 status = _nss_sidtouid(sid, uid, &nss_errno);
310 if (status == NSS_STATUS_NOTFOUND) {
315 if (status != NSS_STATUS_SUCCESS) {
324 convert a sid to a gid
325 Return 0 on success and -1 on error
327 int nss_sidtogid(struct nss_state *nss, const char *sid, gid_t *gid)
329 enum nss_status (*_nss_sidtogid)(const char*, gid_t *, int*);
331 enum nss_status status;
334 _nss_sidtogid = find_fn(nss, "sidtogid");
336 if (!_nss_sidtogid) {
340 status = _nss_sidtogid(sid, gid, &nss_errno);
342 if (status == NSS_STATUS_NOTFOUND) {
347 if (status != NSS_STATUS_SUCCESS) {
356 convert a uid to a sid
358 Return 0 on success and -1 on error
360 int nss_uidtosid(struct nss_state *nss, uid_t uid, char **sid)
362 enum nss_status (*_nss_uidtosid)(uid_t, char **, char *,
364 enum nss_status status;
368 _nss_uidtosid = find_fn(nss, "uidtosid");
370 if (!_nss_uidtosid) {
374 status = _nss_uidtosid(uid, sid, buf, sizeof(buf), &nss_errno);
375 if (status == NSS_STATUS_NOTFOUND) {
379 if (status != NSS_STATUS_SUCCESS) {
390 convert a gid to a sid
392 Return 0 on success and -1 on error
394 int nss_gidtosid(struct nss_state *nss, gid_t gid, char **sid)
396 enum nss_status (*_nss_gidtosid)(gid_t, char **, char *,
398 enum nss_status status;
402 _nss_gidtosid = find_fn(nss, "gidtosid");
404 if (!_nss_gidtosid) {
408 status = _nss_gidtosid(gid, sid, buf, sizeof(buf), &nss_errno);
409 if (status == NSS_STATUS_NOTFOUND) {
413 if (status != NSS_STATUS_SUCCESS) {