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