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
) {