summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEndi S. Dewata <edewata@redhat.com>2010-03-11 14:26:56 -0600
committerRich Megginson <rmeggins@redhat.com>2010-03-12 19:51:21 -0700
commit1ef0ec98b6c91471454647e5f613d26fa015c619 (patch)
treefa7a1da28b15e074bc79307cb765ddfde9f1a300
parented463407ead1f63ba26f64740a1e5cd1d79a03ee (diff)
downloadds-1ef0ec98b6c91471454647e5f613d26fa015c619.tar.gz
ds-1ef0ec98b6c91471454647e5f613d26fa015c619.tar.xz
ds-1ef0ec98b6c91471454647e5f613d26fa015c619.zip
Bug 470684 - Pam_passthru plugin doesn't verify account activation
https://bugzilla.redhat.com/show_bug.cgi?id=470684 Resolves: bug 470684 Bug Description: Pam passthrough doesn't verify account activation Reviewed by: rmeggins Branch: HEAD Fix Description: The check_account_lock() has been renamed to slapi_check_account_lock() and moved into libslapd.so so any plugins can use it. The account_inactivation_only parameter has been replaced by check_password_policy. A new parameter send_result has been added to determine whether to send LDAP results. The pam_passthru plugin has been modified to use this function to check account activation when the pamIDMapMethod is set to ENTRY. The plugin will not check password policy.
-rw-r--r--ldap/servers/plugins/pam_passthru/pam_ptimpl.c17
-rw-r--r--ldap/servers/slapd/bind.c8
-rw-r--r--ldap/servers/slapd/daemon.c10
-rw-r--r--ldap/servers/slapd/libslapd.def1
-rw-r--r--ldap/servers/slapd/pw.c138
-rw-r--r--ldap/servers/slapd/pw_mgmt.c136
-rw-r--r--ldap/servers/slapd/saslbind.c2
-rw-r--r--ldap/servers/slapd/slapi-plugin.h2
8 files changed, 167 insertions, 147 deletions
diff --git a/ldap/servers/plugins/pam_passthru/pam_ptimpl.c b/ldap/servers/plugins/pam_passthru/pam_ptimpl.c
index 6e5fc9fc..662239f3 100644
--- a/ldap/servers/plugins/pam_passthru/pam_ptimpl.c
+++ b/ldap/servers/plugins/pam_passthru/pam_ptimpl.c
@@ -106,7 +106,7 @@ derive_from_bind_dn(Slapi_PBlock *pb, char *binddn, MyStrBuf *pam_id)
}
static char *
-derive_from_bind_entry(Slapi_PBlock *pb, char *binddn, MyStrBuf *pam_id, char *map_ident_attr)
+derive_from_bind_entry(Slapi_PBlock *pb, char *binddn, MyStrBuf *pam_id, char *map_ident_attr, int *locked)
{
char buf[BUFSIZ];
Slapi_Entry *entry = NULL;
@@ -128,6 +128,12 @@ derive_from_bind_entry(Slapi_PBlock *pb, char *binddn, MyStrBuf *pam_id, char *m
"Could not find entry for BIND dn %s\n",
escape_string(binddn, buf));
init_my_str_buf(pam_id, NULL);
+ } else if (slapi_check_account_lock( pb, entry, 0, 0, 0 ) == 1) {
+ slapi_log_error(SLAPI_LOG_FATAL, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
+ "Account %s inactivated.\n",
+ escape_string(binddn, buf));
+ init_my_str_buf(pam_id, NULL);
+ *locked = 1;
} else {
char *val = slapi_entry_attr_get_charptr(entry, map_ident_attr);
init_my_str_buf(pam_id, val);
@@ -266,17 +272,24 @@ do_one_pam_auth(
struct pam_conv my_pam_conv = {pam_conv_func, NULL};
char buf[BUFSIZ]; /* for error messages */
char *errmsg = NULL; /* free with PR_smprintf_free */
+ int locked = 0;
slapi_pblock_get( pb, SLAPI_BIND_TARGET, &binddn );
if (method == PAMPT_MAP_METHOD_RDN) {
derive_from_bind_dn(pb, binddn, &pam_id);
} else if (method == PAMPT_MAP_METHOD_ENTRY) {
- derive_from_bind_entry(pb, binddn, &pam_id, map_ident_attr);
+ derive_from_bind_entry(pb, binddn, &pam_id, map_ident_attr, &locked);
} else {
init_my_str_buf(&pam_id, binddn);
}
+ if (locked) {
+ errmsg = PR_smprintf("Account inactivated. Contact system administrator.");
+ retcode = LDAP_UNWILLING_TO_PERFORM; /* user inactivated */
+ goto done; /* skip the pam stuff */
+ }
+
if (!pam_id.str) {
errmsg = PR_smprintf("Bind DN [%s] is invalid or not found",
escape_string(binddn, buf));
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
index d3e90091..f0bdbae4 100644
--- a/ldap/servers/slapd/bind.c
+++ b/ldap/servers/slapd/bind.c
@@ -441,8 +441,8 @@ do_bind( Slapi_PBlock *pb )
if (!isroot ) {
/* check if the account is locked */
bind_target_entry = get_entry(pb, pb->pb_conn->c_external_dn);
- if ( bind_target_entry != NULL && check_account_lock(pb, bind_target_entry,
- pw_response_requested, 0 /*not account_inactivation_only*/ ) == 1) {
+ if ( bind_target_entry != NULL && slapi_check_account_lock(pb, bind_target_entry,
+ pw_response_requested, 1 /*check password policy*/, 1 /*send ldap result*/) == 1) {
/* call postop plugins */
plugin_call_plugins( pb, SLAPI_PLUGIN_POST_BIND_FN );
goto free_and_return;
@@ -642,10 +642,10 @@ do_bind( Slapi_PBlock *pb )
*
*/
- /* get the entry now, so that we can give it to check_account_lock and reslimit_update_from_dn */
+ /* get the entry now, so that we can give it to slapi_check_account_lock and reslimit_update_from_dn */
if (! slapi_be_is_flag_set(be, SLAPI_BE_FLAG_REMOTE_DATA)) {
bind_target_entry = get_entry(pb, slapi_sdn_get_ndn(&sdn));
- rc = check_account_lock ( pb, bind_target_entry, pw_response_requested,0);
+ rc = slapi_check_account_lock ( pb, bind_target_entry, pw_response_requested, 1, 1);
}
slapi_pblock_set( pb, SLAPI_PLUGIN, be->be_database );
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
index 0db7f136..672a9a4d 100644
--- a/ldap/servers/slapd/daemon.c
+++ b/ldap/servers/slapd/daemon.c
@@ -1922,11 +1922,12 @@ slapd_bind_local_user(Connection *conn)
if(entries[0] && 0 == entries[1])
{
/* observe account locking */
- ret = check_account_lock(
+ ret = slapi_check_account_lock(
0, /* pb not req */
entries[0],
0, /* no response control */
- 1 /* inactivation only */
+ 0, /* don't check password policy */
+ 0 /* don't send ldap result */
);
if(0 == ret)
@@ -1981,11 +1982,12 @@ entry_map_free:
if(0 == ret && e)
{
- ret = check_account_lock(
+ ret = slapi_check_account_lock(
0, /* pb not req */
e,
0, /* no response control */
- 1 /* inactivation only */
+ 0, /* don't check password policy */
+ 0 /* don't send ldap result */
);
if(1 == ret)
diff --git a/ldap/servers/slapd/libslapd.def b/ldap/servers/slapd/libslapd.def
index c2bdfbef..c5fd242e 100644
--- a/ldap/servers/slapd/libslapd.def
+++ b/ldap/servers/slapd/libslapd.def
@@ -1198,3 +1198,4 @@ EXPORTS
config_get_pw_maxrepeats @1205
config_get_pw_mincategories @1206
config_get_pw_mintokenlength @1207
+ slapi_check_account_lock @1208
diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
index f1e87a38..15add061 100644
--- a/ldap/servers/slapd/pw.c
+++ b/ldap/servers/slapd/pw.c
@@ -1982,3 +1982,141 @@ check_pw_storagescheme_value( const char *attr_name, char *value, long minval, l
return retVal;
}
+/* check_account_lock is called before bind opeation; this could be a pre-op. */
+int
+slapi_check_account_lock ( Slapi_PBlock *pb, Slapi_Entry * bind_target_entry, int pwresponse_req, int check_password_policy, int send_result) {
+
+ time_t unlock_time;
+ time_t cur_time;
+ char *cur_time_str = NULL;
+ char *accountUnlockTime;
+ passwdPolicy *pwpolicy = NULL;
+ char *dn = NULL;
+
+ /* kexcoff: account inactivation */
+ int rc = 0;
+ Slapi_ValueSet *values = NULL;
+ int type_name_disposition = 0;
+ char *actual_type_name = NULL;
+ int attr_free_flags = 0;
+ /* kexcoff - end */
+
+ if ( bind_target_entry == NULL )
+ return -1;
+
+ if(check_password_policy)
+ {
+ dn = slapi_entry_get_ndn(bind_target_entry);
+ pwpolicy = new_passwdPolicy(pb, dn);
+ }
+
+ /* kexcoff: account inactivation */
+ /* check if the entry is locked by nsAccountLock attribute - account inactivation feature */
+
+ rc = slapi_vattr_values_get(bind_target_entry, "nsAccountLock",
+ &values,
+ &type_name_disposition, &actual_type_name,
+ SLAPI_VIRTUALATTRS_REQUEST_POINTERS,
+ &attr_free_flags);
+ if ( rc == 0 )
+ {
+ Slapi_Value *v = NULL;
+ const struct berval *bvp = NULL;
+
+ if ( (slapi_valueset_first_value( values, &v ) != -1) &&
+ ( bvp = slapi_value_get_berval( v )) != NULL )
+ {
+ if ( (bvp != NULL) && (strcasecmp(bvp->bv_val, "true") == 0) )
+ {
+ /* account inactivated */
+ if (check_password_policy && pwresponse_req) {
+ slapi_pwpolicy_make_response_control ( pb, -1, -1,
+ LDAP_PWPOLICY_ACCTLOCKED );
+ }
+ if (send_result)
+ send_ldap_result ( pb, LDAP_UNWILLING_TO_PERFORM, NULL,
+ "Account inactivated. Contact system administrator.",
+ 0, NULL );
+ slapi_vattr_values_free(&values, &actual_type_name, attr_free_flags);
+ goto locked;
+ }
+ } /* else, account "activated", keep on the process */
+
+ if ( values != NULL )
+ slapi_vattr_values_free(&values, &actual_type_name, attr_free_flags);
+ }
+ /* kexcoff - end */
+
+ /*
+ * Check if the password policy has to be checked or not
+ */
+ if ( !check_password_policy || pwpolicy->pw_lockout == 0 ) {
+ goto notlocked;
+ }
+
+ /*
+ * Check the attribute of the password policy
+ */
+
+ /* check if account is locked out. If so, send result and return 1 */
+ {
+ unsigned int maxfailure= pwpolicy->pw_maxfailure;
+ /* It's locked if passwordRetryCount >= maxfailure */
+ if ( slapi_entry_attr_get_uint(bind_target_entry,"passwordRetryCount") < maxfailure )
+ {
+ /* Not locked */
+ goto notlocked;
+ }
+ }
+
+ /* locked but maybe it's time to unlock it */
+ accountUnlockTime= slapi_entry_attr_get_charptr(bind_target_entry, "accountUnlockTime");
+ if (accountUnlockTime != NULL)
+ {
+ unlock_time = parse_genTime(accountUnlockTime);
+ slapi_ch_free((void **) &accountUnlockTime );
+
+ if ( pwpolicy->pw_unlock == 0 &&
+ unlock_time == NO_TIME ) {
+
+ /* account is locked forever. contact admin to reset */
+ if (pwresponse_req) {
+ slapi_pwpolicy_make_response_control ( pb, -1, -1,
+ LDAP_PWPOLICY_ACCTLOCKED );
+ }
+ if (send_result)
+ send_ldap_result ( pb, LDAP_CONSTRAINT_VIOLATION, NULL,
+ "Exceed password retry limit. Contact system administrator to reset.",
+ 0, NULL );
+ goto locked;
+ }
+ cur_time = current_time();
+ cur_time_str = format_genTime( cur_time);
+ if ( difftime ( parse_genTime( cur_time_str ), unlock_time ) < 0 ) {
+
+ /* account is locked, cannot do anything */
+ if (pwresponse_req) {
+ slapi_pwpolicy_make_response_control ( pb, -1, -1,
+ LDAP_PWPOLICY_ACCTLOCKED );
+ }
+ if (send_result)
+ send_ldap_result ( pb, LDAP_CONSTRAINT_VIOLATION, NULL,
+ "Exceed password retry limit. Please try later.",
+ 0, NULL );
+ slapi_ch_free((void **) &cur_time_str );
+ goto locked;
+ }
+ slapi_ch_free((void **) &cur_time_str );
+ }
+
+notlocked:
+ /* account is not locked. */
+ if(check_password_policy)
+ delete_passwdPolicy(&pwpolicy);
+ return ( 0 );
+locked:
+ if(check_password_policy)
+ delete_passwdPolicy(&pwpolicy);
+ return (1);
+
+}
diff --git a/ldap/servers/slapd/pw_mgmt.c b/ldap/servers/slapd/pw_mgmt.c
index 34afa15b..97b51c8b 100644
--- a/ldap/servers/slapd/pw_mgmt.c
+++ b/ldap/servers/slapd/pw_mgmt.c
@@ -291,142 +291,6 @@ skip:
return( 0 );
}
-/* check_account_lock is called before bind opeation; this could be a pre-op. */
-int
-check_account_lock ( Slapi_PBlock *pb, Slapi_Entry * bind_target_entry, int pwresponse_req, int account_inactivation_only) {
-
- time_t unlock_time;
- time_t cur_time;
- char *cur_time_str = NULL;
- char *accountUnlockTime;
- passwdPolicy *pwpolicy = NULL;
- char *dn = NULL;
-
- /* kexcoff: account inactivation */
- int rc = 0;
- Slapi_ValueSet *values = NULL;
- int type_name_disposition = 0;
- char *actual_type_name = NULL;
- int attr_free_flags = 0;
- /* kexcoff - end */
-
- if ( bind_target_entry == NULL )
- return -1;
-
- if(!account_inactivation_only)
- {
- dn = slapi_entry_get_ndn(bind_target_entry);
- pwpolicy = new_passwdPolicy(pb, dn);
- }
-
- /* kexcoff: account inactivation */
- /* check if the entry is locked by nsAccountLock attribute - account inactivation feature */
-
- rc = slapi_vattr_values_get(bind_target_entry, "nsAccountLock",
- &values,
- &type_name_disposition, &actual_type_name,
- SLAPI_VIRTUALATTRS_REQUEST_POINTERS,
- &attr_free_flags);
- if ( rc == 0 )
- {
- Slapi_Value *v = NULL;
- const struct berval *bvp = NULL;
-
- if ( (slapi_valueset_first_value( values, &v ) != -1) &&
- ( bvp = slapi_value_get_berval( v )) != NULL )
- {
- if ( (bvp != NULL) && (strcasecmp(bvp->bv_val, "true") == 0) )
- {
- /* account inactivated */
- if (!account_inactivation_only && pwresponse_req) {
- slapi_pwpolicy_make_response_control ( pb, -1, -1,
- LDAP_PWPOLICY_ACCTLOCKED );
- }
- if(!account_inactivation_only)
- send_ldap_result ( pb, LDAP_UNWILLING_TO_PERFORM, NULL,
- "Account inactivated. Contact system administrator.",
- 0, NULL );
- slapi_vattr_values_free(&values, &actual_type_name, attr_free_flags);
- goto locked;
- }
- } /* else, account "activated", keep on the process */
-
- if ( values != NULL )
- slapi_vattr_values_free(&values, &actual_type_name, attr_free_flags);
- }
- /* kexcoff - end */
-
- /*
- * Check if the password policy has to be checked or not
- */
- if ( account_inactivation_only || pwpolicy->pw_lockout == 0 ) {
- goto notlocked;
- }
-
- /*
- * Check the attribute of the password policy
- */
-
- /* check if account is locked out. If so, send result and return 1 */
- {
- unsigned int maxfailure= pwpolicy->pw_maxfailure;
- /* It's locked if passwordRetryCount >= maxfailure */
- if ( slapi_entry_attr_get_uint(bind_target_entry,"passwordRetryCount") < maxfailure )
- {
- /* Not locked */
- goto notlocked;
- }
- }
-
- /* locked but maybe it's time to unlock it */
- accountUnlockTime= slapi_entry_attr_get_charptr(bind_target_entry, "accountUnlockTime");
- if (accountUnlockTime != NULL)
- {
- unlock_time = parse_genTime(accountUnlockTime);
- slapi_ch_free((void **) &accountUnlockTime );
-
- if ( pwpolicy->pw_unlock == 0 &&
- unlock_time == NO_TIME ) {
-
- /* account is locked forever. contact admin to reset */
- if (pwresponse_req) {
- slapi_pwpolicy_make_response_control ( pb, -1, -1,
- LDAP_PWPOLICY_ACCTLOCKED );
- }
- send_ldap_result ( pb, LDAP_CONSTRAINT_VIOLATION, NULL,
- "Exceed password retry limit. Contact system administrator to reset."
- , 0, NULL );
- goto locked;
- }
- cur_time = current_time();
- cur_time_str = format_genTime( cur_time);
- if ( difftime ( parse_genTime( cur_time_str ), unlock_time ) < 0 ) {
-
- /* account is locked, cannot do anything */
- if (pwresponse_req) {
- slapi_pwpolicy_make_response_control ( pb, -1, -1,
- LDAP_PWPOLICY_ACCTLOCKED );
- }
- send_ldap_result ( pb, LDAP_CONSTRAINT_VIOLATION, NULL,
- "Exceed password retry limit. Please try later." , 0, NULL );
- slapi_ch_free((void **) &cur_time_str );
- goto locked;
- }
- slapi_ch_free((void **) &cur_time_str );
- }
-
-notlocked:
- /* account is not locked. */
- if(!account_inactivation_only)
- delete_passwdPolicy(&pwpolicy);
- return ( 0 );
-locked:
- if(!account_inactivation_only)
- delete_passwdPolicy(&pwpolicy);
- return (1);
-
-}
-
void
pw_init ( void ) {
slapdFrontendConfig_t *slapdFrontendConfig;
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
index 42d289a8..1ed9942d 100644
--- a/ldap/servers/slapd/saslbind.c
+++ b/ldap/servers/slapd/saslbind.c
@@ -936,7 +936,7 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
{
break;
}
- if ( check_account_lock(pb, bind_target_entry, pwresponse_requested, 0) == 1) {
+ if ( slapi_check_account_lock(pb, bind_target_entry, pwresponse_requested, 1, 1) == 1) {
slapi_entry_free(bind_target_entry);
break;
}
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 5f97c055..47fc7b86 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -5953,6 +5953,8 @@ int slapi_set_plugin_default_config(const char *type, Slapi_Value *value);
* */
int slapi_get_plugin_default_config(char *type, Slapi_ValueSet **valueset);
+int slapi_check_account_lock( Slapi_PBlock *pb, Slapi_Entry *bind_target_entry, int pwresponse_req, int check_password_policy, int send_result);
+
#ifdef __cplusplus
}
#endif