diff options
author | Alberto Gonzalez Iniesta <agi@inittab.org> | 2012-11-05 16:28:10 +0100 |
---|---|---|
committer | Alberto Gonzalez Iniesta <agi@inittab.org> | 2012-11-05 16:28:10 +0100 |
commit | d213c4e5576e2fd601679e0d7b2fb1262b807111 (patch) | |
tree | 5f0cc82bd0f11fb13b385417604d04c751245a92 /src/plugins/auth-pam/pamdl.c | |
parent | 79c8d3ef7a938f86472e549ef64e1fb820dc80c4 (diff) | |
parent | 8dd0350e1607aa30f7a043c8d5ec7a7eeb874115 (diff) |
Merge tag 'upstream/2.3_rc1'
Upstream version 2.3_rc1
Diffstat (limited to 'src/plugins/auth-pam/pamdl.c')
-rw-r--r-- | src/plugins/auth-pam/pamdl.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/src/plugins/auth-pam/pamdl.c b/src/plugins/auth-pam/pamdl.c new file mode 100644 index 0000000..26e9821 --- /dev/null +++ b/src/plugins/auth-pam/pamdl.c @@ -0,0 +1,184 @@ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef USE_PAM_DLOPEN +/* + * 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 "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 |