• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.5.8/source4/lib/ldb/nssldb/
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}
430