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,
64
&_ldb_nss_ctx->gr_res,
68
_LDB_NSS_GRENT_FILTER);
69
if (ret != LDB_SUCCESS) {
70
return NSS_STATUS_UNAVAIL;
73
return NSS_STATUS_SUCCESS;
76
NSS_STATUS _nss_ldb_endgrent(void)
80
ret = _ldb_nss_init();
81
if (ret != NSS_STATUS_SUCCESS) {
85
_ldb_nss_ctx->gr_cur = 0;
86
if (_ldb_nss_ctx->gr_res) {
87
talloc_free(_ldb_nss_ctx->gr_res);
88
_ldb_nss_ctx->gr_res = NULL;
91
return NSS_STATUS_SUCCESS;
94
NSS_STATUS _nss_ldb_getgrent_r(struct group *result_buf, char *buffer, size_t buflen, int *errnop)
97
struct ldb_result *res;
99
ret = _ldb_nss_init();
100
if (ret != NSS_STATUS_SUCCESS) {
106
if (_ldb_nss_ctx->gr_cur >= _ldb_nss_ctx->gr_res->count) {
107
/* already returned all entries */
108
return NSS_STATUS_NOTFOUND;
111
res = talloc_zero(_ldb_nss_ctx->gr_res, struct ldb_result);
113
errno = *errnop = ENOMEM;
114
_ldb_nss_ctx->gr_cur++; /* skip this entry */
115
return NSS_STATUS_UNAVAIL;
118
ret = _ldb_nss_group_request(&res,
119
_ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur]->dn,
123
if (ret != NSS_STATUS_SUCCESS) {
126
_ldb_nss_ctx->gr_cur++; /* skip this entry */
130
ret = _ldb_nss_fill_group(result_buf,
134
_ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur],
139
if (ret != NSS_STATUS_SUCCESS) {
140
if (ret != NSS_STATUS_TRYAGAIN) {
141
_ldb_nss_ctx->gr_cur++; /* skip this entry */
146
/* this entry is ok, increment counter to nex entry */
147
_ldb_nss_ctx->gr_cur++;
149
return NSS_STATUS_SUCCESS;
152
NSS_STATUS _nss_ldb_getgrnam_r(const char *name, struct group *result_buf, char *buffer, size_t buflen, int *errnop)
157
struct ldb_result *gr_res;
158
struct ldb_result *mem_res;
160
ret = _ldb_nss_init();
161
if (ret != NSS_STATUS_SUCCESS) {
165
ctx = talloc_new(_ldb_nss_ctx->ldb);
167
*errnop = errno = ENOMEM;
168
return NSS_STATUS_UNAVAIL;
171
/* build the filter for this uid */
172
filter = talloc_asprintf(ctx, _LDB_NSS_GRNAM_FILTER, name);
173
if (filter == NULL) {
174
/* this is a fatal error */
175
*errnop = errno = ENOMEM;
176
ret = NSS_STATUS_UNAVAIL;
180
/* search the entry */
181
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,
286
if (ret != LDB_SUCCESS) {
287
/* this is a fatal error */
288
*errnop = errno = ENOENT;
289
ret = NSS_STATUS_UNAVAIL;
293
talloc_steal(ctx, gr_res);
295
/* if none found return */
296
if (gr_res->count == 0) {
297
*errnop = errno = ENOENT;
298
ret = NSS_STATUS_NOTFOUND;
302
if (gr_res->count != 1) {
303
/* this is a fatal error */
304
*errnop = errno = ENOENT;
305
ret = NSS_STATUS_UNAVAIL;
309
mem_res = talloc_zero(ctx, struct ldb_result);
311
errno = *errnop = ENOMEM;
312
ret = NSS_STATUS_UNAVAIL;
316
ret = _ldb_nss_group_request(&mem_res,
321
if (ret != NSS_STATUS_SUCCESS) {
326
ret = _ldb_nss_fill_group(result_buf,
333
if (ret != NSS_STATUS_SUCCESS) {
337
ret = NSS_STATUS_SUCCESS;
343
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)
347
const char * attrs[] = { "uidNumber", "gidNumber", NULL };
348
struct ldb_result *uid_res;
349
struct ldb_result *mem_res;
351
ret = _ldb_nss_init();
352
if (ret != NSS_STATUS_SUCCESS) {
356
mem_res = talloc_zero(_ldb_nss_ctx, struct ldb_result);
358
errno = *errnop = ENOMEM;
359
return NSS_STATUS_UNAVAIL;
362
/* build the filter for this name */
363
filter = talloc_asprintf(mem_res, _LDB_NSS_PWNAM_FILTER, user);
364
if (filter == NULL) {
365
/* this is a fatal error */
366
*errnop = errno = ENOENT;
367
ret = NSS_STATUS_UNAVAIL;
371
/* search the entry */
372
ret = ldb_search(_ldb_nss_ctx->ldb,
379
if (ret != LDB_SUCCESS) {
380
/* this is a fatal error */
381
*errnop = errno = ENOENT;
382
ret = NSS_STATUS_UNAVAIL;
386
talloc_steal(mem_res, uid_res);
388
/* if none found return */
389
if (uid_res->count == 0) {
390
*errnop = errno = ENOENT;
391
ret = NSS_STATUS_NOTFOUND;
395
if (uid_res->count != 1) {
396
/* this is a fatal error */
397
*errnop = errno = ENOENT;
398
ret = NSS_STATUS_UNAVAIL;
402
ret = _ldb_nss_group_request(&mem_res,
403
uid_res->msgs[0]->dn,
407
if (ret != NSS_STATUS_SUCCESS) {
412
ret = _ldb_nss_fill_initgr(group,
420
if (ret != NSS_STATUS_SUCCESS) {
424
ret = NSS_STATUS_SUCCESS;
427
talloc_free(mem_res);