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 3 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 License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 extern struct _ldb_nss_context
*_ldb_nss_ctx
;
24 const char *_ldb_nss_gr_attrs
[] = {
31 const char *_ldb_nss_mem_attrs
[] = {
36 #define _NSS_LDB_ENOMEM(amem) \
40 talloc_free(memctx); \
41 return NSS_STATUS_UNAVAIL; \
45 /* This setgrent, getgrent, endgrent is not very efficient */
47 NSS_STATUS
_nss_ldb_setgrent(void)
51 ret
= _ldb_nss_init();
52 if (ret
!= NSS_STATUS_SUCCESS
) {
56 _ldb_nss_ctx
->gr_cur
= 0;
57 if (_ldb_nss_ctx
->gr_res
!= NULL
) {
58 talloc_free(_ldb_nss_ctx
->gr_res
);
59 _ldb_nss_ctx
->gr_res
= NULL
;
62 ret
= ldb_search(_ldb_nss_ctx
->ldb
,
65 _LDB_NSS_GRENT_FILTER
,
67 &_ldb_nss_ctx
->gr_res
);
68 if (ret
!= LDB_SUCCESS
) {
69 return NSS_STATUS_UNAVAIL
;
72 return NSS_STATUS_SUCCESS
;
75 NSS_STATUS
_nss_ldb_endgrent(void)
79 ret
= _ldb_nss_init();
80 if (ret
!= NSS_STATUS_SUCCESS
) {
84 _ldb_nss_ctx
->gr_cur
= 0;
85 if (_ldb_nss_ctx
->gr_res
) {
86 talloc_free(_ldb_nss_ctx
->gr_res
);
87 _ldb_nss_ctx
->gr_res
= NULL
;
90 return NSS_STATUS_SUCCESS
;
93 NSS_STATUS
_nss_ldb_getgrent_r(struct group
*result_buf
, char *buffer
, size_t buflen
, int *errnop
)
96 struct ldb_result
*res
;
98 ret
= _ldb_nss_init();
99 if (ret
!= NSS_STATUS_SUCCESS
) {
105 if (_ldb_nss_ctx
->gr_cur
>= _ldb_nss_ctx
->gr_res
->count
) {
106 /* already returned all entries */
107 return NSS_STATUS_NOTFOUND
;
110 res
= talloc_zero(_ldb_nss_ctx
->gr_res
, struct ldb_result
);
112 errno
= *errnop
= ENOMEM
;
113 _ldb_nss_ctx
->gr_cur
++; /* skip this entry */
114 return NSS_STATUS_UNAVAIL
;
117 ret
= _ldb_nss_group_request(&res
,
118 _ldb_nss_ctx
->gr_res
->msgs
[_ldb_nss_ctx
->gr_cur
]->dn
,
122 if (ret
!= NSS_STATUS_SUCCESS
) {
125 _ldb_nss_ctx
->gr_cur
++; /* skip this entry */
129 ret
= _ldb_nss_fill_group(result_buf
,
133 _ldb_nss_ctx
->gr_res
->msgs
[_ldb_nss_ctx
->gr_cur
],
138 if (ret
!= NSS_STATUS_SUCCESS
) {
139 if (ret
!= NSS_STATUS_TRYAGAIN
) {
140 _ldb_nss_ctx
->gr_cur
++; /* skip this entry */
145 /* this entry is ok, increment counter to nex entry */
146 _ldb_nss_ctx
->gr_cur
++;
148 return NSS_STATUS_SUCCESS
;
151 NSS_STATUS
_nss_ldb_getgrnam_r(const char *name
, struct group
*result_buf
, char *buffer
, size_t buflen
, int *errnop
)
156 struct ldb_result
*gr_res
;
157 struct ldb_result
*mem_res
;
159 ret
= _ldb_nss_init();
160 if (ret
!= NSS_STATUS_SUCCESS
) {
164 ctx
= talloc_new(_ldb_nss_ctx
->ldb
);
166 *errnop
= errno
= ENOMEM
;
167 return NSS_STATUS_UNAVAIL
;
170 /* build the filter for this uid */
171 filter
= talloc_asprintf(ctx
, _LDB_NSS_GRNAM_FILTER
, name
);
172 if (filter
== NULL
) {
173 /* this is a fatal error */
174 *errnop
= errno
= ENOMEM
;
175 ret
= NSS_STATUS_UNAVAIL
;
179 /* search the entry */
180 ret
= ldb_search(_ldb_nss_ctx
->ldb
,
186 if (ret
!= LDB_SUCCESS
) {
187 /* this is a fatal error */
188 *errnop
= errno
= ENOENT
;
189 ret
= NSS_STATUS_UNAVAIL
;
193 talloc_steal(ctx
, gr_res
);
195 /* if none found return */
196 if (gr_res
->count
== 0) {
197 *errnop
= errno
= ENOENT
;
198 ret
= NSS_STATUS_NOTFOUND
;
202 if (gr_res
->count
!= 1) {
203 /* this is a fatal error */
204 *errnop
= errno
= ENOENT
;
205 ret
= NSS_STATUS_UNAVAIL
;
209 mem_res
= talloc_zero(ctx
, struct ldb_result
);
211 errno
= *errnop
= ENOMEM
;
212 ret
= NSS_STATUS_UNAVAIL
;
216 ret
= _ldb_nss_group_request(&mem_res
,
221 if (ret
!= NSS_STATUS_SUCCESS
) {
226 ret
= _ldb_nss_fill_group(result_buf
,
233 if (ret
!= NSS_STATUS_SUCCESS
) {
237 ret
= NSS_STATUS_SUCCESS
;
243 NSS_STATUS
_nss_ldb_getgrgid_r(gid_t gid
, struct group
*result_buf
, char *buffer
, size_t buflen
, int *errnop
)
248 struct ldb_result
*gr_res
;
249 struct ldb_result
*mem_res
;
251 if (gid
== 0) { /* we don't serve root gid by policy */
252 *errnop
= errno
= ENOENT
;
253 return NSS_STATUS_NOTFOUND
;
256 ret
= _ldb_nss_init();
257 if (ret
!= NSS_STATUS_SUCCESS
) {
261 ctx
= talloc_new(_ldb_nss_ctx
->ldb
);
263 *errnop
= errno
= ENOMEM
;
264 return NSS_STATUS_UNAVAIL
;
267 /* build the filter for this uid */
268 filter
= talloc_asprintf(ctx
, _LDB_NSS_GRGID_FILTER
, gid
);
269 if (filter
== NULL
) {
270 /* this is a fatal error */
271 *errnop
= errno
= ENOMEM
;
272 ret
= NSS_STATUS_UNAVAIL
;
276 /* search the entry */
277 ret
= ldb_search(_ldb_nss_ctx
->ldb
,
283 if (ret
!= LDB_SUCCESS
) {
284 /* this is a fatal error */
285 *errnop
= errno
= ENOENT
;
286 ret
= NSS_STATUS_UNAVAIL
;
290 talloc_steal(ctx
, gr_res
);
292 /* if none found return */
293 if (gr_res
->count
== 0) {
294 *errnop
= errno
= ENOENT
;
295 ret
= NSS_STATUS_NOTFOUND
;
299 if (gr_res
->count
!= 1) {
300 /* this is a fatal error */
301 *errnop
= errno
= ENOENT
;
302 ret
= NSS_STATUS_UNAVAIL
;
306 mem_res
= talloc_zero(ctx
, struct ldb_result
);
308 errno
= *errnop
= ENOMEM
;
309 ret
= NSS_STATUS_UNAVAIL
;
313 ret
= _ldb_nss_group_request(&mem_res
,
318 if (ret
!= NSS_STATUS_SUCCESS
) {
323 ret
= _ldb_nss_fill_group(result_buf
,
330 if (ret
!= NSS_STATUS_SUCCESS
) {
334 ret
= NSS_STATUS_SUCCESS
;
340 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
)
344 const char * attrs
[] = { "uidNumber", "gidNumber", NULL
};
345 struct ldb_result
*uid_res
;
346 struct ldb_result
*mem_res
;
348 ret
= _ldb_nss_init();
349 if (ret
!= NSS_STATUS_SUCCESS
) {
353 mem_res
= talloc_zero(_ldb_nss_ctx
, struct ldb_result
);
355 errno
= *errnop
= ENOMEM
;
356 return NSS_STATUS_UNAVAIL
;
359 /* build the filter for this name */
360 filter
= talloc_asprintf(mem_res
, _LDB_NSS_PWNAM_FILTER
, user
);
361 if (filter
== NULL
) {
362 /* this is a fatal error */
363 *errnop
= errno
= ENOENT
;
364 ret
= NSS_STATUS_UNAVAIL
;
368 /* search the entry */
369 ret
= ldb_search(_ldb_nss_ctx
->ldb
,
375 if (ret
!= LDB_SUCCESS
) {
376 /* this is a fatal error */
377 *errnop
= errno
= ENOENT
;
378 ret
= NSS_STATUS_UNAVAIL
;
382 talloc_steal(mem_res
, uid_res
);
384 /* if none found return */
385 if (uid_res
->count
== 0) {
386 *errnop
= errno
= ENOENT
;
387 ret
= NSS_STATUS_NOTFOUND
;
391 if (uid_res
->count
!= 1) {
392 /* this is a fatal error */
393 *errnop
= errno
= ENOENT
;
394 ret
= NSS_STATUS_UNAVAIL
;
398 ret
= _ldb_nss_group_request(&mem_res
,
399 uid_res
->msgs
[0]->dn
,
403 if (ret
!= NSS_STATUS_SUCCESS
) {
408 ret
= _ldb_nss_fill_initgr(group
,
416 if (ret
!= NSS_STATUS_SUCCESS
) {
420 ret
= NSS_STATUS_SUCCESS
;
423 talloc_free(mem_res
);