]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-sock/config.c
Add overlay config stuff, handle overlay responses
[openldap] / servers / slapd / back-sock / config.c
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 );