]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/controls.c
Another abandon check
[openldap] / servers / slapd / controls.c
index 5ccca5b4ad72c71bfb3a242ae50486107cce6178..f67c7e8f81448aed7499a05ff036d4a0be5c7eaa 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2004 The OpenLDAP Foundation.
+ * Copyright 1998-2005 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -37,10 +37,7 @@ static SLAP_CTRL_PARSE_FN parsePermissiveModify;
 static SLAP_CTRL_PARSE_FN parseDomainScope;
 static SLAP_CTRL_PARSE_FN parseTreeDelete;
 static SLAP_CTRL_PARSE_FN parseSearchOptions;
-
-#ifdef LDAP_CONTROL_SUBENTRIES
 static SLAP_CTRL_PARSE_FN parseSubentries;
-#endif
 
 #undef sc_mask /* avoid conflict with Irix 6.5 <sys/signal.h> */
 
@@ -74,8 +71,19 @@ static LDAP_SLIST_HEAD(ControlsList, slap_control) controls_list
 /*
  * all known request control OIDs should be added to this list
  */
+/*
+ * 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;
+static int num_known_controls = 1;
 
 static char *proxy_authz_extops[] = {
        LDAP_EXOP_MODIFY_PASSWD,
@@ -98,7 +106,7 @@ static struct slap_control control_defs[] = {
                parsePostRead, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { LDAP_CONTROL_VALUESRETURNFILTER,
                (int)offsetof(struct slap_control_ids, sc_valuesReturnFilter),
-               SLAP_CTRL_SEARCH, NULL,
+               SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH, NULL,
                parseValuesReturnFilter, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { LDAP_CONTROL_PAGEDRESULTS,
                (int)offsetof(struct slap_control_ids, sc_pagedResults),
@@ -107,7 +115,7 @@ static struct slap_control control_defs[] = {
 #ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
        { LDAP_CONTROL_X_DOMAIN_SCOPE,
                (int)offsetof(struct slap_control_ids, sc_domainScope),
-               SLAP_CTRL_FRONTEND|SLAP_CTRL_SEARCH, NULL,
+               SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH, NULL,
                parseDomainScope, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #endif
 #ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
@@ -116,16 +124,16 @@ static struct slap_control control_defs[] = {
                SLAP_CTRL_MODIFY, NULL,
                parsePermissiveModify, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #endif
-#ifdef LDAP_CONTROL_X_TREE_DELETE
+#ifdef SLAP_CONTROL_X_TREE_DELETE
        { LDAP_CONTROL_X_TREE_DELETE,
                (int)offsetof(struct slap_control_ids, sc_treeDelete),
-               SLAP_CTRL_DELETE, NULL,
+               SLAP_CTRL_HIDE|SLAP_CTRL_DELETE, NULL,
                parseTreeDelete, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #endif
 #ifdef LDAP_CONTORL_X_SEARCH_OPTIONS
        { LDAP_CONTORL_X_SEARCH_OPTIONS,
                (int)offsetof(struct slap_control_ids, sc_searchOptions),
-               SLAP_CTRL_FRONTEND|SLAP_CTRL_SEARCH, NULL,
+               SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH, NULL,
                parseSearchOptions, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #endif
 #ifdef LDAP_CONTROL_SUBENTRIES
@@ -150,7 +158,7 @@ static struct slap_control control_defs[] = {
                parseManageDSAit, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { LDAP_CONTROL_PROXY_AUTHZ,
                (int)offsetof(struct slap_control_ids, sc_proxyAuthz),
-               SLAP_CTRL_FRONTEND|SLAP_CTRL_ACCESS, proxy_authz_extops,
+               SLAP_CTRL_GLOBAL|SLAP_CTRL_ACCESS, proxy_authz_extops,
                parseProxyAuthz, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { NULL, 0, 0, NULL, 0, LDAP_SLIST_ENTRY_INITIALIZER(next) }
 };
@@ -169,6 +177,7 @@ 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."
@@ -179,6 +188,16 @@ register_supported_control(const char *controloid,
 
        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;
 
@@ -199,8 +218,8 @@ register_supported_control(const char *controloid,
        sc->sc_cid = num_known_controls;
 
        /* Update slap_known_controls, too. */
-       slap_known_controls[num_known_controls++] = sc->sc_oid;
-       slap_known_controls[num_known_controls] = NULL;
+       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 );
@@ -348,6 +367,48 @@ 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;
+}
+
+int
+slap_global_control( Operation *op, const char *oid, int *cid )
+{
+       struct slap_control *ctrl = find_ctrl( oid );
+
+       if ( ctrl == NULL ) {
+               /* should not be reachable */
+               Debug( LDAP_DEBUG_ANY,
+                       "slap_global_control: unrecognized control: %s\n",      
+                       oid, 0, 0 );
+               return LDAP_CONTROL_NOT_FOUND;
+       }
+
+       if ( cid ) *cid = ctrl->sc_cid;
+
+       if ( ( ctrl->sc_mask & SLAP_CTRL_GLOBAL ) ||
+                       ( ( op->o_tag & LDAP_REQ_SEARCH ) &&
+                       ( ctrl->sc_mask & SLAP_CTRL_GLOBAL_SEARCH ) ) )
+       {
+               return LDAP_COMPARE_TRUE;
+       }
+
+       Debug( LDAP_DEBUG_TRACE,
+               "slap_global_control: unavailable control: %s\n",      
+               oid, 0, 0 );
+
+       return LDAP_COMPARE_FALSE;
+}
+
 void slap_free_ctrls(
        Operation *op,
        LDAPControl **ctrls )
@@ -580,17 +641,6 @@ int get_ctrls(
                                        goto return_results;
                                }
 
-                               if ( sc->sc_mask & SLAP_CTRL_FRONTEND ) {
-                                       /* kludge to disable backend_control() check */
-                                       c->ldctl_iscritical = 0;
-
-                               } else if ( tagmask == SLAP_CTRL_SEARCH &&
-                                       sc->sc_mask & SLAP_CTRL_FRONTEND_SEARCH )
-                               {
-                                       /* kludge to disable backend_control() check */
-                                       c->ldctl_iscritical = 0;
-                               }
-
                        } else if( c->ldctl_iscritical ) {
                                /* unavailable CRITICAL control */
                                rs->sr_err = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
@@ -795,13 +845,6 @@ 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)";
                return LDAP_PROTOCOL_ERROR;
@@ -1005,7 +1048,9 @@ static int parsePreRead (
                an[i].an_oc_exclude = 0;
                rc = slap_bv2ad( &an[i].an_name, &an[i].an_desc, &dummy );
                if ( rc != LDAP_SUCCESS && ctrl->ldctl_iscritical ) {
-                       rs->sr_text = dummy ? dummy : "postread control: unknown attributeType";
+                       rs->sr_text = dummy
+                               ? dummy
+                               : "postread control: unknown attributeType";
                        return rc;
                }
        }
@@ -1061,7 +1106,9 @@ static int parsePostRead (
                an[i].an_oc_exclude = 0;
                rc = slap_bv2ad( &an[i].an_name, &an[i].an_desc, &dummy );
                if ( rc != LDAP_SUCCESS && ctrl->ldctl_iscritical ) {
-                       rs->sr_text = dummy ? dummy : "postread control: unknown attributeType";
+                       rs->sr_text = dummy
+                               ? dummy
+                               : "postread control: unknown attributeType";
                        return rc;
                }
        }
@@ -1274,7 +1321,10 @@ static int parseSearchOptions (
        }
 
        if ( search_flags & ~(LDAP_SEARCH_FLAG_DOMAIN_SCOPE) ) {
-               /* Other search flags not recognised so far */
+               /* Other search flags not recognised so far,
+                * including:
+                *              LDAP_SEARCH_FLAG_PHANTOM_ROOM
+                */
                rs->sr_text = "searchOptions contained unrecongized flag";
                return LDAP_UNWILLING_TO_PERFORM;
        }