Back to index

openldap  2.4.31
referral.c
Go to the documentation of this file.
00001 /* referral.c - BDB backend referral handler */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 2000-2012 The OpenLDAP Foundation.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in the file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 
00017 #include "portable.h"
00018 #include <stdio.h>
00019 #include <ac/string.h>
00020 
00021 #include "back-bdb.h"
00022 
00023 int
00024 bdb_referrals( Operation *op, SlapReply *rs )
00025 {
00026        struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
00027        Entry *e = NULL;
00028        EntryInfo *ei;
00029        int rc = LDAP_SUCCESS;
00030 
00031        DB_TXN        *rtxn;
00032        DB_LOCK              lock;
00033 
00034        if( op->o_tag == LDAP_REQ_SEARCH ) {
00035               /* let search take care of itself */
00036               return rc;
00037        }
00038 
00039        if( get_manageDSAit( op ) ) {
00040               /* let op take care of DSA management */
00041               return rc;
00042        } 
00043 
00044        rc = bdb_reader_get(op, bdb->bi_dbenv, &rtxn);
00045        switch(rc) {
00046        case 0:
00047               break;
00048        default:
00049               return LDAP_OTHER;
00050        }
00051 
00052 dn2entry_retry:
00053        /* get entry */
00054        rc = bdb_dn2entry( op, rtxn, &op->o_req_ndn, &ei, 1, &lock );
00055 
00056        /* bdb_dn2entry() may legally leave ei == NULL
00057         * if rc != 0 and rc != DB_NOTFOUND
00058         */
00059        if ( ei ) {
00060               e = ei->bei_e;
00061        }
00062 
00063        switch(rc) {
00064        case DB_NOTFOUND:
00065        case 0:
00066               break;
00067        case LDAP_BUSY:
00068               rs->sr_text = "ldap server busy";
00069               return LDAP_BUSY;
00070        case DB_LOCK_DEADLOCK:
00071        case DB_LOCK_NOTGRANTED:
00072               goto dn2entry_retry;
00073        default:
00074               Debug( LDAP_DEBUG_TRACE,
00075                      LDAP_XSTRING(bdb_referrals)
00076                      ": dn2entry failed: %s (%d)\n",
00077                      db_strerror(rc), rc, 0 ); 
00078               rs->sr_text = "internal error";
00079               return LDAP_OTHER;
00080        }
00081 
00082        if ( rc == DB_NOTFOUND ) {
00083               rc = LDAP_SUCCESS;
00084               rs->sr_matched = NULL;
00085               if ( e != NULL ) {
00086                      Debug( LDAP_DEBUG_TRACE,
00087                             LDAP_XSTRING(bdb_referrals)
00088                             ": tag=%lu target=\"%s\" matched=\"%s\"\n",
00089                             (unsigned long)op->o_tag, op->o_req_dn.bv_val, e->e_name.bv_val );
00090 
00091                      if( is_entry_referral( e ) ) {
00092                             BerVarray ref = get_entry_referrals( op, e );
00093                             rc = LDAP_OTHER;
00094                             rs->sr_ref = referral_rewrite( ref, &e->e_name,
00095                                    &op->o_req_dn, LDAP_SCOPE_DEFAULT );
00096                             ber_bvarray_free( ref );
00097                             if ( rs->sr_ref ) {
00098                                    rs->sr_matched = ber_strdup_x(
00099                                    e->e_name.bv_val, op->o_tmpmemctx );
00100                             }
00101                      }
00102 
00103                      bdb_cache_return_entry_r (bdb, e, &lock);
00104                      e = NULL;
00105               }
00106 
00107               if( rs->sr_ref != NULL ) {
00108                      /* send referrals */
00109                      rc = rs->sr_err = LDAP_REFERRAL;
00110                      send_ldap_result( op, rs );
00111                      ber_bvarray_free( rs->sr_ref );
00112                      rs->sr_ref = NULL;
00113               } else if ( rc != LDAP_SUCCESS ) {
00114                      rs->sr_text = rs->sr_matched ? "bad referral object" : NULL;
00115               }
00116 
00117               if (rs->sr_matched) {
00118                      op->o_tmpfree( (char *)rs->sr_matched, op->o_tmpmemctx );
00119                      rs->sr_matched = NULL;
00120               }
00121               return rc;
00122        }
00123 
00124        if ( is_entry_referral( e ) ) {
00125               /* entry is a referral */
00126               BerVarray refs = get_entry_referrals( op, e );
00127               rs->sr_ref = referral_rewrite(
00128                      refs, &e->e_name, &op->o_req_dn, LDAP_SCOPE_DEFAULT );
00129 
00130               Debug( LDAP_DEBUG_TRACE,
00131                      LDAP_XSTRING(bdb_referrals)
00132                      ": tag=%lu target=\"%s\" matched=\"%s\"\n",
00133                      (unsigned long)op->o_tag, op->o_req_dn.bv_val, e->e_name.bv_val );
00134 
00135               rs->sr_matched = e->e_name.bv_val;
00136               if( rs->sr_ref != NULL ) {
00137                      rc = rs->sr_err = LDAP_REFERRAL;
00138                      send_ldap_result( op, rs );
00139                      ber_bvarray_free( rs->sr_ref );
00140                      rs->sr_ref = NULL;
00141               } else {
00142                      rc = LDAP_OTHER;
00143                      rs->sr_text = "bad referral object";
00144               }
00145 
00146               rs->sr_matched = NULL;
00147               ber_bvarray_free( refs );
00148        }
00149 
00150        bdb_cache_return_entry_r(bdb, e, &lock);
00151        return rc;
00152 }