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 { 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
32int
33dlopen_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
42void
43dlclose_pam(void)
44{
45 if (libpam_h != NULL)
46 {
47 dlclose(libpam_h);
48 libpam_h = NULL;
49 }
50}
51
52int
53pam_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
66int
67pam_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
74int
75pam_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
83int
84pam_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
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),
98 PAM_ABORT);
99 return real_pam_fail_delay(pamh, musec_delay);
100}
101
102typedef const char *const_char_pointer;
103
104const_char_pointer
105pam_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
113int
114pam_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
122const_char_pointer
123pam_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
131typedef char **char_ppointer;
132char_ppointer
133pam_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
143int
144pam_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
152int
153pam_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
162int
163pam_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
172int
173pam_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
181int
182pam_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
192int
193pam_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 */