]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/retcode.c
check for ee == NULL
[openldap] / servers / slapd / overlays / retcode.c
index a92430a9045c07b52918c0643fbb430f59b6fc9e..e7639befa832952fb013629c4acfc3d3f8519a67 100644 (file)
@@ -31,6 +31,7 @@
 #include <ac/socket.h>
 
 #include "slap.h"
+#include "config.h"
 #include "lutil.h"
 #include "ldif.h"
 
@@ -43,6 +44,8 @@ static AttributeDescription   *ad_errSleepTime;
 static AttributeDescription    *ad_errMatchedDN;
 static AttributeDescription    *ad_errUnsolicitedOID;
 static AttributeDescription    *ad_errUnsolicitedData;
+static AttributeDescription    *ad_errDisconnect;
+
 static ObjectClass             *oc_errAbsObject;
 static ObjectClass             *oc_errObject;
 static ObjectClass             *oc_errAuxObject;
@@ -75,6 +78,11 @@ typedef struct retcode_item_t {
        slap_mask_t             rdi_mask;
        struct berval           rdi_unsolicited_oid;
        struct berval           rdi_unsolicited_data;
+
+       unsigned                rdi_flags;
+#define        RDI_PRE_DISCONNECT      (0x1U)
+#define        RDI_POST_DISCONNECT     (0x2U)
+
        struct retcode_item_t   *rdi_next;
 } retcode_item_t;
 
@@ -195,11 +203,11 @@ retcode_cb_response( Operation *op, SlapReply *rs )
 {
        retcode_cb_t    *rdc = (retcode_cb_t *)op->o_callback->sc_private;
 
+       op->o_tag = rdc->rdc_tag;
        if ( rs->sr_type == REP_SEARCH ) {
                ber_tag_t       o_tag = op->o_tag;
                int             rc;
 
-               op->o_tag = rdc->rdc_tag;
                if ( op->o_tag == LDAP_REQ_SEARCH ) {
                        rs->sr_attrs = rdc->rdc_attrs;
                }
@@ -209,7 +217,11 @@ retcode_cb_response( Operation *op, SlapReply *rs )
                return rc;
        }
 
-       if ( rs->sr_err == LDAP_SUCCESS ) {
+       switch ( rs->sr_err ) {
+       case LDAP_SUCCESS:
+       case LDAP_NO_SUCH_OBJECT:
+               /* in case of noSuchObject, stop the internal search
+                * for in-directory error stuff */
                if ( !op->o_abandon ) {
                        rdc->rdc_flags = SLAP_CB_CONTINUE;
                }
@@ -293,8 +305,9 @@ retcode_op_func( Operation *op, SlapReply *rs )
 
                        case LDAP_REQ_BIND:
                                /* skip if rootdn */
+                               /* FIXME: better give the db a chance? */
                                if ( be_isroot_pw( op ) ) {
-                                       return SLAP_CB_CONTINUE;
+                                       return LDAP_SUCCESS;
                                }
                                return retcode_op_internal( op, rs );
 
@@ -407,6 +420,10 @@ retcode_op_func( Operation *op, SlapReply *rs )
                rs->sr_text = "retcode not found";
 
        } else {
+               if ( rdi->rdi_flags & RDI_PRE_DISCONNECT ) {
+                       return rs->sr_err = SLAPD_DISCONNECT;
+               }
+
                rs->sr_err = rdi->rdi_err;
                rs->sr_text = rdi->rdi_text.bv_val;
                rs->sr_matched = rdi->rdi_matched.bv_val;
@@ -482,6 +499,10 @@ retcode_op_func( Operation *op, SlapReply *rs )
                }
                rs->sr_matched = NULL;
                rs->sr_text = NULL;
+
+               if ( rdi && rdi->rdi_flags & RDI_POST_DISCONNECT ) {
+                       return rs->sr_err = SLAPD_DISCONNECT;
+               }
                break;
        }
 
@@ -526,6 +547,7 @@ retcode_entry_response( Operation *op, SlapReply *rs, BackendInfo *bi, Entry *e
        Attribute       *a;
        int             err;
        char            *next;
+       int             disconnect = 0;
 
        if ( get_manageDSAit( op ) ) {
                return SLAP_CB_CONTINUE;
@@ -560,6 +582,15 @@ retcode_entry_response( Operation *op, SlapReply *rs, BackendInfo *bi, Entry *e
                }
        }
 
+       /* disconnect */
+       a = attr_find( e->e_attrs, ad_errDisconnect );
+       if ( a != NULL ) {
+               if ( bvmatch( &a->a_nvals[ 0 ], &slap_true_bv ) ) {
+                       return rs->sr_err = SLAPD_DISCONNECT;
+               }
+               disconnect = 1;
+       }
+
        /* error code */
        a = attr_find( e->e_attrs, ad_errCode );
        if ( a == NULL ) {
@@ -669,8 +700,12 @@ retcode_entry_response( Operation *op, SlapReply *rs, BackendInfo *bi, Entry *e
                op->o_bd = o_bd;
                op->o_callback = o_callback;
        }
-       
+
        if ( rs->sr_err != LDAP_SUCCESS ) {
+               if ( disconnect ) {
+                       return rs->sr_err = SLAPD_DISCONNECT;
+               }
+       
                op->o_abandon = 1;
                return rs->sr_err;
        }
@@ -692,7 +727,7 @@ retcode_response( Operation *op, SlapReply *rs )
 }
 
 static int
-retcode_db_init( BackendDB *be )
+retcode_db_init( BackendDB *be, ConfigReply *cr )
 {
        slap_overinst   *on = (slap_overinst *)be->bd_info;
        retcode_t       *rd;
@@ -983,10 +1018,29 @@ retcode_db_config(
                                                        &rdi.rdi_unsolicited_oid );
                                        }
 
+                               } else if ( strncasecmp( argv[ i ], "flags=", STRLENOF( "flags=" ) ) == 0 )
+                               {
+                                       char *arg = &argv[ i ][ STRLENOF( "flags=" ) ];
+                                       if ( strcasecmp( arg, "disconnect" ) == 0 ) {
+                                               rdi.rdi_flags |= RDI_PRE_DISCONNECT;
+
+                                       } else if ( strcasecmp( arg, "pre-disconnect" ) == 0 ) {
+                                               rdi.rdi_flags |= RDI_PRE_DISCONNECT;
+
+                                       } else if ( strcasecmp( arg, "post-disconnect" ) == 0 ) {
+                                               rdi.rdi_flags |= RDI_POST_DISCONNECT;
+
+                                       } else {
+                                               fprintf( stderr, "%s: line %d: retcode: "
+                                                       "unknown flag \"%s\".\n",
+                                                       fname, lineno, arg );
+                                               return 1;
+                                       }
+
                                } else {
                                        fprintf( stderr, "%s: line %d: retcode: "
                                                "unknown option \"%s\".\n",
-                                                       fname, lineno, argv[ i ] );
+                                               fname, lineno, argv[ i ] );
                                        return 1;
                                }
                        }
@@ -1035,7 +1089,7 @@ retcode_db_config(
 }
 
 static int
-retcode_db_open( BackendDB *be )
+retcode_db_open( BackendDB *be, ConfigReply *cr)
 {
        slap_overinst   *on = (slap_overinst *)be->bd_info;
        retcode_t       *rd = (retcode_t *)on->on_bi.bi_private;
@@ -1159,7 +1213,7 @@ retcode_db_open( BackendDB *be )
 }
 
 static int
-retcode_db_destroy( BackendDB *be )
+retcode_db_destroy( BackendDB *be, ConfigReply *cr )
 {
        slap_overinst   *on = (slap_overinst *)be->bd_info;
        retcode_t       *rd = (retcode_t *)on->on_bi.bi_private;
@@ -1269,6 +1323,12 @@ retcode_initialize( void )
                        "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 "
                        "SINGLE-VALUE )",
                        &ad_errUnsolicitedData },
+               { "( 1.3.6.1.4.1.4203.666.11.4.1.8 "
+                       "NAME ( 'errDisconnect' ) "
+                       "DESC 'Disconnect without notice' "
+                       "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 "
+                       "SINGLE-VALUE )",
+                       &ad_errDisconnect },
                { NULL }
        };
 
@@ -1289,6 +1349,7 @@ retcode_initialize( void )
                                "$ errMatchedDN "
                                "$ errUnsolicitedOID "
                                "$ errUnsolicitedData "
+                               "$ errDisconnect "
                        ") )",
                        &oc_errAbsObject },
                { "( 1.3.6.1.4.1.4203.666.11.4.3.1 "
@@ -1312,6 +1373,8 @@ retcode_initialize( void )
                                "retcode: register_at failed\n", 0, 0, 0 );
                        return code;
                }
+
+               (*retcode_at[ i ].ad)->ad_type->sat_flags |= SLAP_AT_HIDE;
        }
 
        for ( i = 0; retcode_oc[ i ].desc != NULL; i++ ) {
@@ -1321,6 +1384,8 @@ retcode_initialize( void )
                                "retcode: register_oc failed\n", 0, 0, 0 );
                        return code;
                }
+
+               (*retcode_oc[ i ].oc)->soc_flags |= SLAP_OC_HIDE;
        }
 
        retcode.on_bi.bi_type = "retcode";