]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/controls.c
declare oc_bvfind_undef()
[openldap] / servers / slapd / controls.c
index ecdc8fe8355c2cb895e503f8439262d670c00258..688e7266072a9472527b4fabc9687f214cf2672b 100644 (file)
@@ -41,7 +41,6 @@ static SLAP_CTRL_PARSE_FN parseSearchOptions;
 #ifdef LDAP_CONTROL_SUBENTRIES
 static SLAP_CTRL_PARSE_FN parseSubentries;
 #endif
-static SLAP_CTRL_PARSE_FN parseLDAPsync;
 
 #undef sc_mask /* avoid conflict with Irix 6.5 <sys/signal.h> */
 
@@ -75,8 +74,19 @@ static LDAP_SLIST_HEAD(ControlsList, slap_control) controls_list
 /*
  * all known request control OIDs should be added to this list
  */
-char **slap_known_controls = NULL;
-static int num_known_controls;
+/*
+ * NOTE: initialize num_known_controls to 1 so that cid = 0 always
+ * addresses an undefined control; this allows to safely test for 
+ * well known controls even if they are not registered, e.g. if 
+ * they get moved to modules.  An example is sc_LDAPsync, which 
+ * is implemented in the syncprov overlay and thus, if configured 
+ * as dynamic module, may not be registered.  One side effect is that 
+ * slap_known_controls[0] == NULL, so it should always be used 
+ * starting from 1.
+ * FIXME: should we define the "undefined control" oid?
+ */
+char *slap_known_controls[SLAP_MAX_CIDS+1];
+static int num_known_controls = 1;
 
 static char *proxy_authz_extops[] = {
        LDAP_EXOP_MODIFY_PASSWD,
@@ -139,10 +149,6 @@ static struct slap_control control_defs[] = {
                (int)offsetof(struct slap_control_ids, sc_noOp),
                SLAP_CTRL_HIDE|SLAP_CTRL_ACCESS, NULL,
                parseNoOp, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-       { LDAP_CONTROL_SYNC,
-               (int)offsetof(struct slap_control_ids, sc_LDAPsync),
-               SLAP_CTRL_HIDE|SLAP_CTRL_SEARCH, NULL,
-               parseLDAPsync, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #ifdef LDAP_CONTROL_MODIFY_INCREMENT
        { LDAP_CONTROL_MODIFY_INCREMENT,
                (int)offsetof(struct slap_control_ids, sc_modifyIncrement),
@@ -174,9 +180,27 @@ register_supported_control(const char *controloid,
        int *controlcid)
 {
        struct slap_control *sc;
+       int i;
+
+       if ( num_known_controls >= SLAP_MAX_CIDS ) {
+               Debug( LDAP_DEBUG_ANY, "Too many controls registered."
+                       " Recompile slapd with SLAP_MAX_CIDS defined > %d\n",
+               SLAP_MAX_CIDS, 0, 0 );
+               return LDAP_OTHER;
+       }
 
        if ( controloid == NULL ) return LDAP_PARAM_ERROR;
 
+       /* sanity check - should never happen */
+       for ( i = 0; slap_known_controls[ i ]; i++ ) {
+               if ( strcmp( controloid, slap_known_controls[ i ] ) == 0 ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "Control %s already registered.\n",
+                               controloid, 0, 0 );
+                       return LDAP_PARAM_ERROR;
+               }
+       }
+
        sc = (struct slap_control *)SLAP_MALLOC( sizeof( *sc ) );
        if ( sc == NULL ) return LDAP_NO_MEMORY;
 
@@ -193,36 +217,12 @@ register_supported_control(const char *controloid,
        }
        sc->sc_parse = controlparsefn;
 
-       /* Update slap_known_controls, too. */
-       if ( slap_known_controls == NULL ) {
-               slap_known_controls = (char **)SLAP_MALLOC( 2 * sizeof(char *) );
-               if ( slap_known_controls == NULL ) {
-                       if ( sc->sc_extendedops != NULL ) {
-                               ldap_charray_free( sc->sc_extendedops );
-                       }
-                       ch_free( sc );
-                       return LDAP_NO_MEMORY;
-               }
-
-       } else {
-               char **new_known_controls;
-
-               new_known_controls = (char **)SLAP_REALLOC(
-                       slap_known_controls, (num_known_controls + 2) * sizeof(char *) );
-
-               if ( new_known_controls == NULL ) {
-                       if ( sc->sc_extendedops != NULL ) {
-                               ldap_charray_free( sc->sc_extendedops );
-                       }
-                       ch_free( sc );
-                       return LDAP_NO_MEMORY;
-               }
-               slap_known_controls = new_known_controls;
-       }
        if ( controlcid ) *controlcid = num_known_controls;
        sc->sc_cid = num_known_controls;
-       slap_known_controls[num_known_controls++] = ch_strdup( sc->sc_oid );
-       slap_known_controls[num_known_controls] = NULL;
+
+       /* Update slap_known_controls, too. */
+       slap_known_controls[num_known_controls-1] = sc->sc_oid;
+       slap_known_controls[num_known_controls++] = NULL;
 
        LDAP_SLIST_NEXT( sc, sc_next ) = NULL;
        LDAP_SLIST_INSERT_HEAD( &controls_list, sc, sc_next );
@@ -269,7 +269,6 @@ controls_destroy( void )
                }
                ch_free( sc );
        }
-       ldap_charray_free( slap_known_controls );
 }
 
 /*
@@ -371,6 +370,19 @@ find_ctrl( const char *oid )
        return NULL;
 }
 
+int
+slap_find_control_id(
+       const char *oid,
+       int *cid )
+{
+       struct slap_control *ctrl = find_ctrl( oid );
+       if ( ctrl ) {
+               if ( cid ) *cid = ctrl->sc_cid;
+               return LDAP_SUCCESS;
+       }
+       return LDAP_CONTROL_NOT_FOUND;
+}
+
 void slap_free_ctrls(
        Operation *op,
        LDAPControl **ctrls )
@@ -511,6 +523,8 @@ int get_ctrls(
 
                        c->ldctl_iscritical = (crit != 0);
                        tag = ber_peek_tag( ber, &len );
+               } else {
+                       c->ldctl_iscritical = 0;
                }
 
                if( tag == LBER_OCTETSTRING ) {
@@ -527,6 +541,8 @@ int get_ctrls(
                                rs->sr_text = "decoding controls error";
                                goto return_results;
                        }
+               } else {
+                       BER_BVZERO( &c->ldctl_value );
                }
 
                Debug( LDAP_DEBUG_TRACE,
@@ -818,10 +834,12 @@ static int parsePagedResults (
                return LDAP_PROTOCOL_ERROR;
        }
 
+#if 0  /* DELETE ME */
        if ( op->o_sync != SLAP_CONTROL_NONE ) {
                rs->sr_text = "paged results control specified with sync control";
                return LDAP_PROTOCOL_ERROR;
        }
+#endif
 
        if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ) {
                rs->sr_text = "paged results control value is empty (or absent)";
@@ -1304,97 +1322,3 @@ static int parseSearchOptions (
 }
 #endif
 
-static int parseLDAPsync (
-       Operation *op,
-       SlapReply *rs,
-       LDAPControl *ctrl )
-{
-       ber_tag_t tag;
-       BerElement *ber;
-       ber_int_t mode;
-       ber_len_t len;
-       struct slap_session_entry *se;
-
-       if ( op->o_sync != SLAP_CONTROL_NONE ) {
-               rs->sr_text = "Sync control specified multiple times";
-               return LDAP_PROTOCOL_ERROR;
-       }
-
-       if ( op->o_pagedresults != SLAP_CONTROL_NONE ) {
-               rs->sr_text = "Sync control specified with pagedResults control";
-               return LDAP_PROTOCOL_ERROR;
-       }
-
-
-       if ( ctrl->ldctl_value.bv_len == 0 ) {
-               rs->sr_text = "Sync control value is empty (or absent)";
-               return LDAP_PROTOCOL_ERROR;
-       }
-
-       /* Parse the control value
-        *      syncRequestValue ::= SEQUENCE {
-        *              mode   ENUMERATED {
-        *                      -- 0 unused
-        *                      refreshOnly             (1),
-        *                      -- 2 reserved
-        *                      refreshAndPersist       (3)
-        *              },
-        *              cookie  syncCookie OPTIONAL
-        *      }
-        */
-
-       ber = ber_init( &ctrl->ldctl_value );
-       if( ber == NULL ) {
-               rs->sr_text = "internal error";
-               return LDAP_OTHER;
-       }
-
-       if ( (tag = ber_scanf( ber, "{i" /*}*/, &mode )) == LBER_ERROR ) {
-               rs->sr_text = "Sync control : mode decoding error";
-               return LDAP_PROTOCOL_ERROR;
-       }
-
-       switch( mode ) {
-       case LDAP_SYNC_REFRESH_ONLY:
-               mode = SLAP_SYNC_REFRESH;
-               break;
-       case LDAP_SYNC_REFRESH_AND_PERSIST:
-               mode = SLAP_SYNC_REFRESH_AND_PERSIST;
-               break;
-       default:
-               rs->sr_text = "Sync control : unknown update mode";
-               return LDAP_PROTOCOL_ERROR;
-       }
-
-       tag = ber_peek_tag( ber, &len );
-
-       if ( tag == LDAP_TAG_SYNC_COOKIE ) {
-               struct berval tmp_bv;   
-               if (( ber_scanf( ber, /*{*/ "o", &tmp_bv )) == LBER_ERROR ) {
-                       rs->sr_text = "Sync control : cookie decoding error";
-                       return LDAP_PROTOCOL_ERROR;
-               }
-               ber_bvarray_add( &op->o_sync_state.octet_str, &tmp_bv );
-               slap_parse_sync_cookie( &op->o_sync_state );
-       }
-       if ( tag == LDAP_TAG_RELOAD_HINT ) {
-               if (( ber_scanf( ber, /*{*/ "b", &op->o_sync_rhint )) == LBER_ERROR ) {
-                       rs->sr_text = "Sync control : rhint decoding error";
-                       return LDAP_PROTOCOL_ERROR;
-               }
-       }
-       if (( ber_scanf( ber, /*{*/ "}")) == LBER_ERROR ) {
-                       rs->sr_text = "Sync control : decoding error";
-                       return LDAP_PROTOCOL_ERROR;
-       }
-
-       (void) ber_free( ber, 1 );
-
-       op->o_sync_mode = (char) mode;
-
-       op->o_sync = ctrl->ldctl_iscritical
-               ? SLAP_CONTROL_CRITICAL
-               : SLAP_CONTROL_NONCRITICAL;
-
-       return LDAP_SUCCESS;
-}