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
20 static void *libpam_h = NULL;
21
22 #define RESOLVE_PAM_FUNCTION(x, y, z, err) \
23 { \
24 union { const void *tpointer; y(*fn) z; } fptr; \
25 fptr.tpointer = dlsym(libpam_h, #x); real_ ## x = fptr.fn; \
26 if (real_ ## x == NULL) { \
27 fprintf(stderr, "PAMDL: unable to resolve '%s': %s\n", #x, dlerror()); \
28 return err; \
29 } \
30 }
31
32 int
dlopen_pam(const char * so)33 dlopen_pam(const char *so)
34 {
35 if (libpam_h == NULL)
36 {
37 libpam_h = dlopen(so, RTLD_GLOBAL|RTLD_NOW);
38 }
39 return libpam_h != NULL;
40 }
41
42 void
dlclose_pam(void)43 dlclose_pam(void)
44 {
45 if (libpam_h != NULL)
46 {
47 dlclose(libpam_h);
48 libpam_h = NULL;
49 }
50 }
51
52 int
pam_start(const char * service_name,const char * user,const struct pam_conv * pam_conversation,pam_handle_t ** pamh)53 pam_start(const char *service_name, const char *user,
54 const struct pam_conv *pam_conversation,
55 pam_handle_t **pamh)
56 {
57 int (*real_pam_start)(const char *, const char *,
58 const struct pam_conv *,
59 pam_handle_t **);
60 RESOLVE_PAM_FUNCTION(pam_start, int, (const char *, const char *,
61 const struct pam_conv *,
62 pam_handle_t **), PAM_ABORT);
63 return real_pam_start(service_name, user, pam_conversation, pamh);
64 }
65
66 int
pam_end(pam_handle_t * pamh,int pam_status)67 pam_end(pam_handle_t *pamh, int pam_status)
68 {
69 int (*real_pam_end)(pam_handle_t *, int);
70 RESOLVE_PAM_FUNCTION(pam_end, int, (pam_handle_t *, int), PAM_ABORT);
71 return real_pam_end(pamh, pam_status);
72 }
73
74 int
pam_set_item(pam_handle_t * pamh,int item_type,const void * item)75 pam_set_item(pam_handle_t *pamh, int item_type, const void *item)
76 {
77 int (*real_pam_set_item)(pam_handle_t *, int, const void *);
78 RESOLVE_PAM_FUNCTION(pam_set_item, int,
79 (pam_handle_t *, int, const void *), PAM_ABORT);
80 return real_pam_set_item(pamh, item_type, item);
81 }
82
83 int
pam_get_item(const pam_handle_t * pamh,int item_type,const void ** item)84 pam_get_item(const pam_handle_t *pamh, int item_type, const void **item)
85 {
86 int (*real_pam_get_item)(const pam_handle_t *, int, const void **);
87 RESOLVE_PAM_FUNCTION(pam_get_item, int,
88 (const pam_handle_t *, int, const void **),
89 PAM_ABORT);
90 return real_pam_get_item(pamh, item_type, item);
91 }
92
93 int
pam_fail_delay(pam_handle_t * pamh,unsigned int musec_delay)94 pam_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),
98 PAM_ABORT);
99 return real_pam_fail_delay(pamh, musec_delay);
100 }
101
102 typedef const char *const_char_pointer;
103
104 const_char_pointer
pam_strerror(pam_handle_t * pamh,int errnum)105 pam_strerror(pam_handle_t *pamh, int errnum)
106 {
107 const_char_pointer (*real_pam_strerror)(pam_handle_t *, int);
108 RESOLVE_PAM_FUNCTION(pam_strerror, const_char_pointer,
109 (pam_handle_t *, int), NULL);
110 return real_pam_strerror(pamh, errnum);
111 }
112
113 int
pam_putenv(pam_handle_t * pamh,const char * name_value)114 pam_putenv(pam_handle_t *pamh, const char *name_value)
115 {
116 int (*real_pam_putenv)(pam_handle_t *, const char *);
117 RESOLVE_PAM_FUNCTION(pam_putenv, int, (pam_handle_t *, const char *),
118 PAM_ABORT);
119 return real_pam_putenv(pamh, name_value);
120 }
121
122 const_char_pointer
pam_getenv(pam_handle_t * pamh,const char * name)123 pam_getenv(pam_handle_t *pamh, const char *name)
124 {
125 const_char_pointer (*real_pam_getenv)(pam_handle_t *, const char *);
126 RESOLVE_PAM_FUNCTION(pam_getenv, const_char_pointer,
127 (pam_handle_t *, const char *), NULL);
128 return real_pam_getenv(pamh, name);
129 }
130
131 typedef char **char_ppointer;
132 char_ppointer
pam_getenvlist(pam_handle_t * pamh)133 pam_getenvlist(pam_handle_t *pamh)
134 {
135 char_ppointer (*real_pam_getenvlist)(pam_handle_t *);
136 RESOLVE_PAM_FUNCTION(pam_getenvlist, char_ppointer, (pam_handle_t *),
137 NULL);
138 return real_pam_getenvlist(pamh);
139 }
140
141 /* Authentication management */
142
143 int
pam_authenticate(pam_handle_t * pamh,int flags)144 pam_authenticate(pam_handle_t *pamh, int flags)
145 {
146 int (*real_pam_authenticate)(pam_handle_t *, int);
147 RESOLVE_PAM_FUNCTION(pam_authenticate, int, (pam_handle_t *, int),
148 PAM_ABORT);
149 return real_pam_authenticate(pamh, flags);
150 }
151
152 int
pam_setcred(pam_handle_t * pamh,int flags)153 pam_setcred(pam_handle_t *pamh, int flags)
154 {
155 int (*real_pam_setcred)(pam_handle_t *, int);
156 RESOLVE_PAM_FUNCTION(pam_setcred, int, (pam_handle_t *, int), PAM_ABORT);
157 return real_pam_setcred(pamh, flags);
158 }
159
160 /* Account Management API's */
161
162 int
pam_acct_mgmt(pam_handle_t * pamh,int flags)163 pam_acct_mgmt(pam_handle_t *pamh, int flags)
164 {
165 int (*real_pam_acct_mgmt)(pam_handle_t *, int);
166 RESOLVE_PAM_FUNCTION(pam_acct_mgmt, int, (pam_handle_t *, int), PAM_ABORT);
167 return real_pam_acct_mgmt(pamh, flags);
168 }
169
170 /* Session Management API's */
171
172 int
pam_open_session(pam_handle_t * pamh,int flags)173 pam_open_session(pam_handle_t *pamh, int flags)
174 {
175 int (*real_pam_open_session)(pam_handle_t *, int);
176 RESOLVE_PAM_FUNCTION(pam_open_session, int, (pam_handle_t *, int),
177 PAM_ABORT);
178 return real_pam_open_session(pamh, flags);
179 }
180
181 int
pam_close_session(pam_handle_t * pamh,int flags)182 pam_close_session(pam_handle_t *pamh, int flags)
183 {
184 int (*real_pam_close_session)(pam_handle_t *, int);
185 RESOLVE_PAM_FUNCTION(pam_close_session, int, (pam_handle_t *, int),
186 PAM_ABORT);
187 return real_pam_close_session(pamh, flags);
188 }
189
190 /* Password Management API's */
191
192 int
pam_chauthtok(pam_handle_t * pamh,int flags)193 pam_chauthtok(pam_handle_t *pamh, int flags)
194 {
195 int (*real_pam_chauthtok)(pam_handle_t *, int);
196 RESOLVE_PAM_FUNCTION(pam_chauthtok, int, (pam_handle_t *, int), PAM_ABORT);
197 return real_pam_chauthtok(pamh, flags);
198 }
199 #endif /* ifdef USE_PAM_DLOPEN */
200