]> git.sur5r.net Git - openldap/commitdiff
Rework control infrastructure a bit. Add subentries visibility control.
authorKurt Zeilenga <kurt@openldap.org>
Wed, 9 Jan 2002 06:29:54 +0000 (06:29 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Wed, 9 Jan 2002 06:29:54 +0000 (06:29 +0000)
servers/slapd/controls.c
servers/slapd/dn.c
servers/slapd/proto-slap.h
servers/slapd/root_dse.c
servers/slapd/search.c
servers/slapd/slap.h

index 97824331289edfa491dd13b34380b7682f6725ab..3683e23bb5ffa889af3516f3b22e4bae6e46dfb1 100644 (file)
 
 #include "../../libraries/liblber/lber-int.h"
 
-char *supportedControls[] = {
-       LDAP_CONTROL_MANAGEDSAIT,
-       LDAP_CONTROL_SUBENTRIES,
-       NULL
+#define SLAP_CTRL_ABANDON      0x0001
+#define SLAP_CTRL_ADD          0x2002
+#define SLAP_CTRL_BIND         0x0004
+#define SLAP_CTRL_COMPARE      0x1008
+#define SLAP_CTRL_DELETE       0x2010
+#define SLAP_CTRL_MODIFY       0x2020
+#define SLAP_CTRL_RENAME       0x2040
+#define SLAP_CTRL_SEARCH       0x1080
+#define SLAP_CTRL_UNBIND       0x0100
+
+#define SLAP_CTRL_INTROGATE    (SLAP_CTRL_COMPARE|SLAP_CTRL_SEARCH)
+#define SLAP_CTRL_UPDATE \
+       (SLAP_CTRL_ADD|SLAP_CTRL_DELETE|SLAP_CTRL_MODIFY|SLAP_CTRL_RENAME)
+#define SLAP_CTRL_ACCESS       (SLAP_CTRL_INTROGATE|SLAP_CTRL_UPDATE)
+
+typedef int (SLAP_CTRL_PARSE_FN) LDAP_P((
+       Connection *conn,
+       Operation *op,
+       LDAPControl *ctrl,
+       const char **text ));
+
+static SLAP_CTRL_PARSE_FN parseManageDSAit;
+static SLAP_CTRL_PARSE_FN parseSubentries;
+
+static struct slap_control {
+       char *sc_oid;
+       int sc_ops_mask;
+       char **sc_extendedops;
+       SLAP_CTRL_PARSE_FN *sc_parse;
+
+} supportedControls[] = {
+       { LDAP_CONTROL_MANAGEDSAIT,
+               SLAP_CTRL_ACCESS, NULL,
+               parseManageDSAit },
+       { LDAP_CONTROL_SUBENTRIES,
+               SLAP_CTRL_SEARCH, NULL,
+               parseSubentries },
+       { NULL }
 };
 
+char *
+get_supported_ctrl(int index)
+{
+       return supportedControls[index].sc_oid;
+}
+
+static struct slap_control *
+find_ctrl( const char *oid )
+{
+       int i;
+       for( i=0; supportedControls[i].sc_oid; i++ ) {
+               if( strcmp( oid, supportedControls[i].sc_oid ) == 0 ) {
+                       return &supportedControls[i];
+               }
+       }
+       return NULL;
+}
+
 int get_ctrls(
        Connection *conn,
        Operation *op,
@@ -36,6 +88,7 @@ int get_ctrls(
        char *opaque;
        BerElement *ber = op->o_ber;
        LDAPControl ***ctrls = &op->o_ctrls;
+       struct slap_control *c;
        int rc = LDAP_SUCCESS;
        char *errmsg = NULL;
 
@@ -192,11 +245,69 @@ int get_ctrls(
                        }
                }
 
-               if( tctrl->ldctl_iscritical &&
-                       !charray_inlist( supportedControls, tctrl->ldctl_oid ) )
-               {
+               c = find_ctrl( tctrl->ldctl_oid );
+               if( c != NULL ) {
+                       /* recongized control */
+                       int tagmask = -1;
+                       switch( op->o_tag ) {
+                       case LDAP_REQ_ADD:
+                               tagmask = SLAP_CTRL_ADD;
+                               break;
+                       case LDAP_REQ_BIND:
+                               tagmask = SLAP_CTRL_BIND;
+                               break;
+                       case LDAP_REQ_COMPARE:
+                               tagmask = SLAP_CTRL_COMPARE;
+                               break;
+                       case LDAP_REQ_DELETE:
+                               tagmask = SLAP_CTRL_DELETE;
+                               break;
+                       case LDAP_REQ_MODIFY:
+                               tagmask = SLAP_CTRL_MODIFY;
+                               break;
+                       case LDAP_REQ_RENAME:
+                               tagmask = SLAP_CTRL_RENAME;
+                               break;
+                       case LDAP_REQ_SEARCH:
+                               tagmask = SLAP_CTRL_SEARCH;
+                               break;
+                       case LDAP_REQ_UNBIND:
+                               tagmask = SLAP_CTRL_UNBIND;
+                               break;
+                       case LDAP_REQ_EXTENDED:
+                               /* FIXME: check list of extended operations */
+                               tagmask = -1;
+                               break;
+                       default:
+                               rc = LDAP_OTHER;
+                               errmsg = "controls internal error";
+                               goto return_results;
+                       }
+
+                       if (( c->sc_ops_mask & tagmask ) == tagmask ) {
+                               /* available extension */
+
+                               if( !c->sc_parse ) {
+                                       rc = LDAP_OTHER;
+                                       errmsg = "not yet implemented";
+                                       goto return_results;
+                               }
+
+                               rc = c->sc_parse( conn, op, tctrl, &errmsg );
+
+                               if( rc != LDAP_SUCCESS ) goto return_results;
+
+                       } else if( tctrl->ldctl_iscritical ) {
+                               /* unavailable CRITICAL control */
+                               rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
+                               errmsg = "critical extension is unavailable";
+                               goto return_results;
+                       }
+
+               } else if( tctrl->ldctl_iscritical ) {
+                       /* unrecongized CRITICAL control */
                        rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
-                       errmsg = "critical extension is unavailable ";
+                       errmsg = "critical extension is not recongized";
                        goto return_results;
                }
 
@@ -225,46 +336,54 @@ return_results:
        return rc;
 }
 
-
-int get_manageDSAit( Operation *op )
+static int parseManageDSAit (
+       Connection *conn,
+       Operation *op,
+       LDAPControl *ctrl,
+       const char **text )
 {
-       int i;
-       if( op == NULL || op->o_ctrls == NULL ) {
-               return SLAP_NO_CONTROL;
+       if ( op->o_managedsait != SLAP_NO_CONTROL ) {
+               *text = "manageDSAit control specified multiple times";
+               return LDAP_PROTOCOL_ERROR;
        }
 
-       for( i=0; op->o_ctrls[i] != NULL; i++ ) {
-               if( strcmp( LDAP_CONTROL_MANAGEDSAIT,
-                       op->o_ctrls[i]->ldctl_oid )     == 0 )
-               {
-                       return op->o_ctrls[i]->ldctl_iscritical
-                               ? SLAP_CRITICAL_CONTROL
-                               : SLAP_NONCRITICAL_CONTROL;
-               }
+       if ( ctrl->ldctl_value.bv_len ) {
+               *text = "manageDSAit control value not empty";
+               return LDAP_PROTOCOL_ERROR;
        }
 
-       return SLAP_NO_CONTROL;
+       op->o_managedsait = ctrl->ldctl_iscritical
+               ? SLAP_CRITICAL_CONTROL
+               : SLAP_NONCRITICAL_CONTROL;
+
+       return LDAP_SUCCESS;
 }
 
-int get_subentries( Operation *op, int *visibility )
+static int parseSubentries (
+       Connection *conn,
+       Operation *op,
+       LDAPControl *ctrl,
+       const char **text )
 {
-       int i;
-       if( op == NULL || op->o_ctrls == NULL ) {
-               return SLAP_NO_CONTROL;
+       if ( op->o_subentries != SLAP_NO_CONTROL ) {
+               *text = "subentries control specified multiple times";
+               return LDAP_PROTOCOL_ERROR;
        }
 
-       for( i=0; op->o_ctrls[i] != NULL; i++ ) {
-               if( strcmp( LDAP_CONTROL_SUBENTRIES,
-                       op->o_ctrls[i]->ldctl_oid )     == 0 )
-               {
-                       /* need to parse the value */
-                       *visibility = 0;
-
-                       return op->o_ctrls[i]->ldctl_iscritical
-                               ? SLAP_CRITICAL_CONTROL
-                               : SLAP_NONCRITICAL_CONTROL;
-               }
+       /* FIXME: should use BER library */
+       if( ( ctrl->ldctl_value.bv_len != 3 )
+               && ( ctrl->ldctl_value.bv_val[0] != 0x01 )
+               && ( ctrl->ldctl_value.bv_val[1] != 0x01 ))
+       {
+               *text = "subentries control value encoding is bogus";
+               return LDAP_PROTOCOL_ERROR;
        }
 
-       return SLAP_NO_CONTROL;
-}
+       op->o_subentries = ctrl->ldctl_iscritical
+               ? SLAP_CRITICAL_CONTROL
+               : SLAP_NONCRITICAL_CONTROL;
+
+       op->o_subentries_visibility = (ctrl->ldctl_value.bv_val[2] != 0x00);
+
+       return LDAP_SUCCESS;
+}
\ No newline at end of file
index 0f359d4a5fd5d472c85392202f7d8977a395b719..52cbb6e8be93aabf48df95a86c9d2fc86c5db80b 100644 (file)
@@ -646,7 +646,7 @@ dnParent(
        const char      *p;
        int             rc;
 
-       rc = ldap_str2rdn( dn, NULL, &p, LDAP_DN_FORMAT_LDAP | LDAP_DN_SKIP );
+       rc = ldap_str2rdn( dn, NULL, & (char *) p, LDAP_DN_FORMAT_LDAP | LDAP_DN_SKIP );
        if ( rc != LDAP_SUCCESS ) {
                return rc;
        }
@@ -719,7 +719,7 @@ dnExtractRdn(
                return LDAP_OTHER;
        }
 
-       rc = ldap_str2rdn( dn->bv_val, &tmpRDN, &p, LDAP_DN_FORMAT_LDAP );
+       rc = ldap_str2rdn( dn->bv_val, &tmpRDN, &(char *)p, LDAP_DN_FORMAT_LDAP );
        if ( rc != LDAP_SUCCESS ) {
                return rc;
        }
@@ -758,7 +758,7 @@ dn_rdnlen(
                return 0;
        }
 
-       rc = ldap_str2rdn( dn_in->bv_val, NULL, &p, 
+       rc = ldap_str2rdn( dn_in->bv_val, NULL, &(char *)p, 
                        LDAP_DN_FORMAT_LDAP | LDAP_DN_SKIP );
        if ( rc != LDAP_SUCCESS ) {
                return 0;
@@ -904,7 +904,7 @@ rdn_attrs( const char * rdn, char ***types, char ***values)
        assert( *values == NULL );
        assert( types == NULL || *types == NULL );
 
-       rc = ldap_str2rdn( rdn, &tmpRDN, &p, LDAP_DN_FORMAT_LDAP );
+       rc = ldap_str2rdn( rdn, &tmpRDN, &(char *)p, LDAP_DN_FORMAT_LDAP );
        if ( rc != LDAP_SUCCESS ) {
                return rc;
        }
index 998d5f1383a8a44fde2c00c28039b440050b2d75..0bf1aa33d25274bddb3cb8825bc7872c19ce90ae 100644 (file)
@@ -287,15 +287,13 @@ LDAP_SLAPD_F (char *) slap_strcopy LDAP_P((
 /*
  * controls.c
  */
-#define SLAP_NO_CONTROL 0
-#define SLAP_NONCRITICAL_CONTROL 1
-#define SLAP_CRITICAL_CONTROL 2
-
 LDAP_SLAPD_F (int) get_ctrls LDAP_P((
        Connection *co,
        Operation *op,
        int senderrors ));
 
+LDAP_SLAPD_F (char *) get_supported_ctrl LDAP_P((int index));
+
 LDAP_SLAPD_F (int) get_manageDSAit LDAP_P(( Operation *op ));
 LDAP_SLAPD_F (int) get_subentries LDAP_P(( Operation *op, int *visibility ));
 
@@ -565,11 +563,6 @@ LDAP_SLAPD_F (void) *module_resolve LDAP_P((
 
 #endif /* SLAPD_MODULES */
 
-/*
- * controls.c
- */
-LDAP_SLAPD_V (char *) supportedControls[];
-
 /*
  * mra.c
  */
index ff72b78fdfd1068c028cce9ea86af75beab62e3b..4edcebbb8004425e8b8595a4b514fde1d1fc3fb2 100644 (file)
@@ -98,8 +98,7 @@ root_dse_info(
        /* altServer unsupported */
 
        /* supportedControl */
-       for ( i=0; supportedControls[i] != NULL; i++ ) {
-               vals[0].bv_val = supportedControls[i];
+       for ( i=0; (vals[0].bv_val = get_supported_ctrl(i)) != NULL; i++ ) {
                vals[0].bv_len = strlen( vals[0].bv_val );
                attr_merge( e, ad_supportedControl, vals );
        }
index 75795eaabf8c8677e2dff0fd631c37459ba03a0c..6213d10d8b755ef9ee9d2f1fc0f8f888f3878833 100644 (file)
@@ -155,7 +155,6 @@ do_search(
        Debug( LDAP_DEBUG_ARGS, "    filter: %s\n", fstr.bv_val, 0, 0 );
 #endif
 
-
        /* attributes */
        siz = sizeof(AttributeName);
        off = 0;
@@ -180,9 +179,7 @@ do_search(
 #endif
 
                goto return_results;
-       } 
-
-       rc = LDAP_SUCCESS;
+       }
 
 #ifdef NEW_LOGGING
        LDAP_LOG(( "operation", LDAP_LEVEL_ARGS,
@@ -191,7 +188,6 @@ do_search(
        Debug( LDAP_DEBUG_ARGS, "    attrs:", 0, 0, 0 );
 #endif
 
-
        if ( siz != 0 ) {
                for ( i = 0; i<siz; i++ ) {
 #ifdef NEW_LOGGING
@@ -218,9 +214,9 @@ do_search(
        if ( scope == LDAP_SCOPE_BASE ) {
                Entry *entry = NULL;
 
-               if ( strcasecmp( nbase.bv_val, LDAP_ROOT_DSE ) == 0 ) {
+               if ( nbase.bv_len == 0 ) {
 #ifdef LDAP_CONNECTIONLESS
-                       /* Ignore LDAPv2 CLDAP DSE queries */
+                       /* Ignore LDAPv2 CLDAP Root DSE queries */
                        if (op->o_protocol==LDAP_VERSION2 && conn->c_is_udp) {
                                goto return_results;
                        }
@@ -320,7 +316,8 @@ do_search(
                    timelimit, filter, &fstr, an, attrsonly );
        } else {
                send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
-                       NULL, "operation not supported within namingContext", NULL, NULL );
+                       NULL, "operation not supported within namingContext",
+                       NULL, NULL );
        }
 
 return_results:;
index 32f1541e49a0049949c72f44bd80f04ea8474d2f..8fc0fc5b2053180a573a7f8808b79f433cdcb1b1 100644 (file)
@@ -1315,8 +1315,18 @@ typedef struct slap_op {
        LDAP_STAILQ_ENTRY(slap_op)      o_next; /* next operation in list         */
        void    *o_private;     /* anything the backend needs     */
        void    *o_glue;        /* for the glue backend */
+
+#define SLAP_NO_CONTROL 0
+#define SLAP_NONCRITICAL_CONTROL 1
+#define SLAP_CRITICAL_CONTROL 2
+
+       char o_managedsait;
+       char o_subentries;
+       char o_subentries_visibility;
 } Operation;
 
+#define get_manageDSAit(op)    ((int)(op)->o_managedsait)
+
 /*
  * Caches the result of a backend_group check for ACL evaluation
  */