~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/lib/ldb/nssldb/ldb-grp.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
22
extern struct _ldb_nss_context *_ldb_nss_ctx;
 
23
 
 
24
const char *_ldb_nss_gr_attrs[] = {
 
25
        "cn",
 
26
        "userPassword",
 
27
        "gidNumber",
 
28
        NULL
 
29
};
 
30
 
 
31
const 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
 
 
47
NSS_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
 
 
75
NSS_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
 
 
93
NSS_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
 
 
151
NSS_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;
 
227
done:
 
228
        talloc_free(ctx);
 
229
        return ret;
 
230
}
 
231
 
 
232
NSS_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;
 
313
done:
 
314
        talloc_free(ctx);
 
315
        return ret;
 
316
}
 
317
 
 
318
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)
 
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
 
 
389
done:
 
390
        talloc_free(mem_res);
 
391
        return ret;
 
392
}