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)
155
struct ldb_result *gr_res;
156
struct ldb_result *mem_res;
158
ret = _ldb_nss_init();
159
if (ret != NSS_STATUS_SUCCESS) {
163
ctx = talloc_new(_ldb_nss_ctx->ldb);
165
*errnop = errno = ENOMEM;
166
return NSS_STATUS_UNAVAIL;
169
/* search the entry */
170
ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, &gr_res,
174
_LDB_NSS_GRNAM_FILTER, name);
175
if (ret != LDB_SUCCESS) {
176
/* this is a fatal error */
177
*errnop = errno = ENOENT;
178
ret = NSS_STATUS_UNAVAIL;
182
talloc_steal(ctx, gr_res);
184
/* if none found return */
185
if (gr_res->count == 0) {
186
*errnop = errno = ENOENT;
187
ret = NSS_STATUS_NOTFOUND;
191
if (gr_res->count != 1) {
192
/* this is a fatal error */
193
*errnop = errno = ENOENT;
194
ret = NSS_STATUS_UNAVAIL;
198
mem_res = talloc_zero(ctx, struct ldb_result);
200
errno = *errnop = ENOMEM;
201
ret = NSS_STATUS_UNAVAIL;
205
ret = _ldb_nss_group_request(&mem_res,
210
if (ret != NSS_STATUS_SUCCESS) {
215
ret = _ldb_nss_fill_group(result_buf,
222
if (ret != NSS_STATUS_SUCCESS) {
226
ret = NSS_STATUS_SUCCESS;
232
NSS_STATUS _nss_ldb_getgrgid_r(gid_t gid, struct group *result_buf, char *buffer, size_t buflen, int *errnop)
236
struct ldb_result *gr_res;
237
struct ldb_result *mem_res;
239
if (gid == 0) { /* we don't serve root gid by policy */
240
*errnop = errno = ENOENT;
241
return NSS_STATUS_NOTFOUND;
244
ret = _ldb_nss_init();
245
if (ret != NSS_STATUS_SUCCESS) {
249
ctx = talloc_new(_ldb_nss_ctx->ldb);
251
*errnop = errno = ENOMEM;
252
return NSS_STATUS_UNAVAIL;
255
/* search the entry */
256
ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, &gr_res,
260
_LDB_NSS_GRGID_FILTER, gid);
261
if (ret != LDB_SUCCESS) {
262
/* this is a fatal error */
263
*errnop = errno = ENOENT;
264
ret = NSS_STATUS_UNAVAIL;
268
talloc_steal(ctx, gr_res);
270
/* if none found return */
271
if (gr_res->count == 0) {
272
*errnop = errno = ENOENT;
273
ret = NSS_STATUS_NOTFOUND;
277
if (gr_res->count != 1) {
278
/* this is a fatal error */
279
*errnop = errno = ENOENT;
280
ret = NSS_STATUS_UNAVAIL;
284
mem_res = talloc_zero(ctx, struct ldb_result);
286
errno = *errnop = ENOMEM;
287
ret = NSS_STATUS_UNAVAIL;
291
ret = _ldb_nss_group_request(&mem_res,
296
if (ret != NSS_STATUS_SUCCESS) {
301
ret = _ldb_nss_fill_group(result_buf,
308
if (ret != NSS_STATUS_SUCCESS) {
312
ret = NSS_STATUS_SUCCESS;
318
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)
321
const char * attrs[] = { "uidNumber", "gidNumber", NULL };
322
struct ldb_result *uid_res;
323
struct ldb_result *mem_res;
325
ret = _ldb_nss_init();
326
if (ret != NSS_STATUS_SUCCESS) {
330
mem_res = talloc_zero(_ldb_nss_ctx, struct ldb_result);
332
errno = *errnop = ENOMEM;
333
return NSS_STATUS_UNAVAIL;
336
/* search the entry */
337
ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, &uid_res,
341
_LDB_NSS_PWNAM_FILTER, user);
342
if (ret != LDB_SUCCESS) {
343
/* this is a fatal error */
344
*errnop = errno = ENOENT;
345
ret = NSS_STATUS_UNAVAIL;
349
talloc_steal(mem_res, uid_res);
351
/* if none found return */
352
if (uid_res->count == 0) {
353
*errnop = errno = ENOENT;
354
ret = NSS_STATUS_NOTFOUND;
358
if (uid_res->count != 1) {
359
/* this is a fatal error */
360
*errnop = errno = ENOENT;
361
ret = NSS_STATUS_UNAVAIL;
365
ret = _ldb_nss_group_request(&mem_res,
366
uid_res->msgs[0]->dn,
370
if (ret != NSS_STATUS_SUCCESS) {
375
ret = _ldb_nss_fill_initgr(group,
383
if (ret != NSS_STATUS_SUCCESS) {
387
ret = NSS_STATUS_SUCCESS;
390
talloc_free(mem_res);