r25068: Older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for every opcode on the
[Samba.git] / source / lib / ldb / nssldb / ldb-grp.c
blobf33ec65c55e99c645a627bbd6a8ca2a4d7f17941
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 2 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
17 License along with this library; if not, write to the
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
22 #include "ldb-nss.h"
24 extern struct _ldb_nss_context *_ldb_nss_ctx;
26 const char *_ldb_nss_gr_attrs[] = {
27 "cn",
28 "userPassword",
29 "gidNumber",
30 NULL
33 const char *_ldb_nss_mem_attrs[] = {
34 "uid",
35 NULL
38 #define _NSS_LDB_ENOMEM(amem) \
39 do { \
40 if ( ! amem) { \
41 errno = ENOMEM; \
42 talloc_free(memctx); \
43 return NSS_STATUS_UNAVAIL; \
44 } \
45 } while(0)
47 /* This setgrent, getgrent, endgrent is not very efficient */
49 NSS_STATUS _nss_ldb_setgrent(void)
51 int ret;
53 ret = _ldb_nss_init();
54 if (ret != NSS_STATUS_SUCCESS) {
55 return ret;
58 _ldb_nss_ctx->gr_cur = 0;
59 if (_ldb_nss_ctx->gr_res != NULL) {
60 talloc_free(_ldb_nss_ctx->gr_res);
61 _ldb_nss_ctx->gr_res = NULL;
64 ret = ldb_search(_ldb_nss_ctx->ldb,
65 _ldb_nss_ctx->base,
66 LDB_SCOPE_SUBTREE,
67 _LDB_NSS_GRENT_FILTER,
68 _ldb_nss_gr_attrs,
69 &_ldb_nss_ctx->gr_res);
70 if (ret != LDB_SUCCESS) {
71 return NSS_STATUS_UNAVAIL;
74 return NSS_STATUS_SUCCESS;
77 NSS_STATUS _nss_ldb_endgrent(void)
79 int ret;
81 ret = _ldb_nss_init();
82 if (ret != NSS_STATUS_SUCCESS) {
83 return ret;
86 _ldb_nss_ctx->gr_cur = 0;
87 if (_ldb_nss_ctx->gr_res) {
88 talloc_free(_ldb_nss_ctx->gr_res);
89 _ldb_nss_ctx->gr_res = NULL;
92 return NSS_STATUS_SUCCESS;
95 NSS_STATUS _nss_ldb_getgrent_r(struct group *result_buf, char *buffer, size_t buflen, int *errnop)
97 int ret;
98 struct ldb_result *res;
100 ret = _ldb_nss_init();
101 if (ret != NSS_STATUS_SUCCESS) {
102 return ret;
105 *errnop = 0;
107 if (_ldb_nss_ctx->gr_cur >= _ldb_nss_ctx->gr_res->count) {
108 /* already returned all entries */
109 return NSS_STATUS_NOTFOUND;
112 res = talloc_zero(_ldb_nss_ctx->gr_res, struct ldb_result);
113 if ( ! res) {
114 errno = *errnop = ENOMEM;
115 _ldb_nss_ctx->gr_cur++; /* skip this entry */
116 return NSS_STATUS_UNAVAIL;
119 ret = _ldb_nss_group_request(&res,
120 _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur]->dn,
121 _ldb_nss_mem_attrs,
122 "member");
124 if (ret != NSS_STATUS_SUCCESS) {
125 *errnop = errno;
126 talloc_free(res);
127 _ldb_nss_ctx->gr_cur++; /* skip this entry */
128 return ret;
131 ret = _ldb_nss_fill_group(result_buf,
132 buffer,
133 buflen,
134 errnop,
135 _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur],
136 res);
138 talloc_free(res);
140 if (ret != NSS_STATUS_SUCCESS) {
141 if (ret != NSS_STATUS_TRYAGAIN) {
142 _ldb_nss_ctx->gr_cur++; /* skip this entry */
144 return ret;
147 /* this entry is ok, increment counter to nex entry */
148 _ldb_nss_ctx->gr_cur++;
150 return NSS_STATUS_SUCCESS;
153 NSS_STATUS _nss_ldb_getgrnam_r(const char *name, struct group *result_buf, char *buffer, size_t buflen, int *errnop)
155 int ret;
156 char *filter;
157 TALLOC_CTX *ctx;
158 struct ldb_result *gr_res;
159 struct ldb_result *mem_res;
161 ret = _ldb_nss_init();
162 if (ret != NSS_STATUS_SUCCESS) {
163 return ret;
166 ctx = talloc_new(_ldb_nss_ctx->ldb);
167 if ( ! ctx) {
168 *errnop = errno = ENOMEM;
169 return NSS_STATUS_UNAVAIL;
172 /* build the filter for this uid */
173 filter = talloc_asprintf(ctx, _LDB_NSS_GRNAM_FILTER, name);
174 if (filter == NULL) {
175 /* this is a fatal error */
176 *errnop = errno = ENOMEM;
177 ret = NSS_STATUS_UNAVAIL;
178 goto done;
181 /* search the entry */
182 ret = ldb_search(_ldb_nss_ctx->ldb,
183 _ldb_nss_ctx->base,
184 LDB_SCOPE_SUBTREE,
185 filter,
186 _ldb_nss_gr_attrs,
187 &gr_res);
188 if (ret != LDB_SUCCESS) {
189 /* this is a fatal error */
190 *errnop = errno = ENOENT;
191 ret = NSS_STATUS_UNAVAIL;
192 goto done;
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;
201 goto done;
204 if (gr_res->count != 1) {
205 /* this is a fatal error */
206 *errnop = errno = ENOENT;
207 ret = NSS_STATUS_UNAVAIL;
208 goto done;
211 mem_res = talloc_zero(ctx, struct ldb_result);
212 if ( ! mem_res) {
213 errno = *errnop = ENOMEM;
214 ret = NSS_STATUS_UNAVAIL;
215 goto done;
218 ret = _ldb_nss_group_request(&mem_res,
219 gr_res->msgs[0]->dn,
220 _ldb_nss_mem_attrs,
221 "member");
223 if (ret != NSS_STATUS_SUCCESS) {
224 *errnop = errno;
225 goto done;
228 ret = _ldb_nss_fill_group(result_buf,
229 buffer,
230 buflen,
231 errnop,
232 gr_res->msgs[0],
233 mem_res);
235 if (ret != NSS_STATUS_SUCCESS) {
236 goto done;
239 ret = NSS_STATUS_SUCCESS;
240 done:
241 talloc_free(ctx);
242 return ret;
245 NSS_STATUS _nss_ldb_getgrgid_r(gid_t gid, struct group *result_buf, char *buffer, size_t buflen, int *errnop)
247 int ret;
248 char *filter;
249 TALLOC_CTX *ctx;
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) {
260 return ret;
263 ctx = talloc_new(_ldb_nss_ctx->ldb);
264 if ( ! ctx) {
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;
275 goto done;
278 /* search the entry */
279 ret = ldb_search(_ldb_nss_ctx->ldb,
280 _ldb_nss_ctx->base,
281 LDB_SCOPE_SUBTREE,
282 filter,
283 _ldb_nss_gr_attrs,
284 &gr_res);
285 if (ret != LDB_SUCCESS) {
286 /* this is a fatal error */
287 *errnop = errno = ENOENT;
288 ret = NSS_STATUS_UNAVAIL;
289 goto done;
292 talloc_steal(ctx, gr_res);
294 /* if none found return */
295 if (gr_res->count == 0) {
296 *errnop = errno = ENOENT;
297 ret = NSS_STATUS_NOTFOUND;
298 goto done;
301 if (gr_res->count != 1) {
302 /* this is a fatal error */
303 *errnop = errno = ENOENT;
304 ret = NSS_STATUS_UNAVAIL;
305 goto done;
308 mem_res = talloc_zero(ctx, struct ldb_result);
309 if ( ! mem_res) {
310 errno = *errnop = ENOMEM;
311 ret = NSS_STATUS_UNAVAIL;
312 goto done;
315 ret = _ldb_nss_group_request(&mem_res,
316 gr_res->msgs[0]->dn,
317 _ldb_nss_mem_attrs,
318 "member");
320 if (ret != NSS_STATUS_SUCCESS) {
321 *errnop = errno;
322 goto done;
325 ret = _ldb_nss_fill_group(result_buf,
326 buffer,
327 buflen,
328 errnop,
329 gr_res->msgs[0],
330 mem_res);
332 if (ret != NSS_STATUS_SUCCESS) {
333 goto done;
336 ret = NSS_STATUS_SUCCESS;
337 done:
338 talloc_free(ctx);
339 return ret;
342 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 int ret;
345 char *filter;
346 const char * attrs[] = { "uidNumber", "gidNumber", NULL };
347 struct ldb_result *uid_res;
348 struct ldb_result *mem_res;
350 ret = _ldb_nss_init();
351 if (ret != NSS_STATUS_SUCCESS) {
352 return ret;
355 mem_res = talloc_zero(_ldb_nss_ctx, struct ldb_result);
356 if ( ! mem_res) {
357 errno = *errnop = ENOMEM;
358 return NSS_STATUS_UNAVAIL;
361 /* build the filter for this name */
362 filter = talloc_asprintf(mem_res, _LDB_NSS_PWNAM_FILTER, user);
363 if (filter == NULL) {
364 /* this is a fatal error */
365 *errnop = errno = ENOENT;
366 ret = NSS_STATUS_UNAVAIL;
367 goto done;
370 /* search the entry */
371 ret = ldb_search(_ldb_nss_ctx->ldb,
372 _ldb_nss_ctx->base,
373 LDB_SCOPE_SUBTREE,
374 filter,
375 attrs,
376 &uid_res);
377 if (ret != LDB_SUCCESS) {
378 /* this is a fatal error */
379 *errnop = errno = ENOENT;
380 ret = NSS_STATUS_UNAVAIL;
381 goto done;
384 talloc_steal(mem_res, uid_res);
386 /* if none found return */
387 if (uid_res->count == 0) {
388 *errnop = errno = ENOENT;
389 ret = NSS_STATUS_NOTFOUND;
390 goto done;
393 if (uid_res->count != 1) {
394 /* this is a fatal error */
395 *errnop = errno = ENOENT;
396 ret = NSS_STATUS_UNAVAIL;
397 goto done;
400 ret = _ldb_nss_group_request(&mem_res,
401 uid_res->msgs[0]->dn,
402 attrs,
403 "memberOf");
405 if (ret != NSS_STATUS_SUCCESS) {
406 *errnop = errno;
407 goto done;
410 ret = _ldb_nss_fill_initgr(group,
411 limit,
412 start,
413 size,
414 groups,
415 errnop,
416 mem_res);
418 if (ret != NSS_STATUS_SUCCESS) {
419 goto done;
422 ret = NSS_STATUS_SUCCESS;
424 done:
425 talloc_free(mem_res);
426 return ret;