From 87e9a9fc6d8a98e421f2363f97b33afd75f4158e Mon Sep 17 00:00:00 2001 From: Rich Megginson Date: Fri, 15 Jul 2005 18:13:28 +0000 Subject: PAM is not thread safe. Therefore, we must put the code that accesses PAM in a critical section. This fix creates a mutex at init time and uses that mutex to create a critical section around all PAM API access. --- ldap/servers/plugins/pam_passthru/pam_passthru.h | 1 + ldap/servers/plugins/pam_passthru/pam_ptimpl.c | 23 +++++++++++++++++++++++ ldap/servers/plugins/pam_passthru/pam_ptpreop.c | 6 ++++++ 3 files changed, 30 insertions(+) diff --git a/ldap/servers/plugins/pam_passthru/pam_passthru.h b/ldap/servers/plugins/pam_passthru/pam_passthru.h index e0de9960..19e93b22 100644 --- a/ldap/servers/plugins/pam_passthru/pam_passthru.h +++ b/ldap/servers/plugins/pam_passthru/pam_passthru.h @@ -131,6 +131,7 @@ int pam_passthru_check_suffix(Pam_PassthruConfig *cfg, char *binddn); /* * pam_ptimpl.c */ +int pam_passthru_pam_init( void ); int pam_passthru_do_pam_auth(Slapi_PBlock *pb, Pam_PassthruConfig *cfg); #endif /* _PAM_PASSTHRU_H_ */ diff --git a/ldap/servers/plugins/pam_passthru/pam_ptimpl.c b/ldap/servers/plugins/pam_passthru/pam_ptimpl.c index eb2c42ee..232ce3c4 100644 --- a/ldap/servers/plugins/pam_passthru/pam_ptimpl.c +++ b/ldap/servers/plugins/pam_passthru/pam_ptimpl.c @@ -39,6 +39,11 @@ #include "pam_passthru.h" +/* + * PAM is not thread safe. We have to execute any PAM API calls in + * a critical section. This is the lock that protects that code. + */ +static Slapi_Mutex *PAMLock; /* Utility struct to wrap strings to avoid mallocs if possible - use stack allocated string space */ @@ -271,6 +276,8 @@ do_one_pam_auth( my_data.pb = pb; my_data.pam_identity = pam_id.str; my_pam_conv.appdata_ptr = &my_data; + slapi_lock_mutex(PAMLock); + /* from this point on we are in the critical section */ rc = pam_start(pam_service, pam_id.str, &my_pam_conv, &pam_handle); report_pam_error("during pam_start", rc, pam_handle); @@ -351,6 +358,8 @@ do_one_pam_auth( rc = pam_end(pam_handle, rc); report_pam_error("during pam_end", rc, pam_handle); + slapi_unlock_mutex(PAMLock); + /* not in critical section any more */ delete_my_str_buf(&pam_id); @@ -375,6 +384,20 @@ do_one_pam_auth( return retcode; } +/* + * Perform any PAM subsystem initialization that must be done at startup time. + * For now, this means only the PAM mutex since PAM is not thread safe. + */ +int +pam_passthru_pam_init( void ) +{ + if (!(PAMLock = slapi_new_mutex())) { + return LDAP_LOCAL_ERROR; + } + + return 0; +} + /* * Entry point into the PAM auth code. Shields the rest of the app * from PAM API code. Get our config params, then call the actual diff --git a/ldap/servers/plugins/pam_passthru/pam_ptpreop.c b/ldap/servers/plugins/pam_passthru/pam_ptpreop.c index ed1a5bde..40a425ce 100644 --- a/ldap/servers/plugins/pam_passthru/pam_ptpreop.c +++ b/ldap/servers/plugins/pam_passthru/pam_ptpreop.c @@ -128,6 +128,12 @@ pam_passthru_bindpreop_start( Slapi_PBlock *pb ) return( -1 ); } + if (( rc = pam_passthru_pam_init()) != LDAP_SUCCESS ) { + slapi_log_error( SLAPI_LOG_FATAL, PAM_PASSTHRU_PLUGIN_SUBSYSTEM, + "could not initialize PAM subsystem (%d)\n", rc); + return( -1 ); + } + return( 0 ); } -- cgit