xref: /dflybsd-src/lib/libc/net/nss_compat.c (revision a1ff66cb7764cf805b759f2c7bfc51a8a11cf1aa)
1ed5d5720SPeter Avalos /*-
2ed5d5720SPeter Avalos  * Copyright (c) 2003 Networks Associates Technology, Inc.
3ed5d5720SPeter Avalos  * All rights reserved.
4ed5d5720SPeter Avalos  *
5ed5d5720SPeter Avalos  * This software was developed for the FreeBSD Project by
6ed5d5720SPeter Avalos  * Jacques A. Vidrine, Safeport Network Services, and Network
7ed5d5720SPeter Avalos  * Associates Laboratories, the Security Research Division of Network
8ed5d5720SPeter Avalos  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035
9ed5d5720SPeter Avalos  * ("CBOSS"), as part of the DARPA CHATS research program.
10ed5d5720SPeter Avalos  *
11ed5d5720SPeter Avalos  * Redistribution and use in source and binary forms, with or without
12ed5d5720SPeter Avalos  * modification, are permitted provided that the following conditions
13ed5d5720SPeter Avalos  * are met:
14ed5d5720SPeter Avalos  * 1. Redistributions of source code must retain the above copyright
15ed5d5720SPeter Avalos  *    notice, this list of conditions and the following disclaimer.
16ed5d5720SPeter Avalos  * 2. Redistributions in binary form must reproduce the above copyright
17ed5d5720SPeter Avalos  *    notice, this list of conditions and the following disclaimer in the
18ed5d5720SPeter Avalos  *    documentation and/or other materials provided with the distribution.
19ed5d5720SPeter Avalos  *
20ed5d5720SPeter Avalos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21ed5d5720SPeter Avalos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22ed5d5720SPeter Avalos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23ed5d5720SPeter Avalos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24ed5d5720SPeter Avalos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25ed5d5720SPeter Avalos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26ed5d5720SPeter Avalos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27ed5d5720SPeter Avalos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28ed5d5720SPeter Avalos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29ed5d5720SPeter Avalos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30ed5d5720SPeter Avalos  * SUCH DAMAGE.
31ed5d5720SPeter Avalos  *
32ed5d5720SPeter Avalos  * Compatibility shims for the GNU C Library-style nsswitch interface.
33ed5d5720SPeter Avalos  *
34ed5d5720SPeter Avalos  * $FreeBSD: src/lib/libc/net/nss_compat.c,v 1.3 2004/03/30 15:56:15 nectar Exp $
35ed5d5720SPeter Avalos  */
36ed5d5720SPeter Avalos 
37ed5d5720SPeter Avalos #include "namespace.h"
38ed5d5720SPeter Avalos #include <sys/param.h>
39ed5d5720SPeter Avalos #include <errno.h>
40ed5d5720SPeter Avalos #include <nss.h>
41ed5d5720SPeter Avalos #include <pthread.h>
42ed5d5720SPeter Avalos #include <pthread_np.h>
43ed5d5720SPeter Avalos #include "un-namespace.h"
44ed5d5720SPeter Avalos #include "libc_private.h"
45ed5d5720SPeter Avalos 
46ed5d5720SPeter Avalos 
47ed5d5720SPeter Avalos struct group;
48ed5d5720SPeter Avalos struct passwd;
49ed5d5720SPeter Avalos 
50ed5d5720SPeter Avalos static int	terminator;
51ed5d5720SPeter Avalos 
52ed5d5720SPeter Avalos #define DECLARE_TERMINATOR(x)					\
53ed5d5720SPeter Avalos static pthread_key_t	 _term_key_##x;				\
54ed5d5720SPeter Avalos static void							\
55ed5d5720SPeter Avalos _term_create_##x(void)						\
56ed5d5720SPeter Avalos {								\
57ed5d5720SPeter Avalos 	_pthread_key_create(&_term_key_##x, NULL);		\
58ed5d5720SPeter Avalos }								\
59ed5d5720SPeter Avalos static void		*_term_main_##x;			\
60ed5d5720SPeter Avalos static pthread_once_t	 _term_once_##x = PTHREAD_ONCE_INIT
61ed5d5720SPeter Avalos 
62ed5d5720SPeter Avalos #define SET_TERMINATOR(x, y)						\
63ed5d5720SPeter Avalos do {									\
64ed5d5720SPeter Avalos 	if (!__isthreaded || _pthread_main_np())			\
65ed5d5720SPeter Avalos 		_term_main_##x = (y);					\
66ed5d5720SPeter Avalos 	else {								\
67ed5d5720SPeter Avalos 		_pthread_once(&_term_once_##x, _term_create_##x);	\
68ed5d5720SPeter Avalos 		_pthread_setspecific(_term_key_##x, y);			\
69ed5d5720SPeter Avalos 	}								\
70ed5d5720SPeter Avalos } while (0)
71ed5d5720SPeter Avalos 
72ed5d5720SPeter Avalos #define CHECK_TERMINATOR(x)					\
73ed5d5720SPeter Avalos (!__isthreaded || _pthread_main_np() ?				\
74ed5d5720SPeter Avalos     (_term_main_##x) :						\
75ed5d5720SPeter Avalos     (_pthread_once(&_term_once_##x, _term_create_##x),		\
76ed5d5720SPeter Avalos     _pthread_getspecific(_term_key_##x)))
77ed5d5720SPeter Avalos 
78ed5d5720SPeter Avalos 
79ed5d5720SPeter Avalos 
80ed5d5720SPeter Avalos DECLARE_TERMINATOR(group);
81ed5d5720SPeter Avalos 
82*a1ff66cbSSascha Wildner int __nss_compat_getgrnam_r(void *, void *, va_list);
83*a1ff66cbSSascha Wildner int __nss_compat_getgrgid_r(void *, void *, va_list);
84*a1ff66cbSSascha Wildner int __nss_compat_getgrent_r(void *, void *, va_list);
85*a1ff66cbSSascha Wildner int __nss_compat_setgrent(void *, void *, va_list);
86*a1ff66cbSSascha Wildner int __nss_compat_endgrent(void *, void *, va_list);
87ed5d5720SPeter Avalos 
88ed5d5720SPeter Avalos int
__nss_compat_getgrnam_r(void * retval,void * mdata,va_list ap)89ed5d5720SPeter Avalos __nss_compat_getgrnam_r(void *retval, void *mdata, va_list ap)
90ed5d5720SPeter Avalos {
91ed5d5720SPeter Avalos 	int (*fn)(const char *, struct group *, char *, size_t, int *);
92ed5d5720SPeter Avalos 	const char	*name;
93ed5d5720SPeter Avalos 	struct group	*grp;
94ed5d5720SPeter Avalos 	char		*buffer;
95ed5d5720SPeter Avalos 	int		*errnop;
96ed5d5720SPeter Avalos 	size_t		 bufsize;
97ed5d5720SPeter Avalos 	enum nss_status	 status;
98ed5d5720SPeter Avalos 
99ed5d5720SPeter Avalos 	fn = mdata;
100ed5d5720SPeter Avalos 	name = va_arg(ap, const char *);
101ed5d5720SPeter Avalos 	grp = va_arg(ap, struct group *);
102ed5d5720SPeter Avalos 	buffer = va_arg(ap, char *);
103ed5d5720SPeter Avalos 	bufsize = va_arg(ap, size_t);
104ed5d5720SPeter Avalos 	errnop = va_arg(ap, int *);
105ed5d5720SPeter Avalos 	status = fn(name, grp, buffer, bufsize, errnop);
106ed5d5720SPeter Avalos 	status = __nss_compat_result(status, *errnop);
107ed5d5720SPeter Avalos 	if (status == NS_SUCCESS)
108ed5d5720SPeter Avalos 		*(struct group **)retval = grp;
109ed5d5720SPeter Avalos 	return (status);
110ed5d5720SPeter Avalos }
111ed5d5720SPeter Avalos 
112ed5d5720SPeter Avalos 
113ed5d5720SPeter Avalos int
__nss_compat_getgrgid_r(void * retval,void * mdata,va_list ap)114ed5d5720SPeter Avalos __nss_compat_getgrgid_r(void *retval, void *mdata, va_list ap)
115ed5d5720SPeter Avalos {
116ed5d5720SPeter Avalos 	int (*fn)(gid_t, struct group *, char *, size_t, int *);
117ed5d5720SPeter Avalos 	gid_t		 gid;
118ed5d5720SPeter Avalos 	struct group	*grp;
119ed5d5720SPeter Avalos 	char		*buffer;
120ed5d5720SPeter Avalos 	int		*errnop;
121ed5d5720SPeter Avalos 	size_t		 bufsize;
122ed5d5720SPeter Avalos 	enum nss_status	 status;
123ed5d5720SPeter Avalos 
124ed5d5720SPeter Avalos 	fn = mdata;
125ed5d5720SPeter Avalos 	gid = va_arg(ap, gid_t);
126ed5d5720SPeter Avalos 	grp = va_arg(ap, struct group *);
127ed5d5720SPeter Avalos 	buffer = va_arg(ap, char *);
128ed5d5720SPeter Avalos 	bufsize = va_arg(ap, size_t);
129ed5d5720SPeter Avalos 	errnop = va_arg(ap, int *);
130ed5d5720SPeter Avalos 	status = fn(gid, grp, buffer, bufsize, errnop);
131ed5d5720SPeter Avalos 	status = __nss_compat_result(status, *errnop);
132ed5d5720SPeter Avalos 	if (status == NS_SUCCESS)
133ed5d5720SPeter Avalos 		*(struct group **)retval = grp;
134ed5d5720SPeter Avalos 	return (status);
135ed5d5720SPeter Avalos }
136ed5d5720SPeter Avalos 
137ed5d5720SPeter Avalos 
138ed5d5720SPeter Avalos int
__nss_compat_getgrent_r(void * retval,void * mdata,va_list ap)139ed5d5720SPeter Avalos __nss_compat_getgrent_r(void *retval, void *mdata, va_list ap)
140ed5d5720SPeter Avalos {
141ed5d5720SPeter Avalos 	int (*fn)(struct group *, char *, size_t, int *);
142ed5d5720SPeter Avalos 	struct group	*grp;
143ed5d5720SPeter Avalos 	char		*buffer;
144ed5d5720SPeter Avalos 	int		*errnop;
145ed5d5720SPeter Avalos 	size_t		 bufsize;
146ed5d5720SPeter Avalos 	enum nss_status	 status;
147ed5d5720SPeter Avalos 
148ed5d5720SPeter Avalos 	if (CHECK_TERMINATOR(group))
149ed5d5720SPeter Avalos 		return (NS_NOTFOUND);
150ed5d5720SPeter Avalos 	fn = mdata;
151ed5d5720SPeter Avalos 	grp = va_arg(ap, struct group *);
152ed5d5720SPeter Avalos 	buffer = va_arg(ap, char *);
153ed5d5720SPeter Avalos 	bufsize = va_arg(ap, size_t);
154ed5d5720SPeter Avalos 	errnop = va_arg(ap, int *);
155ed5d5720SPeter Avalos 	status = fn(grp, buffer, bufsize, errnop);
156ed5d5720SPeter Avalos 	status = __nss_compat_result(status, *errnop);
157ed5d5720SPeter Avalos 	if (status == NS_SUCCESS)
158ed5d5720SPeter Avalos 		*(struct group **)retval = grp;
159ed5d5720SPeter Avalos 	else if (status != NS_RETURN)
160ed5d5720SPeter Avalos 		SET_TERMINATOR(group, &terminator);
161ed5d5720SPeter Avalos 	return (status);
162ed5d5720SPeter Avalos }
163ed5d5720SPeter Avalos 
164ed5d5720SPeter Avalos 
165ed5d5720SPeter Avalos int
__nss_compat_setgrent(void * retval __unused,void * mdata,va_list ap __unused)1666d7019e6SSascha Wildner __nss_compat_setgrent(void *retval __unused, void *mdata, va_list ap __unused)
167ed5d5720SPeter Avalos {
168ed5d5720SPeter Avalos 
169ed5d5720SPeter Avalos 	SET_TERMINATOR(group, NULL);
170ed5d5720SPeter Avalos 	((int (*)(void))mdata)();
171ed5d5720SPeter Avalos 	return (NS_UNAVAIL);
172ed5d5720SPeter Avalos }
173ed5d5720SPeter Avalos 
174ed5d5720SPeter Avalos 
175ed5d5720SPeter Avalos int
__nss_compat_endgrent(void * retval __unused,void * mdata,va_list ap __unused)1766d7019e6SSascha Wildner __nss_compat_endgrent(void *retval __unused, void *mdata, va_list ap __unused)
177ed5d5720SPeter Avalos {
178ed5d5720SPeter Avalos 
179ed5d5720SPeter Avalos 	SET_TERMINATOR(group, NULL);
180ed5d5720SPeter Avalos 	((int (*)(void))mdata)();
181ed5d5720SPeter Avalos 	return (NS_UNAVAIL);
182ed5d5720SPeter Avalos }
183ed5d5720SPeter Avalos 
184ed5d5720SPeter Avalos 
185ed5d5720SPeter Avalos 
186ed5d5720SPeter Avalos DECLARE_TERMINATOR(passwd);
187ed5d5720SPeter Avalos 
188*a1ff66cbSSascha Wildner int __nss_compat_getpwnam_r(void *, void *, va_list);
189*a1ff66cbSSascha Wildner int __nss_compat_getpwuid_r(void *, void *, va_list);
190*a1ff66cbSSascha Wildner int __nss_compat_getpwent_r(void *, void *, va_list);
191*a1ff66cbSSascha Wildner int __nss_compat_setpwent(void *, void *, va_list);
192*a1ff66cbSSascha Wildner int __nss_compat_endpwent(void *, void *, va_list);
193ed5d5720SPeter Avalos 
194ed5d5720SPeter Avalos int
__nss_compat_getpwnam_r(void * retval,void * mdata,va_list ap)195ed5d5720SPeter Avalos __nss_compat_getpwnam_r(void *retval, void *mdata, va_list ap)
196ed5d5720SPeter Avalos {
197ed5d5720SPeter Avalos 	int (*fn)(const char *, struct passwd *, char *, size_t, int *);
198ed5d5720SPeter Avalos 	const char	*name;
199ed5d5720SPeter Avalos 	struct passwd	*pwd;
200ed5d5720SPeter Avalos 	char		*buffer;
201ed5d5720SPeter Avalos 	int		*errnop;
202ed5d5720SPeter Avalos 	size_t		 bufsize;
203ed5d5720SPeter Avalos 	enum nss_status	 status;
204ed5d5720SPeter Avalos 
205ed5d5720SPeter Avalos 	fn = mdata;
206ed5d5720SPeter Avalos 	name = va_arg(ap, const char *);
207ed5d5720SPeter Avalos 	pwd = va_arg(ap, struct passwd *);
208ed5d5720SPeter Avalos 	buffer = va_arg(ap, char *);
209ed5d5720SPeter Avalos 	bufsize = va_arg(ap, size_t);
210ed5d5720SPeter Avalos 	errnop = va_arg(ap, int *);
211ed5d5720SPeter Avalos 	status = fn(name, pwd, buffer, bufsize, errnop);
212ed5d5720SPeter Avalos 	status = __nss_compat_result(status, *errnop);
213ed5d5720SPeter Avalos 	if (status == NS_SUCCESS)
214ed5d5720SPeter Avalos 		*(struct passwd **)retval = pwd;
215ed5d5720SPeter Avalos 	return (status);
216ed5d5720SPeter Avalos }
217ed5d5720SPeter Avalos 
218ed5d5720SPeter Avalos 
219ed5d5720SPeter Avalos int
__nss_compat_getpwuid_r(void * retval,void * mdata,va_list ap)220ed5d5720SPeter Avalos __nss_compat_getpwuid_r(void *retval, void *mdata, va_list ap)
221ed5d5720SPeter Avalos {
222ed5d5720SPeter Avalos 	int (*fn)(uid_t, struct passwd *, char *, size_t, int *);
223ed5d5720SPeter Avalos 	uid_t		 uid;
224ed5d5720SPeter Avalos 	struct passwd	*pwd;
225ed5d5720SPeter Avalos 	char		*buffer;
226ed5d5720SPeter Avalos 	int		*errnop;
227ed5d5720SPeter Avalos 	size_t		 bufsize;
228ed5d5720SPeter Avalos 	enum nss_status	 status;
229ed5d5720SPeter Avalos 
230ed5d5720SPeter Avalos 	fn = mdata;
231ed5d5720SPeter Avalos 	uid = va_arg(ap, uid_t);
232ed5d5720SPeter Avalos 	pwd = va_arg(ap, struct passwd *);
233ed5d5720SPeter Avalos 	buffer = va_arg(ap, char *);
234ed5d5720SPeter Avalos 	bufsize = va_arg(ap, size_t);
235ed5d5720SPeter Avalos 	errnop = va_arg(ap, int *);
236ed5d5720SPeter Avalos 	status = fn(uid, pwd, buffer, bufsize, errnop);
237ed5d5720SPeter Avalos 	status = __nss_compat_result(status, *errnop);
238ed5d5720SPeter Avalos 	if (status == NS_SUCCESS)
239ed5d5720SPeter Avalos 		*(struct passwd **)retval = pwd;
240ed5d5720SPeter Avalos 	return (status);
241ed5d5720SPeter Avalos }
242ed5d5720SPeter Avalos 
243ed5d5720SPeter Avalos 
244ed5d5720SPeter Avalos int
__nss_compat_getpwent_r(void * retval,void * mdata,va_list ap)245ed5d5720SPeter Avalos __nss_compat_getpwent_r(void *retval, void *mdata, va_list ap)
246ed5d5720SPeter Avalos {
247ed5d5720SPeter Avalos 	int (*fn)(struct passwd *, char *, size_t, int *);
248ed5d5720SPeter Avalos 	struct passwd	*pwd;
249ed5d5720SPeter Avalos 	char		*buffer;
250ed5d5720SPeter Avalos 	int		*errnop;
251ed5d5720SPeter Avalos 	size_t		 bufsize;
252ed5d5720SPeter Avalos 	enum nss_status	 status;
253ed5d5720SPeter Avalos 
254ed5d5720SPeter Avalos 	if (CHECK_TERMINATOR(passwd))
255ed5d5720SPeter Avalos 		return (NS_NOTFOUND);
256ed5d5720SPeter Avalos 	fn = mdata;
257ed5d5720SPeter Avalos 	pwd = va_arg(ap, struct passwd *);
258ed5d5720SPeter Avalos 	buffer = va_arg(ap, char *);
259ed5d5720SPeter Avalos 	bufsize = va_arg(ap, size_t);
260ed5d5720SPeter Avalos 	errnop = va_arg(ap, int *);
261ed5d5720SPeter Avalos 	status = fn(pwd, buffer, bufsize, errnop);
262ed5d5720SPeter Avalos 	status = __nss_compat_result(status, *errnop);
263ed5d5720SPeter Avalos 	if (status == NS_SUCCESS)
264ed5d5720SPeter Avalos 		*(struct passwd **)retval = pwd;
265ed5d5720SPeter Avalos 	else if (status != NS_RETURN)
266ed5d5720SPeter Avalos 		SET_TERMINATOR(passwd, &terminator);
267ed5d5720SPeter Avalos 	return (status);
268ed5d5720SPeter Avalos }
269ed5d5720SPeter Avalos 
270ed5d5720SPeter Avalos 
271ed5d5720SPeter Avalos int
__nss_compat_setpwent(void * retval __unused,void * mdata,va_list ap __unused)2726d7019e6SSascha Wildner __nss_compat_setpwent(void *retval __unused, void *mdata, va_list ap __unused)
273ed5d5720SPeter Avalos {
274ed5d5720SPeter Avalos 
275ed5d5720SPeter Avalos 	SET_TERMINATOR(passwd, NULL);
276ed5d5720SPeter Avalos 	((int (*)(void))mdata)();
277ed5d5720SPeter Avalos 	return (NS_UNAVAIL);
278ed5d5720SPeter Avalos }
279ed5d5720SPeter Avalos 
280ed5d5720SPeter Avalos 
281ed5d5720SPeter Avalos int
__nss_compat_endpwent(void * retval __unused,void * mdata,va_list ap __unused)2826d7019e6SSascha Wildner __nss_compat_endpwent(void *retval __unused, void *mdata, va_list ap __unused)
283ed5d5720SPeter Avalos {
284ed5d5720SPeter Avalos 
285ed5d5720SPeter Avalos 	SET_TERMINATOR(passwd, NULL);
286ed5d5720SPeter Avalos 	((int (*)(void))mdata)();
287ed5d5720SPeter Avalos 	return (NS_UNAVAIL);
288ed5d5720SPeter Avalos }
289