From 6f378341a29b5003692cc2f9b830659608b6ab15 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Fri, 16 Jun 2000 01:19:30 +0000 Subject: [PATCH] Add backend_check_referrals() framework. --- servers/slapd/add.c | 15 ++++++++--- servers/slapd/backend.c | 17 ++++++++++++ servers/slapd/compare.c | 53 +++++++++++++++++++++----------------- servers/slapd/delete.c | 11 +++++++- servers/slapd/modify.c | 19 +++++++++----- servers/slapd/modrdn.c | 11 +++++++- servers/slapd/proto-slap.h | 7 +++++ servers/slapd/search.c | 15 ++++++++--- servers/slapd/slap.h | 6 +++++ 9 files changed, 114 insertions(+), 40 deletions(-) diff --git a/servers/slapd/add.c b/servers/slapd/add.c index b9b2c63f7e..3db0bf9d02 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -18,7 +18,6 @@ #include "portable.h" #include - #include #include #include @@ -45,6 +44,7 @@ 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 ); @@ -134,8 +134,7 @@ do_add( Connection *conn, Operation *op ) goto done; } - if ( modlist == NULL ) - { + if ( modlist == NULL ) { send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL, "no attributes provided", NULL, NULL ); goto done; @@ -158,13 +157,21 @@ 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 ); goto done; } + /* check for referrals */ + rc = backend_check_referrals( be, conn, op, &urls, &text ); + if ( rc != LDAP_SUCCESS ) { + send_ldap_result( conn, op, rc, + NULL, text, urls, NULL ); + ber_bvecfree( urls ); + goto done; + } + if ( global_readonly || be->be_readonly ) { Debug( LDAP_DEBUG_ANY, "do_add: database is read-only\n", 0, 0, 0 ); diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index bcb3e0424f..d9023d509c 100644 --- a/servers/slapd/backend.c +++ b/servers/slapd/backend.c @@ -615,6 +615,23 @@ backend_check_controls( return LDAP_SUCCESS; } +int backend_check_referrals( + Backend *be, + Connection *conn, + Operation *op, + struct berval ***bv, + const char **text ) +{ + *bv = NULL; + + if( be->be_chk_referrals ) { + return be->be_chk_referrals( be, + conn, op, bv, text ); + } + + return LDAP_SUCCESS; +} + int backend_group( Backend *be, diff --git a/servers/slapd/compare.c b/servers/slapd/compare.c index 821281aa37..b4b46ab83e 100644 --- a/servers/slapd/compare.c +++ b/servers/slapd/compare.c @@ -18,7 +18,6 @@ #include "portable.h" #include - #include #include "ldap_pvt.h" @@ -37,6 +36,7 @@ do_compare( AttributeAssertion ava; Backend *be; int rc = LDAP_SUCCESS; + struct berval **urls = NULL; const char *text = NULL; ava.aa_desc = NULL; @@ -94,6 +94,35 @@ do_compare( goto cleanup; } + /* + * We could be serving multiple database backends. Select the + * appropriate one, or send a referral to our "referral server" + * if we don't hold it. + */ + if ( (be = select_backend( ndn )) == NULL ) { + send_ldap_result( conn, op, rc = LDAP_REFERRAL, + NULL, NULL, default_referral, NULL ); + rc = 1; + goto cleanup; + } + + /* 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 ); + goto cleanup; + } + + /* check for referrals */ + rc = backend_check_referrals( be, conn, op, &urls, &text ); + if ( rc != LDAP_SUCCESS ) { + send_ldap_result( conn, op, rc, + NULL, text, urls, NULL ); + ber_bvecfree( urls ); + goto cleanup; + } + rc = slap_bv2ad( &desc, &ava.aa_desc, &text ); if( rc != LDAP_SUCCESS ) { send_ldap_result( conn, op, rc, NULL, @@ -125,28 +154,6 @@ do_compare( op->o_connid, op->o_opid, dn, ava.aa_desc->ad_cname->bv_val, 0 ); - - /* - * We could be serving multiple database backends. Select the - * appropriate one, or send a referral to our "referral server" - * if we don't hold it. - */ - if ( (be = select_backend( ndn )) == NULL ) { - send_ldap_result( conn, op, rc = LDAP_REFERRAL, - NULL, NULL, default_referral, NULL ); - rc = 1; - goto cleanup; - } - - /* 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 ); - goto cleanup; - } - /* deref suffix alias if appropriate */ ndn = suffix_alias( be, ndn ); diff --git a/servers/slapd/delete.c b/servers/slapd/delete.c index ad6988ef9e..06eb38fb2d 100644 --- a/servers/slapd/delete.c +++ b/servers/slapd/delete.c @@ -33,6 +33,7 @@ do_delete( { char *dn, *ndn = NULL; const char *text; + struct berval **urls = NULL; Backend *be; int rc; @@ -81,13 +82,21 @@ 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 ); goto cleanup; } + /* check for referrals */ + rc = backend_check_referrals( be, conn, op, &urls, &text ); + if ( rc != LDAP_SUCCESS ) { + send_ldap_result( conn, op, rc, + NULL, text, urls, NULL ); + ber_bvecfree( urls ); + goto cleanup; + } + if ( global_readonly || be->be_readonly ) { Debug( LDAP_DEBUG_ANY, "do_delete: database is read-only\n", 0, 0, 0 ); diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index b39e4fa363..d648633f25 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -27,12 +27,10 @@ #include "slap.h" - int do_modify( Connection *conn, - Operation *op -) + Operation *op ) { char *dn, *ndn = NULL; char *last; @@ -47,6 +45,7 @@ do_modify( Backend *be; int rc; const char *text; + struct berval **urls; Debug( LDAP_DEBUG_TRACE, "do_modify\n", 0, 0, 0 ); @@ -129,8 +128,6 @@ do_modify( } (*modtail)->ml_op = mop; - - modtail = &(*modtail)->ml_next; } *modtail = NULL; @@ -159,7 +156,6 @@ do_modify( } #endif - Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d MOD dn=\"%s\"\n", op->o_connid, op->o_opid, dn, 0, 0 ); @@ -183,11 +179,20 @@ do_modify( goto cleanup; } + /* check for referrals */ + rc = backend_check_referrals( be, conn, op, &urls, &text ); + if ( rc != LDAP_SUCCESS ) { + send_ldap_result( conn, op, rc, + NULL, text, urls, NULL ); + ber_bvecfree( urls ); + goto cleanup; + } + if ( global_readonly || be->be_readonly ) { Debug( LDAP_DEBUG_ANY, "do_modify: database is read-only\n", 0, 0, 0 ); send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM, - NULL, "directory is read-only", NULL, NULL ); + NULL, "directory is read-only", NULL, NULL ); goto cleanup; } diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index 11434c9635..cf56ae9e19 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -54,6 +54,7 @@ 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 ); @@ -167,13 +168,21 @@ 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 ); goto cleanup; } + /* check for referrals */ + rc = backend_check_referrals( be, conn, op, &urls, &text ); + if ( rc != LDAP_SUCCESS ) { + send_ldap_result( conn, op, rc, + NULL, text, urls, NULL ); + ber_bvecfree( urls ); + goto cleanup; + } + if ( global_readonly || be->be_readonly ) { Debug( LDAP_DEBUG_ANY, "do_modrdn: database is read-only\n", 0, 0, 0 ); diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 1f4e352171..1fa51f44c1 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -155,6 +155,13 @@ LIBSLAPD_F( int ) backend_check_controls LDAP_P(( Operation *op, const char **text )); +LIBSLAPD_F( int ) backend_check_referrals LDAP_P(( + Backend *be, + Connection *conn, + Operation *op, + struct berval ***bv, + const char **text )); + LIBSLAPD_F (int) backend_connection_init LDAP_P((Connection *conn)); LIBSLAPD_F (int) backend_connection_destroy LDAP_P((Connection *conn)); diff --git a/servers/slapd/search.c b/servers/slapd/search.c index 51ed005796..ed400b0718 100644 --- a/servers/slapd/search.c +++ b/servers/slapd/search.c @@ -25,13 +25,11 @@ #include "ldap_pvt.h" #include "slap.h" - int do_search( Connection *conn, /* where to send results */ Operation *op /* info about the op to which we're responding */ -) -{ +) { int i; ber_int_t scope, deref, attrsonly; ber_int_t sizelimit, timelimit; @@ -41,6 +39,7 @@ do_search( Backend *be; int rc; const char *text; + struct berval **urls = NULL; Debug( LDAP_DEBUG_TRACE, "do_search\n", 0, 0, 0 ); @@ -218,13 +217,21 @@ do_search( /* 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 ); goto return_results; } + /* check for referrals */ + rc = backend_check_referrals( be, conn, op, &urls, &text ); + if ( rc != LDAP_SUCCESS ) { + send_ldap_result( conn, op, rc, + NULL, text, urls, NULL ); + ber_bvecfree( urls ); + goto return_results; + } + /* deref the base if needed */ nbase = suffix_alias( be, nbase ); diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 5a7bf3582e..023ed076ef 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -743,6 +743,7 @@ struct slap_backend_db { #define be_extended bd_info->bi_extended #define be_release bd_info->bi_entry_release_rw +#define be_chk_referrals bd_info->bi_chk_referrals #define be_group bd_info->bi_acl_group #define be_controls bd_info->bi_controls @@ -907,6 +908,11 @@ struct slap_backend_info { /* Auxilary Functions */ int (*bi_entry_release_rw) LDAP_P((BackendDB *bd, Entry *e, int rw)); + int (*bi_chk_referrals) LDAP_P((BackendDB *bd, + struct slap_conn *c, struct slap_op *o, + struct berval ***urls, + const char **text )); + int (*bi_acl_group) LDAP_P((Backend *bd, Entry *e, const char *bdn, const char *edn, ObjectClass *group_oc, -- 2.39.5