Diff for /servers/slapd/back-relay/op.c between versions 1.15 and 1.15.2.7

version 1.15, 2006/01/03 22:12:23 version 1.15.2.7, 2009/01/22 00:01:10
Line 1 Line 1
 /* op.c - relay backend operations */  /* op.c - relay backend operations */
   /* $OpenLDAP: pkg/ldap/servers/slapd/back-relay/op.c,v 1.15.2.6 2008/02/12 01:03:16 quanah Exp $ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.  /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *   *
  * Copyright 2004-2006 The OpenLDAP Foundation.   * Copyright 2004-2009 The OpenLDAP Foundation.
  * Portions Copyright 2004 Pierangelo Masarati.   * Portions Copyright 2004 Pierangelo Masarati.
  * All rights reserved.   * All rights reserved.
  *   *
Line 25 Line 26
 #include "slap.h"  #include "slap.h"
 #include "back-relay.h"  #include "back-relay.h"
   
   #define RB_ERR_MASK             (0x0000FFFFU)
   #define RB_ERR                  (0x10000000U)
   #define RB_UNSUPPORTED_FLAG     (0x20000000U)
   #define RB_REFERRAL             (0x40000000U)
   #define RB_SEND                 (0x80000000U)
   #define RB_UNSUPPORTED          (LDAP_UNWILLING_TO_PERFORM|RB_ERR|RB_UNSUPPORTED_FLAG)
   #define RB_UNSUPPORTED_SEND     (RB_UNSUPPORTED|RB_SEND)
   #define RB_REFERRAL_SEND        (RB_REFERRAL|RB_SEND)
   #define RB_ERR_SEND             (RB_ERR|RB_SEND)
   #define RB_ERR_REFERRAL_SEND    (RB_ERR|RB_REFERRAL|RB_SEND)
   
 static int  static int
 relay_back_swap_bd( struct slap_op *op, struct slap_rep *rs )  relay_back_swap_bd( Operation *op, SlapReply *rs )
 {  {
         slap_callback   *cb = op->o_callback;          slap_callback   *cb = op->o_callback;
         BackendDB       *be = op->o_bd;          BackendDB       *be = op->o_bd;
Line 37  relay_back_swap_bd( struct slap_op *op, Line 49  relay_back_swap_bd( struct slap_op *op,
         return SLAP_CB_CONTINUE;          return SLAP_CB_CONTINUE;
 }  }
   
 static void  #define relay_back_add_cb( cb, op ) \
 relay_back_add_cb( slap_callback *cb, struct slap_op *op )          {                                               \
 {                  (cb)->sc_next = (op)->o_callback;       \
         cb->sc_next = op->o_callback;                  (cb)->sc_response = relay_back_swap_bd; \
         cb->sc_response = relay_back_swap_bd;                  (cb)->sc_cleanup = relay_back_swap_bd;  \
         cb->sc_cleanup = relay_back_swap_bd;                  (cb)->sc_private = (op)->o_bd;          \
         cb->sc_private = op->o_bd;                  (op)->o_callback = (cb);                \
         op->o_callback = cb;          }
 }  
   
 /*  /*
  * selects the backend if not enforced at config;   * selects the backend if not enforced at config;
  * in case of failure, behaves based on err:   * in case of failure, behaves based on err:
  *      -1                      don't send result   *      -1                      don't send result
  *      LDAP_SUCCESS            don't send result; may send referral   *      LDAP_SUCCESS            don't send result; may send referral if dosend
  *      any valid error         send as error result   *      any valid error         send as error result if dosend
  */   */
 static BackendDB *  static BackendDB *
 relay_back_select_backend( struct slap_op *op, struct slap_rep *rs, int err )  relay_back_select_backend( Operation *op, SlapReply *rs, slap_mask_t fail_mode )
 {  {
         relay_back_info         *ri = (relay_back_info *)op->o_bd->be_private;          relay_back_info         *ri = (relay_back_info *)op->o_bd->be_private;
         BackendDB               *bd = ri->ri_bd;          BackendDB               *bd = ri->ri_bd;
           int                     rc = ( fail_mode & RB_ERR_MASK );
   
         if ( bd == NULL ) {          if ( bd == NULL && !BER_BVISNULL( &op->o_req_ndn ) ) {
                 bd = select_backend( &op->o_req_ndn, 0, 1 );                  bd = select_backend( &op->o_req_ndn, 1 );
                 if ( bd == op->o_bd ) {                  if ( bd == op->o_bd ) {
                         if ( err > LDAP_SUCCESS ) {                          Debug( LDAP_DEBUG_ANY,
                                 send_ldap_error( op, rs,                                  "%s: back-relay for DN=\"%s\" would call self.\n",
                                                 LDAP_UNWILLING_TO_PERFORM,                                   op->o_log_prefix, op->o_req_dn.bv_val, 0 );
                                                 "back-relay would call self" );                          if ( fail_mode & RB_ERR ) {
                                   rs->sr_err = rc;
                                   if ( fail_mode & RB_SEND ) {
                                           send_ldap_result( op, rs );
                                   }
                         }                          }
   
                         return NULL;                          return NULL;
                 }                  }
         }          }
   
         if ( bd == NULL && err > -1 ) {          if ( bd == NULL ) {
                 if ( default_referral ) {                  if ( ( fail_mode & RB_REFERRAL )
                         rs->sr_ref = referral_rewrite( default_referral,                          && ( fail_mode & RB_SEND )
                                 NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT );                          && !BER_BVISNULL( &op->o_req_ndn )
                           && default_referral )
                   {
                           rs->sr_err = LDAP_REFERRAL;
   
                           /* if we set sr_err to LDAP_REFERRAL,
                            * we must provide one */
                           rs->sr_ref = referral_rewrite(
                                   default_referral,
                                   NULL, &op->o_req_dn,
                                   LDAP_SCOPE_DEFAULT );
                         if ( !rs->sr_ref ) {                          if ( !rs->sr_ref ) {
                                 rs->sr_ref = default_referral;                                  rs->sr_ref = default_referral;
                         }                          }
   
                         rs->sr_err = LDAP_REFERRAL;  
                         send_ldap_result( op, rs );                          send_ldap_result( op, rs );
   
                         if ( rs->sr_ref != default_referral ) {                          if ( rs->sr_ref != default_referral ) {
                                 ber_bvarray_free( rs->sr_ref );                                  ber_bvarray_free( rs->sr_ref );
                         }                          }
   
                 } else {                          return NULL;
                         /* NOTE: err is LDAP_INVALID_CREDENTIALS for bind,                  }
                          * LDAP_NO_SUCH_OBJECT for other operations.  
                          * noSuchObject cannot be returned by bind */                  /* NOTE: err is LDAP_INVALID_CREDENTIALS for bind,
                         rs->sr_err = err;                   * LDAP_NO_SUCH_OBJECT for other operations.
                    * noSuchObject cannot be returned by bind */
                   rs->sr_err = rc;
                   if ( fail_mode & RB_SEND ) {
                         send_ldap_result( op, rs );                          send_ldap_result( op, rs );
                 }                  }
         }          }
Line 99  relay_back_select_backend( struct slap_o Line 128  relay_back_select_backend( struct slap_o
         return bd;          return bd;
 }  }
   
 int  static int
 relay_back_op_bind( struct slap_op *op, struct slap_rep *rs )  relay_back_op(
           Operation       *op,
           SlapReply       *rs,
           BackendDB       *bd,
           BI_op_func      *func,
           slap_mask_t     fail_mode )
 {  {
         BackendDB               *bd;          int                     rc = ( fail_mode & RB_ERR_MASK );
         int                     rc = 1;  
   
         bd = relay_back_select_backend( op, rs, LDAP_INVALID_CREDENTIALS );  
         if ( bd == NULL ) {  
                 return rc;  
         }  
   
         if ( bd->be_bind ) {          if ( func ) {
                 BackendDB       *be = op->o_bd;                  BackendDB       *be = op->o_bd;
                 slap_callback   cb;                  slap_callback   cb;
   
                 relay_back_add_cb( &cb, op );                  relay_back_add_cb( &cb, op );
   
                 op->o_bd = bd;                  op->o_bd = bd;
                 rc = ( bd->be_bind )( op, rs );                  rc = func( op, rs );
                 op->o_bd = be;                  op->o_bd = be;
   
                 if ( op->o_callback == &cb ) {                  if ( op->o_callback == &cb ) {
                         op->o_callback = op->o_callback->sc_next;                          op->o_callback = op->o_callback->sc_next;
                 }                  }
   
         } else {          } else if ( fail_mode & RB_ERR ) {
                 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,                  rs->sr_err = rc;
                                 "operation not supported "                  if ( fail_mode & RB_UNSUPPORTED_FLAG ) {
                                 "within naming context" );                          rs->sr_text = "operation not supported within naming context";
                   }
   
                   if ( fail_mode & RB_SEND ) {
                           send_ldap_result( op, rs );
                   }
         }          }
   
         return rc;          return rc;
 }  }
   
 int  int
 relay_back_op_unbind( struct slap_op *op, struct slap_rep *rs )  relay_back_op_bind( Operation *op, SlapReply *rs )
 {  {
         relay_back_info         *ri = (relay_back_info *)op->o_bd->be_private;          BackendDB       *bd;
         BackendDB               *bd;  
         int                     rc = 1;  
   
         bd = ri->ri_bd;          /* allow rootdn as a means to auth without the need to actually
         if ( bd == NULL ) {           * contact the proxied DSA */
                 bd = select_backend( &op->o_req_ndn, 0, 1 );          switch ( be_rootdn_bind( op, rs ) ) {
           case SLAP_CB_CONTINUE:
                   break;
   
           default:
                   return rs->sr_err;
         }          }
   
         if ( bd && bd->be_unbind ) {          bd = relay_back_select_backend( op, rs,
                 BackendDB       *be = op->o_bd;                  ( LDAP_INVALID_CREDENTIALS | RB_ERR_SEND ) );
                 slap_callback   cb;          if ( bd == NULL ) {
                   return rs->sr_err;
           }
   
                 relay_back_add_cb( &cb, op );          return relay_back_op( op, rs, bd, bd->be_bind,
                   ( LDAP_INVALID_CREDENTIALS | RB_ERR_SEND ) );
   }
   
                 op->o_bd = bd;  int
                 rc = ( bd->be_unbind )( op, rs );  relay_back_op_unbind( Operation *op, SlapReply *rs )
                 op->o_bd = be;  {
           BackendDB               *bd;
   
                 if ( op->o_callback == &cb ) {          bd = relay_back_select_backend( op, rs, 0 );
                         op->o_callback = op->o_callback->sc_next;          if ( bd != NULL ) {
                 }                  (void)relay_back_op( op, rs, bd, bd->be_unbind, 0 );
         }          }
   
         return 0;          return 0;
   
 }  }
   
 int  int
 relay_back_op_search( struct slap_op *op, struct slap_rep *rs )  relay_back_op_search( Operation *op, SlapReply *rs )
 {  {
         BackendDB               *bd;          BackendDB               *bd;
         int                     rc = 1;  
   
         bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );          bd = relay_back_select_backend( op, rs,
                   ( LDAP_NO_SUCH_OBJECT | RB_ERR_REFERRAL_SEND ) );
         if ( bd == NULL ) {          if ( bd == NULL ) {
                 return 1;                  return rs->sr_err;
         }          }
   
         if ( bd->be_search ) {          return relay_back_op( op, rs, bd, bd->be_search,
                 BackendDB       *be = op->o_bd;                  RB_UNSUPPORTED_SEND );
                 slap_callback   cb;  
   
                 relay_back_add_cb( &cb, op );  
   
                 op->o_bd = bd;  
                 rc = ( bd->be_search )( op, rs );  
                 op->o_bd = be;  
   
                 if ( op->o_callback == &cb ) {  
                         op->o_callback = op->o_callback->sc_next;  
                 }  
   
         } else {  
                 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,  
                                 "operation not supported "  
                                 "within naming context" );  
         }  
   
         return rc;  
   
 }  }
   
 int  int
 relay_back_op_compare( struct slap_op *op, struct slap_rep *rs )  relay_back_op_compare( Operation *op, SlapReply *rs )
 {  {
         BackendDB               *bd;          BackendDB               *bd;
         int                     rc = 1;  
   
         bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );          bd = relay_back_select_backend( op, rs,
                   ( LDAP_NO_SUCH_OBJECT | RB_ERR_REFERRAL_SEND ) );
         if ( bd == NULL ) {          if ( bd == NULL ) {
                 return 1;                  return rs->sr_err;
         }          }
   
         if ( bd->be_compare ) {          return relay_back_op( op, rs, bd, bd->be_compare,
                 BackendDB       *be = op->o_bd;                  ( SLAP_CB_CONTINUE | RB_ERR ) );
                 slap_callback   cb;  
   
                 relay_back_add_cb( &cb, op );  
   
                 op->o_bd = bd;  
                 rc = ( bd->be_compare )( op, rs );  
                 op->o_bd = be;  
   
                 if ( op->o_callback == &cb ) {  
                         op->o_callback = op->o_callback->sc_next;  
                 }  
   
         } else {  
                 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,  
                                 "operation not supported "  
                                 "within naming context" );  
         }  
   
         return rc;  
   
 }  }
   
 int  int
 relay_back_op_modify( struct slap_op *op, struct slap_rep *rs )  relay_back_op_modify( Operation *op, SlapReply *rs )
 {  {
         BackendDB               *bd;          BackendDB               *bd;
         int                     rc = 1;  
   
         bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );          bd = relay_back_select_backend( op, rs,
                   ( LDAP_NO_SUCH_OBJECT | RB_ERR_REFERRAL_SEND ) );
         if ( bd == NULL ) {          if ( bd == NULL ) {
                 return 1;                  return rs->sr_err;
         }  
   
         if ( bd->be_modify ) {  
                 BackendDB       *be = op->o_bd;  
                 slap_callback   cb;  
   
                 relay_back_add_cb( &cb, op );  
   
                 op->o_bd = bd;  
                 rc = ( bd->be_modify )( op, rs );  
                 op->o_bd = be;  
   
                 if ( op->o_callback == &cb ) {  
                         op->o_callback = op->o_callback->sc_next;  
                 }  
   
         } else {  
                 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,  
                                 "operation not supported "  
                                 "within naming context" );  
         }          }
   
         return rc;          return relay_back_op( op, rs, bd, bd->be_modify,
                   RB_UNSUPPORTED_SEND );
 }  }
   
 int  int
 relay_back_op_modrdn( struct slap_op *op, struct slap_rep *rs )  relay_back_op_modrdn( Operation *op, SlapReply *rs )
 {  {
         BackendDB               *bd;          BackendDB               *bd;
         int                     rc = 1;  
   
         bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );          bd = relay_back_select_backend( op, rs,
                   ( LDAP_NO_SUCH_OBJECT | RB_ERR_REFERRAL_SEND ) );
         if ( bd == NULL ) {          if ( bd == NULL ) {
                 return 1;                  return rs->sr_err;
         }          }
   
         if ( bd->be_modrdn ) {          return relay_back_op( op, rs, bd, bd->be_modrdn,
                 BackendDB       *be = op->o_bd;                  RB_UNSUPPORTED_SEND );
                 slap_callback   cb;  
   
                 relay_back_add_cb( &cb, op );  
   
                 op->o_bd = bd;  
                 rc = ( bd->be_modrdn )( op, rs );  
                 op->o_bd = be;  
   
                 if ( op->o_callback == &cb ) {  
                         op->o_callback = op->o_callback->sc_next;  
                 }  
   
         } else {  
                 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,  
                                 "operation not supported "  
                                 "within naming context" );  
         }  
   
         return rc;  
   
 }  }
   
 int  int
 relay_back_op_add( struct slap_op *op, struct slap_rep *rs )  relay_back_op_add( Operation *op, SlapReply *rs )
 {  {
         BackendDB               *bd;          BackendDB               *bd;
         int                     rc = 1;  
   
         bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );          bd = relay_back_select_backend( op, rs,
                   ( LDAP_NO_SUCH_OBJECT | RB_ERR_REFERRAL_SEND ) );
         if ( bd == NULL ) {          if ( bd == NULL ) {
                 return 1;                  return rs->sr_err;
         }          }
   
         if ( bd->be_add ) {          return relay_back_op( op, rs, bd, bd->be_add,
                 BackendDB       *be = op->o_bd;                  RB_UNSUPPORTED_SEND );
                 slap_callback   cb;  
   
                 relay_back_add_cb( &cb, op );  
   
                 op->o_bd = bd;  
                 rc = ( bd->be_add )( op, rs );  
                 op->o_bd = be;  
   
                 if ( op->o_callback == &cb ) {  
                         op->o_callback = op->o_callback->sc_next;  
                 }  
   
         } else {  
                 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,  
                                 "operation not supported "  
                                 "within naming context" );  
         }  
   
         return rc;  
   
 }  }
   
 int  int
 relay_back_op_delete( struct slap_op *op, struct slap_rep *rs )  relay_back_op_delete( Operation *op, SlapReply *rs )
 {  {
         BackendDB               *bd;          BackendDB               *bd;
         int                     rc = 1;  
   
         bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );          bd = relay_back_select_backend( op, rs,
                   ( LDAP_NO_SUCH_OBJECT | RB_ERR_REFERRAL_SEND ) );
         if ( bd == NULL ) {          if ( bd == NULL ) {
                 return 1;                  return rs->sr_err;
         }          }
   
         if ( bd->be_delete ) {          return relay_back_op( op, rs, bd, bd->be_delete,
                 BackendDB       *be = op->o_bd;                  RB_UNSUPPORTED_SEND );
                 slap_callback   cb;  
   
                 relay_back_add_cb( &cb, op );  
   
                 op->o_bd = bd;  
                 rc = ( bd->be_delete )( op, rs );  
                 op->o_bd = be;  
   
                 if ( op->o_callback == &cb ) {  
                         op->o_callback = op->o_callback->sc_next;  
                 }  
         }  
   
         return rc;  
   
 }  }
   
 int  int
 relay_back_op_abandon( struct slap_op *op, struct slap_rep *rs )  relay_back_op_abandon( Operation *op, SlapReply *rs )
 {  {
         BackendDB               *bd;          BackendDB               *bd;
         int                     rc = 1;  
   
         bd = relay_back_select_backend( op, rs, -1 );          bd = relay_back_select_backend( op, rs, 0 );
         if ( bd == NULL ) {          if ( bd == NULL ) {
                 return 1;                  return rs->sr_err;
         }  
   
         if ( bd->be_abandon ) {  
                 BackendDB       *be = op->o_bd;  
                 slap_callback   cb;  
   
                 relay_back_add_cb( &cb, op );  
   
                 op->o_bd = bd;  
                 rc = ( bd->be_abandon )( op, rs );  
                 op->o_bd = be;  
   
                 if ( op->o_callback == &cb ) {  
                         op->o_callback = op->o_callback->sc_next;  
                 }  
         }          }
   
         return rc;          return relay_back_op( op, rs, bd, bd->be_abandon, 0 );
   
 }  }
   
 int  int
 relay_back_op_cancel( struct slap_op *op, struct slap_rep *rs )  relay_back_op_cancel( Operation *op, SlapReply *rs )
 {  {
         BackendDB               *bd;          BackendDB               *bd;
         int                     rc = 1;          int                     rc;
   
         bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );          bd = relay_back_select_backend( op, rs,
                   ( LDAP_CANNOT_CANCEL | RB_ERR ) );
         if ( bd == NULL ) {          if ( bd == NULL ) {
                 return 1;                  if ( op->o_cancel == SLAP_CANCEL_REQ ) {
         }                          op->o_cancel = LDAP_CANNOT_CANCEL;
   
         if ( bd->be_cancel ) {  
                 BackendDB       *be = op->o_bd;  
                 slap_callback   cb;  
   
                 relay_back_add_cb( &cb, op );  
   
                 op->o_bd = bd;  
                 rc = ( bd->be_cancel )( op, rs );  
                 op->o_bd = be;  
   
                 if ( op->o_callback == &cb ) {  
                         op->o_callback = op->o_callback->sc_next;  
                 }                  }
                   return rs->sr_err;
           }
   
         } else {          rc = relay_back_op( op, rs, bd, bd->be_cancel,
                 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,                  ( LDAP_CANNOT_CANCEL | RB_ERR ) );
                                 "operation not supported "          if ( rc == LDAP_CANNOT_CANCEL && op->o_cancel == SLAP_CANCEL_REQ )
                                 "within naming context" );          {
                   op->o_cancel = LDAP_CANNOT_CANCEL;
         }          }
   
         return rc;          return rc;
   
 }  }
   
 int  int
 relay_back_op_extended( struct slap_op *op, struct slap_rep *rs )  relay_back_op_extended( Operation *op, SlapReply *rs )
 {  {
         BackendDB               *bd;          BackendDB               *bd;
         int                     rc = 1;  
   
         bd = relay_back_select_backend( op, rs, LDAP_NO_SUCH_OBJECT );          bd = relay_back_select_backend( op, rs,
                   ( LDAP_NO_SUCH_OBJECT | RB_ERR | RB_REFERRAL ) );
         if ( bd == NULL ) {          if ( bd == NULL ) {
                 return 1;                  return rs->sr_err;
         }  
   
         if ( bd->be_extended ) {  
                 BackendDB       *be = op->o_bd;  
                 slap_callback   cb;  
   
                 relay_back_add_cb( &cb, op );  
   
                 op->o_bd = bd;  
                 rc = ( bd->be_extended )( op, rs );  
                 op->o_bd = be;  
   
                 if ( op->o_callback == &cb ) {  
                         op->o_callback = op->o_callback->sc_next;  
                 }  
   
         } else {  
                 send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,  
                                 "operation not supported "  
                                 "within naming context" );  
         }          }
   
         return rc;          return relay_back_op( op, rs, bd, bd->be_extended,
                   RB_UNSUPPORTED );
 }  }
   
 int  int
 relay_back_entry_release_rw( struct slap_op *op, Entry *e, int rw )  relay_back_entry_release_rw( Operation *op, Entry *e, int rw )
 {  {
         relay_back_info         *ri = (relay_back_info *)op->o_bd->be_private;          relay_back_info         *ri = (relay_back_info *)op->o_bd->be_private;
         BackendDB               *bd;          BackendDB               *bd;
Line 478  relay_back_entry_release_rw( struct slap Line 356  relay_back_entry_release_rw( struct slap
   
         bd = ri->ri_bd;          bd = ri->ri_bd;
         if ( bd == NULL) {          if ( bd == NULL) {
                 bd = select_backend( &op->o_req_ndn, 0, 1 );                  bd = select_backend( &op->o_req_ndn, 1 );
                 if ( bd == NULL ) {                  if ( bd == NULL ) {
                         return 1;                          return 1;
                 }                  }
Line 488  relay_back_entry_release_rw( struct slap Line 366  relay_back_entry_release_rw( struct slap
                 BackendDB       *be = op->o_bd;                  BackendDB       *be = op->o_bd;
   
                 op->o_bd = bd;                  op->o_bd = bd;
                 rc = ( bd->be_release )( op, e, rw );                  rc = bd->be_release( op, e, rw );
                 op->o_bd = be;                  op->o_bd = be;
         }          }
   
Line 497  relay_back_entry_release_rw( struct slap Line 375  relay_back_entry_release_rw( struct slap
 }  }
   
 int  int
 relay_back_entry_get_rw( struct slap_op *op, struct berval *ndn,  relay_back_entry_get_rw( Operation *op, struct berval *ndn,
         ObjectClass *oc, AttributeDescription *at, int rw, Entry **e )          ObjectClass *oc, AttributeDescription *at, int rw, Entry **e )
 {  {
         relay_back_info         *ri = (relay_back_info *)op->o_bd->be_private;          relay_back_info         *ri = (relay_back_info *)op->o_bd->be_private;
Line 506  relay_back_entry_get_rw( struct slap_op Line 384  relay_back_entry_get_rw( struct slap_op
   
         bd = ri->ri_bd;          bd = ri->ri_bd;
         if ( bd == NULL) {          if ( bd == NULL) {
                 bd = select_backend( &op->o_req_ndn, 0, 1 );                  bd = select_backend( &op->o_req_ndn, 1 );
                 if ( bd == NULL ) {                  if ( bd == NULL ) {
                         return 1;                          return 1;
                 }                  }
Line 516  relay_back_entry_get_rw( struct slap_op Line 394  relay_back_entry_get_rw( struct slap_op
                 BackendDB       *be = op->o_bd;                  BackendDB       *be = op->o_bd;
   
                 op->o_bd = bd;                  op->o_bd = bd;
                 rc = ( bd->be_fetch )( op, ndn, oc, at, rw, e );                  rc = bd->be_fetch( op, ndn, oc, at, rw, e );
                 op->o_bd = be;                  op->o_bd = be;
         }          }
   
Line 532  relay_back_entry_get_rw( struct slap_op Line 410  relay_back_entry_get_rw( struct slap_op
  * naming context... mmmh.   * naming context... mmmh.
  */   */
 int  int
 relay_back_chk_referrals( struct slap_op *op, struct slap_rep *rs )  relay_back_chk_referrals( Operation *op, SlapReply *rs )
 {  {
         BackendDB               *bd;          BackendDB               *bd;
         int                     rc = 0;  
   
         bd = relay_back_select_backend( op, rs, LDAP_SUCCESS );          bd = relay_back_select_backend( op, rs,
                   ( LDAP_SUCCESS | RB_ERR_REFERRAL_SEND ) );
         /* FIXME: this test only works if there are no overlays, so          /* FIXME: this test only works if there are no overlays, so
          * it is nearly useless; if made stricter, no nested back-relays           * it is nearly useless; if made stricter, no nested back-relays
          * can be instantiated... too bad. */           * can be instantiated... too bad. */
Line 554  relay_back_chk_referrals( struct slap_op Line 432  relay_back_chk_referrals( struct slap_op
                 }                  }
         }          }
   
         if ( bd->be_chk_referrals ) {          return relay_back_op( op, rs, bd, bd->be_chk_referrals, LDAP_SUCCESS );
                 BackendDB       *be = op->o_bd;  
                 slap_callback   cb;  
   
                 relay_back_add_cb( &cb, op );  
   
                 op->o_bd = bd;  
                 rc = ( bd->be_chk_referrals )( op, rs );  
                 op->o_bd = be;  
   
                 if ( op->o_callback == &cb ) {  
                         op->o_callback = op->o_callback->sc_next;  
                 }  
         }  
   
         return rc;  
   
 }  }
   
 int  int
 relay_back_operational( struct slap_op *op, struct slap_rep *rs )  relay_back_operational( Operation *op, SlapReply *rs )
 {  {
         relay_back_info         *ri = (relay_back_info *)op->o_bd->be_private;  
         BackendDB               *bd;          BackendDB               *bd;
         int                     rc = 1;  
   
         bd = ri->ri_bd;  
         if ( bd == NULL) {  
                 bd = select_backend( &op->o_req_ndn, 0, 1 );  
                 if ( bd == NULL ) {  
                         return 1;  
                 }  
         }  
   
         if ( bd->be_operational ) {          bd = relay_back_select_backend( op, rs,
                 BackendDB       *be = op->o_bd;                  ( LDAP_SUCCESS | RB_ERR ) );
                 slap_callback   cb;          /* FIXME: this test only works if there are no overlays, so
            * it is nearly useless; if made stricter, no nested back-relays
                 relay_back_add_cb( &cb, op );           * can be instantiated... too bad. */
           if ( bd == NULL || bd == op->o_bd ) {
                 op->o_bd = bd;                  return 0;
                 rc = ( bd->be_operational )( op, rs );  
                 op->o_bd = be;  
   
                 if ( op->o_callback == &cb ) {  
                         op->o_callback = op->o_callback->sc_next;  
                 }  
         }          }
   
         return rc;          return relay_back_op( op, rs, bd, bd->be_operational, 0 );
   
 }  }
   
 int  int
 relay_back_has_subordinates( struct slap_op *op, Entry *e, int *hasSubs )  relay_back_has_subordinates( Operation *op, Entry *e, int *hasSubs )
 {  {
         relay_back_info         *ri = (relay_back_info *)op->o_bd->be_private;          SlapReply               rs = { 0 };
         BackendDB               *bd;          BackendDB               *bd;
         int                     rc = 1;          int                     rc = 1;
   
         bd = ri->ri_bd;          bd = relay_back_select_backend( op, &rs,
         if ( bd == NULL) {                  ( LDAP_SUCCESS | RB_ERR ) );
                 bd = select_backend( &op->o_req_ndn, 0, 1 );          /* FIXME: this test only works if there are no overlays, so
                 if ( bd == NULL ) {           * it is nearly useless; if made stricter, no nested back-relays
                         return 1;           * can be instantiated... too bad. */
                 }          if ( bd == NULL || bd == op->o_bd ) {
                   return 0;
         }          }
   
         if ( bd->be_has_subordinates ) {          if ( bd->be_has_subordinates ) {
                 BackendDB       *be = op->o_bd;                  BackendDB       *be = op->o_bd;
   
                 op->o_bd = bd;                  op->o_bd = bd;
                 rc = ( bd->be_has_subordinates )( op, e, hasSubs );                  rc = bd->be_has_subordinates( op, e, hasSubs );
                 op->o_bd = be;                  op->o_bd = be;
         }          }
   
Line 635  relay_back_has_subordinates( struct slap Line 481  relay_back_has_subordinates( struct slap
 }  }
   
 int  int
 relay_back_connection_init( BackendDB *bd, struct slap_conn *c )  relay_back_connection_init( BackendDB *bd, Connection *c )
 {  {
         relay_back_info         *ri = (relay_back_info *)bd->be_private;          relay_back_info         *ri = (relay_back_info *)bd->be_private;
   
Line 645  relay_back_connection_init( BackendDB *b Line 491  relay_back_connection_init( BackendDB *b
         }          }
   
         if ( bd->be_connection_init ) {          if ( bd->be_connection_init ) {
                 return ( bd->be_connection_init )( bd, c );                  return bd->be_connection_init( bd, c );
         }          }
   
         return 0;          return 0;
 }  }
   
 int  int
 relay_back_connection_destroy( BackendDB *bd, struct slap_conn *c )  relay_back_connection_destroy( BackendDB *bd, Connection *c )
 {  {
         relay_back_info         *ri = (relay_back_info *)bd->be_private;          relay_back_info         *ri = (relay_back_info *)bd->be_private;
   
         bd = ri->ri_bd;          bd = ri->ri_bd;
         if ( bd == NULL) {          if ( bd == NULL ) {
                 return 0;                  return 0;
         }          }
   
         if ( bd->be_connection_destroy ) {          if ( bd->be_connection_destroy ) {
                 return ( bd->be_connection_destroy )( bd, c );                  return bd->be_connection_destroy( bd, c );
         }          }
   
         return 0;          return 0;

Removed from v.1.15  
changed lines
  Added in v.1.15.2.7


______________
© Copyright 1998-2020, OpenLDAP Foundation, info@OpenLDAP.org