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