summaryrefslogtreecommitdiffstats
path: root/ldap
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 /ldap
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.
Diffstat (limited to 'ldap')
-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