source: vendor/current/lib/ldb/nssldb/ldb-grp.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

File size: 8.4 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->ldb,
64 &_ldb_nss_ctx->gr_res,
65 _ldb_nss_ctx->base,
66 LDB_SCOPE_SUBTREE,
67 _ldb_nss_gr_attrs,
68 _LDB_NSS_GRENT_FILTER);
69 if (ret != LDB_SUCCESS) {
70 return NSS_STATUS_UNAVAIL;
71 }
72
73 return NSS_STATUS_SUCCESS;
74}
75
76NSS_STATUS _nss_ldb_endgrent(void)
77{
78 int ret;
79
80 ret = _ldb_nss_init();
81 if (ret != NSS_STATUS_SUCCESS) {
82 return ret;
83 }
84
85 _ldb_nss_ctx->gr_cur = 0;
86 if (_ldb_nss_ctx->gr_res) {
87 talloc_free(_ldb_nss_ctx->gr_res);
88 _ldb_nss_ctx->gr_res = NULL;
89 }
90
91 return NSS_STATUS_SUCCESS;
92}
93
94NSS_STATUS _nss_ldb_getgrent_r(struct group *result_buf, char *buffer, size_t buflen, int *errnop)
95{
96 int ret;
97 struct ldb_result *res;
98
99 ret = _ldb_nss_init();
100 if (ret != NSS_STATUS_SUCCESS) {
101 return ret;
102 }
103
104 *errnop = 0;
105
106 if (_ldb_nss_ctx->gr_cur >= _ldb_nss_ctx->gr_res->count) {
107 /* already returned all entries */
108 return NSS_STATUS_NOTFOUND;
109 }
110
111 res = talloc_zero(_ldb_nss_ctx->gr_res, struct ldb_result);
112 if ( ! res) {
113 errno = *errnop = ENOMEM;
114 _ldb_nss_ctx->gr_cur++; /* skip this entry */
115 return NSS_STATUS_UNAVAIL;
116 }
117
118 ret = _ldb_nss_group_request(&res,
119 _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur]->dn,
120 _ldb_nss_mem_attrs,
121 "member");
122
123 if (ret != NSS_STATUS_SUCCESS) {
124 *errnop = errno;
125 talloc_free(res);
126 _ldb_nss_ctx->gr_cur++; /* skip this entry */
127 return ret;
128 }
129
130 ret = _ldb_nss_fill_group(result_buf,
131 buffer,
132 buflen,
133 errnop,
134 _ldb_nss_ctx->gr_res->msgs[_ldb_nss_ctx->gr_cur],
135 res);
136
137 talloc_free(res);
138
139 if (ret != NSS_STATUS_SUCCESS) {
140 if (ret != NSS_STATUS_TRYAGAIN) {
141 _ldb_nss_ctx->gr_cur++; /* skip this entry */
142 }
143 return ret;
144 }
145
146 /* this entry is ok, increment counter to nex entry */
147 _ldb_nss_ctx->gr_cur++;
148
149 return NSS_STATUS_SUCCESS;
150}
151
152NSS_STATUS _nss_ldb_getgrnam_r(const char *name, struct group *result_buf, char *buffer, size_t buflen, int *errnop)
153{
154 int ret;
155 char *filter;
156 TALLOC_CTX *ctx;
157 struct ldb_result *gr_res;
158 struct ldb_result *mem_res;
159
160 ret = _ldb_nss_init();
161 if (ret != NSS_STATUS_SUCCESS) {
162 return ret;
163 }
164
165 ctx = talloc_new(_ldb_nss_ctx->ldb);
166 if ( ! ctx) {
167 *errnop = errno = ENOMEM;
168 return NSS_STATUS_UNAVAIL;
169 }
170
171 /* build the filter for this uid */
172 filter = talloc_asprintf(ctx, _LDB_NSS_GRNAM_FILTER, name);
173 if (filter == NULL) {
174 /* this is a fatal error */
175 *errnop = errno = ENOMEM;
176 ret = NSS_STATUS_UNAVAIL;
177 goto done;
178 }
179
180 /* search the entry */
181 ret = ldb_search(_ldb_nss_ctx->ldb,
182 _ldb_nss_ctx->ldb,
183 &gr_res,
184 _ldb_nss_ctx->base,
185 LDB_SCOPE_SUBTREE,
186 _ldb_nss_gr_attrs,
187 filter);
188 if (ret != LDB_SUCCESS) {
189 /* this is a fatal error */
190 *errnop = errno = ENOENT;
191 ret = NSS_STATUS_UNAVAIL;
192 goto done;
193 }
194
195 talloc_steal(ctx, gr_res);
196
197 /* if none found return */
198 if (gr_res->count == 0) {
199 *errnop = errno = ENOENT;
200 ret = NSS_STATUS_NOTFOUND;
201 goto done;
202 }
203
204 if (gr_res->count != 1) {
205 /* this is a fatal error */
206 *errnop = errno = ENOENT;
207 ret = NSS_STATUS_UNAVAIL;
208 goto done;
209 }
210
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;
216 }
217
218 ret = _ldb_nss_group_request(&mem_res,
219 gr_res->msgs[0]->dn,
220 _ldb_nss_mem_attrs,
221 "member");
222
223 if (ret != NSS_STATUS_SUCCESS) {
224 *errnop = errno;
225 goto done;
226 }
227
228 ret = _ldb_nss_fill_group(result_buf,
229 buffer,
230 buflen,
231 errnop,
232 gr_res->msgs[0],
233 mem_res);
234
235 if (ret != NSS_STATUS_SUCCESS) {
236 goto done;
237 }
238
239 ret = NSS_STATUS_SUCCESS;
240done:
241 talloc_free(ctx);
242 return ret;
243}
244
245NSS_STATUS _nss_ldb_getgrgid_r(gid_t gid, struct group *result_buf, char *buffer, size_t buflen, int *errnop)
246{
247 int ret;
248 char *filter;
249 TALLOC_CTX *ctx;
250 struct ldb_result *gr_res;
251 struct ldb_result *mem_res;
252
253 if (gid == 0) { /* we don't serve root gid by policy */
254 *errnop = errno = ENOENT;
255 return NSS_STATUS_NOTFOUND;
256 }
257
258 ret = _ldb_nss_init();
259 if (ret != NSS_STATUS_SUCCESS) {
260 return ret;
261 }
262
263 ctx = talloc_new(_ldb_nss_ctx->ldb);
264 if ( ! ctx) {
265 *errnop = errno = ENOMEM;
266 return NSS_STATUS_UNAVAIL;
267 }
268
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;
276 }
277
278 /* search the entry */
279 ret = ldb_search(_ldb_nss_ctx->ldb,
280 _ldb_nss_ctx->ldb,
281 &gr_res,
282 _ldb_nss_ctx->base,
283 LDB_SCOPE_SUBTREE,
284 _ldb_nss_gr_attrs,
285 filter);
286 if (ret != LDB_SUCCESS) {
287 /* this is a fatal error */
288 *errnop = errno = ENOENT;
289 ret = NSS_STATUS_UNAVAIL;
290 goto done;
291 }
292
293 talloc_steal(ctx, gr_res);
294
295 /* if none found return */
296 if (gr_res->count == 0) {
297 *errnop = errno = ENOENT;
298 ret = NSS_STATUS_NOTFOUND;
299 goto done;
300 }
301
302 if (gr_res->count != 1) {
303 /* this is a fatal error */
304 *errnop = errno = ENOENT;
305 ret = NSS_STATUS_UNAVAIL;
306 goto done;
307 }
308
309 mem_res = talloc_zero(ctx, struct ldb_result);
310 if ( ! mem_res) {
311 errno = *errnop = ENOMEM;
312 ret = NSS_STATUS_UNAVAIL;
313 goto done;
314 }
315
316 ret = _ldb_nss_group_request(&mem_res,
317 gr_res->msgs[0]->dn,
318 _ldb_nss_mem_attrs,
319 "member");
320
321 if (ret != NSS_STATUS_SUCCESS) {
322 *errnop = errno;
323 goto done;
324 }
325
326 ret = _ldb_nss_fill_group(result_buf,
327 buffer,
328 buflen,
329 errnop,
330 gr_res->msgs[0],
331 mem_res);
332
333 if (ret != NSS_STATUS_SUCCESS) {
334 goto done;
335 }
336
337 ret = NSS_STATUS_SUCCESS;
338done:
339 talloc_free(ctx);
340 return ret;
341}
342
343NSS_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{
345 int ret;
346 char *filter;
347 const char * attrs[] = { "uidNumber", "gidNumber", NULL };
348 struct ldb_result *uid_res;
349 struct ldb_result *mem_res;
350
351 ret = _ldb_nss_init();
352 if (ret != NSS_STATUS_SUCCESS) {
353 return ret;
354 }
355
356 mem_res = talloc_zero(_ldb_nss_ctx, struct ldb_result);
357 if ( ! mem_res) {
358 errno = *errnop = ENOMEM;
359 return NSS_STATUS_UNAVAIL;
360 }
361
362 /* build the filter for this name */
363 filter = talloc_asprintf(mem_res, _LDB_NSS_PWNAM_FILTER, user);
364 if (filter == NULL) {
365 /* this is a fatal error */
366 *errnop = errno = ENOENT;
367 ret = NSS_STATUS_UNAVAIL;
368 goto done;
369 }
370
371 /* search the entry */
372 ret = ldb_search(_ldb_nss_ctx->ldb,
373 _ldb_nss_ctx->ldb,
374 &uid_res,
375 _ldb_nss_ctx->base,
376 LDB_SCOPE_SUBTREE,
377 attrs,
378 filter);
379 if (ret != LDB_SUCCESS) {
380 /* this is a fatal error */
381 *errnop = errno = ENOENT;
382 ret = NSS_STATUS_UNAVAIL;
383 goto done;
384 }
385
386 talloc_steal(mem_res, uid_res);
387
388 /* if none found return */
389 if (uid_res->count == 0) {
390 *errnop = errno = ENOENT;
391 ret = NSS_STATUS_NOTFOUND;
392 goto done;
393 }
394
395 if (uid_res->count != 1) {
396 /* this is a fatal error */
397 *errnop = errno = ENOENT;
398 ret = NSS_STATUS_UNAVAIL;
399 goto done;
400 }
401
402 ret = _ldb_nss_group_request(&mem_res,
403 uid_res->msgs[0]->dn,
404 attrs,
405 "memberOf");
406
407 if (ret != NSS_STATUS_SUCCESS) {
408 *errnop = errno;
409 goto done;
410 }
411
412 ret = _ldb_nss_fill_initgr(group,
413 limit,
414 start,
415 size,
416 groups,
417 errnop,
418 mem_res);
419
420 if (ret != NSS_STATUS_SUCCESS) {
421 goto done;
422 }
423
424 ret = NSS_STATUS_SUCCESS;
425
426done:
427 talloc_free(mem_res);
428 return ret;
429}
Note: See TracBrowser for help on using the repository browser.