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 { BER_BVC(LDAP_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 );
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;
85 ldap_back_release_conn( op, rs, lc );
92 rs->sr_text = "not supported within naming context";
93 return LDAP_UNWILLING_TO_PERFORM;
97 ldap_back_exop_passwd(
102 req_pwdexop_s *qpw = &op->oq_pwdexop;
108 lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
109 if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
113 isproxy = ber_bvcmp( &op->o_req_ndn, &op->o_ndn );
115 Debug( LDAP_DEBUG_ARGS, "==> ldap_back_exop_passwd(\"%s\")%s\n",
116 op->o_req_dn.bv_val, isproxy ? " (proxy)" : "", 0 );
119 rc = ldap_passwd( lc->lc_ld, isproxy ? &op->o_req_dn : NULL,
120 qpw->rs_old.bv_val ? &qpw->rs_old : NULL,
121 qpw->rs_new.bv_val ? &qpw->rs_new : NULL,
122 op->o_ctrls, NULL, &msgid );
124 if ( rc == LDAP_SUCCESS ) {
125 if ( ldap_result( lc->lc_ld, msgid, LDAP_MSG_ALL, NULL, &res ) == -1 ) {
126 ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER, &rc );
127 ldap_back_freeconn( op, lc, 0 );
131 /* sigh. parse twice, because parse_passwd
132 * doesn't give us the err / match / msg info.
134 rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err,
135 (char **)&rs->sr_matched,
136 (char **)&rs->sr_text,
138 #ifndef LDAP_NULL_IS_NULL
139 if ( rs->sr_matched && rs->sr_matched[ 0 ] == '\0' ) {
140 free( (char *)rs->sr_matched );
141 rs->sr_matched = NULL;
143 if ( rs->sr_text && rs->sr_text[ 0 ] == '\0' ) {
144 free( (char *)rs->sr_text );
147 #endif /* LDAP_NULL_IS_NULL */
148 if ( rc == LDAP_SUCCESS ) {
149 if ( rs->sr_err == LDAP_SUCCESS ) {
152 rc = ldap_parse_passwd( lc->lc_ld, res,
154 if ( rc == LDAP_SUCCESS &&
155 !BER_BVISNULL( &newpw ) )
157 rs->sr_type = REP_EXTENDED;
158 rs->sr_rspdata = slap_passwd_return( &newpw );
159 free( newpw.bv_val );
169 if ( rc != LDAP_SUCCESS ) {
170 rs->sr_err = slap_map_api2result( rs );
171 if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
173 if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
177 send_ldap_result( op, rs );
181 /* these have to be freed anyway... */
182 if ( rs->sr_matched ) {
183 free( (char *)rs->sr_matched );
184 rs->sr_matched = NULL;
187 free( (char *)rs->sr_text );
192 ldap_back_release_conn( op, rs, lc );