- rc = slap_passwd_parse( op->oq_extended.rs_reqdata, &id, &old, &new, &rs->sr_text );
- if (rc != LDAP_SUCCESS)
- return rc;
-
- if (id.bv_len) {
- dn = id;
- } else {
- dn = op->o_dn;
- }
-
-#ifdef NEW_LOGGING
- LDAP_LOG ( ACL, DETAIL1, "ldap_back_exop_passwd: \"%s\"%s\"\n",
- dn.bv_val, id.bv_len ? " (proxy)" : "", 0 );
-#else
- Debug( LDAP_DEBUG_TRACE, "ldap_back_exop_passwd: \"%s\"%s\n",
- dn.bv_val, id.bv_len ? " (proxy)" : "", 0 );
-#endif
-
- if (dn.bv_len == 0) {
- rs->sr_text = "No password is associated with the Root DSE";
- return LDAP_UNWILLING_TO_PERFORM;
- }
- if (id.bv_len) {
- dc.rwmap = &li->rwmap;
-#ifdef ENABLE_REWRITE
- dc.conn = op->o_conn;
- dc.rs = rs;
- dc.ctx = "modifyPwd";
-#else
- dc.tofrom = 1;
- dc.normalized = 0;
-#endif
- if ( ldap_back_dn_massage( &dc, &dn, &mdn ) ) {
- send_ldap_result( op, rs );
- return -1;
+ isproxy = ber_bvcmp( &ndn, &op->o_ndn );
+
+ Debug( LDAP_DEBUG_ARGS, "==> ldap_back_exop_passwd(\"%s\")%s\n",
+ dn.bv_val, isproxy ? " (proxy)" : "", 0 );
+
+retry:
+ rc = ldap_passwd( lc->lc_ld, isproxy ? &dn : NULL,
+ qpw->rs_old.bv_val ? &qpw->rs_old : NULL,
+ qpw->rs_new.bv_val ? &qpw->rs_new : NULL,
+ op->o_ctrls, NULL, &msgid );
+
+ if ( rc == LDAP_SUCCESS ) {
+ /* TODO: set timeout? */
+ /* by now, make sure no timeout is used (ITS#6282) */
+ struct timeval tv = { -1, 0 };
+ if ( ldap_result( lc->lc_ld, msgid, LDAP_MSG_ALL, &tv, &res ) == -1 ) {
+ ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER, &rc );
+ rs->sr_err = rc;
+
+ } else {
+ /* only touch when activity actually took place... */
+ if ( li->li_idle_timeout && lc ) {
+ lc->lc_time = op->o_time;
+ }
+
+ /* sigh. parse twice, because parse_passwd
+ * doesn't give us the err / match / msg info.
+ */
+ rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err,
+ (char **)&rs->sr_matched,
+ &text,
+ NULL, &rs->sr_ctrls, 0 );
+
+ if ( rc == LDAP_SUCCESS ) {
+ if ( rs->sr_err == LDAP_SUCCESS ) {
+ struct berval newpw;
+
+ /* this never happens because
+ * the frontend is generating
+ * the new password, so when
+ * the passwd exop is proxied,
+ * it never delegates password
+ * generation to the remote server
+ */
+ rc = ldap_parse_passwd( lc->lc_ld, res,
+ &newpw );
+ if ( rc == LDAP_SUCCESS &&
+ !BER_BVISNULL( &newpw ) )
+ {
+ rs->sr_type = REP_EXTENDED;
+ rs->sr_rspdata = slap_passwd_return( &newpw );
+ free( newpw.bv_val );
+ }
+
+ } else {
+ rc = rs->sr_err;
+ }
+ }
+ ldap_msgfree( res );