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 Lesser 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 Lesser 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);