• 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/nsswitch/
1/*
2   Unix SMB/CIFS implementation.
3
4   NetBSD loadable authentication module, providing identification
5   routines against Samba winbind/Windows NT Domain
6
7   Copyright (C) Luke Mewburn 2004-2005
8
9   This library is free software; you can redistribute it and/or
10   modify it under the terms of the GNU Lesser General Public
11   License as published by the Free Software Foundation; either
12   version 3 of the License, or (at your option) any later version.
13
14   This library is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   Library General Public License for more details.
18
19   You should have received a copy of the GNU Lesser General Public
20   License along with this library; if not, see <http://www.gnu.org/licenses/>.
21*/
22
23
24#include "winbind_client.h"
25
26#include <sys/param.h>
27#include <stdarg.h>
28#include <syslog.h>
29
30	/* dynamic nsswitch with "new" getpw* nsdispatch API available */
31#if defined(NSS_MODULE_INTERFACE_VERSION) && defined(HAVE_GETPWENT_R)
32
33/*
34	group functions
35	---------------
36*/
37
38static struct group	_winbind_group;
39static char		_winbind_groupbuf[1024];
40
41/*
42 * We need a proper prototype for this :-)
43 */
44
45NSS_STATUS _nss_winbind_setpwent(void);
46NSS_STATUS _nss_winbind_endpwent(void);
47NSS_STATUS _nss_winbind_getpwent_r(struct passwd *result, char *buffer,
48				   size_t buflen, int *errnop);
49NSS_STATUS _nss_winbind_getpwuid_r(uid_t uid, struct passwd *result,
50				   char *buffer, size_t buflen, int *errnop);
51NSS_STATUS _nss_winbind_getpwnam_r(const char *name, struct passwd *result,
52				   char *buffer, size_t buflen, int *errnop);
53NSS_STATUS _nss_winbind_setgrent(void);
54NSS_STATUS _nss_winbind_endgrent(void);
55NSS_STATUS _nss_winbind_getgrent_r(struct group *result, char *buffer,
56				   size_t buflen, int *errnop);
57NSS_STATUS _nss_winbind_getgrlst_r(struct group *result, char *buffer,
58				   size_t buflen, int *errnop);
59NSS_STATUS _nss_winbind_getgrnam_r(const char *name, struct group *result,
60				   char *buffer, size_t buflen, int *errnop);
61NSS_STATUS _nss_winbind_getgrgid_r(gid_t gid, struct group *result, char *buffer,
62				   size_t buflen, int *errnop);
63NSS_STATUS _nss_winbind_initgroups_dyn(char *user, gid_t group, long int *start,
64				       long int *size, gid_t **groups,
65				       long int limit, int *errnop);
66NSS_STATUS _nss_winbind_getusersids(const char *user_sid, char **group_sids,
67				    int *num_groups, char *buffer, size_t buf_size,
68				    int *errnop);
69NSS_STATUS _nss_winbind_nametosid(const char *name, char **sid, char *buffer,
70				  size_t buflen, int *errnop);
71NSS_STATUS _nss_winbind_sidtoname(const char *sid, char **name, char *buffer,
72				  size_t buflen, int *errnop);
73NSS_STATUS _nss_winbind_sidtouid(const char *sid, uid_t *uid, int *errnop);
74NSS_STATUS _nss_winbind_sidtogid(const char *sid, gid_t *gid, int *errnop);
75NSS_STATUS _nss_winbind_uidtosid(uid_t uid, char **sid, char *buffer,
76				 size_t buflen, int *errnop);
77NSS_STATUS _nss_winbind_gidtosid(gid_t gid, char **sid, char *buffer,
78				 size_t buflen, int *errnop);
79
80int
81netbsdwinbind_endgrent(void *nsrv, void *nscb, va_list ap)
82{
83	int	rv;
84
85	rv = _nss_winbind_endgrent();
86	return rv;
87}
88
89int
90netbsdwinbind_setgrent(void *nsrv, void *nscb, va_list ap)
91{
92	int	rv;
93
94	rv = _nss_winbind_setgrent();
95	return rv;
96}
97
98int
99netbsdwinbind_getgrent(void *nsrv, void *nscb, va_list ap)
100{
101	struct group   **retval	= va_arg(ap, struct group **);
102
103	int	rv, rerrno;
104
105	*retval = NULL;
106	rv = _nss_winbind_getgrent_r(&_winbind_group,
107	    _winbind_groupbuf, sizeof(_winbind_groupbuf), &rerrno);
108	if (rv == NS_SUCCESS)
109		*retval = &_winbind_group;
110	return rv;
111}
112
113int
114netbsdwinbind_getgrent_r(void *nsrv, void *nscb, va_list ap)
115{
116	int		*retval = va_arg(ap, int *);
117	struct group	*grp	= va_arg(ap, struct group *);
118	char		*buffer	= va_arg(ap, char *);
119	size_t		 buflen	= va_arg(ap, size_t);
120	struct group   **result	= va_arg(ap, struct group **);
121
122	int	rv, rerrno;
123
124	*result = NULL;
125	rerrno = 0;
126
127	rv = _nss_winbind_getgrent_r(grp, buffer, buflen, &rerrno);
128	if (rv == NS_SUCCESS)
129		*result = grp;
130	else
131		*retval = rerrno;
132	return rv;
133}
134
135int
136netbsdwinbind_getgrgid(void *nsrv, void *nscb, va_list ap)
137{
138	struct group   **retval	= va_arg(ap, struct group **);
139	gid_t		 gid	= va_arg(ap, gid_t);
140
141	int	rv, rerrno;
142
143	*retval = NULL;
144	rv = _nss_winbind_getgrgid_r(gid, &_winbind_group,
145	    _winbind_groupbuf, sizeof(_winbind_groupbuf), &rerrno);
146	if (rv == NS_SUCCESS)
147		*retval = &_winbind_group;
148	return rv;
149}
150
151int
152netbsdwinbind_getgrgid_r(void *nsrv, void *nscb, va_list ap)
153{
154	int		*retval = va_arg(ap, int *);
155	gid_t		 gid	= va_arg(ap, gid_t);
156	struct group	*grp	= va_arg(ap, struct group *);
157	char		*buffer	= va_arg(ap, char *);
158	size_t		 buflen	= va_arg(ap, size_t);
159	struct group   **result	= va_arg(ap, struct group **);
160
161	int	rv, rerrno;
162
163	*result = NULL;
164	rerrno = 0;
165
166	rv = _nss_winbind_getgrgid_r(gid, grp, buffer, buflen, &rerrno);
167	if (rv == NS_SUCCESS)
168		*result = grp;
169	else
170		*retval = rerrno;
171	return rv;
172}
173
174int
175netbsdwinbind_getgrnam(void *nsrv, void *nscb, va_list ap)
176{
177	struct group   **retval	= va_arg(ap, struct group **);
178	const char	*name	= va_arg(ap, const char *);
179
180	int	rv, rerrno;
181
182	*retval = NULL;
183	rv = _nss_winbind_getgrnam_r(name, &_winbind_group,
184	    _winbind_groupbuf, sizeof(_winbind_groupbuf), &rerrno);
185	if (rv == NS_SUCCESS)
186		*retval = &_winbind_group;
187	return rv;
188}
189
190int
191netbsdwinbind_getgrnam_r(void *nsrv, void *nscb, va_list ap)
192{
193	int		*retval = va_arg(ap, int *);
194	const char	*name	= va_arg(ap, const char *);
195	struct group	*grp	= va_arg(ap, struct group *);
196	char		*buffer	= va_arg(ap, char *);
197	size_t		 buflen	= va_arg(ap, size_t);
198	struct group   **result	= va_arg(ap, struct group **);
199
200	int	rv, rerrno;
201
202	*result = NULL;
203	rerrno = 0;
204
205	rv = _nss_winbind_getgrnam_r(name, grp, buffer, buflen, &rerrno);
206	if (rv == NS_SUCCESS)
207		*result = grp;
208	else
209		*retval = rerrno;
210	return rv;
211}
212
213int
214netbsdwinbind_getgroupmembership(void *nsrv, void *nscb, va_list ap)
215{
216	int		*result	= va_arg(ap, int *);
217	const char 	*uname	= va_arg(ap, const char *);
218	gid_t		*groups	= va_arg(ap, gid_t *);
219	int		 maxgrp	= va_arg(ap, int);
220	int		*groupc	= va_arg(ap, int *);
221
222	struct winbindd_request request;
223	struct winbindd_response response;
224	gid_t	*wblistv;
225	int	wblistc, i, isdup, dupc;
226
227	ZERO_STRUCT(request);
228	ZERO_STRUCT(response);
229	strncpy(request.data.username, uname,
230				sizeof(request.data.username) - 1);
231	i = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response);
232	if (i != NSS_STATUS_SUCCESS)
233		return NS_NOTFOUND;
234	wblistv = (gid_t *)response.extra_data.data;
235	wblistc = response.data.num_entries;
236
237	for (i = 0; i < wblistc; i++) {			/* add winbind gids */
238		isdup = 0;				/* skip duplicates */
239		for (dupc = 0; dupc < MIN(maxgrp, *groupc); dupc++) {
240			if (groups[dupc] == wblistv[i]) {
241				isdup = 1;
242				break;
243			}
244		}
245		if (isdup)
246			continue;
247		if (*groupc < maxgrp)			/* add this gid */
248			groups[*groupc] = wblistv[i];
249		else
250			*result = -1;
251		(*groupc)++;
252	}
253	SAFE_FREE(wblistv);
254	return NS_NOTFOUND;
255}
256
257
258/*
259	passwd functions
260	----------------
261*/
262
263static struct passwd	_winbind_passwd;
264static char		_winbind_passwdbuf[1024];
265
266int
267netbsdwinbind_endpwent(void *nsrv, void *nscb, va_list ap)
268{
269	int	rv;
270
271	rv = _nss_winbind_endpwent();
272	return rv;
273}
274
275int
276netbsdwinbind_setpwent(void *nsrv, void *nscb, va_list ap)
277{
278	int	rv;
279
280	rv = _nss_winbind_setpwent();
281	return rv;
282}
283
284int
285netbsdwinbind_getpwent(void *nsrv, void *nscb, va_list ap)
286{
287	struct passwd  **retval	= va_arg(ap, struct passwd **);
288
289	int	rv, rerrno;
290
291	*retval = NULL;
292
293	rv = _nss_winbind_getpwent_r(&_winbind_passwd,
294	    _winbind_passwdbuf, sizeof(_winbind_passwdbuf), &rerrno);
295	if (rv == NS_SUCCESS)
296		*retval = &_winbind_passwd;
297	return rv;
298}
299
300int
301netbsdwinbind_getpwent_r(void *nsrv, void *nscb, va_list ap)
302{
303	int		*retval = va_arg(ap, int *);
304	struct passwd	*pw	= va_arg(ap, struct passwd *);
305	char		*buffer	= va_arg(ap, char *);
306	size_t		 buflen	= va_arg(ap, size_t);
307	struct passwd  **result	= va_arg(ap, struct passwd **);
308
309	int	rv, rerrno;
310
311	*result = NULL;
312	rerrno = 0;
313
314	rv = _nss_winbind_getpwent_r(pw, buffer, buflen, &rerrno);
315	if (rv == NS_SUCCESS)
316		*result = pw;
317	else
318		*retval = rerrno;
319	return rv;
320}
321
322int
323netbsdwinbind_getpwnam(void *nsrv, void *nscb, va_list ap)
324{
325	struct passwd  **retval	= va_arg(ap, struct passwd **);
326	const char	*name	= va_arg(ap, const char *);
327
328	int	rv, rerrno;
329
330	*retval = NULL;
331	rv = _nss_winbind_getpwnam_r(name, &_winbind_passwd,
332	    _winbind_passwdbuf, sizeof(_winbind_passwdbuf), &rerrno);
333	if (rv == NS_SUCCESS)
334		*retval = &_winbind_passwd;
335	return rv;
336}
337
338int
339netbsdwinbind_getpwnam_r(void *nsrv, void *nscb, va_list ap)
340{
341	int		*retval = va_arg(ap, int *);
342	const char	*name	= va_arg(ap, const char *);
343	struct passwd	*pw	= va_arg(ap, struct passwd *);
344	char		*buffer	= va_arg(ap, char *);
345	size_t		 buflen	= va_arg(ap, size_t);
346	struct passwd  **result	= va_arg(ap, struct passwd **);
347
348	int	rv, rerrno;
349
350	*result = NULL;
351	rerrno = 0;
352
353	rv = _nss_winbind_getpwnam_r(name, pw, buffer, buflen, &rerrno);
354	if (rv == NS_SUCCESS)
355		*result = pw;
356	else
357		*retval = rerrno;
358	return rv;
359}
360
361int
362netbsdwinbind_getpwuid(void *nsrv, void *nscb, va_list ap)
363{
364	struct passwd  **retval	= va_arg(ap, struct passwd **);
365	uid_t		 uid	= va_arg(ap, uid_t);
366
367	int	rv, rerrno;
368
369	*retval = NULL;
370	rv = _nss_winbind_getpwuid_r(uid, &_winbind_passwd,
371	    _winbind_passwdbuf, sizeof(_winbind_passwdbuf), &rerrno);
372	if (rv == NS_SUCCESS)
373		*retval = &_winbind_passwd;
374	return rv;
375}
376
377int
378netbsdwinbind_getpwuid_r(void *nsrv, void *nscb, va_list ap)
379{
380	int		*retval = va_arg(ap, int *);
381	uid_t		 uid	= va_arg(ap, uid_t);
382	struct passwd	*pw	= va_arg(ap, struct passwd *);
383	char		*buffer	= va_arg(ap, char *);
384	size_t		 buflen	= va_arg(ap, size_t);
385	struct passwd  **result	= va_arg(ap, struct passwd **);
386
387	int	rv, rerrno;
388
389	*result = NULL;
390	rerrno = 0;
391
392	rv = _nss_winbind_getpwuid_r(uid, pw, buffer, buflen, &rerrno);
393	if (rv == NS_SUCCESS)
394		*result = pw;
395	else
396		*retval = rerrno;
397	return rv;
398}
399
400
401/*
402	nsswitch module setup
403	---------------------
404*/
405
406
407static ns_mtab winbind_methods[] = {
408
409{ NSDB_GROUP, "endgrent",	netbsdwinbind_endgrent,		NULL },
410{ NSDB_GROUP, "getgrent",	netbsdwinbind_getgrent,		NULL },
411{ NSDB_GROUP, "getgrent_r",	netbsdwinbind_getgrent_r,	NULL },
412{ NSDB_GROUP, "getgrgid",	netbsdwinbind_getgrgid,		NULL },
413{ NSDB_GROUP, "getgrgid_r",	netbsdwinbind_getgrgid_r,	NULL },
414{ NSDB_GROUP, "getgrnam",	netbsdwinbind_getgrnam,		NULL },
415{ NSDB_GROUP, "getgrnam_r",	netbsdwinbind_getgrnam_r,	NULL },
416{ NSDB_GROUP, "setgrent",	netbsdwinbind_setgrent,		NULL },
417{ NSDB_GROUP, "setgroupent",	netbsdwinbind_setgrent,		NULL },
418{ NSDB_GROUP, "getgroupmembership", netbsdwinbind_getgroupmembership, NULL },
419
420{ NSDB_PASSWD, "endpwent",	netbsdwinbind_endpwent,		NULL },
421{ NSDB_PASSWD, "getpwent",	netbsdwinbind_getpwent,		NULL },
422{ NSDB_PASSWD, "getpwent_r",	netbsdwinbind_getpwent_r,	NULL },
423{ NSDB_PASSWD, "getpwnam",	netbsdwinbind_getpwnam,		NULL },
424{ NSDB_PASSWD, "getpwnam_r",	netbsdwinbind_getpwnam_r,	NULL },
425{ NSDB_PASSWD, "getpwuid",	netbsdwinbind_getpwuid,		NULL },
426{ NSDB_PASSWD, "getpwuid_r",	netbsdwinbind_getpwuid_r,	NULL },
427{ NSDB_PASSWD, "setpassent",	netbsdwinbind_setpwent,		NULL },
428{ NSDB_PASSWD, "setpwent",	netbsdwinbind_setpwent,		NULL },
429
430};
431
432ns_mtab *
433nss_module_register(const char *source, unsigned int *mtabsize,
434    nss_module_unregister_fn *unreg)
435{
436        *mtabsize = sizeof(winbind_methods)/sizeof(winbind_methods[0]);
437        *unreg = NULL;
438        return (winbind_methods);
439}
440
441#endif /* NSS_MODULE_INTERFACE_VERSION && HAVE_GETPWENT_R */
442