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, _ldb_nss_ctx->ldb,
63 &_ldb_nss_ctx->gr_res,
67 _LDB_NSS_GRENT_FILTER);
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, _ldb_nss_ctx->ldb, &gr_res,
185 if (ret != LDB_SUCCESS) {
186 /* this is a fatal error */
187 *errnop = errno = ENOENT;
188 ret = NSS_STATUS_UNAVAIL;
192 talloc_steal(ctx, gr_res);
194 /* if none found return */
195 if (gr_res->count == 0) {
196 *errnop = errno = ENOENT;
197 ret = NSS_STATUS_NOTFOUND;
201 if (gr_res->count != 1) {
202 /* this is a fatal error */
203 *errnop = errno = ENOENT;
204 ret = NSS_STATUS_UNAVAIL;
208 mem_res = talloc_zero(ctx, struct ldb_result);
210 errno = *errnop = ENOMEM;
211 ret = NSS_STATUS_UNAVAIL;
215 ret = _ldb_nss_group_request(&mem_res,
220 if (ret != NSS_STATUS_SUCCESS) {
225 ret = _ldb_nss_fill_group(result_buf,
232 if (ret != NSS_STATUS_SUCCESS) {
236 ret = NSS_STATUS_SUCCESS;
242 NSS_STATUS _nss_ldb_getgrgid_r(gid_t gid, struct group *result_buf, char *buffer, size_t buflen, int *errnop)
247 struct ldb_result *gr_res;
248 struct ldb_result *mem_res;
250 if (gid == 0) { /* we don't serve root gid by policy */
251 *errnop = errno = ENOENT;
252 return NSS_STATUS_NOTFOUND;
255 ret = _ldb_nss_init();
256 if (ret != NSS_STATUS_SUCCESS) {
260 ctx = talloc_new(_ldb_nss_ctx->ldb);
262 *errnop = errno = ENOMEM;
263 return NSS_STATUS_UNAVAIL;
266 /* build the filter for this uid */
267 filter = talloc_asprintf(ctx, _LDB_NSS_GRGID_FILTER, gid);
268 if (filter == NULL) {
269 /* this is a fatal error */
270 *errnop = errno = ENOMEM;
271 ret = NSS_STATUS_UNAVAIL;
275 /* search the entry */
276 ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, &gr_res,
281 if (ret != LDB_SUCCESS) {
282 /* this is a fatal error */
283 *errnop = errno = ENOENT;
284 ret = NSS_STATUS_UNAVAIL;
288 talloc_steal(ctx, gr_res);
290 /* if none found return */
291 if (gr_res->count == 0) {
292 *errnop = errno = ENOENT;
293 ret = NSS_STATUS_NOTFOUND;
297 if (gr_res->count != 1) {
298 /* this is a fatal error */
299 *errnop = errno = ENOENT;
300 ret = NSS_STATUS_UNAVAIL;
304 mem_res = talloc_zero(ctx, struct ldb_result);
306 errno = *errnop = ENOMEM;
307 ret = NSS_STATUS_UNAVAIL;
311 ret = _ldb_nss_group_request(&mem_res,
316 if (ret != NSS_STATUS_SUCCESS) {
321 ret = _ldb_nss_fill_group(result_buf,
328 if (ret != NSS_STATUS_SUCCESS) {
332 ret = NSS_STATUS_SUCCESS;
338 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)
342 const char * attrs[] = { "uidNumber", "gidNumber", NULL };
343 struct ldb_result *uid_res;
344 struct ldb_result *mem_res;
346 ret = _ldb_nss_init();
347 if (ret != NSS_STATUS_SUCCESS) {
351 mem_res = talloc_zero(_ldb_nss_ctx, struct ldb_result);
353 errno = *errnop = ENOMEM;
354 return NSS_STATUS_UNAVAIL;
357 /* build the filter for this name */
358 filter = talloc_asprintf(mem_res, _LDB_NSS_PWNAM_FILTER, user);
359 if (filter == NULL) {
360 /* this is a fatal error */
361 *errnop = errno = ENOENT;
362 ret = NSS_STATUS_UNAVAIL;
366 /* search the entry */
367 ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, &uid_res,
372 if (ret != LDB_SUCCESS) {
373 /* this is a fatal error */
374 *errnop = errno = ENOENT;
375 ret = NSS_STATUS_UNAVAIL;
379 talloc_steal(mem_res, uid_res);
381 /* if none found return */
382 if (uid_res->count == 0) {
383 *errnop = errno = ENOENT;
384 ret = NSS_STATUS_NOTFOUND;
388 if (uid_res->count != 1) {
389 /* this is a fatal error */
390 *errnop = errno = ENOENT;
391 ret = NSS_STATUS_UNAVAIL;
395 ret = _ldb_nss_group_request(&mem_res,
396 uid_res->msgs[0]->dn,
400 if (ret != NSS_STATUS_SUCCESS) {
405 ret = _ldb_nss_fill_initgr(group,
413 if (ret != NSS_STATUS_SUCCESS) {
417 ret = NSS_STATUS_SUCCESS;
420 talloc_free(mem_res);