1 /* extended.c - ldap backend extended routines */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2003-2005 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 ) )
52 LDAPControl **oldctrls = NULL;
55 /* FIXME: this needs to be called here, so it is
56 * called twice; maybe we could avoid the
57 * ldap_back_dobind() call inside each extended()
59 lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
60 if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
64 oldctrls = op->o_ctrls;
65 if ( ldap_back_proxy_authz_ctrl( lc, op, rs,
68 op->o_ctrls = oldctrls;
69 send_ldap_result( op, rs );
74 rc = ( *exop_table[i].extended )( op, rs );
76 if ( op->o_ctrls && op->o_ctrls != oldctrls ) {
77 free( op->o_ctrls[ 0 ] );
80 op->o_ctrls = oldctrls;
86 rs->sr_text = "not supported within naming context";
87 return LDAP_UNWILLING_TO_PERFORM;
91 ldap_back_exop_passwd(
96 req_pwdexop_s *qpw = &op->oq_pwdexop;
102 lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
103 if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
107 isproxy = ber_bvcmp( &op->o_req_ndn, &op->o_ndn );
109 Debug( LDAP_DEBUG_ARGS, "==> ldap_back_exop_passwd(\"%s\")%s\n",
110 op->o_req_dn.bv_val, isproxy ? " (proxy)" : "", 0 );
113 rc = ldap_passwd( lc->lc_ld, isproxy ? &op->o_req_dn : NULL,
114 qpw->rs_old.bv_val ? &qpw->rs_old : NULL,
115 qpw->rs_new.bv_val ? &qpw->rs_new : NULL,
116 op->o_ctrls, NULL, &msgid );
118 if ( rc == LDAP_SUCCESS ) {
119 if ( ldap_result( lc->lc_ld, msgid, 1, NULL, &res ) == -1 ) {
120 ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER, &rc );
121 ldap_back_freeconn( op, lc );
125 /* sigh. parse twice, because parse_passwd
126 * doesn't give us the err / match / msg info.
128 rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err,
129 (char **)&rs->sr_matched,
130 (char **)&rs->sr_text,
132 if ( rc == LDAP_SUCCESS ) {
133 if ( rs->sr_err == LDAP_SUCCESS ) {
136 rc = ldap_parse_passwd( lc->lc_ld, res,
138 if ( rc == LDAP_SUCCESS &&
139 !BER_BVISNULL( &newpw ) )
141 rs->sr_type = REP_EXTENDED;
142 rs->sr_rspdata = slap_passwd_return( &newpw );
143 free( newpw.bv_val );
153 if ( rc != LDAP_SUCCESS ) {
154 rs->sr_err = slap_map_api2result( rs );
155 if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
157 if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
161 send_ldap_result( op, rs );
162 if ( rs->sr_matched ) {
163 free( (char *)rs->sr_matched );
166 free( (char *)rs->sr_text );
168 rs->sr_matched = NULL;