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 pam_start(const char *service_name, const char *user,
53	      const struct pam_conv *pam_conversation,
54	      pam_handle_t **pamh)
55{
56    int (*real_pam_start)(const char *, const char *,
57				 const struct pam_conv *,
58				 pam_handle_t **);
59    RESOLVE_PAM_FUNCTION(pam_start, int, (const char *, const char *,
60					  const struct pam_conv *,
61					  pam_handle_t **), PAM_ABORT);
62    return real_pam_start(service_name, user, pam_conversation, pamh);
63}
64
65int pam_end(pam_handle_t *pamh, int pam_status)
66{
67    int (*real_pam_end)(pam_handle_t *, int);
68    RESOLVE_PAM_FUNCTION(pam_end, int, (pam_handle_t *, int), PAM_ABORT);
69    return real_pam_end(pamh, pam_status);
70}
71
72int pam_set_item(pam_handle_t *pamh, int item_type, const void *item)
73{
74    int (*real_pam_set_item)(pam_handle_t *, int, const void *);
75    RESOLVE_PAM_FUNCTION(pam_set_item, int,
76			 (pam_handle_t *, int, const void *), PAM_ABORT);
77    return real_pam_set_item(pamh, item_type, item);
78}
79
80int pam_get_item(const pam_handle_t *pamh, int item_type, const void **item)
81{
82    int (*real_pam_get_item)(const pam_handle_t *, int, const void **);
83    RESOLVE_PAM_FUNCTION(pam_get_item, int,
84			 (const pam_handle_t *, int, const void **),
85			 PAM_ABORT);
86    return real_pam_get_item(pamh, item_type, item);
87}
88
89int pam_fail_delay(pam_handle_t *pamh, unsigned int musec_delay)
90{
91    int (*real_pam_fail_delay)(pam_handle_t *, unsigned int);
92    RESOLVE_PAM_FUNCTION(pam_fail_delay, int, (pam_handle_t *, unsigned int),
93			 PAM_ABORT);
94    return real_pam_fail_delay(pamh, musec_delay);
95}
96
97typedef const char * const_char_pointer;
98
99const_char_pointer pam_strerror(pam_handle_t *pamh, int errnum)
100{
101    const_char_pointer (*real_pam_strerror)(pam_handle_t *, int);
102    RESOLVE_PAM_FUNCTION(pam_strerror, const_char_pointer,
103			 (pam_handle_t *, int), NULL);
104    return real_pam_strerror(pamh, errnum);
105}
106
107int pam_putenv(pam_handle_t *pamh, const char *name_value)
108{
109    int (*real_pam_putenv)(pam_handle_t *, const char *);
110    RESOLVE_PAM_FUNCTION(pam_putenv, int, (pam_handle_t *, const char *),
111			 PAM_ABORT);
112    return real_pam_putenv(pamh, name_value);
113}
114
115const_char_pointer pam_getenv(pam_handle_t *pamh, const char *name)
116{
117    const_char_pointer (*real_pam_getenv)(pam_handle_t *, const char *);
118    RESOLVE_PAM_FUNCTION(pam_getenv, const_char_pointer,
119			 (pam_handle_t *, const char *), NULL);
120    return real_pam_getenv(pamh, name);
121}
122
123typedef char ** char_ppointer;
124char_ppointer pam_getenvlist(pam_handle_t *pamh)
125{
126    char_ppointer (*real_pam_getenvlist)(pam_handle_t *);
127    RESOLVE_PAM_FUNCTION(pam_getenvlist, char_ppointer, (pam_handle_t *),
128			 NULL);
129    return real_pam_getenvlist(pamh);
130}
131
132/* Authentication management */
133
134int pam_authenticate(pam_handle_t *pamh, int flags)
135{
136    int (*real_pam_authenticate)(pam_handle_t *, int);
137    RESOLVE_PAM_FUNCTION(pam_authenticate, int, (pam_handle_t *, int),
138			 PAM_ABORT);
139    return real_pam_authenticate(pamh, flags);
140}
141
142int pam_setcred(pam_handle_t *pamh, int flags)
143{
144    int (*real_pam_setcred)(pam_handle_t *, int);
145    RESOLVE_PAM_FUNCTION(pam_setcred, int, (pam_handle_t *, int), PAM_ABORT);
146    return real_pam_setcred(pamh, flags);
147}
148
149/* Account Management API's */
150
151int pam_acct_mgmt(pam_handle_t *pamh, int flags)
152{
153    int (*real_pam_acct_mgmt)(pam_handle_t *, int);
154    RESOLVE_PAM_FUNCTION(pam_acct_mgmt, int, (pam_handle_t *, int), PAM_ABORT);
155    return real_pam_acct_mgmt(pamh, flags);
156}
157
158/* Session Management API's */
159
160int pam_open_session(pam_handle_t *pamh, int flags)
161{
162    int (*real_pam_open_session)(pam_handle_t *, int);
163    RESOLVE_PAM_FUNCTION(pam_open_session, int, (pam_handle_t *, int),
164			 PAM_ABORT);
165    return real_pam_open_session(pamh, flags);
166}
167
168int pam_close_session(pam_handle_t *pamh, int flags)
169{
170    int (*real_pam_close_session)(pam_handle_t *, int);
171    RESOLVE_PAM_FUNCTION(pam_close_session, int, (pam_handle_t *, int),
172			 PAM_ABORT);
173    return real_pam_close_session(pamh, flags);
174}
175
176/* Password Management API's */
177
178int pam_chauthtok(pam_handle_t *pamh, int flags)
179{
180    int (*real_pam_chauthtok)(pam_handle_t *, int);
181    RESOLVE_PAM_FUNCTION(pam_chauthtok, int, (pam_handle_t *, int), PAM_ABORT);
182    return real_pam_chauthtok(pamh, flags);
183}
184#endif
185