1#include <stdlib.h>
2#include <stdio.h>
3#include <dlfcn.h>
4#include <security/pam_appl.h>
5#include <syslog.h>
6
7const char libopenpam[] = "/usr/lib/libpam.2.dylib";
8
9
10#define xlate(oldname, oldvalue, newname, newvalue) \
11    COMPAT_AUTH_##oldname = oldvalue,
12enum {
13#include "pam_shim_authenticate_flags.h"
14};
15#undef xlate
16
17int
18xlate_pam_shim_authenticate_flags(int flags)
19{
20	int newflags = 0;
21
22#define xlate(oldname, oldvalue, newname, newvalue) \
23    if (flags & COMPAT_AUTH_##oldname) newflags |= newname;
24#include "pam_shim_authenticate_flags.h"
25#undef xlate
26	return newflags;
27}
28
29
30#define xlate(oldname, oldvalue, newname, newvalue) \
31    COMPAT_CHAUTH_##oldname = oldvalue,
32enum {
33#include "pam_shim_chauthtok_flags.h"
34};
35#undef xlate
36
37int
38xlate_pam_shim_chauthtok_flags(int flags)
39{
40	int newflags = 0;
41
42#define xlate(oldname, oldvalue, newname, newvalue) \
43    if (flags & COMPAT_CHAUTH_##oldname) newflags |= newname;
44#include "pam_shim_chauthtok_flags.h"
45#undef xlate
46	return newflags;
47}
48
49
50#define xlate(oldname, oldvalue, newname, newvalue) \
51    COMPAT_SESSION_##oldname = oldvalue,
52enum {
53#include "pam_shim_session_flags.h"
54};
55#undef xlate
56
57int
58xlate_pam_shim_session_flags(int flags)
59{
60	int newflags = 0;
61
62#define xlate(oldname, oldvalue, newname, newvalue) \
63    if (flags & COMPAT_SESSION_##oldname) newflags |= newname;
64#include "pam_shim_session_flags.h"
65#undef xlate
66	return newflags;
67}
68
69
70#define xlate(oldname, oldvalue, newname, newvalue) \
71    COMPAT_AUTH_##oldname = oldvalue,
72enum {
73#include "pam_shim_setcred_flags.h"
74};
75#undef xlate
76
77int
78xlate_pam_shim_setcred_flags(int flags)
79{
80	int newflags = 0;
81
82#define xlate(oldname, oldvalue, newname, newvalue) \
83    if (flags & COMPAT_AUTH_##oldname) newflags |= newname;
84#include "pam_shim_setcred_flags.h"
85#undef xlate
86	return newflags;
87}
88
89
90#define xlate(oldname, oldvalue, newname, newvalue) \
91    COMPAT_##oldname = oldvalue,
92enum {
93#include "pam_shim_retval.h"
94};
95#undef xlate
96
97int
98xlate_pam_shim_retval(int retval)
99{
100#define xlate(oldname, oldvalue, newname, newvalue) \
101	case COMPAT_##oldname: return newname;
102	switch (retval) {
103#include "pam_shim_retval.h"
104	default: return retval;
105	}
106#undef xlate
107}
108
109
110#define xlate(oldname, oldvalue, newname, newvalue) \
111    COMPAT_##oldname = oldvalue,
112enum {
113#include "pam_shim_item_type.h"
114};
115#undef xlate
116
117int
118xlate_pam_shim_item_type(int item_type)
119{
120#define xlate(oldname, oldvalue, newname, newvalue) \
121	case COMPAT_##oldname: return newname;
122	switch (item_type) {
123#include "pam_shim_item_type.h"
124	default: return item_type;
125	}
126#undef xlate
127}
128
129
130void dlfailure (const char *caller)
131{
132	syslog(LOG_ERR, "libpam.1.dylib failed calling %s: %s", caller, dlerror());
133	abort();
134}
135
136
137typedef int (*pam_start_func)(const char *, const char *, const struct pam_conv *, pam_handle_t **);
138
139int
140pam_start(const char *service_name, const char *user, const struct pam_conv *pam_conversation, pam_handle_t **pamh)
141{
142	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
143	if (NULL == openpam) dlfailure("pam_start");
144	pam_start_func func = dlsym(openpam, "pam_start");
145	if (NULL == func) dlfailure("pam_start");
146	return xlate_pam_shim_retval(func(service_name, user, pam_conversation, pamh));
147}
148
149
150typedef int (*pam_end_func)(pam_handle_t *, int);
151
152int
153pam_end(pam_handle_t *pamh, int pam_status)
154{
155	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
156	if (NULL == openpam) dlfailure("pam_end");
157	pam_end_func func = dlsym(openpam, "pam_end");
158	if (NULL == func) dlfailure("pam_end");
159	return xlate_pam_shim_retval(func(pamh, pam_status));
160}
161
162
163typedef int (*pam_authenticate_func)(pam_handle_t *, int);
164
165int
166pam_authenticate(pam_handle_t *pamh, int flags)
167{
168	int newflags = xlate_pam_shim_authenticate_flags(flags);
169	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
170	if (NULL == openpam) dlfailure("pam_authenticate");
171	pam_authenticate_func func = dlsym(openpam, "pam_authenticate");
172	if (NULL == func) dlfailure("pam_authenticate");
173	return xlate_pam_shim_retval(func(pamh, newflags));
174}
175
176
177typedef int (*pam_setcred_func)(pam_handle_t *, int);
178
179int
180pam_setcred(pam_handle_t *pamh, int flags)
181{
182	int newflags = xlate_pam_shim_authenticate_flags(flags);
183	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
184	if (NULL == openpam) dlfailure("pam_setcred");
185	pam_setcred_func func = dlsym(openpam, "pam_setcred");
186	if (NULL == func) dlfailure("pam_setcred");
187	return xlate_pam_shim_retval(func(pamh, newflags));
188}
189
190
191typedef int (*pam_acct_mgmt_func)(pam_handle_t *, int);
192
193int
194pam_acct_mgmt(pam_handle_t *pamh, int flags)
195{
196	int newflags = xlate_pam_shim_authenticate_flags(flags);
197	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
198	if (NULL == openpam) dlfailure("pam_acct_mgmt");
199	pam_acct_mgmt_func func = dlsym(openpam, "pam_acct_mgmt");
200	if (NULL == func) dlfailure("pam_acct_mgmt");
201	return xlate_pam_shim_retval(func(pamh, newflags));
202}
203
204
205typedef int (*pam_chauthtok_func)(pam_handle_t *, int);
206
207int
208pam_chauthtok(pam_handle_t *pamh, int flags)
209{
210	int newflags = xlate_pam_shim_chauthtok_flags(flags);
211	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
212	if (NULL == openpam) dlfailure("pam_chauthtok");
213	pam_chauthtok_func func = dlsym(openpam, "pam_chauthtok");
214	if (NULL == func) dlfailure("pam_chauthtok");
215	return xlate_pam_shim_retval(func(pamh, newflags));
216}
217
218
219typedef int (*pam_open_session_func)(pam_handle_t *, int);
220
221int
222pam_open_session(pam_handle_t *pamh, int flags)
223{
224	int newflags = xlate_pam_shim_session_flags(flags);
225	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
226	if (NULL == openpam) dlfailure("pam_open_session");
227	pam_open_session_func func = dlsym(openpam, "pam_open_session");
228	if (NULL == func) dlfailure("pam_open_session");
229	return xlate_pam_shim_retval(func(pamh, newflags));
230}
231
232
233typedef int (*pam_close_session_func)(pam_handle_t *, int);
234
235int
236pam_close_session(pam_handle_t *pamh, int flags)
237{
238	int newflags = xlate_pam_shim_session_flags(flags);
239	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
240	if (NULL == openpam) dlfailure("pam_close_session");
241	pam_close_session_func func = dlsym(openpam, "pam_close_session");
242	if (NULL == func) dlfailure("pam_close_session");
243	return xlate_pam_shim_retval(func(pamh, newflags));
244}
245
246
247typedef int (*pam_set_item_func)(pam_handle_t *, int, const void *);
248
249int
250pam_set_item(pam_handle_t *pamh, int item_type, const void *item)
251{
252	int newitemtype = xlate_pam_shim_item_type(item_type);
253	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
254	if (NULL == openpam) dlfailure("pam_set_item");
255	pam_set_item_func func = dlsym(openpam, "pam_set_item");
256	if (NULL == func) dlfailure("pam_set_item");
257	return xlate_pam_shim_retval(func(pamh, newitemtype, item));
258}
259
260
261typedef int (*pam_get_item_func)(const pam_handle_t *, int, const void **);
262
263int
264pam_get_item(const pam_handle_t *pamh, int item_type, const void **item)
265{
266	int newitemtype = xlate_pam_shim_item_type(item_type);
267	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
268	if (NULL == openpam) dlfailure("pam_get_item");
269	pam_get_item_func func = dlsym(openpam, "pam_get_item");
270	if (NULL == func) dlfailure("pam_get_item");
271	return xlate_pam_shim_retval(func(pamh, newitemtype, item));
272}
273
274
275typedef int (*misc_conv_func)(int, const struct pam_message **, struct pam_response **, void *);
276
277int
278misc_conv(int num_msg, const struct pam_message **msgm, struct pam_response **response, void *appdata_ptr)
279{
280	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
281	if (NULL == openpam) dlfailure("misc_conv");
282	misc_conv_func func = dlsym(openpam, "openpam_ttyconv");
283	if (NULL == func) dlfailure("misc_conv");
284	return xlate_pam_shim_retval(func(num_msg, msgm, response, appdata_ptr));
285}
286
287
288typedef const char * (*pam_strerr_func)(const pam_handle_t *, int);
289
290const char *
291pam_strerror(const pam_handle_t *pamh, int pam_error)
292{
293	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
294	if (NULL == openpam) dlfailure("pam_strerror");
295	pam_strerr_func func = dlsym(openpam, "pam_strerror");
296	if (NULL == func) dlfailure("pam_strerror");
297	return func(pamh, pam_error);
298}
299
300
301typedef int (*pam_putenv_func)(pam_handle_t *, const char *);
302
303int
304pam_putenv(pam_handle_t *pamh, const char *name_value)
305{
306	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
307	if (NULL == openpam) dlfailure("pam_putenv");
308	pam_putenv_func func = dlsym(openpam, "pam_putenv");
309	if (NULL == func) dlfailure("pam_putenv");
310	return xlate_pam_shim_retval(func(pamh, name_value));
311}
312
313
314typedef const char * (*pam_getenv_func)(pam_handle_t *, const char *);
315
316const char *
317pam_getenv(pam_handle_t *pamh, const char *name)
318{
319	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
320	if (NULL == openpam) dlfailure("pam_getenv");
321	pam_getenv_func func = dlsym(openpam, "pam_getenv");
322	if (NULL == func) dlfailure("pam_getenv");
323	return func(pamh, name);
324}
325
326
327typedef char ** (*pam_getenvlist_func)(pam_handle_t *);
328
329char **
330pam_getenvlist(pam_handle_t *pamh)
331{
332	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
333	if (NULL == openpam) dlfailure("pam_getenvlist");
334	pam_getenvlist_func func = dlsym(openpam, "pam_getenvlist");
335	if (NULL == func) dlfailure("pam_getenvlist");
336	return func(pamh);
337}
338
339
340typedef int (*pam_get_data_func)(pam_handle_t *, const char *, const void **);
341int aliased_pam_get_data(pam_handle_t *pamh, const char *module_data_name, const void **data) __asm("_pam_get_data");
342
343int
344aliased_pam_get_data(pam_handle_t *pamh, const char *module_data_name, const void **data)
345{
346	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
347	if (NULL == openpam) dlfailure("pam_get_data");
348	pam_get_data_func func = dlsym(openpam, "pam_get_data");
349	if (NULL == func) dlfailure("pam_get_data");
350	return xlate_pam_shim_retval(func(pamh, module_data_name, data));
351}
352
353
354typedef void (*pam_set_data_cleanup_func)(pam_handle_t, void *, int);
355typedef int (*pam_set_data_func)(pam_handle_t *, const char *, void *, pam_set_data_cleanup_func);
356int aliased_pam_set_data(pam_handle_t *pamh, const char *modue_data_name, void *data, pam_set_data_cleanup_func cleanup) __asm("_pam_set_data");
357
358int
359aliased_pam_set_data(pam_handle_t *pamh, const char *modue_data_name, void *data, pam_set_data_cleanup_func cleanup)
360{
361	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
362	if (NULL == openpam) dlfailure("pam_set_data");
363	pam_set_data_func func = dlsym(openpam, "pam_set_data");
364	if (NULL == func) dlfailure("pam_set_data");
365	return xlate_pam_shim_retval(func(pamh, modue_data_name, data, cleanup));
366}
367
368
369typedef int (*pam_get_user_func)(pam_handle_t *, char **, const char *);
370int aliased_pam_get_user(pam_handle_t *pamh, char **user, const char *prompt) __asm("_pam_get_user");
371
372int
373aliased_pam_get_user(pam_handle_t *pamh, char **user, const char *prompt)
374{
375	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
376	if (NULL == openpam) dlfailure("pam_get_user");
377	pam_get_user_func func = dlsym(openpam, "pam_get_user");
378	if (NULL == func) dlfailure("pam_get_user");
379	return xlate_pam_shim_retval(func(pamh, user, prompt));
380}
381
382
383typedef int (*pam_prompt_func)(const pam_handle_t *, int, char **, const char *, ...);
384
385int
386pam_prompt(pam_handle_t *pamh, int style, const char *prompt, char **user_msg)
387{
388	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
389	if (NULL == openpam) dlfailure("pam_prompt");
390	pam_prompt_func func = dlsym(openpam, "pam_prompt");
391	if (NULL == func) dlfailure("pam_prompt");
392	return xlate_pam_shim_retval(func(pamh, style, user_msg, "%s", prompt));
393}
394
395
396typedef int (*pam_get_pass_func)(pam_handle_t *, int, const char **, const char *);
397
398int
399pam_get_pass(pam_handle_t *pamh, const char **passp, const char *prompt, __unused int options)
400{
401	void *openpam = dlopen(libopenpam, RTLD_LOCAL | RTLD_LAZY | RTLD_FIRST);
402	if (NULL == openpam) dlfailure("pam_get_pass");
403	pam_get_pass_func func = dlsym(openpam, "pam_get_authtok");
404	if (NULL == func) dlfailure("pam_get_authtok");
405	return xlate_pam_shim_retval(func(pamh, PAM_AUTHTOK, passp, prompt));
406}
407