From 532eea87c93db031d4a563bf7e47e3ebb4c18b23 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sun, 16 Feb 2003 09:22:44 +0000 Subject: [PATCH] Added passwd_exop, added matchedDN rewrite for results. --- servers/slapd/back-ldap/Makefile.in | 4 +- servers/slapd/back-ldap/add.c | 4 +- servers/slapd/back-ldap/attribute.c | 2 +- servers/slapd/back-ldap/back-ldap.h | 4 +- servers/slapd/back-ldap/bind.c | 62 +++++----- servers/slapd/back-ldap/compare.c | 4 +- servers/slapd/back-ldap/delete.c | 4 +- servers/slapd/back-ldap/extended.c | 178 ++++++++++++++++++++++++++++ servers/slapd/back-ldap/external.h | 2 + servers/slapd/back-ldap/group.c | 2 +- servers/slapd/back-ldap/init.c | 2 +- servers/slapd/back-ldap/modify.c | 4 +- servers/slapd/back-ldap/modrdn.c | 4 +- servers/slapd/back-ldap/search.c | 4 +- 14 files changed, 232 insertions(+), 48 deletions(-) create mode 100644 servers/slapd/back-ldap/extended.c diff --git a/servers/slapd/back-ldap/Makefile.in b/servers/slapd/back-ldap/Makefile.in index 2ce5a7fef3..7122f6e80b 100644 --- a/servers/slapd/back-ldap/Makefile.in +++ b/servers/slapd/back-ldap/Makefile.in @@ -2,10 +2,10 @@ SRCS = init.c config.c search.c bind.c unbind.c add.c compare.c \ delete.c modify.c modrdn.c group.c attribute.c \ - suffixmassage.c map.c + suffixmassage.c map.c extended.c OBJS = init.lo config.lo search.lo bind.lo unbind.lo add.lo compare.lo \ delete.lo modify.lo modrdn.lo group.lo attribute.lo \ - suffixmassage.lo map.lo + suffixmassage.lo map.lo extended.lo LDAP_INCDIR= ../../../include LDAP_LIBDIR= ../../../libraries diff --git a/servers/slapd/back-ldap/add.c b/servers/slapd/back-ldap/add.c index cacc1b1dd4..2b02a50ba3 100644 --- a/servers/slapd/back-ldap/add.c +++ b/servers/slapd/back-ldap/add.c @@ -69,7 +69,7 @@ ldap_back_add( #endif /* !NEW_LOGGING */ lc = ldap_back_getconn(li, conn, op); - if ( !lc || !ldap_back_dobind( lc, conn, op ) ) { + if ( !lc || !ldap_back_dobind( li, lc, conn, op ) ) { return( -1 ); } @@ -187,7 +187,7 @@ ldap_back_add( free( mdn.bv_val ); } - return( ldap_back_op_result( lc, conn, op, msgid, j ) ); + return( ldap_back_op_result( li, lc, conn, op, msgid, j ) ); } #ifdef ENABLE_REWRITE diff --git a/servers/slapd/back-ldap/attribute.c b/servers/slapd/back-ldap/attribute.c index 7b6eebd9a1..8b572024b6 100644 --- a/servers/slapd/back-ldap/attribute.c +++ b/servers/slapd/back-ldap/attribute.c @@ -72,7 +72,7 @@ ldap_back_attribute( is_oc = op->o_do_not_cache; op->o_do_not_cache = 1; lc = ldap_back_getconn(li, conn, op); - if ( !lc || !ldap_back_dobind(lc, NULL, op) ) { + if ( !lc || !ldap_back_dobind(li, lc, NULL, op) ) { op->o_do_not_cache = is_oc; return 1; } diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index 77f09561c5..d2dc6c9f19 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -93,9 +93,9 @@ struct ldapinfo { struct ldapconn *ldap_back_getconn(struct ldapinfo *li, struct slap_conn *conn, struct slap_op *op); -int ldap_back_dobind(struct ldapconn *lc, Connection *conn, Operation *op); +int ldap_back_dobind(struct ldapinfo *li, struct ldapconn *lc, Connection *conn, Operation *op); int ldap_back_map_result(int err); -int ldap_back_op_result(struct ldapconn *lc, Connection *conn, Operation *op, +int ldap_back_op_result(struct ldapinfo *li, struct ldapconn *lc, Connection *conn, Operation *op, ber_int_t msgid, int rc); int back_ldap_LTX_init_module(int argc, char *argv[]); diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index e5a2614754..fe6b6e6c03 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -116,7 +116,7 @@ ldap_back_bind( /* method is always LDAP_AUTH_SIMPLE if we got here */ rc = ldap_sasl_bind(lc->ld, mdn.bv_val, LDAP_SASL_SIMPLE, cred, op->o_ctrls, NULL, &msgid); - rc = ldap_back_op_result( lc, conn, op, msgid, rc ); + rc = ldap_back_op_result( li, lc, conn, op, msgid, rc ); if (rc == LDAP_SUCCESS) { lc->bound = 1; if ( mdn.bv_val != dn->bv_val ) { @@ -410,7 +410,7 @@ ldap_back_getconn(struct ldapinfo *li, Connection *conn, Operation *op) * it can be used to simplify the check. */ int -ldap_back_dobind( struct ldapconn *lc, Connection *conn, Operation *op ) +ldap_back_dobind( struct ldapinfo *li, struct ldapconn *lc, Connection *conn, Operation *op ) { int rc; ber_int_t msgid; @@ -419,7 +419,7 @@ ldap_back_dobind( struct ldapconn *lc, Connection *conn, Operation *op ) if ( !lc->bound ) { rc = ldap_sasl_bind(lc->ld, lc->bound_dn.bv_val, LDAP_SASL_SIMPLE, &lc->cred, NULL, NULL, &msgid); - rc = ldap_back_op_result( lc, conn, op, msgid, rc ); + rc = ldap_back_op_result( li, lc, conn, op, msgid, rc ); if (rc == LDAP_SUCCESS) { lc->bound = 1; } @@ -492,8 +492,8 @@ ldap_back_map_result(int err) } int -ldap_back_op_result(struct ldapconn *lc, Connection *conn, Operation *op, - ber_int_t msgid, int err) +ldap_back_op_result(struct ldapinfo *li, struct ldapconn *lc, + Connection *conn, Operation *op, ber_int_t msgid, int err) { char *msg = NULL; char *match = NULL; @@ -509,34 +509,38 @@ ldap_back_op_result(struct ldapconn *lc, Connection *conn, Operation *op, if (rc != LDAP_SUCCESS) err = rc; } } - err = ldap_back_map_result(err); - - /* internal ops must not reply to client */ - if ( !conn || op->o_do_not_cache ) goto quiet; + if (err != LDAP_SUCCESS) { + err = ldap_back_map_result(err); + /* internal ops must not reply to client */ + if ( conn && !op->o_do_not_cache ) { + char *mmatch = NULL; #ifdef ENABLE_REWRITE - - /* - * FIXME: need rewrite info for match; mmmh ... - */ - send_ldap_result( conn, op, err, match, msg, NULL, NULL ); - /* better test the pointers before freeing? */ - if ( match ) { - free( match ); - } - -#else /* !ENABLE_REWRITE */ - - send_ldap_result( conn, op, err, match, msg, NULL, NULL ); - /* better test the pointers before freeing? */ - if ( match ) { - free( match ); + if (match) { + + switch(rewrite_session(li->rwinfo, "matchedDn", match, conn, + &mmatch)) { + case REWRITE_REGEXEC_OK: + if (!mmatch) mmatch = match; break; + case REWRITE_REGEXEC_UNWILLING: + case REWRITE_REGEXEC_ERR: + break; + } + } +#else + struct berval dn, mdn; + if (match) { + ber_str2bv(match, 0, 0, &dn); + ldap_back_dn_massage(li, &dn, &mdn, 0, 0); + mmatch = mdn.bv_val; + } +#endif + send_ldap_result( conn, op, err, mmatch, msg, NULL, NULL ); + if (mmatch != match) free(mmatch); + } } - -#endif /* !ENABLE_REWRITE */ - + if ( match ) free( match ); if ( msg ) free( msg ); -quiet: return( (err==LDAP_SUCCESS) ? 0 : -1 ); } diff --git a/servers/slapd/back-ldap/compare.c b/servers/slapd/back-ldap/compare.c index 3b9c101b92..348736f2f1 100644 --- a/servers/slapd/back-ldap/compare.c +++ b/servers/slapd/back-ldap/compare.c @@ -63,7 +63,7 @@ ldap_back_compare( ber_int_t msgid; lc = ldap_back_getconn(li, conn, op); - if (!lc || !ldap_back_dobind( lc, conn, op ) ) { + if (!lc || !ldap_back_dobind( li, lc, conn, op ) ) { return( -1 ); } @@ -124,5 +124,5 @@ ldap_back_compare( free( mdn.bv_val ); } - return( ldap_back_op_result( lc, conn, op, msgid, rc ) ); + return( ldap_back_op_result( li, lc, conn, op, msgid, rc ) ); } diff --git a/servers/slapd/back-ldap/delete.c b/servers/slapd/back-ldap/delete.c index 48ab3c3533..a2e737f7a8 100644 --- a/servers/slapd/back-ldap/delete.c +++ b/servers/slapd/back-ldap/delete.c @@ -63,7 +63,7 @@ ldap_back_delete( lc = ldap_back_getconn( li, conn, op ); - if ( !lc || !ldap_back_dobind( lc, conn, op ) ) { + if ( !lc || !ldap_back_dobind( li, lc, conn, op ) ) { return( -1 ); } @@ -105,5 +105,5 @@ ldap_back_delete( free( mdn.bv_val ); } - return( ldap_back_op_result( lc, conn, op, msgid, rc ) ); + return( ldap_back_op_result( li, lc, conn, op, msgid, rc ) ); } diff --git a/servers/slapd/back-ldap/extended.c b/servers/slapd/back-ldap/extended.c new file mode 100644 index 0000000000..f5c5df81d6 --- /dev/null +++ b/servers/slapd/back-ldap/extended.c @@ -0,0 +1,178 @@ +/* extended.c - ldap backend extended routines */ +/* $OpenLDAP$ */ +/* + * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. + * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + */ + +#include "portable.h" + +#include +#include + +#include "slap.h" +#include "back-ldap.h" +#include "lber_pvt.h" + +BI_op_extended ldap_back_exop_passwd; + +static struct exop { + struct berval *oid; + BI_op_extended *extended; +} exop_table[] = { + { (struct berval *)&slap_EXOP_MODIFY_PASSWD, ldap_back_exop_passwd }, + { NULL, NULL } +}; + +int +ldap_back_extended( + Backend *be, + Connection *conn, + Operation *op, + struct berval *reqoid, + struct berval *reqdata, + char **rspoid, + struct berval **rspdata, + LDAPControl *** rspctrls, + const char** text, + BerVarray *refs +) +{ + int i; + + for( i=0; exop_table[i].extended != NULL; i++ ) { + if( ber_bvcmp( exop_table[i].oid, reqoid ) == 0 ) { + return (exop_table[i].extended)( + be, conn, op, + reqoid, reqdata, + rspoid, rspdata, rspctrls, + text, refs ); + } + } + + *text = "not supported within naming context"; + return LDAP_UNWILLING_TO_PERFORM; +} + +int +ldap_back_exop_passwd( + Backend *be, + Connection *conn, + Operation *op, + struct berval *reqoid, + struct berval *reqdata, + char **rspoid, + struct berval **rspdata, + LDAPControl *** rspctrls, + const char **text, + BerVarray *refs ) +{ + struct ldapinfo *li = (struct ldapinfo *) be->be_private; + struct ldapconn *lc; + struct berval id = { 0, NULL }; + struct berval old = { 0, NULL }; + struct berval new = { 0, NULL }; + struct berval dn, mdn = { 0, NULL }, *newpw = NULL; + LDAPMessage *res; + ber_int_t msgid; + char *msg = NULL, *match = NULL; + int rc; + + lc = ldap_back_getconn(li, conn, op); + if (!lc || !ldap_back_dobind(li, lc, conn, op) ) { + return -1; + } + + rc = slap_passwd_parse( reqdata, &id, &old, &new, 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) { + *text = "No password is associated with the Root DSE"; + return LDAP_UNWILLING_TO_PERFORM; + } + if (id.bv_len) { +#ifdef ENABLE_REWRITE + switch ( rewrite_session( li->rwinfo, "modifyPwd", dn.bv_val, conn, &mdn.bv_val ) ) { + case REWRITE_REGEXEC_OK: + if ( mdn.bv_val == NULL ) { + mdn.bv_val = dn.bv_val; + } + mdn.bv_len = strlen(mdn.bv_val); +#ifdef NEW_LOGGING + LDAP_LOG( BACK_LDAP, DETAIL1, + "[rw] modifyPwd: \"%s\" -> \"%s\"\n", dn.bv_val, mdn.bv_val, 0 ); +#else /* !NEW_LOGGING */ + Debug( LDAP_DEBUG_ARGS, "rw> modifyPwd: \"%s\" -> \"%s\"\n%s", + dn.bv_val, mdn.bv_val, "" ); +#endif /* !NEW_LOGGING */ + break; + + case REWRITE_REGEXEC_UNWILLING: + send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, + NULL, "Operation not allowed", NULL, NULL ); + return( -1 ); + + case REWRITE_REGEXEC_ERR: + send_ldap_result( conn, op, LDAP_OTHER, + NULL, "Rewrite error", NULL, NULL ); + return( -1 ); + } +#else /* !ENABLE_REWRITE */ + ldap_back_dn_massage( li, &dn, &mdn, 0, 1 ); +#endif /* !ENABLE_REWRITE */ + } + + rc = ldap_passwd(lc->ld, id.bv_len ? &mdn : NULL, old.bv_len ? &old : NULL, + new.bv_len ? &new : NULL, op->o_ctrls, NULL, &msgid); +#ifdef ENABLE_REWRITE + if (mdn.bv_val != dn.bv_val) +#endif + free(mdn.bv_val); + if (rc == LDAP_SUCCESS) { + if (ldap_result(lc->ld, msgid, 1, NULL, &res) == -1) { + ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER, &rc); + } else { + /* sigh. parse twice, because parse_passwd doesn't give + * us the err / match / msg info. + */ + int err; + rc = ldap_parse_result(lc->ld, res, &err, &match, &msg, + NULL, NULL, 0); + if (rc == LDAP_SUCCESS) { + if (err == LDAP_SUCCESS) { + rc = ldap_parse_passwd(lc->ld, res, &newpw); + if (rc == LDAP_SUCCESS && newpw) { + *rspdata = slap_passwd_return(newpw); + ber_bvfree(newpw); + } + } else { + rc = err; + } + } + ldap_msgfree(res); + } + } + if (rc != LDAP_SUCCESS) { + rc = ldap_back_map_result(rc); + send_ldap_result(conn, op, rc, match, msg, NULL, NULL); + if (match) free(match); + if (msg) free(msg); + rc = -1; + } + return rc; +} diff --git a/servers/slapd/back-ldap/external.h b/servers/slapd/back-ldap/external.h index 2872e0d72a..e12b6b5ecb 100644 --- a/servers/slapd/back-ldap/external.h +++ b/servers/slapd/back-ldap/external.h @@ -37,6 +37,8 @@ extern BI_op_delete ldap_back_delete; extern BI_op_abandon ldap_back_abandon; +extern BI_op_extended ldap_back_extended; + extern BI_acl_group ldap_back_group; extern BI_acl_attribute ldap_back_attribute; diff --git a/servers/slapd/back-ldap/group.c b/servers/slapd/back-ldap/group.c index b6dbe107dd..ca1e11c118 100644 --- a/servers/slapd/back-ldap/group.c +++ b/servers/slapd/back-ldap/group.c @@ -174,7 +174,7 @@ ldap_back_group( oc = op->o_do_not_cache; op->o_do_not_cache = 1; lc = ldap_back_getconn(li, conn, op); - if ( !lc || !ldap_back_dobind( lc, NULL, op ) ) { + if ( !lc || !ldap_back_dobind( li, lc, NULL, op ) ) { op->o_do_not_cache = oc; goto cleanup; } diff --git a/servers/slapd/back-ldap/init.c b/servers/slapd/back-ldap/init.c index aa76717800..5cffa2f67f 100644 --- a/servers/slapd/back-ldap/init.c +++ b/servers/slapd/back-ldap/init.c @@ -87,7 +87,7 @@ ldap_back_initialize( bi->bi_op_delete = ldap_back_delete; bi->bi_op_abandon = 0; - bi->bi_extended = 0; + bi->bi_extended = ldap_back_extended; bi->bi_acl_group = ldap_back_group; bi->bi_acl_attribute = ldap_back_attribute; diff --git a/servers/slapd/back-ldap/modify.c b/servers/slapd/back-ldap/modify.c index a44915618d..83de06937a 100644 --- a/servers/slapd/back-ldap/modify.c +++ b/servers/slapd/back-ldap/modify.c @@ -66,7 +66,7 @@ ldap_back_modify( ber_int_t msgid; lc = ldap_back_getconn(li, conn, op); - if ( !lc || !ldap_back_dobind( lc, conn, op ) ) { + if ( !lc || !ldap_back_dobind( li, lc, conn, op ) ) { return( -1 ); } @@ -171,6 +171,6 @@ cleanup:; ch_free(modv[i]->mod_bvalues); ch_free(mods); ch_free(modv); - return( ldap_back_op_result( lc, conn, op, msgid, rc )); + return( ldap_back_op_result( li, lc, conn, op, msgid, rc )); } diff --git a/servers/slapd/back-ldap/modrdn.c b/servers/slapd/back-ldap/modrdn.c index 1dd14ea1fc..447122920a 100644 --- a/servers/slapd/back-ldap/modrdn.c +++ b/servers/slapd/back-ldap/modrdn.c @@ -67,7 +67,7 @@ ldap_back_modrdn( struct berval mdn = { 0, NULL }, mnewSuperior = { 0, NULL }; lc = ldap_back_getconn( li, conn, op ); - if ( !lc || !ldap_back_dobind(lc, conn, op) ) { + if ( !lc || !ldap_back_dobind(li, lc, conn, op) ) { return( -1 ); } @@ -159,5 +159,5 @@ ldap_back_modrdn( free( mnewSuperior.bv_val ); } - return( ldap_back_op_result( lc, conn, op, msgid, rc ) ); + return( ldap_back_op_result( li, lc, conn, op, msgid, rc ) ); } diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index d4d8051a5d..3db8993455 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -93,7 +93,7 @@ ldap_back_search( * FIXME: in case of values return filter, we might want * to map attrs and maybe rewrite value */ - if ( !ldap_back_dobind( lc, conn, op ) ) { + if ( !ldap_back_dobind( li, lc, conn, op ) ) { return( -1 ); } @@ -265,7 +265,7 @@ ldap_back_search( : NULL, slimit, &msgid); if ( rc != LDAP_SUCCESS ) { fail:; - rc = ldap_back_op_result(lc, conn, op, msgid, rc); + rc = ldap_back_op_result(li, lc, conn, op, msgid, rc); goto finish; } -- 2.39.5