[389-commits] ldap/servers

Richard Allen Megginson rmeggins at fedoraproject.org
Sat Mar 13 02:50:33 UTC 2010


 ldap/servers/plugins/pam_passthru/pam_ptimpl.c |   17 ++-
 ldap/servers/slapd/bind.c                      |    8 -
 ldap/servers/slapd/daemon.c                    |   10 +
 ldap/servers/slapd/libslapd.def                |    1 
 ldap/servers/slapd/pw.c                        |  138 +++++++++++++++++++++++++
 ldap/servers/slapd/pw_mgmt.c                   |  136 ------------------------
 ldap/servers/slapd/saslbind.c                  |    2 
 ldap/servers/slapd/slapi-plugin.h              |    2 
 8 files changed, 167 insertions(+), 147 deletions(-)

New commits:
commit 1ef0ec98b6c91471454647e5f613d26fa015c619
Author: Endi S. Dewata <edewata at redhat.com>
Date:   Thu Mar 11 14:26:56 2010 -0600

    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.

diff --git a/ldap/servers/plugins/pam_passthru/pam_ptimpl.c b/ldap/servers/plugins/pam_passthru/pam_ptimpl.c
index 6e5fc9f..662239f 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 d3e9009..f0bdbae 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 0db7f13..672a9a4 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 c2bdfbe..c5fd242 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 f1e87a3..15add06 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 34afa15..97b51c8 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 42d289a..1ed9942 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 5f97c05..47fc7b8 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




More information about the 389-commits mailing list