source: branches/samba-3.3.x/source/lib/ldb/nssldb/ldb-grp.c

Last change on this file was 206, checked in by Herwig Bauernfeind, 16 years ago

Import Samba 3.3 branch at 3.0.0 level (psmedley's port)

File size: 8.3 KB
Line 
1/*
2 LDB nsswitch module
3
4 Copyright (C) Simo Sorce 2006
5
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.
10
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.
15
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/>.
18*/
19
20#include "ldb-nss.h"
21
22extern struct _ldb_nss_context *_ldb_nss_ctx;
23
24const char *_ldb_nss_gr_attrs[] = {
25 "cn",
26 "userPassword",
27 "gidNumber",
28 NULL
29};
30
31const char *_ldb_nss_mem_attrs[] = {
32 "uid",
33 NULL
34};
35
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)
44
45/* This setgrent, getgrent, endgrent is not very efficient */
46
47NSS_STATUS _nss_ldb_setgrent(void)
48{
49 int ret;
50
51 ret = _ldb_nss_init();
52 if (ret != NSS_STATUS_SUCCESS) {
53 return ret;
54 }
55
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;
60 }
61
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;
70 }
71
72 return NSS_STATUS_SUCCESS;
73}
74
75NSS_STATUS _nss_ldb_endgrent(void)
76{
77 int ret;
78
79 ret = _ldb_nss_init();
80 if (ret != NSS_STATUS_SUCCESS) {
81 return ret;
82 }
83
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;
88 }
89
90 return NSS_STATUS_SUCCESS;
91}
92
93NSS_STATUS _nss_ldb_getgrent_r(struct group *result_buf, char *buffer, size_t buflen, int *errnop)
94{
95 int ret;
96 struct ldb_result *res;
97
98 ret = _ldb_nss_init();
99 if (ret != NSS_STATUS_SUCCESS) {
100 return ret;
101 }
102
103 *errnop = 0;
104
105 if (_ldb_nss_ctx->gr_cur >= _ldb_nss_ctx->gr_res->count) {
106 /* already returned all entries */
107 return NSS_STATUS_NOTFOUND;
108 }
109
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;
115 }
116
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");
121
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;
127 }
128
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);
135
136 talloc_free(res);
137
138 if (ret != NSS_STATUS_SUCCESS) {
139 if (ret != NSS_STATUS_TRYAGAIN) {
140 _ldb_nss_ctx->gr_cur++; /* skip this entry */
141 }
142 return ret;
143 }
144
145 /* this entry is ok, increment counter to nex entry */
146 _ldb_nss_ctx->gr_cur++;
147
148 return NSS_STATUS_SUCCESS;
149}
150
151NSS_STATUS _nss_ldb_getgrnam_r(const char *name, struct group *result_buf, char *buffer, size_t buflen, int *errnop)
152{
153 int ret;
154 char *filter;
155 TALLOC_CTX *ctx;
156 struct ldb_result *gr_res;
157 struct ldb_result *mem_res;
158
159 ret = _ldb_nss_init();
160 if (ret != NSS_STATUS_SUCCESS) {
161 return ret;
162 }
163
164 ctx = talloc_new(_ldb_nss_ctx->ldb);
165 if ( ! ctx) {
166 *errnop = errno = ENOMEM;
167 return NSS_STATUS_UNAVAIL;
168 }
169
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;
177 }
178
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;
191 }
192
193 talloc_steal(ctx, gr_res);
194
195 /* if none found return */
196 if (gr_res->count == 0) {
197 *errnop = errno = ENOENT;
198 ret = NSS_STATUS_NOTFOUND;
199 goto done;
200 }
201
202 if (gr_res->count != 1) {
203 /* this is a fatal error */
204 *errnop = errno = ENOENT;
205 ret = NSS_STATUS_UNAVAIL;
206 goto done;
207 }
208
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;
214 }
215
216 ret = _ldb_nss_group_request(&mem_res,
217 gr_res->msgs[0]->dn,
218 _ldb_nss_mem_attrs,
219 "member");
220
221 if (ret != NSS_STATUS_SUCCESS) {
222 *errnop = errno;
223 goto done;
224 }
225
226 ret = _ldb_nss_fill_group(result_buf,
227 buffer,
228 buflen,
229 errnop,
230 gr_res->msgs[0],
231 mem_res);
232
233 if (ret != NSS_STATUS_SUCCESS) {
234 goto done;
235 }
236
237 ret = NSS_STATUS_SUCCESS;
238done:
239 talloc_free(ctx);
240 return ret;
241}
242
243NSS_STATUS _nss_ldb_getgrgid_r(gid_t gid, struct group *result_buf, char *buffer, size_t buflen, int *errnop)
244{
245 int ret;
246 char *filter;
247 TALLOC_CTX *ctx;
248 struct ldb_result *gr_res;
249 struct ldb_result *mem_res;
250
251 if (gid == 0) { /* we don't serve root gid by policy */
252 *errnop = errno = ENOENT;
253 return NSS_STATUS_NOTFOUND;
254 }
255
256 ret = _ldb_nss_init();
257 if (ret != NSS_STATUS_SUCCESS) {
258 return ret;
259 }
260
261 ctx = talloc_new(_ldb_nss_ctx->ldb);
262 if ( ! ctx) {
263 *errnop = errno = ENOMEM;
264 return NSS_STATUS_UNAVAIL;
265 }
266
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;
274 }
275
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;
288 }
289
290 talloc_steal(ctx, gr_res);
291
292 /* if none found return */
293 if (gr_res->count == 0) {
294 *errnop = errno = ENOENT;
295 ret = NSS_STATUS_NOTFOUND;
296 goto done;
297 }
298
299 if (gr_res->count != 1) {
300 /* this is a fatal error */
301 *errnop = errno = ENOENT;
302 ret = NSS_STATUS_UNAVAIL;
303 goto done;
304 }
305
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;
311 }
312
313 ret = _ldb_nss_group_request(&mem_res,
314 gr_res->msgs[0]->dn,
315 _ldb_nss_mem_attrs,
316 "member");
317
318 if (ret != NSS_STATUS_SUCCESS) {
319 *errnop = errno;
320 goto done;
321 }
322
323 ret = _ldb_nss_fill_group(result_buf,
324 buffer,
325 buflen,
326 errnop,
327 gr_res->msgs[0],
328 mem_res);
329
330 if (ret != NSS_STATUS_SUCCESS) {
331 goto done;
332 }
333
334 ret = NSS_STATUS_SUCCESS;
335done:
336 talloc_free(ctx);
337 return ret;
338}
339
340NSS_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)
341{
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;
347
348 ret = _ldb_nss_init();
349 if (ret != NSS_STATUS_SUCCESS) {
350 return ret;
351 }
352
353 mem_res = talloc_zero(_ldb_nss_ctx, struct ldb_result);
354 if ( ! mem_res) {
355 errno = *errnop = ENOMEM;
356 return NSS_STATUS_UNAVAIL;
357 }
358
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;
366 }
367
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;
380 }
381
382 talloc_steal(mem_res, uid_res);
383
384 /* if none found return */
385 if (uid_res->count == 0) {
386 *errnop = errno = ENOENT;
387 ret = NSS_STATUS_NOTFOUND;
388 goto done;
389 }
390
391 if (uid_res->count != 1) {
392 /* this is a fatal error */
393 *errnop = errno = ENOENT;
394 ret = NSS_STATUS_UNAVAIL;
395 goto done;
396 }
397
398 ret = _ldb_nss_group_request(&mem_res,
399 uid_res->msgs[0]->dn,
400 attrs,
401 "memberOf");
402
403 if (ret != NSS_STATUS_SUCCESS) {
404 *errnop = errno;
405 goto done;
406 }
407
408 ret = _ldb_nss_fill_initgr(group,
409 limit,
410 start,
411 size,
412 groups,
413 errnop,
414 mem_res);
415
416 if (ret != NSS_STATUS_SUCCESS) {
417 goto done;
418 }
419
420 ret = NSS_STATUS_SUCCESS;
421
422done:
423 talloc_free(mem_res);
424 return ret;
425}
Note: See TracBrowser for help on using the repository browser.