OpenVPN
pamdl.c
Go to the documentation of this file.
1#ifdef HAVE_CONFIG_H
2#include <config.h>
3#endif
4
5#ifdef USE_PAM_DLOPEN
6/*
7 * If you want to dynamically load libpam using dlopen() or something,
8 * then dlopen( ' this shared object ' ); It takes care of exporting
9 * the right symbols to any modules loaded by libpam.
10 *
11 * Modified by JY for use with openvpn-pam-auth
12 */
13
14#include <stdio.h>
15#include <dlfcn.h>
16#include <security/pam_appl.h>
17
18#include "pamdl.h"
19
20static void *libpam_h = NULL;
21
22#define RESOLVE_PAM_FUNCTION(x, y, z, err) \
23 { \
24 union \
25 { \
26 const void *tpointer; \
27 y(*fn) z; \
28 } fptr; \
29 fptr.tpointer = dlsym(libpam_h, #x); \
30 real_##x = fptr.fn; \
31 if (real_##x == NULL) \
32 { \
33 fprintf(stderr, "PAMDL: unable to resolve '%s': %s\n", #x, dlerror()); \
34 return err; \
35 } \
36 }
37
38int
39dlopen_pam(const char *so)
40{
41 if (libpam_h == NULL)
42 {
43 libpam_h = dlopen(so, RTLD_GLOBAL | RTLD_NOW);
44 }
45 return libpam_h != NULL;
46}
47
48void
49dlclose_pam(void)
50{
51 if (libpam_h != NULL)
52 {
53 dlclose(libpam_h);
54 libpam_h = NULL;
55 }
56}
57
58int
59pam_start(const char *service_name, const char *user, const struct pam_conv *pam_conversation,
60 pam_handle_t **pamh)
61{
62 int (*real_pam_start)(const char *, const char *, const struct pam_conv *, pam_handle_t **);
63 RESOLVE_PAM_FUNCTION(pam_start, int,
64 (const char *, const char *, const struct pam_conv *, pam_handle_t **),
65 PAM_ABORT);
66 return real_pam_start(service_name, user, pam_conversation, pamh);
67}
68
69int
70pam_end(pam_handle_t *pamh, int pam_status)
71{
72 int (*real_pam_end)(pam_handle_t *, int);
73 RESOLVE_PAM_FUNCTION(pam_end, int, (pam_handle_t *, int), PAM_ABORT);
74 return real_pam_end(pamh, pam_status);
75}
76
77int
78pam_set_item(pam_handle_t *pamh, int item_type, const void *item)
79{
80 int (*real_pam_set_item)(pam_handle_t *, int, const void *);
81 RESOLVE_PAM_FUNCTION(pam_set_item, int, (pam_handle_t *, int, const void *), PAM_ABORT);
82 return real_pam_set_item(pamh, item_type, item);
83}
84
85int
86pam_get_item(const pam_handle_t *pamh, int item_type, const void **item)
87{
88 int (*real_pam_get_item)(const pam_handle_t *, int, const void **);
89 RESOLVE_PAM_FUNCTION(pam_get_item, int, (const pam_handle_t *, int, const void **), PAM_ABORT);
90 return real_pam_get_item(pamh, item_type, item);
91}
92
93int
94pam_fail_delay(pam_handle_t *pamh, unsigned int musec_delay)
95{
96 int (*real_pam_fail_delay)(pam_handle_t *, unsigned int);
97 RESOLVE_PAM_FUNCTION(pam_fail_delay, int, (pam_handle_t *, unsigned int), PAM_ABORT);
98 return real_pam_fail_delay(pamh, musec_delay);
99}
100
101typedef const char *const_char_pointer;
102
103const_char_pointer
104pam_strerror(pam_handle_t *pamh, int errnum)
105{
106 const_char_pointer (*real_pam_strerror)(pam_handle_t *, int);
107 RESOLVE_PAM_FUNCTION(pam_strerror, const_char_pointer, (pam_handle_t *, int), NULL);
108 return real_pam_strerror(pamh, errnum);
109}
110
111int
112pam_putenv(pam_handle_t *pamh, const char *name_value)
113{
114 int (*real_pam_putenv)(pam_handle_t *, const char *);
115 RESOLVE_PAM_FUNCTION(pam_putenv, int, (pam_handle_t *, const char *), PAM_ABORT);
116 return real_pam_putenv(pamh, name_value);
117}
118
119const_char_pointer
120pam_getenv(pam_handle_t *pamh, const char *name)
121{
122 const_char_pointer (*real_pam_getenv)(pam_handle_t *, const char *);
123 RESOLVE_PAM_FUNCTION(pam_getenv, const_char_pointer, (pam_handle_t *, const char *), NULL);
124 return real_pam_getenv(pamh, name);
125}
126
127typedef char **char_ppointer;
128char_ppointer
129pam_getenvlist(pam_handle_t *pamh)
130{
131 char_ppointer (*real_pam_getenvlist)(pam_handle_t *);
132 RESOLVE_PAM_FUNCTION(pam_getenvlist, char_ppointer, (pam_handle_t *), NULL);
133 return real_pam_getenvlist(pamh);
134}
135
136/* Authentication management */
137
138int
139pam_authenticate(pam_handle_t *pamh, int flags)
140{
141 int (*real_pam_authenticate)(pam_handle_t *, int);
142 RESOLVE_PAM_FUNCTION(pam_authenticate, int, (pam_handle_t *, int), PAM_ABORT);
143 return real_pam_authenticate(pamh, flags);
144}
145
146int
147pam_setcred(pam_handle_t *pamh, int flags)
148{
149 int (*real_pam_setcred)(pam_handle_t *, int);
150 RESOLVE_PAM_FUNCTION(pam_setcred, int, (pam_handle_t *, int), PAM_ABORT);
151 return real_pam_setcred(pamh, flags);
152}
153
154/* Account Management API's */
155
156int
157pam_acct_mgmt(pam_handle_t *pamh, int flags)
158{
159 int (*real_pam_acct_mgmt)(pam_handle_t *, int);
160 RESOLVE_PAM_FUNCTION(pam_acct_mgmt, int, (pam_handle_t *, int), PAM_ABORT);
161 return real_pam_acct_mgmt(pamh, flags);
162}
163
164/* Session Management API's */
165
166int
167pam_open_session(pam_handle_t *pamh, int flags)
168{
169 int (*real_pam_open_session)(pam_handle_t *, int);
170 RESOLVE_PAM_FUNCTION(pam_open_session, int, (pam_handle_t *, int), PAM_ABORT);
171 return real_pam_open_session(pamh, flags);
172}
173
174int
175pam_close_session(pam_handle_t *pamh, int flags)
176{
177 int (*real_pam_close_session)(pam_handle_t *, int);
178 RESOLVE_PAM_FUNCTION(pam_close_session, int, (pam_handle_t *, int), PAM_ABORT);
179 return real_pam_close_session(pamh, flags);
180}
181
182/* Password Management API's */
183
184int
185pam_chauthtok(pam_handle_t *pamh, int flags)
186{
187 int (*real_pam_chauthtok)(pam_handle_t *, int);
188 RESOLVE_PAM_FUNCTION(pam_chauthtok, int, (pam_handle_t *, int), PAM_ABORT);
189 return real_pam_chauthtok(pamh, flags);
190}
191#endif /* ifdef USE_PAM_DLOPEN */