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

Last change on this file was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

File size: 7.7 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, _ldb_nss_ctx->ldb,
63 &_ldb_nss_ctx->gr_res,
64 _ldb_nss_ctx->base,
65 LDB_SCOPE_SUBTREE,
66 _ldb_nss_gr_attrs,
67 _LDB_NSS_GRENT_FILTER);
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 TALLOC_CTX *ctx;
155 struct ldb_result *gr_res;
156 struct ldb_result *mem_res;
157
158 ret = _ldb_nss_init();
159 if (ret != NSS_STATUS_SUCCESS) {
160 return ret;
161 }
162
163 ctx = talloc_new(_ldb_nss_ctx->ldb);
164 if ( ! ctx) {
165 *errnop = errno = ENOMEM;
166 return NSS_STATUS_UNAVAIL;
167 }
168
169 /* search the entry */
170 ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, &gr_res,
171 _ldb_nss_ctx->base,
172 LDB_SCOPE_SUBTREE,
173 _ldb_nss_gr_attrs,
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;
179 goto done;
180 }
181
182 talloc_steal(ctx, gr_res);
183
184 /* if none found return */
185 if (gr_res->count == 0) {
186 *errnop = errno = ENOENT;
187 ret = NSS_STATUS_NOTFOUND;
188 goto done;
189 }
190
191 if (gr_res->count != 1) {
192 /* this is a fatal error */
193 *errnop = errno = ENOENT;
194 ret = NSS_STATUS_UNAVAIL;
195 goto done;
196 }
197
198 mem_res = talloc_zero(ctx, struct ldb_result);
199 if ( ! mem_res) {
200 errno = *errnop = ENOMEM;
201 ret = NSS_STATUS_UNAVAIL;
202 goto done;
203 }
204
205 ret = _ldb_nss_group_request(&mem_res,
206 gr_res->msgs[0]->dn,
207 _ldb_nss_mem_attrs,
208 "member");
209
210 if (ret != NSS_STATUS_SUCCESS) {
211 *errnop = errno;
212 goto done;
213 }
214
215 ret = _ldb_nss_fill_group(result_buf,
216 buffer,
217 buflen,
218 errnop,
219 gr_res->msgs[0],
220 mem_res);
221
222 if (ret != NSS_STATUS_SUCCESS) {
223 goto done;
224 }
225
226 ret = NSS_STATUS_SUCCESS;
227done:
228 talloc_free(ctx);
229 return ret;
230}
231
232NSS_STATUS _nss_ldb_getgrgid_r(gid_t gid, struct group *result_buf, char *buffer, size_t buflen, int *errnop)
233{
234 int ret;
235 TALLOC_CTX *ctx;
236 struct ldb_result *gr_res;
237 struct ldb_result *mem_res;
238
239 if (gid == 0) { /* we don't serve root gid by policy */
240 *errnop = errno = ENOENT;
241 return NSS_STATUS_NOTFOUND;
242 }
243
244 ret = _ldb_nss_init();
245 if (ret != NSS_STATUS_SUCCESS) {
246 return ret;
247 }
248
249 ctx = talloc_new(_ldb_nss_ctx->ldb);
250 if ( ! ctx) {
251 *errnop = errno = ENOMEM;
252 return NSS_STATUS_UNAVAIL;
253 }
254
255 /* search the entry */
256 ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, &gr_res,
257 _ldb_nss_ctx->base,
258 LDB_SCOPE_SUBTREE,
259 _ldb_nss_gr_attrs,
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;
265 goto done;
266 }
267
268 talloc_steal(ctx, gr_res);
269
270 /* if none found return */
271 if (gr_res->count == 0) {
272 *errnop = errno = ENOENT;
273 ret = NSS_STATUS_NOTFOUND;
274 goto done;
275 }
276
277 if (gr_res->count != 1) {
278 /* this is a fatal error */
279 *errnop = errno = ENOENT;
280 ret = NSS_STATUS_UNAVAIL;
281 goto done;
282 }
283
284 mem_res = talloc_zero(ctx, struct ldb_result);
285 if ( ! mem_res) {
286 errno = *errnop = ENOMEM;
287 ret = NSS_STATUS_UNAVAIL;
288 goto done;
289 }
290
291 ret = _ldb_nss_group_request(&mem_res,
292 gr_res->msgs[0]->dn,
293 _ldb_nss_mem_attrs,
294 "member");
295
296 if (ret != NSS_STATUS_SUCCESS) {
297 *errnop = errno;
298 goto done;
299 }
300
301 ret = _ldb_nss_fill_group(result_buf,
302 buffer,
303 buflen,
304 errnop,
305 gr_res->msgs[0],
306 mem_res);
307
308 if (ret != NSS_STATUS_SUCCESS) {
309 goto done;
310 }
311
312 ret = NSS_STATUS_SUCCESS;
313done:
314 talloc_free(ctx);
315 return ret;
316}
317
318NSS_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)
319{
320 int ret;
321 const char * attrs[] = { "uidNumber", "gidNumber", NULL };
322 struct ldb_result *uid_res;
323 struct ldb_result *mem_res;
324
325 ret = _ldb_nss_init();
326 if (ret != NSS_STATUS_SUCCESS) {
327 return ret;
328 }
329
330 mem_res = talloc_zero(_ldb_nss_ctx, struct ldb_result);
331 if ( ! mem_res) {
332 errno = *errnop = ENOMEM;
333 return NSS_STATUS_UNAVAIL;
334 }
335
336 /* search the entry */
337 ret = ldb_search(_ldb_nss_ctx->ldb, _ldb_nss_ctx->ldb, &uid_res,
338 _ldb_nss_ctx->base,
339 LDB_SCOPE_SUBTREE,
340 attrs,
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;
346 goto done;
347 }
348
349 talloc_steal(mem_res, uid_res);
350
351 /* if none found return */
352 if (uid_res->count == 0) {
353 *errnop = errno = ENOENT;
354 ret = NSS_STATUS_NOTFOUND;
355 goto done;
356 }
357
358 if (uid_res->count != 1) {
359 /* this is a fatal error */
360 *errnop = errno = ENOENT;
361 ret = NSS_STATUS_UNAVAIL;
362 goto done;
363 }
364
365 ret = _ldb_nss_group_request(&mem_res,
366 uid_res->msgs[0]->dn,
367 attrs,
368 "memberOf");
369
370 if (ret != NSS_STATUS_SUCCESS) {
371 *errnop = errno;
372 goto done;
373 }
374
375 ret = _ldb_nss_fill_initgr(group,
376 limit,
377 start,
378 size,
379 groups,
380 errnop,
381 mem_res);
382
383 if (ret != NSS_STATUS_SUCCESS) {
384 goto done;
385 }
386
387 ret = NSS_STATUS_SUCCESS;
388
389done:
390 talloc_free(mem_res);
391 return ret;
392}
Note: See TracBrowser for help on using the repository browser.