From 79ebfbc4fe7ff53c49eadac57210b1396e63d016 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Fri, 16 Jun 2000 03:50:02 +0000 Subject: [PATCH] Rework referral entry point with DNS SRV implementation (needs testing). --- servers/slapd/add.c | 9 +- servers/slapd/back-dnssrv/Makefile.in | 6 +- servers/slapd/back-dnssrv/bind.c | 2 +- servers/slapd/back-dnssrv/config.c | 2 +- servers/slapd/back-dnssrv/external.h | 17 +-- servers/slapd/back-dnssrv/init.c | 12 +- servers/slapd/back-dnssrv/search.c | 192 +++++++++++++++++++++++++- servers/slapd/backend.c | 15 +- servers/slapd/compare.c | 9 +- servers/slapd/delete.c | 9 +- servers/slapd/modify.c | 8 +- servers/slapd/modrdn.c | 9 +- servers/slapd/proto-slap.h | 3 +- servers/slapd/search.c | 8 +- servers/slapd/slap.h | 2 +- 15 files changed, 235 insertions(+), 68 deletions(-) diff --git a/servers/slapd/add.c b/servers/slapd/add.c index 3db0bf9d02..c0b93363ce 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -44,7 +44,6 @@ do_add( Connection *conn, Operation *op ) Modifications *mods = NULL; const char *text; int rc = LDAP_SUCCESS; - struct berval **urls = NULL; Debug( LDAP_DEBUG_TRACE, "do_add\n", 0, 0, 0 ); @@ -157,6 +156,7 @@ do_add( Connection *conn, Operation *op ) /* make sure this backend recongizes critical controls */ rc = backend_check_controls( be, conn, op, &text ) ; + if( rc != LDAP_SUCCESS ) { send_ldap_result( conn, op, rc, NULL, text, NULL, NULL ); @@ -164,11 +164,10 @@ do_add( Connection *conn, Operation *op ) } /* check for referrals */ - rc = backend_check_referrals( be, conn, op, &urls, &text ); + rc = backend_check_referrals( be, conn, op, + e->e_dn, e->e_ndn, &text ); + if ( rc != LDAP_SUCCESS ) { - send_ldap_result( conn, op, rc, - NULL, text, urls, NULL ); - ber_bvecfree( urls ); goto done; } diff --git a/servers/slapd/back-dnssrv/Makefile.in b/servers/slapd/back-dnssrv/Makefile.in index 8849ce38a0..9d01c5a57b 100644 --- a/servers/slapd/back-dnssrv/Makefile.in +++ b/servers/slapd/back-dnssrv/Makefile.in @@ -10,10 +10,8 @@ # DNSSRV backend written by Kurt Zeilenga ########################################################################## -SRCS = init.c bind.c search.c config.c compare.c \ - modify.c add.c modrdn.c delete.c request.c -OBJS = init.lo bind.lo search.lo config.lo compare.lo \ - modify.lo add.lo modrdn.lo delete.lo request.lo +SRCS = init.c bind.c search.c config.c referral.c +OBJS = init.lo bind.lo search.lo config.lo referral.lo LDAP_INCDIR= ../../../include LDAP_LIBDIR= ../../../libraries diff --git a/servers/slapd/back-dnssrv/bind.c b/servers/slapd/back-dnssrv/bind.c index 4739746a2e..0dca311c89 100644 --- a/servers/slapd/back-dnssrv/bind.c +++ b/servers/slapd/back-dnssrv/bind.c @@ -14,7 +14,7 @@ #include #include "slap.h" -#include "back-dnssrv.h" +#include "external.h" int dnssrv_back_bind( diff --git a/servers/slapd/back-dnssrv/config.c b/servers/slapd/back-dnssrv/config.c index 5aaa66f558..99dad353af 100644 --- a/servers/slapd/back-dnssrv/config.c +++ b/servers/slapd/back-dnssrv/config.c @@ -13,7 +13,7 @@ #include #include "slap.h" -#include "back-dnssrv.h" +#include "external.h" int dnssrv_back_db_config( diff --git a/servers/slapd/back-dnssrv/external.h b/servers/slapd/back-dnssrv/external.h index 3358a30827..dfa4cc5c62 100644 --- a/servers/slapd/back-dnssrv/external.h +++ b/servers/slapd/back-dnssrv/external.h @@ -39,23 +39,10 @@ extern int dnssrv_back_compare LDAP_P((BackendDB *bd, Connection *conn, Operation *op, const char *dn, const char *ndn, AttributeAssertion *ava )); -extern int dnssrv_back_modify LDAP_P(( BackendDB *bd, +extern int dnssrv_back_referrals LDAP_P(( BackendDB *bd, Connection *conn, Operation *op, const char *dn, const char *ndn, - Modifications *ml )); - -extern int dnssrv_back_modrdn LDAP_P(( BackendDB *bd, - Connection *conn, Operation *op, - const char *dn, const char *ndn, - const char *newrdn, int deleteoldrdn, - const char *newSuperior )); - -extern int dnssrv_back_add LDAP_P(( BackendDB *bd, - Connection *conn, Operation *op, Entry *e )); - -extern int dnssrv_back_delete LDAP_P(( BackendDB *bd, - Connection *conn, Operation *op, - const char *dn, const char *ndn )); + const char **text )); LDAP_END_DECL diff --git a/servers/slapd/back-dnssrv/init.c b/servers/slapd/back-dnssrv/init.c index 46f2b162da..b75cced1b6 100644 --- a/servers/slapd/back-dnssrv/init.c +++ b/servers/slapd/back-dnssrv/init.c @@ -12,7 +12,7 @@ #include #include "slap.h" -#include "back-dnssrv.h" +#include "external.h" #ifdef SLAPD_DNSSRV_DYNAMIC @@ -56,16 +56,16 @@ dnssrv_back_initialize( bi->bi_op_unbind = 0; bi->bi_op_search = dnssrv_back_search; bi->bi_op_compare = dnssrv_back_compare; - bi->bi_op_modify = dnssrv_back_modify; - bi->bi_op_modrdn = dnssrv_back_modrdn; - bi->bi_op_add = dnssrv_back_add; - bi->bi_op_delete = dnssrv_back_delete; + bi->bi_op_modify = 0; + bi->bi_op_modrdn = 0; + bi->bi_op_add = 0; + bi->bi_op_delete = 0; bi->bi_op_abandon = 0; bi->bi_extended = 0; bi->bi_acl_group = 0; - bi->bi_chk_referrals = 0; + bi->bi_chk_referrals = dnssrv_back_referrals; #ifdef HAVE_CYRUS_SASL bi->bi_sasl_authorize = 0; diff --git a/servers/slapd/back-dnssrv/search.c b/servers/slapd/back-dnssrv/search.c index d9dea2e3ed..6658191cc8 100644 --- a/servers/slapd/back-dnssrv/search.c +++ b/servers/slapd/back-dnssrv/search.c @@ -15,7 +15,7 @@ #include #include "slap.h" -#include "back-dnssrv.h" +#include "external.h" int dnssrv_back_search( @@ -31,9 +31,191 @@ dnssrv_back_search( Filter *filter, const char *filterstr, char **attrs, - int attrsonly -) + int attrsonly ) { - return dnssrv_back_request( be, conn, op, dn, ndn, - scope, filter, attrs, attrsonly ); + int i; + int rc; + char *domain = NULL; + char *hostlist = NULL; + char **hosts = NULL; + char *refdn, *nrefdn; + struct berval **urls = NULL; + + assert( get_manageDSAit( op ) ); + + if( ldap_dn2domain( dn, &domain ) ) { + send_ldap_result( conn, op, LDAP_REFERRAL, + NULL, NULL, default_referral, NULL ); + goto done; + } + + Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> domain=\"%s\"\n", + dn == NULL ? "" : dn, + domain == NULL ? "" : domain, + 0 ); + + if( rc = ldap_domain2hostlist( domain, &hostlist ) ) { + Debug( LDAP_DEBUG_TRACE, "DNSSRV: domain2hostlist returned %d\n", + rc, 0, 0 ); + send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT, + NULL, "no DNS SRV RR available for DN", NULL, NULL ); + goto done; + } + + hosts = str2charray( hostlist, " " ); + + if( hosts == NULL ) { + Debug( LDAP_DEBUG_TRACE, "DNSSRV: str2charrary error\n", 0, 0, 0 ); + send_ldap_result( conn, op, LDAP_OTHER, + NULL, "problem processing DNS SRV records for DN", NULL, NULL ); + goto done; + } + + for( i=0; hosts[i] != NULL; i++) { + struct berval *url = ch_malloc( sizeof( struct berval ) ); + + url->bv_len = sizeof("ldap://")-1 + strlen(hosts[i]); + url->bv_val = ch_malloc( url->bv_len + 1 ); + + strcpy( url->bv_val, "ldap://" ); + strcpy( &url->bv_val[sizeof("ldap://")-1], hosts[i] ); + + if( ber_bvecadd( &urls, url ) < 0 ) { + ber_bvfree( url ); + send_ldap_result( conn, op, LDAP_OTHER, + NULL, "problem processing DNS SRV records for DN", + NULL, NULL ); + goto done; + } + } + + Statslog( LDAP_DEBUG_STATS, + "conn=%ld op=%d DNSSRV p=%d dn=\"%s\" url=\"%s\"\n", + op->o_connid, op->o_opid, op->o_protocol, dn, urls[0]->bv_val ); + + Debug( LDAP_DEBUG_TRACE, "DNSSRV: ManageDSAit dn=\"%s\" -> url=\"%s\"\n", + dn == NULL ? "" : dn, + urls[0]->bv_val, 0 ); + + rc = ldap_domain2dn(domain, &refdn); + + if( rc != LDAP_SUCCESS ) { + send_ldap_result( conn, op, LDAP_OTHER, + NULL, "DNS SRV problem processing manageDSAit control", + NULL, NULL ); + goto done; + } + + nrefdn = ch_strdup( refdn ); + dn_normalize(nrefdn); + + if( strcmp( nrefdn, ndn ) != 0 ) { + /* requested dn is subordinate */ + + Debug( LDAP_DEBUG_TRACE, + "DNSSRV: dn=\"%s\" subordindate to refdn=\"%s\"\n", + dn == NULL ? "" : dn, + refdn == NULL ? "" : refdn, + NULL ); + + send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT, + refdn, NULL, + NULL, NULL ); + + } else if ( scope == LDAP_SCOPE_ONELEVEL ) { + send_ldap_result( conn, op, LDAP_SUCCESS, + NULL, NULL, NULL, NULL ); + + } else { + struct berval val; + struct berval *vals[2]; + Entry *e = ch_calloc( 1, sizeof(Entry) ); + AttributeDescription *ad_objectClass + = slap_schema.si_ad_objectClass; + AttributeDescription *ad_ref = slap_schema.si_ad_ref; + e->e_dn = strdup( dn ); + e->e_ndn = strdup( ndn ); + + e->e_attrs = NULL; + e->e_private = NULL; + + vals[0] = &val; + vals[1] = NULL; + + val.bv_val = "top"; + val.bv_len = sizeof("top")-1; + attr_merge( e, ad_objectClass, vals ); + + val.bv_val = "referral"; + val.bv_len = sizeof("referral")-1; + attr_merge( e, ad_objectClass, vals ); + + val.bv_val = "extensibleObject"; + val.bv_len = sizeof("extensibleObject")-1; + attr_merge( e, ad_objectClass, vals ); + + { + AttributeDescription *ad = NULL; + const char *text; + + rc = slap_str2ad( "dc", &ad, &text ); + + if( rc == LDAP_SUCCESS ) { + char *p; + val.bv_val = ch_strdup( domain ); + + p = strchr( val.bv_val, '.' ); + + if( p == val.bv_val ) { + val.bv_val[1] = '\0'; + } else if ( p != NULL ) { + *p = '\0'; + } + + val.bv_len = strlen(val.bv_val); + attr_merge( e, ad, vals ); + + ad_free( ad, 1 ); + } + } + + { + AttributeDescription *ad = NULL; + const char *text; + + rc = slap_str2ad( "associatedDomain", &ad, &text ); + + if( rc == LDAP_SUCCESS ) { + val.bv_val = domain; + val.bv_len = strlen(domain); + attr_merge( e, ad, vals ); + + ad_free( ad, 1 ); + } + } + + attr_merge( e, ad_ref, urls ); + + rc = test_filter( be, conn, op, e, filter ); + + if( rc == LDAP_COMPARE_TRUE ) { + send_search_entry( be, conn, op, + e, attrs, attrsonly, NULL ); + } + + entry_free( e ); + + send_ldap_result( conn, op, LDAP_SUCCESS, + NULL, NULL, NULL, NULL ); + } + + free( refdn ); + free( nrefdn ); + +done: + if( domain != NULL ) ch_free( domain ); + if( hostlist != NULL ) ch_free( hostlist ); + if( hosts != NULL ) charray_free( hosts ); + if( urls != NULL ) ber_bvecfree( urls ); + return 0; } diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index d9023d509c..d1c0adaab9 100644 --- a/servers/slapd/backend.c +++ b/servers/slapd/backend.c @@ -619,17 +619,24 @@ int backend_check_referrals( Backend *be, Connection *conn, Operation *op, - struct berval ***bv, + const char *dn, + const char *ndn, const char **text ) { + int rc = LDAP_SUCCESS; *bv = NULL; if( be->be_chk_referrals ) { - return be->be_chk_referrals( be, - conn, op, bv, text ); + rc = be->be_chk_referrals( be, + conn, op, dn, ndn, text ); + + if( rc != LDAP_SUCCESS && rc != LDAP_REFERRAL ) { + send_ldap_result( conn, op, rc, + NULL, text, NULL, NULL ); + } } - return LDAP_SUCCESS; + return rc; } int diff --git a/servers/slapd/compare.c b/servers/slapd/compare.c index b4b46ab83e..6c1f8a6ed3 100644 --- a/servers/slapd/compare.c +++ b/servers/slapd/compare.c @@ -36,7 +36,6 @@ do_compare( AttributeAssertion ava; Backend *be; int rc = LDAP_SUCCESS; - struct berval **urls = NULL; const char *text = NULL; ava.aa_desc = NULL; @@ -108,6 +107,7 @@ do_compare( /* make sure this backend recongizes critical controls */ rc = backend_check_controls( be, conn, op, &text ) ; + if( rc != LDAP_SUCCESS ) { send_ldap_result( conn, op, rc, NULL, text, NULL, NULL ); @@ -115,11 +115,10 @@ do_compare( } /* check for referrals */ - rc = backend_check_referrals( be, conn, op, &urls, &text ); + rc = backend_check_referrals( be, conn, op, + dn, ndn, &text ); + if ( rc != LDAP_SUCCESS ) { - send_ldap_result( conn, op, rc, - NULL, text, urls, NULL ); - ber_bvecfree( urls ); goto cleanup; } diff --git a/servers/slapd/delete.c b/servers/slapd/delete.c index 06eb38fb2d..324b3524c1 100644 --- a/servers/slapd/delete.c +++ b/servers/slapd/delete.c @@ -33,7 +33,6 @@ do_delete( { char *dn, *ndn = NULL; const char *text; - struct berval **urls = NULL; Backend *be; int rc; @@ -82,6 +81,7 @@ do_delete( /* make sure this backend recongizes critical controls */ rc = backend_check_controls( be, conn, op, &text ) ; + if( rc != LDAP_SUCCESS ) { send_ldap_result( conn, op, rc, NULL, text, NULL, NULL ); @@ -89,11 +89,10 @@ do_delete( } /* check for referrals */ - rc = backend_check_referrals( be, conn, op, &urls, &text ); + rc = backend_check_referrals( be, conn, op, + dn, ndn, &text ); + if ( rc != LDAP_SUCCESS ) { - send_ldap_result( conn, op, rc, - NULL, text, urls, NULL ); - ber_bvecfree( urls ); goto cleanup; } diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index d648633f25..d0427f7e7b 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -45,7 +45,6 @@ do_modify( Backend *be; int rc; const char *text; - struct berval **urls; Debug( LDAP_DEBUG_TRACE, "do_modify\n", 0, 0, 0 ); @@ -180,11 +179,10 @@ do_modify( } /* check for referrals */ - rc = backend_check_referrals( be, conn, op, &urls, &text ); + rc = backend_check_referrals( be, conn, op, + dn, ndn, &text ); + if ( rc != LDAP_SUCCESS ) { - send_ldap_result( conn, op, rc, - NULL, text, urls, NULL ); - ber_bvecfree( urls ); goto cleanup; } diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index cf56ae9e19..0ac91bdff4 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -54,7 +54,6 @@ do_modrdn( ber_len_t length; int rc; const char *text; - struct berval **urls = NULL; Debug( LDAP_DEBUG_TRACE, "do_modrdn\n", 0, 0, 0 ); @@ -168,6 +167,7 @@ do_modrdn( /* make sure this backend recongizes critical controls */ rc = backend_check_controls( be, conn, op, &text ) ; + if( rc != LDAP_SUCCESS ) { send_ldap_result( conn, op, rc, NULL, text, NULL, NULL ); @@ -175,11 +175,10 @@ do_modrdn( } /* check for referrals */ - rc = backend_check_referrals( be, conn, op, &urls, &text ); + rc = backend_check_referrals( be, conn, op, + dn, ndn, &text ); + if ( rc != LDAP_SUCCESS ) { - send_ldap_result( conn, op, rc, - NULL, text, urls, NULL ); - ber_bvecfree( urls ); goto cleanup; } diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 1fa51f44c1..9b6418045b 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -159,7 +159,8 @@ LIBSLAPD_F( int ) backend_check_referrals LDAP_P(( Backend *be, Connection *conn, Operation *op, - struct berval ***bv, + const char *dn, + const char *ndn, const char **text )); LIBSLAPD_F (int) backend_connection_init LDAP_P((Connection *conn)); diff --git a/servers/slapd/search.c b/servers/slapd/search.c index ed400b0718..73db58b2e6 100644 --- a/servers/slapd/search.c +++ b/servers/slapd/search.c @@ -39,7 +39,6 @@ do_search( Backend *be; int rc; const char *text; - struct berval **urls = NULL; Debug( LDAP_DEBUG_TRACE, "do_search\n", 0, 0, 0 ); @@ -224,11 +223,10 @@ do_search( } /* check for referrals */ - rc = backend_check_referrals( be, conn, op, &urls, &text ); + rc = backend_check_referrals( be, conn, op, + base, nbase, &text ); + if ( rc != LDAP_SUCCESS ) { - send_ldap_result( conn, op, rc, - NULL, text, urls, NULL ); - ber_bvecfree( urls ); goto return_results; } diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 023ed076ef..105937c807 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -910,7 +910,7 @@ struct slap_backend_info { int (*bi_chk_referrals) LDAP_P((BackendDB *bd, struct slap_conn *c, struct slap_op *o, - struct berval ***urls, + const char *dn, const char *ndn, const char **text )); int (*bi_acl_group) LDAP_P((Backend *bd, -- 2.39.5