]> git.sur5r.net Git - openldap/commitdiff
Add overlay config stuff, handle overlay responses
authorHoward Chu <hyc@openldap.org>
Fri, 4 Feb 2011 10:52:34 +0000 (10:52 +0000)
committerHoward Chu <hyc@openldap.org>
Fri, 4 Feb 2011 10:52:34 +0000 (10:52 +0000)
servers/slapd/back-sock/back-sock.h
servers/slapd/back-sock/config.c
servers/slapd/back-sock/result.c

index 10bebd6e1bc159302e54d9fd1fe83d9b1c1a1a92..167fd22577322dc050d1c9c0bf5cda05b2625e1a 100644 (file)
@@ -28,6 +28,8 @@ LDAP_BEGIN_DECL
 struct sockinfo {
        const char      *si_sockpath;
        slap_mask_t     si_extensions;
+       slap_mask_t     si_ops;         /* overlay: operations to act on */
+       slap_mask_t     si_resps;       /* overlay: responses to forward */
 };
 
 #define        SOCK_EXT_BINDDN 1
index e4a17ab00926067bca82831b7c912cf730af7c7f..92f5f56e506f1d745be20eae692e56057b474da5 100644 (file)
@@ -34,10 +34,26 @@ static int sock_over_setup();
 static slap_response sock_over_response;
 
 enum {
-       BS_EXT = 1
+       BS_EXT = 1,
+       BS_OPS,
+       BS_RESP
 };
 
+/* The number of overlay-only config attrs */
+#define NUM_OV_ATTRS   2
+
 static ConfigTable bscfg[] = {
+       { "sockops", "ops", 2, 0, 0, ARG_MAGIC|BS_OPS,
+               bs_cf_gen, "( OLcfgDbAt:7.3 NAME 'olcOvSocketOps' "
+                       "DESC 'Operation types to forward' "
+                       "EQUALITY caseIgnoreMatch "
+                       "SYNTAX OMsDirectoryString )", NULL, NULL },
+       { "sockresps", "resps", 2, 0, 0, ARG_MAGIC|BS_RESP,
+               bs_cf_gen, "( OLcfgDbAt:7.4 NAME 'olcOvSocketResps' "
+                       "DESC 'Response types to forward' "
+                       "EQUALITY caseIgnoreMatch "
+                       "SYNTAX OMsDirectoryString )", NULL, NULL },
+
        { "socketpath", "pathname", 2, 2, 0, ARG_STRING|ARG_OFFSET,
                (void *)offsetof(struct sockinfo, si_sockpath),
                "( OLcfgDbAt:7.1 NAME 'olcDbSocketPath' "
@@ -59,7 +75,7 @@ static ConfigOCs bsocs[] = {
                "SUP olcDatabaseConfig "
                "MUST olcDbSocketPath "
                "MAY olcDbSocketExtensions )",
-                       Cft_Database, bscfg },
+                       Cft_Database, bscfg+NUM_OV_ATTRS },
        { NULL, 0, NULL }
 };
 
@@ -69,11 +85,24 @@ static ConfigOCs osocs[] = {
                "DESC 'Socket overlay configuration' "
                "SUP olcOverlayConfig "
                "MUST olcDbSocketPath "
-               "MAY olcDbSocketExtensions )",
+               "MAY ( olcDbSocketExtensions $ "
+                       " olcOvSocketOps $ olcOvSocketResps ) )",
                        Cft_Overlay, bscfg },
        { NULL, 0, NULL }
 };
 
+#define SOCK_OP_BIND   0x001
+#define SOCK_OP_UNBIND 0x002
+#define SOCK_OP_SEARCH 0x004
+#define SOCK_OP_COMPARE        0x008
+#define SOCK_OP_MODIFY 0x010
+#define SOCK_OP_MODRDN 0x020
+#define SOCK_OP_ADD            0x040
+#define SOCK_OP_DELETE 0x080
+
+#define SOCK_REP_RESULT        0x001
+#define SOCK_REP_SEARCH        0x002
+
 static slap_verbmasks bs_exts[] = {
        { BER_BVC("binddn"), SOCK_EXT_BINDDN },
        { BER_BVC("peername"), SOCK_EXT_PEERNAME },
@@ -82,6 +111,24 @@ static slap_verbmasks bs_exts[] = {
        { BER_BVNULL, 0 }
 };
 
+static slap_verbmasks ov_ops[] = {
+       { BER_BVC("bind"), SOCK_OP_BIND },
+       { BER_BVC("unbind"), SOCK_OP_UNBIND },
+       { BER_BVC("search"), SOCK_OP_SEARCH },
+       { BER_BVC("compare"), SOCK_OP_COMPARE },
+       { BER_BVC("modify"), SOCK_OP_MODIFY },
+       { BER_BVC("modrdn"), SOCK_OP_MODRDN },
+       { BER_BVC("add"), SOCK_OP_ADD },
+       { BER_BVC("delete"), SOCK_OP_DELETE },
+       { BER_BVNULL, 0 }
+};
+
+static slap_verbmasks ov_resps[] = {
+       { BER_BVC("result"), SOCK_REP_RESULT },
+       { BER_BVC("search"), SOCK_REP_SEARCH },
+       { BER_BVNULL, 0 }
+};
+
 static int
 bs_cf_gen( ConfigArgs *c )
 {
@@ -99,6 +146,10 @@ bs_cf_gen( ConfigArgs *c )
                switch( c->type ) {
                case BS_EXT:
                        return mask_to_verbs( bs_exts, si->si_extensions, &c->rvalue_vals );
+               case BS_OPS:
+                       return mask_to_verbs( ov_ops, si->si_ops, &c->rvalue_vals );
+               case BS_RESP:
+                       return mask_to_verbs( ov_resps, si->si_resps, &c->rvalue_vals );
                }
        } else if ( c->op == LDAP_MOD_DELETE ) {
                switch( c->type ) {
@@ -113,12 +164,38 @@ bs_cf_gen( ConfigArgs *c )
                                        si->si_extensions ^= dels;
                        }
                        return rc;
+               case BS_OPS:
+                       if ( c->valx < 0 ) {
+                               si->si_ops = 0;
+                               rc = 0;
+                       } else {
+                               slap_mask_t dels = 0;
+                               rc = verbs_to_mask( c->argc, c->argv, ov_ops, &dels );
+                               if ( rc == 0 )
+                                       si->si_ops ^= dels;
+                       }
+                       return rc;
+               case BS_RESP:
+                       if ( c->valx < 0 ) {
+                               si->si_resps = 0;
+                               rc = 0;
+                       } else {
+                               slap_mask_t dels = 0;
+                               rc = verbs_to_mask( c->argc, c->argv, ov_resps, &dels );
+                               if ( rc == 0 )
+                                       si->si_resps ^= dels;
+                       }
+                       return rc;
                }
 
        } else {
                switch( c->type ) {
                case BS_EXT:
                        return verbs_to_mask( c->argc, c->argv, bs_exts, &si->si_extensions );
+               case BS_OPS:
+                       return verbs_to_mask( c->argc, c->argv, ov_ops, &si->si_ops );
+               case BS_RESP:
+                       return verbs_to_mask( c->argc, c->argv, ov_resps, &si->si_resps );
                }
        }
        return 1;
@@ -153,6 +230,17 @@ static BI_op_bind *sockfuncs[] = {
        sock_back_delete
 };
 
+static const int sockopflags[] = {
+       SOCK_OP_BIND,
+       SOCK_OP_UNBIND,
+       SOCK_OP_SEARCH,
+       SOCK_OP_COMPARE,
+       SOCK_OP_MODIFY,
+       SOCK_OP_MODRDN,
+       SOCK_OP_ADD,
+       SOCK_OP_DELETE
+};
+
 static int sock_over_op(
        Operation *op,
        SlapReply *rs
@@ -160,7 +248,8 @@ static int sock_over_op(
 {
        slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
        void *private = op->o_bd->be_private;
-       slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
+       slap_callback *sc;
+       struct sockinfo *si;
        slap_operation_t which;
        int rc;
 
@@ -176,13 +265,17 @@ static int sock_over_op(
        default:
                return SLAP_CB_CONTINUE;
        }
-       op->o_bd->be_private = on->on_bi.bi_private;
-       cb.sc_next = op->o_callback;
-       op->o_callback = &cb;
+       si = on->on_bi.bi_private;
+       if ( !(si->si_ops & sockopflags[which]))
+               return SLAP_CB_CONTINUE;
+
+       op->o_bd->be_private = si;
+       sc = op->o_callback;
+       op->o_callback = NULL;
        rc = sockfuncs[which]( op, rs );
        op->o_bd->be_private = private;
-       op->o_callback = cb.sc_next;
-       return SLAP_CB_CONTINUE;
+       op->o_callback = sc;
+       return rc;
 }
 
 static int
@@ -192,21 +285,38 @@ sock_over_response( Operation *op, SlapReply *rs )
        struct sockinfo *si = (struct sockinfo *)on->on_bi.bi_private;
        FILE *fp;
 
-       if ( rs->sr_type != REP_RESULT )
+       if ( rs->sr_type == REP_RESULT ) {
+               if ( !( si->si_resps & SOCK_REP_RESULT ))
+                       return SLAP_CB_CONTINUE;
+       } else if ( rs->sr_type == REP_SEARCH ) {
+               if ( !( si->si_resps & SOCK_REP_SEARCH ))
+                       return SLAP_CB_CONTINUE;
+       } else
                return SLAP_CB_CONTINUE;
 
        if (( fp = opensock( si->si_sockpath )) == NULL )
                return SLAP_CB_CONTINUE;
 
-       /* write out the result */
-       fprintf( fp, "RESULT\n" );
-       fprintf( fp, "msgid: %ld\n", (long) op->o_msgid );
-       sock_print_conn( fp, op->o_conn, si );
-       fprintf( fp, "code: %d\n", rs->sr_err );
-       if ( rs->sr_matched )
-               fprintf( fp, "matched: %s\n", rs->sr_matched );
-       if (rs->sr_text )
-               fprintf( fp, "info: %s\n", rs->sr_text );
+       if ( rs->sr_type == REP_RESULT ) {
+               /* write out the result */
+               fprintf( fp, "RESULT\n" );
+               fprintf( fp, "msgid: %ld\n", (long) op->o_msgid );
+               sock_print_conn( fp, op->o_conn, si );
+               fprintf( fp, "code: %d\n", rs->sr_err );
+               if ( rs->sr_matched )
+                       fprintf( fp, "matched: %s\n", rs->sr_matched );
+               if (rs->sr_text )
+                       fprintf( fp, "info: %s\n", rs->sr_text );
+       } else {
+               /* write out the search entry */
+               int len;
+               fprintf( fp, "ENTRY\n" );
+               fprintf( fp, "msgid: %ld\n", (long) op->o_msgid );
+               sock_print_conn( fp, op->o_conn, si );
+               ldap_pvt_thread_mutex_lock( &entry2str_mutex );
+               fprintf( fp, "%s", entry2str( rs->sr_entry, &len ) );
+               ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
+       }
        fprintf( fp, "\n" );
        fclose( fp );
 
index 63cdc9be36afd865109e1d9c047ac9e1f0284d13..07df15cced4226cefec456cf5cf69cb20f3cd5bf 100644 (file)
@@ -91,6 +91,13 @@ sock_read_and_send_results(
                        if ( strncasecmp( buf, "RESULT", 6 ) == 0 ) {
                                break;
                        }
+                       if ( strncasecmp( buf, "CONTINUE", 8 ) == 0 ) {
+                               struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private;
+                               /* Only valid when operating as an overlay! */
+                               assert( si->si_ops != 0 );
+                               rs->sr_err = SLAP_CB_CONTINUE;
+                               goto skip;
+                       }
 
                        if ( (rs->sr_entry = str2entry( buf )) == NULL ) {
                                Debug( LDAP_DEBUG_ANY, "str2entry(%s) failed\n",
@@ -113,7 +120,8 @@ sock_read_and_send_results(
                send_ldap_result( op, rs );
        }
 
-       free( buf );
+skip:
+       ch_free( buf );
 
        return( rs->sr_err );
 }