|
|
dc8c34 |
From cb1ef86c225632f7ac2d267a5e3687b156ffc3bf Mon Sep 17 00:00:00 2001
|
|
|
dc8c34 |
From: Noriko Hosoi <nhosoi@redhat.com>
|
|
|
dc8c34 |
Date: Fri, 21 Mar 2014 14:21:13 -0700
|
|
|
dc8c34 |
Subject: [PATCH 190/225] Ticket #47748 - Simultaneous adding a user and
|
|
|
dc8c34 |
binding as the user could fail in the password policy check
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Bug description: In do_bind, bind_target_entry is retrieved from the
|
|
|
dc8c34 |
DB or the entry cache. There was a small window that the entry failed
|
|
|
dc8c34 |
to retrieve from there but the bind procedure in the backend (be_bind)
|
|
|
dc8c34 |
succeeds. In the case, NULL bind_target_entry is passed to the Pass-
|
|
|
dc8c34 |
word Policy check and it fails.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Fix description: If be_bind returns SUCCESS and bind_target_entry is
|
|
|
dc8c34 |
NULL, retrieve bind_target_entry agian, which is guaranteed since the
|
|
|
dc8c34 |
entry was retrieved in the backend and placed in the entry cache.
|
|
|
dc8c34 |
|
|
|
dc8c34 |
https://fedorahosted.org/389/ticket/47748
|
|
|
dc8c34 |
|
|
|
dc8c34 |
Reviewed by rmeggins@redhat.com (Thank you, Rich!!)
|
|
|
dc8c34 |
(cherry picked from commit 4fc53e1a63222d0ff67c30a59f2cff4b535f90a8)
|
|
|
dc8c34 |
(cherry picked from commit f8f063c3fb2c7642506cbad923c71972f78edac2)
|
|
|
dc8c34 |
(cherry picked from commit feed9ba773766ade744ca4d45aca46c91d4b7f4f)
|
|
|
dc8c34 |
(cherry picked from commit f9b2bec732645bf0d219e790448b191c4652858e)
|
|
|
dc8c34 |
---
|
|
|
dc8c34 |
ldap/servers/slapd/bind.c | 105 ++++++++++++++++++++++++++-----------------
|
|
|
dc8c34 |
ldap/servers/slapd/entry.c | 18 ++++----
|
|
|
dc8c34 |
ldap/servers/slapd/pw_mgmt.c | 3 ++
|
|
|
dc8c34 |
3 files changed, 75 insertions(+), 51 deletions(-)
|
|
|
dc8c34 |
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
|
|
|
dc8c34 |
index ec874cc..97b236e 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/bind.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/bind.c
|
|
|
dc8c34 |
@@ -429,6 +429,7 @@ do_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
if (!strcasecmp (saslmech, LDAP_SASL_EXTERNAL)) {
|
|
|
dc8c34 |
/* call preop plugins */
|
|
|
dc8c34 |
if (plugin_call_plugins( pb, SLAPI_PLUGIN_PRE_BIND_FN ) != 0){
|
|
|
dc8c34 |
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "", 0, NULL);
|
|
|
dc8c34 |
goto free_and_return;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
@@ -474,10 +475,10 @@ do_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
goto free_and_return;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- if (!isroot ) {
|
|
|
dc8c34 |
+ if (!isroot) {
|
|
|
dc8c34 |
/* check if the account is locked */
|
|
|
dc8c34 |
bind_target_entry = get_entry(pb, pb->pb_conn->c_external_dn);
|
|
|
dc8c34 |
- if ( bind_target_entry != NULL && slapi_check_account_lock(pb, bind_target_entry,
|
|
|
dc8c34 |
+ if ( bind_target_entry && slapi_check_account_lock(pb, bind_target_entry,
|
|
|
dc8c34 |
pw_response_requested, 1 /*check password policy*/, 1 /*send ldap result*/) == 1) {
|
|
|
dc8c34 |
/* call postop plugins */
|
|
|
dc8c34 |
plugin_call_plugins( pb, SLAPI_PLUGIN_POST_BIND_FN );
|
|
|
dc8c34 |
@@ -553,6 +554,8 @@ do_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* call postop plugins */
|
|
|
dc8c34 |
plugin_call_plugins( pb, SLAPI_PLUGIN_POST_BIND_FN );
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "", 0, NULL);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
goto free_and_return;
|
|
|
dc8c34 |
/* Check if unauthenticated binds are allowed. */
|
|
|
dc8c34 |
@@ -651,7 +654,7 @@ do_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
bind_credentials_set( pb->pb_conn, SLAPD_AUTH_SIMPLE, slapi_ch_strdup(slapi_sdn_get_ndn(sdn)),
|
|
|
dc8c34 |
NULL, NULL, NULL , NULL);
|
|
|
dc8c34 |
} else {
|
|
|
dc8c34 |
- /*
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
* right dn, wrong passwd - reject with invalid credentials
|
|
|
dc8c34 |
*/
|
|
|
dc8c34 |
send_ldap_result( pb, LDAP_INVALID_CREDENTIALS, NULL, NULL, 0, NULL );
|
|
|
dc8c34 |
@@ -675,6 +678,8 @@ do_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
|
|
|
dc8c34 |
/* call postop plugins */
|
|
|
dc8c34 |
plugin_call_plugins( pb, SLAPI_PLUGIN_POST_BIND_FN );
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "", 0, NULL);
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
goto free_and_return;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
@@ -733,9 +738,10 @@ do_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
(rc == SLAPI_BIND_ANONYMOUS))) ) {
|
|
|
dc8c34 |
long t;
|
|
|
dc8c34 |
char* authtype = NULL;
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
- if(auto_bind)
|
|
|
dc8c34 |
+ /* rc is SLAPI_BIND_SUCCESS or SLAPI_BIND_ANONYMOUS */
|
|
|
dc8c34 |
+ if(auto_bind) {
|
|
|
dc8c34 |
rc = SLAPI_BIND_SUCCESS;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
|
|
|
dc8c34 |
switch ( method ) {
|
|
|
dc8c34 |
case LDAP_AUTH_SIMPLE:
|
|
|
dc8c34 |
@@ -755,53 +761,68 @@ do_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
/* authtype = SLAPD_AUTH_SASL && saslmech: */
|
|
|
dc8c34 |
PR_snprintf(authtypebuf, sizeof(authtypebuf), "%s%s", SLAPD_AUTH_SASL, saslmech);
|
|
|
dc8c34 |
authtype = authtypebuf;
|
|
|
dc8c34 |
- break;
|
|
|
dc8c34 |
- default: /* ??? */
|
|
|
dc8c34 |
+ break;
|
|
|
dc8c34 |
+ default:
|
|
|
dc8c34 |
break;
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if ( rc == SLAPI_BIND_SUCCESS ) {
|
|
|
dc8c34 |
- if(!auto_bind)
|
|
|
dc8c34 |
- bind_credentials_set( pb->pb_conn,
|
|
|
dc8c34 |
- authtype, slapi_ch_strdup(
|
|
|
dc8c34 |
- slapi_sdn_get_ndn(sdn)),
|
|
|
dc8c34 |
- NULL, NULL, NULL, bind_target_entry );
|
|
|
dc8c34 |
- if ( auth_response_requested ) {
|
|
|
dc8c34 |
- slapi_add_auth_response_control( pb,
|
|
|
dc8c34 |
- slapi_sdn_get_ndn(sdn));
|
|
|
dc8c34 |
+ if (!auto_bind) {
|
|
|
dc8c34 |
+ /*
|
|
|
dc8c34 |
+ * There could be a race that bind_target_entry was not added
|
|
|
dc8c34 |
+ * when bind_target_entry was retrieved before be_bind, but it
|
|
|
dc8c34 |
+ * was in be_bind. Since be_bind returned SLAPI_BIND_SUCCESS,
|
|
|
dc8c34 |
+ * the entry is in the DS. So, we need to retrieve it once more.
|
|
|
dc8c34 |
+ */
|
|
|
dc8c34 |
+ if (!bind_target_entry) {
|
|
|
dc8c34 |
+ bind_target_entry = get_entry(pb, slapi_sdn_get_ndn(sdn));
|
|
|
dc8c34 |
+ if (bind_target_entry) {
|
|
|
dc8c34 |
+ rc = slapi_check_account_lock(pb, bind_target_entry,
|
|
|
dc8c34 |
+ pw_response_requested, 1, 1);
|
|
|
dc8c34 |
+ if (1 == rc) { /* account is locked */
|
|
|
dc8c34 |
+ goto account_locked;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+ send_ldap_result(pb, LDAP_NO_SUCH_OBJECT, NULL, "", 0, NULL);
|
|
|
dc8c34 |
+ goto free_and_return;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ bind_credentials_set(pb->pb_conn, authtype,
|
|
|
dc8c34 |
+ slapi_ch_strdup(slapi_sdn_get_ndn(sdn)),
|
|
|
dc8c34 |
+ NULL, NULL, NULL, bind_target_entry);
|
|
|
dc8c34 |
+ if (!slapi_be_is_flag_set(be, SLAPI_BE_FLAG_REMOTE_DATA)) {
|
|
|
dc8c34 |
+ /* check if need new password before sending
|
|
|
dc8c34 |
+ the bind success result */
|
|
|
dc8c34 |
+ rc = need_new_pw(pb, &t, bind_target_entry, pw_response_requested);
|
|
|
dc8c34 |
+ switch (rc) {
|
|
|
dc8c34 |
+ case 1:
|
|
|
dc8c34 |
+ (void)slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
|
|
|
dc8c34 |
+ break;
|
|
|
dc8c34 |
+ case 2:
|
|
|
dc8c34 |
+ (void)slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRING, t);
|
|
|
dc8c34 |
+ break;
|
|
|
dc8c34 |
+ default:
|
|
|
dc8c34 |
+ break;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
+ if (auth_response_requested) {
|
|
|
dc8c34 |
+ slapi_add_auth_response_control(pb, slapi_sdn_get_ndn(sdn));
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
+ if (-1 == rc) {
|
|
|
dc8c34 |
+ /* neeed_new_pw failed; need_new_pw already send_ldap_result in it. */
|
|
|
dc8c34 |
+ goto free_and_return;
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
} else { /* anonymous */
|
|
|
dc8c34 |
/* set bind creds here so anonymous limits are set */
|
|
|
dc8c34 |
- bind_credentials_set( pb->pb_conn, authtype, NULL,
|
|
|
dc8c34 |
- NULL, NULL, NULL, NULL );
|
|
|
dc8c34 |
+ bind_credentials_set(pb->pb_conn, authtype, NULL, NULL, NULL, NULL, NULL);
|
|
|
dc8c34 |
|
|
|
dc8c34 |
if ( auth_response_requested ) {
|
|
|
dc8c34 |
- slapi_add_auth_response_control( pb,
|
|
|
dc8c34 |
- "" );
|
|
|
dc8c34 |
+ slapi_add_auth_response_control(pb, "");
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
- if ( 0 == auto_bind && (rc != SLAPI_BIND_ANONYMOUS) &&
|
|
|
dc8c34 |
- ! slapi_be_is_flag_set(be, SLAPI_BE_FLAG_REMOTE_DATA)) {
|
|
|
dc8c34 |
- /* check if need new password before sending
|
|
|
dc8c34 |
- the bind success result */
|
|
|
dc8c34 |
- switch ( need_new_pw (pb, &t, bind_target_entry, pw_response_requested )) {
|
|
|
dc8c34 |
- case 1:
|
|
|
dc8c34 |
- (void)slapi_add_pwd_control ( pb,
|
|
|
dc8c34 |
- LDAP_CONTROL_PWEXPIRED, 0);
|
|
|
dc8c34 |
- break;
|
|
|
dc8c34 |
- case 2:
|
|
|
dc8c34 |
- (void)slapi_add_pwd_control ( pb,
|
|
|
dc8c34 |
- LDAP_CONTROL_PWEXPIRING, t);
|
|
|
dc8c34 |
- break;
|
|
|
dc8c34 |
- case -1:
|
|
|
dc8c34 |
- goto free_and_return;
|
|
|
dc8c34 |
- default:
|
|
|
dc8c34 |
- break;
|
|
|
dc8c34 |
- }
|
|
|
dc8c34 |
- } /* end if */
|
|
|
dc8c34 |
- }else{
|
|
|
dc8c34 |
-
|
|
|
dc8c34 |
+ } else {
|
|
|
dc8c34 |
+account_locked:
|
|
|
dc8c34 |
if(cred.bv_len == 0) {
|
|
|
dc8c34 |
/* its an UnAuthenticated Bind, DN specified but no pw */
|
|
|
dc8c34 |
slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsUnAuthBinds);
|
|
|
dc8c34 |
@@ -837,7 +858,7 @@ do_bind( Slapi_PBlock *pb )
|
|
|
dc8c34 |
"Function not implemented", 0, NULL );
|
|
|
dc8c34 |
}
|
|
|
dc8c34 |
|
|
|
dc8c34 |
- free_and_return:;
|
|
|
dc8c34 |
+free_and_return:;
|
|
|
dc8c34 |
if (be)
|
|
|
dc8c34 |
slapi_be_Unlock(be);
|
|
|
dc8c34 |
slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &sdn;;
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c
|
|
|
dc8c34 |
index 04bac0d..d9226af 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/entry.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/entry.c
|
|
|
dc8c34 |
@@ -2654,8 +2654,8 @@ slapi_entry_attr_get_charray( const Slapi_Entry* e, const char *type)
|
|
|
dc8c34 |
char *
|
|
|
dc8c34 |
slapi_entry_attr_get_charptr( const Slapi_Entry* e, const char *type)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
- char *p= NULL;
|
|
|
dc8c34 |
- Slapi_Attr* attr;
|
|
|
dc8c34 |
+ char *p= NULL;
|
|
|
dc8c34 |
+ Slapi_Attr* attr = NULL;
|
|
|
dc8c34 |
slapi_entry_attr_find(e, type, &attr);
|
|
|
dc8c34 |
if(attr!=NULL)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
@@ -2674,7 +2674,7 @@ int
|
|
|
dc8c34 |
slapi_entry_attr_get_int( const Slapi_Entry* e, const char *type)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
int r= 0;
|
|
|
dc8c34 |
- Slapi_Attr* attr;
|
|
|
dc8c34 |
+ Slapi_Attr* attr = NULL;
|
|
|
dc8c34 |
slapi_entry_attr_find(e, type, &attr);
|
|
|
dc8c34 |
if (attr!=NULL)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
@@ -2689,7 +2689,7 @@ unsigned int
|
|
|
dc8c34 |
slapi_entry_attr_get_uint( const Slapi_Entry* e, const char *type)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
unsigned int r= 0;
|
|
|
dc8c34 |
- Slapi_Attr* attr;
|
|
|
dc8c34 |
+ Slapi_Attr* attr = NULL;
|
|
|
dc8c34 |
slapi_entry_attr_find(e, type, &attr);
|
|
|
dc8c34 |
if (attr!=NULL)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
@@ -2704,7 +2704,7 @@ long
|
|
|
dc8c34 |
slapi_entry_attr_get_long( const Slapi_Entry* e, const char *type)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
long r = 0;
|
|
|
dc8c34 |
- Slapi_Attr* attr;
|
|
|
dc8c34 |
+ Slapi_Attr* attr = NULL;
|
|
|
dc8c34 |
slapi_entry_attr_find(e, type, &attr);
|
|
|
dc8c34 |
if (attr!=NULL)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
@@ -2719,7 +2719,7 @@ unsigned long
|
|
|
dc8c34 |
slapi_entry_attr_get_ulong( const Slapi_Entry* e, const char *type)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
unsigned long r = 0;
|
|
|
dc8c34 |
- Slapi_Attr* attr;
|
|
|
dc8c34 |
+ Slapi_Attr* attr = NULL;
|
|
|
dc8c34 |
slapi_entry_attr_find(e, type, &attr);
|
|
|
dc8c34 |
if (attr!=NULL)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
@@ -2734,7 +2734,7 @@ long long
|
|
|
dc8c34 |
slapi_entry_attr_get_longlong( const Slapi_Entry* e, const char *type)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
long long r = 0;
|
|
|
dc8c34 |
- Slapi_Attr* attr;
|
|
|
dc8c34 |
+ Slapi_Attr* attr = NULL;
|
|
|
dc8c34 |
slapi_entry_attr_find(e, type, &attr);
|
|
|
dc8c34 |
if (attr!=NULL)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
@@ -2749,7 +2749,7 @@ unsigned long long
|
|
|
dc8c34 |
slapi_entry_attr_get_ulonglong( const Slapi_Entry* e, const char *type)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
unsigned long long r = 0;
|
|
|
dc8c34 |
- Slapi_Attr* attr;
|
|
|
dc8c34 |
+ Slapi_Attr* attr = NULL;
|
|
|
dc8c34 |
slapi_entry_attr_find(e, type, &attr);
|
|
|
dc8c34 |
if (attr!=NULL)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
@@ -2764,7 +2764,7 @@ PRBool
|
|
|
dc8c34 |
slapi_entry_attr_get_bool( const Slapi_Entry* e, const char *type)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
PRBool r = PR_FALSE; /* default if no attr */
|
|
|
dc8c34 |
- Slapi_Attr* attr;
|
|
|
dc8c34 |
+ Slapi_Attr* attr = NULL;
|
|
|
dc8c34 |
slapi_entry_attr_find(e, type, &attr);
|
|
|
dc8c34 |
if (attr!=NULL)
|
|
|
dc8c34 |
{
|
|
|
dc8c34 |
diff --git a/ldap/servers/slapd/pw_mgmt.c b/ldap/servers/slapd/pw_mgmt.c
|
|
|
dc8c34 |
index f173128..7a8d390 100644
|
|
|
dc8c34 |
--- a/ldap/servers/slapd/pw_mgmt.c
|
|
|
dc8c34 |
+++ b/ldap/servers/slapd/pw_mgmt.c
|
|
|
dc8c34 |
@@ -68,6 +68,9 @@ need_new_pw( Slapi_PBlock *pb, long *t, Slapi_Entry *e, int pwresponse_req )
|
|
|
dc8c34 |
int pwdGraceUserTime = 0;
|
|
|
dc8c34 |
char graceUserTime[8];
|
|
|
dc8c34 |
|
|
|
dc8c34 |
+ if (NULL == e) {
|
|
|
dc8c34 |
+ return (-1);
|
|
|
dc8c34 |
+ }
|
|
|
dc8c34 |
slapi_mods_init (&smods, 0);
|
|
|
dc8c34 |
sdn = slapi_entry_get_sdn_const( e );
|
|
|
dc8c34 |
dn = slapi_entry_get_ndn( e );
|
|
|
dc8c34 |
--
|
|
|
dc8c34 |
1.8.1.4
|
|
|
dc8c34 |
|