4 Copyright (C) Simo Sorce 2006
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with this library; if not, write to the
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
24 extern struct _ldb_nss_context
*_ldb_nss_ctx
;
26 const char *_ldb_nss_gr_attrs
[] = {
33 const char *_ldb_nss_mem_attrs
[] = {
38 #define _NSS_LDB_ENOMEM(amem) \
42 talloc_free(memctx); \
43 return NSS_STATUS_UNAVAIL; \
47 /* This setgrent, getgrent, endgrent is not very efficient */
49 NSS_STATUS
_nss_ldb_setgrent(void)
53 ret
= _ldb_nss_init();
54 if (ret
!= NSS_STATUS_SUCCESS
) {
58 _ldb_nss_ctx
->gr_cur
= 0;
59 if (_ldb_nss_ctx
->gr_res
!= NULL
) {
60 talloc_free(_ldb_nss_ctx
->gr_res
);
61 _ldb_nss_ctx
->gr_res
= NULL
;
64 ret
= ldb_search(_ldb_nss_ctx
->ldb
,
67 _LDB_NSS_GRENT_FILTER
,
69 &_ldb_nss_ctx
->gr_res
);
70 if (ret
!= LDB_SUCCESS
) {
71 return NSS_STATUS_UNAVAIL
;
74 return NSS_STATUS_SUCCESS
;
77 NSS_STATUS
_nss_ldb_endgrent(void)
81 ret
= _ldb_nss_init();
82 if (ret
!= NSS_STATUS_SUCCESS
) {
86 _ldb_nss_ctx
->gr_cur
= 0;
87 if (_ldb_nss_ctx
->gr_res
) {
88 talloc_free(_ldb_nss_ctx
->gr_res
);
89 _ldb_nss_ctx
->gr_res
= NULL
;
92 return NSS_STATUS_SUCCESS
;
95 NSS_STATUS
_nss_ldb_getgrent_r(struct group
*result_buf
, char *buffer
, size_t buflen
, int *errnop
)
98 struct ldb_result
*res
;
100 ret
= _ldb_nss_init();
101 if (ret
!= NSS_STATUS_SUCCESS
) {
107 if (_ldb_nss_ctx
->gr_cur
>= _ldb_nss_ctx
->gr_res
->count
) {
108 /* already returned all entries */
109 return NSS_STATUS_NOTFOUND
;
112 res
= talloc_zero(_ldb_nss_ctx
->gr_res
, struct ldb_result
);
114 errno
= *errnop
= ENOMEM
;
115 _ldb_nss_ctx
->gr_cur
++; /* skip this entry */
116 return NSS_STATUS_UNAVAIL
;
119 ret
= _ldb_nss_group_request(&res
,
120 _ldb_nss_ctx
->gr_res
->msgs
[_ldb_nss_ctx
->gr_cur
]->dn
,
124 if (ret
!= NSS_STATUS_SUCCESS
) {
127 _ldb_nss_ctx
->gr_cur
++; /* skip this entry */
131 ret
= _ldb_nss_fill_group(result_buf
,
135 _ldb_nss_ctx
->gr_res
->msgs
[_ldb_nss_ctx
->gr_cur
],
140 if (ret
!= NSS_STATUS_SUCCESS
) {
141 if (ret
!= NSS_STATUS_TRYAGAIN
) {
142 _ldb_nss_ctx
->gr_cur
++; /* skip this entry */
147 /* this entry is ok, increment counter to nex entry */
148 _ldb_nss_ctx
->gr_cur
++;
150 return NSS_STATUS_SUCCESS
;
153 NSS_STATUS
_nss_ldb_getgrnam_r(const char *name
, struct group
*result_buf
, char *buffer
, size_t buflen
, int *errnop
)
158 struct ldb_result
*gr_res
;
159 struct ldb_result
*mem_res
;
161 ret
= _ldb_nss_init();
162 if (ret
!= NSS_STATUS_SUCCESS
) {
166 ctx
= talloc_new(_ldb_nss_ctx
->ldb
);
168 *errnop
= errno
= ENOMEM
;
169 return NSS_STATUS_UNAVAIL
;
172 /* build the filter for this uid */
173 filter
= talloc_asprintf(ctx
, _LDB_NSS_GRNAM_FILTER
, name
);
174 if (filter
== NULL
) {
175 /* this is a fatal error */
176 *errnop
= errno
= ENOMEM
;
177 ret
= NSS_STATUS_UNAVAIL
;
181 /* search the entry */
182 ret
= ldb_search(_ldb_nss_ctx
->ldb
,
188 if (ret
!= LDB_SUCCESS
) {
189 /* this is a fatal error */
190 *errnop
= errno
= ENOENT
;
191 ret
= NSS_STATUS_UNAVAIL
;
195 talloc_steal(ctx
, gr_res
);
197 /* if none found return */
198 if (gr_res
->count
== 0) {
199 *errnop
= errno
= ENOENT
;
200 ret
= NSS_STATUS_NOTFOUND
;
204 if (gr_res
->count
!= 1) {
205 /* this is a fatal error */
206 *errnop
= errno
= ENOENT
;
207 ret
= NSS_STATUS_UNAVAIL
;
211 mem_res
= talloc_zero(ctx
, struct ldb_result
);
213 errno
= *errnop
= ENOMEM
;
214 ret
= NSS_STATUS_UNAVAIL
;
218 ret
= _ldb_nss_group_request(&mem_res
,
223 if (ret
!= NSS_STATUS_SUCCESS
) {
228 ret
= _ldb_nss_fill_group(result_buf
,
235 if (ret
!= NSS_STATUS_SUCCESS
) {
239 ret
= NSS_STATUS_SUCCESS
;
245 NSS_STATUS
_nss_ldb_getgrgid_r(gid_t gid
, struct group
*result_buf
, char *buffer
, size_t buflen
, int *errnop
)
250 struct ldb_result
*gr_res
;
251 struct ldb_result
*mem_res
;
253 if (gid
== 0) { /* we don't serve root gid by policy */
254 *errnop
= errno
= ENOENT
;
255 return NSS_STATUS_NOTFOUND
;
258 ret
= _ldb_nss_init();
259 if (ret
!= NSS_STATUS_SUCCESS
) {
263 ctx
= talloc_new(_ldb_nss_ctx
->ldb
);
265 *errnop
= errno
= ENOMEM
;
266 return NSS_STATUS_UNAVAIL
;
269 /* build the filter for this uid */
270 filter
= talloc_asprintf(ctx
, _LDB_NSS_GRGID_FILTER
, gid
);
271 if (filter
== NULL
) {
272 /* this is a fatal error */
273 *errnop
= errno
= ENOMEM
;
274 ret
= NSS_STATUS_UNAVAIL
;
278 /* search the entry */
279 ret
= ldb_search(_ldb_nss_ctx
->ldb
,
285 if (ret
!= LDB_SUCCESS
) {
286 /* this is a fatal error */
287 *errnop
= errno
= ENOENT
;
288 ret
= NSS_STATUS_UNAVAIL
;
292 talloc_steal(ctx
, gr_res
);
294 /* if none found return */
295 if (gr_res
->count
== 0) {
296 *errnop
= errno
= ENOENT
;
297 ret
= NSS_STATUS_NOTFOUND
;
301 if (gr_res
->count
!= 1) {
302 /* this is a fatal error */
303 *errnop
= errno
= ENOENT
;
304 ret
= NSS_STATUS_UNAVAIL
;
308 mem_res
= talloc_zero(ctx
, struct ldb_result
);
310 errno
= *errnop
= ENOMEM
;
311 ret
= NSS_STATUS_UNAVAIL
;
315 ret
= _ldb_nss_group_request(&mem_res
,
320 if (ret
!= NSS_STATUS_SUCCESS
) {
325 ret
= _ldb_nss_fill_group(result_buf
,
332 if (ret
!= NSS_STATUS_SUCCESS
) {
336 ret
= NSS_STATUS_SUCCESS
;
342 NSS_STATUS
_nss_ldb_initgroups_dyn(const char *user
, gid_t group
, long int *start
, long int *size
, gid_t
**groups
, long int limit
, int *errnop
)
346 const char * attrs
[] = { "uidNumber", "gidNumber", NULL
};
347 struct ldb_result
*uid_res
;
348 struct ldb_result
*mem_res
;
350 ret
= _ldb_nss_init();
351 if (ret
!= NSS_STATUS_SUCCESS
) {
355 mem_res
= talloc_zero(_ldb_nss_ctx
, struct ldb_result
);
357 errno
= *errnop
= ENOMEM
;
358 return NSS_STATUS_UNAVAIL
;
361 /* build the filter for this name */
362 filter
= talloc_asprintf(mem_res
, _LDB_NSS_PWNAM_FILTER
, user
);
363 if (filter
== NULL
) {
364 /* this is a fatal error */
365 *errnop
= errno
= ENOENT
;
366 ret
= NSS_STATUS_UNAVAIL
;
370 /* search the entry */
371 ret
= ldb_search(_ldb_nss_ctx
->ldb
,
377 if (ret
!= LDB_SUCCESS
) {
378 /* this is a fatal error */
379 *errnop
= errno
= ENOENT
;
380 ret
= NSS_STATUS_UNAVAIL
;
384 talloc_steal(mem_res
, uid_res
);
386 /* if none found return */
387 if (uid_res
->count
== 0) {
388 *errnop
= errno
= ENOENT
;
389 ret
= NSS_STATUS_NOTFOUND
;
393 if (uid_res
->count
!= 1) {
394 /* this is a fatal error */
395 *errnop
= errno
= ENOENT
;
396 ret
= NSS_STATUS_UNAVAIL
;
400 ret
= _ldb_nss_group_request(&mem_res
,
401 uid_res
->msgs
[0]->dn
,
405 if (ret
!= NSS_STATUS_SUCCESS
) {
410 ret
= _ldb_nss_fill_initgr(group
,
418 if (ret
!= NSS_STATUS_SUCCESS
) {
422 ret
= NSS_STATUS_SUCCESS
;
425 talloc_free(mem_res
);