From: Pierangelo Masarati Date: Mon, 5 Apr 2004 17:31:27 +0000 (+0000) Subject: exploit new isroot_dn helper X-Git-Tag: OPENLDAP_REL_ENG_2_2_BP~144 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=e51624706896073e902338fdd0bcfc39ff2be798;p=openldap exploit new isroot_dn helper --- diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index 9896b77d74..823efe7728 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -1568,7 +1568,7 @@ acl_check_modlist( assert( be != NULL ); /* short circuit root database access */ - if ( be_isroot( op->o_bd, &op->o_ndn ) ) { + if ( be_isroot_dn( op ) ) { #ifdef NEW_LOGGING LDAP_LOG( ACL, DETAIL1, "acl_check_modlist: conn %lu access granted to root user\n", diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c index 6b30fed39a..b56377b30b 100644 --- a/servers/slapd/back-bdb/add.c +++ b/servers/slapd/back-bdb/add.c @@ -298,7 +298,7 @@ retry: /* transaction retry */ * no parent! * if not attempting to add entry at suffix or with parent "" */ - if (( !be_isroot( op->o_bd, &op->o_ndn ) || pdn.bv_len > 0 ) + if (( !be_isroot_dn( op ) || pdn.bv_len > 0 ) && !is_entry_glue( op->oq_add.rs_e )) { #ifdef NEW_LOGGING diff --git a/servers/slapd/back-bdb/delete.c b/servers/slapd/back-bdb/delete.c index c8e46b6fd3..d7a22a3e75 100644 --- a/servers/slapd/back-bdb/delete.c +++ b/servers/slapd/back-bdb/delete.c @@ -244,7 +244,7 @@ retry: /* transaction retry */ } else { /* no parent, must be root to delete */ - if( ! be_isroot( op->o_bd, &op->o_ndn ) ) { + if( ! be_isroot_dn( op ) ) { if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv ) || be_isupdate( op->o_bd, &op->o_ndn ) ) { p = (Entry *)&slap_entry_root; diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c index ecef5038d8..0d6f8118c3 100644 --- a/servers/slapd/back-bdb/modrdn.c +++ b/servers/slapd/back-bdb/modrdn.c @@ -390,7 +390,7 @@ retry: /* transaction retry */ } else { /* no parent, modrdn entry directly under root */ - isroot = be_isroot( op->o_bd, &op->o_ndn ); + isroot = be_isroot_dn( op ); if ( ! isroot ) { if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv ) || be_isupdate( op->o_bd, &op->o_ndn ) ) { @@ -600,7 +600,7 @@ retry: /* transaction retry */ } else { if ( isroot == -1 ) { - isroot = be_isroot( op->o_bd, &op->o_ndn ); + isroot = be_isroot_dn( op ); } np_dn = NULL; diff --git a/servers/slapd/back-bdb/referral.c b/servers/slapd/back-bdb/referral.c index cf6dbd15a9..d69c35a7d9 100644 --- a/servers/slapd/back-bdb/referral.c +++ b/servers/slapd/back-bdb/referral.c @@ -150,7 +150,7 @@ dn2entry_retry: rs->sr_matched = e->e_name.bv_val; if( rs->sr_ref != NULL ) { - rs->sr_err = LDAP_REFERRAL; + rc = rs->sr_err = LDAP_REFERRAL; send_ldap_result( op, rs ); ber_bvarray_free( rs->sr_ref ); rs->sr_ref = NULL; diff --git a/servers/slapd/back-ldbm/add.c b/servers/slapd/back-ldbm/add.c index 34ab716fd1..9293ec5f3c 100644 --- a/servers/slapd/back-ldbm/add.c +++ b/servers/slapd/back-ldbm/add.c @@ -247,7 +247,7 @@ ldbm_back_add( } else { assert( pdn.bv_val == NULL || *pdn.bv_val == '\0' ); - if ( !be_isroot( op->o_bd, &op->o_ndn ) + if ( !be_isroot_dn( op ) && !is_entry_glue( op->oq_add.rs_e )) { ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); diff --git a/servers/slapd/back-ldbm/delete.c b/servers/slapd/back-ldbm/delete.c index 7276f84d37..0e97d74e62 100644 --- a/servers/slapd/back-ldbm/delete.c +++ b/servers/slapd/back-ldbm/delete.c @@ -194,7 +194,7 @@ ldbm_back_delete( } else { /* no parent, must be root to delete */ - if( ! be_isroot( op->o_bd, &op->o_ndn ) ) { + if( ! be_isroot_dn( op ) ) { if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv ) || be_isupdate( op->o_bd, &op->o_ndn ) ) { p = (Entry *)&slap_entry_root; diff --git a/servers/slapd/back-ldbm/modrdn.c b/servers/slapd/back-ldbm/modrdn.c index eb463e3b96..c73f55d4bc 100644 --- a/servers/slapd/back-ldbm/modrdn.c +++ b/servers/slapd/back-ldbm/modrdn.c @@ -246,7 +246,7 @@ ldbm_back_modrdn( } else { /* no parent, must be root to modify rdn */ - isroot = be_isroot( op->o_bd, &op->o_ndn ); + isroot = be_isroot_dn( op ); if ( ! isroot ) { if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv ) || be_isupdate( op->o_bd, &op->o_ndn ) ) { int can_access; @@ -418,7 +418,7 @@ ldbm_back_modrdn( /* no parent, must be root to modify newSuperior */ if ( isroot == -1 ) { - isroot = be_isroot( op->o_bd, &op->o_ndn ); + isroot = be_isroot_dn( op ); } if ( ! isroot ) { diff --git a/servers/slapd/limits.c b/servers/slapd/limits.c index d1dd42f25b..f2fc78f915 100644 --- a/servers/slapd/limits.c +++ b/servers/slapd/limits.c @@ -780,7 +780,7 @@ limits_check( Operation *op, SlapReply *rs ) assert( op->o_tag == LDAP_REQ_SEARCH); /* allow root to set no limit */ - if ( be_isroot( op->o_bd, &op->o_ndn ) ) { + if ( be_isroot_dn( op ) ) { op->ors_limit = NULL; if ( op->ors_tlimit == 0 ) { diff --git a/servers/slapd/overlays/chain.c b/servers/slapd/overlays/chain.c index 94506f96ad..d3fefae60b 100644 --- a/servers/slapd/overlays/chain.c +++ b/servers/slapd/overlays/chain.c @@ -33,36 +33,72 @@ #include "slap.h" #include "../back-ldap/back-ldap.h" +static int +ldap_chain_chk_referrals( Operation *op, SlapReply *rs ) +{ + return LDAP_SUCCESS; +} + static int ldap_chain_response( Operation *op, SlapReply *rs ) { - slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; - void *private = op->o_bd->be_private; - slap_callback *sc = op->o_callback; - LDAPControl **prev = op->o_ctrls; - LDAPControl **ctrls = NULL, authz; - int i, nctrls, rc = 0; - int cache = op->o_do_not_cache; - char *authzid = NULL; - BerVarray ref; - struct berval ndn = op->o_ndn; + slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; + void *private = op->o_bd->be_private; + slap_callback *sc = op->o_callback; + LDAPControl **prev = op->o_ctrls; + LDAPControl **ctrls = NULL, authz; + int i, nctrls, rc = 0; + int cache = op->o_do_not_cache; + char *authzid = NULL; + BerVarray ref; + struct berval ndn = op->o_ndn; + + struct ldapinfo li, *lip = (struct ldapinfo *)on->on_bi.bi_private; if ( rs->sr_err != LDAP_REFERRAL && rs->sr_type != REP_SEARCHREF ) return SLAP_CB_CONTINUE; - /* currently we assume only one referral destination. - * we'll have to parse this in the future. - */ - /* leave in place if result type is search reference; - * will be cleared later */ ref = rs->sr_ref; - if ( rs->sr_type != REP_SEARCHREF ) { - rs->sr_ref = NULL; - } + rs->sr_ref = NULL; - op->o_bd->be_private = on->on_bi.bi_private; op->o_callback = NULL; + if ( lip->url == NULL ) { + li = *lip; + op->o_bd->be_private = &li; + + if ( rs->sr_type != REP_SEARCHREF ) { + LDAPURLDesc *srv; + char *save_dn; + + /* parse reference and use proto://[host][:port]/ only */ + rc = ldap_url_parse_ext( ref[0].bv_val, &srv ); + if ( rc != LDAP_SUCCESS) { + /* error */ + return 1; + } + + /* remove DN essentially because later on + * ldap_initialize() will parse the URL + * as a comma-separated URL list */ + save_dn = srv->lud_dn; + srv->lud_dn = ""; + li.url = ldap_url_desc2str( srv ); + if ( li.url == NULL ) { + /* error */ + srv->lud_dn = save_dn; + ldap_free_urldesc( srv ); + return 1; + } + + srv->lud_dn = save_dn; + ldap_free_urldesc( srv ); + } + + } else { + op->o_bd->be_private = on->on_bi.bi_private; + } + /* Chaining is performed by a privileged user on behalf * of a normal user, using the ProxyAuthz control. However, * Binds are done separately, on an anonymous session. @@ -84,11 +120,11 @@ ldap_chain_response( Operation *op, SlapReply *rs ) authz.ldctl_iscritical = 1; authz.ldctl_value = op->o_dn; if ( op->o_dn.bv_len ) { - authzid = op->o_tmpalloc( op->o_dn.bv_len+4, + authzid = op->o_tmpalloc( op->o_dn.bv_len + sizeof("dn:") - 1, op->o_tmpmemctx ); - strcpy(authzid, "dn: "); - strcpy(authzid+4, op->o_dn.bv_val); - authz.ldctl_value.bv_len = op->o_dn.bv_len + 4; + strcpy(authzid, "dn:"); + strcpy(authzid + sizeof("dn:") - 1, op->o_dn.bv_val); + authz.ldctl_value.bv_len = op->o_dn.bv_len + sizeof("dn:") - 1; authz.ldctl_value.bv_val = authzid; } op->o_ctrls = ctrls; @@ -97,9 +133,11 @@ ldap_chain_response( Operation *op, SlapReply *rs ) switch( op->o_tag ) { case LDAP_REQ_BIND: { - struct berval rndn = op->o_req_ndn; - Connection *conn = op->o_conn; + struct berval rndn = op->o_req_ndn; + Connection *conn = op->o_conn; + op->o_req_ndn = slap_empty_bv; + op->o_conn = NULL; rc = ldap_back_bind( op, rs ); op->o_req_ndn = rndn; @@ -123,17 +161,13 @@ ldap_chain_response( Operation *op, SlapReply *rs ) break; case LDAP_REQ_SEARCH: if ( rs->sr_type == REP_SEARCHREF ) { - struct ldapinfo li; - struct berval *curr = rs->sr_ref, + struct berval *curr = ref, odn = op->o_req_dn, ondn = op->o_req_ndn; - op->o_bd->be_private = &li; rs->sr_type = REP_SEARCH; - rs->sr_ref = NULL; /* copy the private info because we need to modify it */ - AC_MEMCPY( &li, on->on_bi.bi_private, sizeof( struct ldapinfo ) ); for ( ; curr[0].bv_val; curr++ ) { LDAPURLDesc *srv; @@ -141,7 +175,8 @@ ldap_chain_response( Operation *op, SlapReply *rs ) rc = ldap_url_parse_ext( curr[0].bv_val, &srv ); if ( rc != LDAP_SUCCESS) { /* error */ - continue; + rc = 1; + goto end_of_searchref; } ber_str2bv(srv->lud_dn, 0, 0, &op->o_req_dn); @@ -156,7 +191,8 @@ ldap_chain_response( Operation *op, SlapReply *rs ) /* error */ srv->lud_dn = op->o_req_dn.bv_val; ldap_free_urldesc( srv ); - continue; + rc = 1; + goto end_of_searchref; } /* FIXME: should we also copy filter and scope? @@ -164,19 +200,23 @@ ldap_chain_response( Operation *op, SlapReply *rs ) rc = ldap_back_search( op, rs ); + ldap_memfree( li.url ); + li.url = NULL; + srv->lud_dn = op->o_req_dn.bv_val; ldap_free_urldesc( srv ); if ( rc ) { /* error */ - continue; + rc = 1; + goto end_of_searchref; } } +end_of_searchref:; op->o_req_dn = odn; op->o_req_ndn = ondn; rs->sr_type = REP_SEARCHREF; - op->o_bd->be_private = on->on_bi.bi_private; } else { rc = ldap_back_search( op, rs ); @@ -197,6 +237,9 @@ ldap_chain_response( Operation *op, SlapReply *rs ) if ( ctrls ) op->o_tmpfree( ctrls, op->o_tmpmemctx ); if ( authzid ) op->o_tmpfree( authzid, op->o_tmpmemctx ); rs->sr_ref = ref; + if ( lip->url == NULL && li.url ) { + ldap_memfree( li.url ); + } return rc; } @@ -240,6 +283,7 @@ static int ldap_chain_init( rc = ldap_back_db_init( be ); on->on_bi.bi_private = be->be_private; be->be_private = private; + return rc; } @@ -268,6 +312,8 @@ int chain_init() ldapchain.on_bi.bi_db_destroy = ldap_chain_destroy; ldapchain.on_response = ldap_chain_response; + ldapchain.on_bi.bi_chk_referrals = ldap_chain_chk_referrals; + return overlay_register( &ldapchain ); } diff --git a/servers/slapd/overlays/ppolicy.c b/servers/slapd/overlays/ppolicy.c index 857240fb70..4091ced8b9 100644 --- a/servers/slapd/overlays/ppolicy.c +++ b/servers/slapd/overlays/ppolicy.c @@ -1176,7 +1176,7 @@ ppolicy_add( * security policy for the new entry. */ ppolicy_get( op, op->oq_add.rs_e, &pp ); - if (pp.pwdCheckQuality > 0 && !be_isroot( op->o_bd, &op->o_ndn )) { + if (pp.pwdCheckQuality > 0 && !be_isroot_dn( op )) { struct berval *bv = &(pa->a_vals[0]); int rc, i, send_ctrl = 0; LDAPPasswordPolicyError pErr = PP_noError; @@ -1386,7 +1386,7 @@ ppolicy_modify( Operation *op, SlapReply *rs ) for(p=tl; p; p=p->next, hsize++); /* count history size */ } - if (be_isroot( op->o_bd, &op->o_ndn)) goto do_modify; + if (be_isroot_dn( op )) goto do_modify; /* This is a pwdModify exop that provided the old pw. * We need to create a Delete mod for this old pw and diff --git a/servers/slapd/slapi/slapi_utils.c b/servers/slapd/slapi/slapi_utils.c index 3944a4c81c..a811e06d78 100644 --- a/servers/slapd/slapi/slapi_utils.c +++ b/servers/slapd/slapi/slapi_utils.c @@ -2461,7 +2461,7 @@ int slapi_int_pblock_set_operation( Slapi_PBlock *pb, Operation *op ) char *opAuthType; if ( op->o_bd != NULL ) { - isRoot = be_isroot( op->o_bd, &op->o_ndn ); + isRoot = be_isroot_dn( op ); isUpdateDn = be_isupdate( op->o_bd, &op->o_ndn ); }