diff options
author | Rich Megginson <rmeggins@redhat.com> | 2006-02-15 21:22:46 +0000 |
---|---|---|
committer | Rich Megginson <rmeggins@redhat.com> | 2006-02-15 21:22:46 +0000 |
commit | 191bf22c1f01d96e89b6359722580e9581506475 (patch) | |
tree | 0514929ba358cb71ea71de508caf9e2ec39349fc /ldap | |
parent | 92a9ca8975f64a89e5b1dfe569dce38b0ffb5f25 (diff) | |
download | ds-191bf22c1f01d96e89b6359722580e9581506475.tar.gz ds-191bf22c1f01d96e89b6359722580e9581506475.tar.xz ds-191bf22c1f01d96e89b6359722580e9581506475.zip |
Bug(s) fixed: 181587
Bug Description: Password Modify LDAPv3 extended operation erroneously
forces the client to supply old password
Reviewed by: Pete & Nathan (Thanks!)
Fix Description: If the BIND operation was successful, the CONN_DN field
is always set to the proper DN. This is even the case during a SASL or
client cert DN if the authentication was successful AND the given
identity could be mapped to a real user in the directory. Also, the
authmethod will be something other than NULL or none. So, if the old
password was not given, that is ok if there is a non-anonymous bind DN
and a real authmethod. The rest of the operation passes through the usual access control.
Platforms tested: Fedora Core 4
Flag Day: no
Doc impact: no
Diffstat (limited to 'ldap')
-rw-r--r-- | ldap/servers/slapd/passwd_extop.c | 74 |
1 files changed, 45 insertions, 29 deletions
diff --git a/ldap/servers/slapd/passwd_extop.c b/ldap/servers/slapd/passwd_extop.c index 4455c158..f7dae57c 100644 --- a/ldap/servers/slapd/passwd_extop.c +++ b/ldap/servers/slapd/passwd_extop.c @@ -201,6 +201,7 @@ passwd_modify_extop( Slapi_PBlock *pb ) { char *oid = NULL; char *bindDN = NULL; + char *authmethod = NULL; char *dn = NULL; char *oldPasswd = NULL; char *newPasswd = NULL; @@ -297,6 +298,7 @@ passwd_modify_extop( Slapi_PBlock *pb ) { if ( ber_scanf( ber, "a", &dn) == LBER_ERROR ) { + slapi_ch_free_string(&dn); LDAPDebug( LDAP_DEBUG_ANY, "ber_scanf failed :{\n", 0, 0, 0 ); errMesg = "ber_scanf failed at userID parse.\n"; @@ -313,6 +315,7 @@ passwd_modify_extop( Slapi_PBlock *pb ) { if ( ber_scanf( ber, "a", &oldPasswd ) == LBER_ERROR ) { + slapi_ch_free_string(&oldPasswd); LDAPDebug( LDAP_DEBUG_ANY, "ber_scanf failed :{\n", 0, 0, 0 ); errMesg = "ber_scanf failed at oldPasswd parse.\n"; @@ -320,10 +323,6 @@ passwd_modify_extop( Slapi_PBlock *pb ) goto free_and_return; } tag = ber_peek_tag( ber, &len); - } else { - errMesg = "Current passwd must be supplied by the user.\n"; - rc = LDAP_PARAM_ERROR; - goto free_and_return; } /* identify newPasswd field by tags */ @@ -331,6 +330,7 @@ passwd_modify_extop( Slapi_PBlock *pb ) { if ( ber_scanf( ber, "a", &newPasswd ) == LBER_ERROR ) { + slapi_ch_free_string(&newPasswd); LDAPDebug( LDAP_DEBUG_ANY, "ber_scanf failed :{\n", 0, 0, 0 ); errMesg = "ber_scanf failed at newPasswd parse.\n"; @@ -348,12 +348,27 @@ passwd_modify_extop( Slapi_PBlock *pb ) dn, oldPasswd, newPasswd); */ - if (oldPasswd == NULL || *oldPasswd == '\0') { - /* Refuse to handle this operation because current password is not provided */ - errMesg = "Current passwd must be supplied by the user.\n"; - rc = LDAP_PARAM_ERROR; + /* Get Bind DN */ + slapi_pblock_get( pb, SLAPI_CONN_DN, &bindDN ); + + /* If the connection is bound anonymously, we must refuse to process this operation. */ + if (bindDN == NULL || *bindDN == '\0') { + /* Refuse the operation because they're bound anonymously */ + errMesg = "Anonymous Binds are not allowed.\n"; + rc = LDAP_INSUFFICIENT_ACCESS; goto free_and_return; } + + if (oldPasswd == NULL || *oldPasswd == '\0') { + /* If user is authenticated, they already gave their password during + the bind operation (or used sasl or client cert auth) */ + slapi_pblock_get(pb, SLAPI_CONN_AUTHMETHOD, &authmethod); + if (!authmethod || !strcmp(authmethod, SLAPD_AUTH_NONE)) { + errMesg = "User must be authenticated to the directory server.\n"; + rc = LDAP_INSUFFICIENT_ACCESS; + goto free_and_return; + } + } /* We don't implement password generation, so if the request implies * that they asked us to do that, we must refuse to process it */ @@ -364,22 +379,12 @@ passwd_modify_extop( Slapi_PBlock *pb ) goto free_and_return; } - /* Get Bind DN */ - slapi_pblock_get( pb, SLAPI_CONN_DN, &bindDN ); - - /* If the connection is bound anonymously, we must refuse to process this operation. */ - if (bindDN == NULL || *bindDN == '\0') { - /* Refuse the operation because they're bound anonymously */ - errMesg = "Anonymous Binds are not allowed.\n"; - rc = LDAP_INSUFFICIENT_ACCESS; - goto free_and_return; - } /* Determine the target DN for this operation */ /* Did they give us a DN ? */ if (dn == NULL || *dn == '\0') { /* Get the DN from the bind identity on this connection */ - dn = bindDN; + dn = slapi_ch_strdup(bindDN); LDAPDebug( LDAP_DEBUG_ANY, "Missing userIdentity in request, using the bind DN instead.\n", 0, 0, 0 ); @@ -433,13 +438,15 @@ passwd_modify_extop( Slapi_PBlock *pb ) * They gave us a password (old), check it against the target entry * Is the old password valid ? */ - ret = passwd_check_pwd(targetEntry, oldPasswd); - if (ret) { - /* No, then we fail this operation */ - errMesg = "Invalid oldPasswd value.\n"; - rc = ret; - goto free_and_return; - } + if (oldPasswd && *oldPasswd) { + ret = passwd_check_pwd(targetEntry, oldPasswd); + if (ret) { + /* No, then we fail this operation */ + errMesg = "Invalid oldPasswd value.\n"; + rc = ret; + goto free_and_return; + } + } /* Now we're ready to make actual password change */ @@ -455,7 +462,17 @@ passwd_modify_extop( Slapi_PBlock *pb ) /* Free anything that we allocated above */ free_and_return: - + + slapi_ch_free_string(&oldPasswd); + slapi_ch_free_string(&newPasswd); + /* Either this is the same pointer that we allocated and set above, + or whoever used it should have freed it and allocated a new + value that we need to free here */ + slapi_pblock_get( pb, SLAPI_ORIGINAL_TARGET, &dn ); + slapi_ch_free_string(&dn); + slapi_pblock_set( pb, SLAPI_ORIGINAL_TARGET, NULL ); + slapi_ch_free_string(&authmethod); + if ( targetEntry != NULL ){ slapi_entry_free (targetEntry); } @@ -465,9 +482,8 @@ passwd_modify_extop( Slapi_PBlock *pb ) ber = NULL; } - slapi_log_error( SLAPI_LOG_PLUGIN, "passwd_modify_extop", - errMesg ); + errMesg ? errMesg : "success" ); send_ldap_result( pb, rc, NULL, errMesg, 0, NULL ); |