1 /* extended.c - ldap backend extended routines */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2003-2004 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
17 * This work was initially developed by the Howard Chu for inclusion
18 * in OpenLDAP Software and subsequently enhanced by Pierangelo
25 #include <ac/string.h>
28 #include "back-ldap.h"
31 BI_op_extended ldap_back_exop_passwd;
35 BI_op_extended *extended;
37 { (struct berval *)&slap_EXOP_MODIFY_PASSWD, ldap_back_exop_passwd },
48 for ( i = 0; exop_table[i].extended != NULL; i++ ) {
49 if ( bvmatch( exop_table[i].oid, &op->oq_extended.rs_reqoid ) )
51 #ifdef LDAP_BACK_PROXY_AUTHZ
53 LDAPControl **oldctrls = NULL;
56 /* FIXME: this needs to be called here, so it is
57 * called twice; maybe we could avoid the
58 * ldap_back_dobind() call inside each extended()
60 lc = ldap_back_getconn( op, rs );
61 if ( !lc || !ldap_back_dobind( lc, op, rs ) ) {
65 oldctrls = op->o_ctrls;
66 if ( ldap_back_proxy_authz_ctrl( lc, op, rs,
69 op->o_ctrls = oldctrls;
70 send_ldap_result( op, rs );
75 rc = ( *exop_table[i].extended )( op, rs );
77 if ( op->o_ctrls && op->o_ctrls != oldctrls ) {
78 free( op->o_ctrls[ 0 ] );
81 op->o_ctrls = oldctrls;
84 #else /* ! LDAP_BACK_PROXY_AUTHZ */
85 return ( *exop_table[i].extended )( op, rs );
86 #endif /* ! LDAP_BACK_PROXY_AUTHZ */
90 rs->sr_text = "not supported within naming context";
91 return LDAP_UNWILLING_TO_PERFORM;
95 ldap_back_exop_passwd(
100 req_pwdexop_s *qpw = &op->oq_pwdexop;
106 lc = ldap_back_getconn( op, rs );
107 if ( !lc || !ldap_back_dobind( lc, op, rs ) ) {
111 isproxy = ber_bvcmp( &op->o_req_ndn, &op->o_ndn );
113 Debug( LDAP_DEBUG_ARGS, "==> ldap_back_exop_passwd(\"%s\")%s\n",
114 op->o_req_dn.bv_val, isproxy ? " (proxy)" : "", 0 );
117 rc = ldap_passwd( lc->lc_ld, isproxy ? &op->o_req_dn : NULL,
118 qpw->rs_old.bv_val ? &qpw->rs_old : NULL,
119 qpw->rs_new.bv_val ? &qpw->rs_new : NULL,
120 op->o_ctrls, NULL, &msgid );
122 if ( rc == LDAP_SUCCESS ) {
123 if ( ldap_result( lc->lc_ld, msgid, 1, NULL, &res ) == -1 ) {
124 ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER, &rc );
125 ldap_back_freeconn( op, lc );
129 /* sigh. parse twice, because parse_passwd
130 * doesn't give us the err / match / msg info.
132 rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err,
133 (char **)&rs->sr_matched,
134 (char **)&rs->sr_text,
136 if ( rc == LDAP_SUCCESS ) {
137 if ( rs->sr_err == LDAP_SUCCESS ) {
140 rc = ldap_parse_passwd( lc->lc_ld, res,
142 if ( rc == LDAP_SUCCESS &&
143 !BER_BVISNULL( &newpw ) )
145 rs->sr_type = REP_EXTENDED;
146 rs->sr_rspdata = slap_passwd_return( &newpw );
147 free( newpw.bv_val );
157 if ( rc != LDAP_SUCCESS ) {
158 rs->sr_err = slap_map_api2result( rs );
159 if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
161 if ( ldap_back_retry(lc, op, rs ) ) {
165 send_ldap_result( op, rs );
166 if ( rs->sr_matched ) {
167 free( (char *)rs->sr_matched );
170 free( (char *)rs->sr_text );
172 rs->sr_matched = NULL;