r23794: convert more code from LGPLv2+ to LGPLv3+
[Samba/bb.git] / source / lib / ldb / nssldb / ldb-grp.c
blobf8121b25ca417da73889f733f0920c9bead34e5c
1 /*
2 LDB nsswitch module
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/>.
20 #include "ldb-nss.h"
22 extern struct _ldb_nss_context *_ldb_nss_ctx;
24 const char *_ldb_nss_gr_attrs[] = {
25 "cn",
26 "userPassword",
27 "gidNumber",
28 NULL
31 const char *_ldb_nss_mem_attrs[] = {
32 "uid",
33 NULL
36 #define _NSS_LDB_ENOMEM(amem) \
37 do { \
38 if ( ! amem) { \
39 errno = ENOMEM; \
40 talloc_free(memctx); \
41 return NSS_STATUS_UNAVAIL; \
42 } \
43 } while(0)
45 /* This setgrent, getgrent, endgrent is not very efficient */
47 NSS_STATUS _nss_ldb_setgrent(void)
49 int ret;
51 ret = _ldb_nss_init();
52 if (ret != NSS_STATUS_SUCCESS) {
53 return ret;
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,
63 _ldb_nss_ctx->base,
64 LDB_SCOPE_SUBTREE,
65 _LDB_NSS_GRENT_FILTER,
66 _ldb_nss_gr_attrs,
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)
77 int ret;
79 ret = _ldb_nss_init();
80 if (ret != NSS_STATUS_SUCCESS) {
81 return ret;
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)
95 int ret;
96 struct ldb_result *res;
98 ret = _ldb_nss_init();
99 if (ret != NSS_STATUS_SUCCESS) {
100 return ret;
103 *errnop = 0;
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);
111 if ( ! res) {
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,
119 _ldb_nss_mem_attrs,
120 "member");
122 if (ret != NSS_STATUS_SUCCESS) {
123 *errnop = errno;
124 talloc_free(res);
125 _ldb_nss_ctx->gr_cur++; /* skip this entry */
126 return ret;
129 ret = _ldb_nss_fill_group(result_buf,
130 buffer,
131 buflen,
132 errnop,
133 _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur],
134 res);
136 talloc_free(res);
138 if (ret != NSS_STATUS_SUCCESS) {
139 if (ret != NSS_STATUS_TRYAGAIN) {
140 _ldb_nss_ctx->gr_cur++; /* skip this entry */
142 return ret;
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)
153 int ret;
154 char *filter;
155 TALLOC_CTX *ctx;
156 struct ldb_result *gr_res;
157 struct ldb_result *mem_res;
159 ret = _ldb_nss_init();
160 if (ret != NSS_STATUS_SUCCESS) {
161 return ret;
164 ctx = talloc_new(_ldb_nss_ctx->ldb);
165 if ( ! ctx) {
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;
176 goto done;
179 /* search the entry */
180 ret = ldb_search(_ldb_nss_ctx->ldb,
181 _ldb_nss_ctx->base,
182 LDB_SCOPE_SUBTREE,
183 filter,
184 _ldb_nss_gr_attrs,
185 &gr_res);
186 if (ret != LDB_SUCCESS) {
187 /* this is a fatal error */
188 *errnop = errno = ENOENT;
189 ret = NSS_STATUS_UNAVAIL;
190 goto done;
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;
199 goto done;
202 if (gr_res->count != 1) {
203 /* this is a fatal error */
204 *errnop = errno = ENOENT;
205 ret = NSS_STATUS_UNAVAIL;
206 goto done;
209 mem_res = talloc_zero(ctx, struct ldb_result);
210 if ( ! mem_res) {
211 errno = *errnop = ENOMEM;
212 ret = NSS_STATUS_UNAVAIL;
213 goto done;
216 ret = _ldb_nss_group_request(&mem_res,
217 gr_res->msgs[0]->dn,
218 _ldb_nss_mem_attrs,
219 "member");
221 if (ret != NSS_STATUS_SUCCESS) {
222 *errnop = errno;
223 goto done;
226 ret = _ldb_nss_fill_group(result_buf,
227 buffer,
228 buflen,
229 errnop,
230 gr_res->msgs[0],
231 mem_res);
233 if (ret != NSS_STATUS_SUCCESS) {
234 goto done;
237 ret = NSS_STATUS_SUCCESS;
238 done:
239 talloc_free(ctx);
240 return ret;
243 NSS_STATUS _nss_ldb_getgrgid_r(gid_t gid, struct group *result_buf, char *buffer, size_t buflen, int *errnop)
245 int ret;
246 char *filter;
247 TALLOC_CTX *ctx;
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) {
258 return ret;
261 ctx = talloc_new(_ldb_nss_ctx->ldb);
262 if ( ! ctx) {
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;
273 goto done;
276 /* search the entry */
277 ret = ldb_search(_ldb_nss_ctx->ldb,
278 _ldb_nss_ctx->base,
279 LDB_SCOPE_SUBTREE,
280 filter,
281 _ldb_nss_gr_attrs,
282 &gr_res);
283 if (ret != LDB_SUCCESS) {
284 /* this is a fatal error */
285 *errnop = errno = ENOENT;
286 ret = NSS_STATUS_UNAVAIL;
287 goto done;
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;
296 goto done;
299 if (gr_res->count != 1) {
300 /* this is a fatal error */
301 *errnop = errno = ENOENT;
302 ret = NSS_STATUS_UNAVAIL;
303 goto done;
306 mem_res = talloc_zero(ctx, struct ldb_result);
307 if ( ! mem_res) {
308 errno = *errnop = ENOMEM;
309 ret = NSS_STATUS_UNAVAIL;
310 goto done;
313 ret = _ldb_nss_group_request(&mem_res,
314 gr_res->msgs[0]->dn,
315 _ldb_nss_mem_attrs,
316 "member");
318 if (ret != NSS_STATUS_SUCCESS) {
319 *errnop = errno;
320 goto done;
323 ret = _ldb_nss_fill_group(result_buf,
324 buffer,
325 buflen,
326 errnop,
327 gr_res->msgs[0],
328 mem_res);
330 if (ret != NSS_STATUS_SUCCESS) {
331 goto done;
334 ret = NSS_STATUS_SUCCESS;
335 done:
336 talloc_free(ctx);
337 return ret;
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)
342 int ret;
343 char *filter;
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) {
350 return ret;
353 mem_res = talloc_zero(_ldb_nss_ctx, struct ldb_result);
354 if ( ! mem_res) {
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;
365 goto done;
368 /* search the entry */
369 ret = ldb_search(_ldb_nss_ctx->ldb,
370 _ldb_nss_ctx->base,
371 LDB_SCOPE_SUBTREE,
372 filter,
373 attrs,
374 &uid_res);
375 if (ret != LDB_SUCCESS) {
376 /* this is a fatal error */
377 *errnop = errno = ENOENT;
378 ret = NSS_STATUS_UNAVAIL;
379 goto done;
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;
388 goto done;
391 if (uid_res->count != 1) {
392 /* this is a fatal error */
393 *errnop = errno = ENOENT;
394 ret = NSS_STATUS_UNAVAIL;
395 goto done;
398 ret = _ldb_nss_group_request(&mem_res,
399 uid_res->msgs[0]->dn,
400 attrs,
401 "memberOf");
403 if (ret != NSS_STATUS_SUCCESS) {
404 *errnop = errno;
405 goto done;
408 ret = _ldb_nss_fill_initgr(group,
409 limit,
410 start,
411 size,
412 groups,
413 errnop,
414 mem_res);
416 if (ret != NSS_STATUS_SUCCESS) {
417 goto done;
420 ret = NSS_STATUS_SUCCESS;
422 done:
423 talloc_free(mem_res);
424 return ret;