Back to index

openldap  2.4.31
referral.c
Go to the documentation of this file.
00001 /* referral.c - MDB 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-mdb.h"
00022 
00023 int
00024 mdb_referrals( Operation *op, SlapReply *rs )
00025 {
00026        struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
00027        Entry *e = NULL;
00028        int rc = LDAP_SUCCESS;
00029 
00030        MDB_txn              *rtxn;
00031        mdb_op_info   opinfo = {0}, *moi = &opinfo;
00032 
00033        if( op->o_tag == LDAP_REQ_SEARCH ) {
00034               /* let search take care of itself */
00035               return rc;
00036        }
00037 
00038        if( get_manageDSAit( op ) ) {
00039               /* let op take care of DSA management */
00040               return rc;
00041        } 
00042 
00043        rc = mdb_opinfo_get(op, mdb, 1, &moi);
00044        switch(rc) {
00045        case 0:
00046               break;
00047        default:
00048               return LDAP_OTHER;
00049        }
00050 
00051        rtxn = moi->moi_txn;
00052 
00053        /* get entry */
00054        rc = mdb_dn2entry( op, rtxn, &op->o_req_ndn, &e, 1 );
00055 
00056        switch(rc) {
00057        case MDB_NOTFOUND:
00058        case 0:
00059               break;
00060        case LDAP_BUSY:
00061               rs->sr_text = "ldap server busy";
00062               goto done;
00063        default:
00064               Debug( LDAP_DEBUG_TRACE,
00065                      LDAP_XSTRING(mdb_referrals)
00066                      ": dn2entry failed: %s (%d)\n",
00067                      mdb_strerror(rc), rc, 0 );
00068               rs->sr_text = "internal error";
00069               rc = LDAP_OTHER;
00070               goto done;
00071        }
00072 
00073        if ( rc == MDB_NOTFOUND ) {
00074               rc = LDAP_SUCCESS;
00075               rs->sr_matched = NULL;
00076               if ( e != NULL ) {
00077                      Debug( LDAP_DEBUG_TRACE,
00078                             LDAP_XSTRING(mdb_referrals)
00079                             ": tag=%lu target=\"%s\" matched=\"%s\"\n",
00080                             (unsigned long)op->o_tag, op->o_req_dn.bv_val, e->e_name.bv_val );
00081 
00082                      if( is_entry_referral( e ) ) {
00083                             BerVarray ref = get_entry_referrals( op, e );
00084                             rc = LDAP_OTHER;
00085                             rs->sr_ref = referral_rewrite( ref, &e->e_name,
00086                                    &op->o_req_dn, LDAP_SCOPE_DEFAULT );
00087                             ber_bvarray_free( ref );
00088                             if ( rs->sr_ref ) {
00089                                    rs->sr_matched = ber_strdup_x(
00090                                    e->e_name.bv_val, op->o_tmpmemctx );
00091                             }
00092                      }
00093 
00094                      mdb_entry_return( op, e );
00095                      e = NULL;
00096               }
00097 
00098               if( rs->sr_ref != NULL ) {
00099                      /* send referrals */
00100                      rc = rs->sr_err = LDAP_REFERRAL;
00101                      send_ldap_result( op, rs );
00102                      ber_bvarray_free( rs->sr_ref );
00103                      rs->sr_ref = NULL;
00104               } else if ( rc != LDAP_SUCCESS ) {
00105                      rs->sr_text = rs->sr_matched ? "bad referral object" : NULL;
00106               }
00107 
00108               if (rs->sr_matched) {
00109                      op->o_tmpfree( (char *)rs->sr_matched, op->o_tmpmemctx );
00110                      rs->sr_matched = NULL;
00111               }
00112               goto done;
00113        }
00114 
00115        if ( is_entry_referral( e ) ) {
00116               /* entry is a referral */
00117               BerVarray refs = get_entry_referrals( op, e );
00118               rs->sr_ref = referral_rewrite(
00119                      refs, &e->e_name, &op->o_req_dn, LDAP_SCOPE_DEFAULT );
00120 
00121               Debug( LDAP_DEBUG_TRACE,
00122                      LDAP_XSTRING(mdb_referrals)
00123                      ": tag=%lu target=\"%s\" matched=\"%s\"\n",
00124                      (unsigned long)op->o_tag, op->o_req_dn.bv_val, e->e_name.bv_val );
00125 
00126               rs->sr_matched = e->e_name.bv_val;
00127               if( rs->sr_ref != NULL ) {
00128                      rc = rs->sr_err = LDAP_REFERRAL;
00129                      send_ldap_result( op, rs );
00130                      ber_bvarray_free( rs->sr_ref );
00131                      rs->sr_ref = NULL;
00132               } else {
00133                      rc = LDAP_OTHER;
00134                      rs->sr_text = "bad referral object";
00135               }
00136 
00137               rs->sr_matched = NULL;
00138               ber_bvarray_free( refs );
00139        }
00140 
00141 done:
00142        if ( moi == &opinfo ) {
00143               mdb_txn_reset( moi->moi_txn );
00144               LDAP_SLIST_REMOVE( &op->o_extra, &moi->moi_oe, OpExtra, oe_next );
00145        }
00146        if ( e )
00147               mdb_entry_return( op, e );
00148        return rc;
00149 }