]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/controls.c
allow proxying of dynamic objects (irrespective of the support provided to dynamic...
[openldap] / servers / slapd / controls.c
index 4eddc8310b4bbbffdeb00b1ca033cf407177003f..08003bee1c53c246853a6fc8787653250881ae15 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2005 The OpenLDAP Foundation.
+ * Copyright 1998-2006 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -29,6 +29,7 @@ static SLAP_CTRL_PARSE_FN parsePreRead;
 static SLAP_CTRL_PARSE_FN parsePostRead;
 static SLAP_CTRL_PARSE_FN parseProxyAuthz;
 #ifdef LDAP_DEVEL
+static SLAP_CTRL_PARSE_FN parseDontUseCopy;
 static SLAP_CTRL_PARSE_FN parseManageDIT;
 #endif
 static SLAP_CTRL_PARSE_FN parseManageDSAit;
@@ -64,7 +65,8 @@ struct slap_control {
        slap_mask_t sc_mask;
 
        /* Extended operations supported by control */
-       char **sc_extendedops;
+       char **sc_extendedops;          /* input */
+       BerVarray sc_extendedopsbv;     /* run-time use */
 
        /* Control parsing callback */
        SLAP_CTRL_PARSE_FN *sc_parse;
@@ -98,80 +100,97 @@ static char *proxy_authz_extops[] = {
        NULL
 };
 
+static char *manageDSAit_extops[] = {
+       NULL
+};
+
 static struct slap_control control_defs[] = {
        {  LDAP_CONTROL_ASSERT,
                (int)offsetof(struct slap_control_ids, sc_assert),
-               SLAP_CTRL_ACCESS, NULL,
+               SLAP_CTRL_DELETE|SLAP_CTRL_MODIFY|SLAP_CTRL_RENAME|
+                       SLAP_CTRL_COMPARE|SLAP_CTRL_SEARCH,
+               NULL, NULL,
                parseAssert, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { LDAP_CONTROL_PRE_READ,
                (int)offsetof(struct slap_control_ids, sc_preRead),
-               SLAP_CTRL_DELETE|SLAP_CTRL_MODIFY|SLAP_CTRL_RENAME, NULL,
+               SLAP_CTRL_DELETE|SLAP_CTRL_MODIFY|SLAP_CTRL_RENAME,
+               NULL, NULL,
                parsePreRead, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { LDAP_CONTROL_POST_READ,
                (int)offsetof(struct slap_control_ids, sc_postRead),
-               SLAP_CTRL_ADD|SLAP_CTRL_MODIFY|SLAP_CTRL_RENAME, NULL,
+               SLAP_CTRL_ADD|SLAP_CTRL_MODIFY|SLAP_CTRL_RENAME,
+               NULL, NULL,
                parsePostRead, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { LDAP_CONTROL_VALUESRETURNFILTER,
                (int)offsetof(struct slap_control_ids, sc_valuesReturnFilter),
-               SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH, NULL,
+               SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH,
+               NULL, NULL,
                parseValuesReturnFilter, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { LDAP_CONTROL_PAGEDRESULTS,
                (int)offsetof(struct slap_control_ids, sc_pagedResults),
-               SLAP_CTRL_SEARCH, NULL,
+               SLAP_CTRL_SEARCH,
+               NULL, NULL,
                parsePagedResults, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #ifdef LDAP_DEVEL
        { LDAP_CONTROL_SORTREQUEST,
                (int)offsetof(struct slap_control_ids, sc_sortedResults),
-               SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE, NULL,
+               SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE,
+               NULL, NULL,
                parseSortedResults, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #endif
-#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
        { LDAP_CONTROL_X_DOMAIN_SCOPE,
                (int)offsetof(struct slap_control_ids, sc_domainScope),
-               SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH, NULL,
+               SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE,
+               NULL, NULL,
                parseDomainScope, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-#endif
-#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
        { LDAP_CONTROL_X_PERMISSIVE_MODIFY,
                (int)offsetof(struct slap_control_ids, sc_permissiveModify),
-               SLAP_CTRL_MODIFY, NULL,
+               SLAP_CTRL_MODIFY|SLAP_CTRL_HIDE,
+               NULL, NULL,
                parsePermissiveModify, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-#endif
 #ifdef SLAP_CONTROL_X_TREE_DELETE
        { LDAP_CONTROL_X_TREE_DELETE,
                (int)offsetof(struct slap_control_ids, sc_treeDelete),
-               SLAP_CTRL_HIDE|SLAP_CTRL_DELETE, NULL,
+               SLAP_CTRL_DELETE|SLAP_CTRL_HIDE,
+               NULL, NULL,
                parseTreeDelete, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #endif
-#ifdef LDAP_CONTROL_X_SEARCH_OPTIONS
        { LDAP_CONTROL_X_SEARCH_OPTIONS,
                (int)offsetof(struct slap_control_ids, sc_searchOptions),
-               SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH, NULL,
+               SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE,
+               NULL, NULL,
                parseSearchOptions, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-#endif
-#ifdef LDAP_CONTROL_SUBENTRIES
        { LDAP_CONTROL_SUBENTRIES,
                (int)offsetof(struct slap_control_ids, sc_subentries),
-               SLAP_CTRL_SEARCH, NULL,
+               SLAP_CTRL_SEARCH,
+               NULL, NULL,
                parseSubentries, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-#endif
        { LDAP_CONTROL_NOOP,
                (int)offsetof(struct slap_control_ids, sc_noOp),
-               SLAP_CTRL_HIDE|SLAP_CTRL_ACCESS, NULL,
+               SLAP_CTRL_ACCESS|SLAP_CTRL_HIDE,
+               NULL, NULL,
                parseNoOp, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #ifdef LDAP_DEVEL
+       { LDAP_CONTROL_DONTUSECOPY,
+               (int)offsetof(struct slap_control_ids, sc_dontUseCopy),
+               SLAP_CTRL_INTROGATE|SLAP_CTRL_HIDE,
+               NULL, NULL,
+               parseDontUseCopy, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { LDAP_CONTROL_MANAGEDIT,
                (int)offsetof(struct slap_control_ids, sc_manageDIT),
-               SLAP_CTRL_GLOBAL|SLAP_CTRL_UPDATE, NULL,
+               SLAP_CTRL_GLOBAL|SLAP_CTRL_UPDATE|SLAP_CTRL_HIDE,
+               NULL, NULL,
                parseManageDIT, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #endif
        { LDAP_CONTROL_MANAGEDSAIT,
                (int)offsetof(struct slap_control_ids, sc_manageDSAit),
-               SLAP_CTRL_ACCESS, NULL,
+               SLAP_CTRL_ACCESS,
+               manageDSAit_extops, NULL,
                parseManageDSAit, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { LDAP_CONTROL_PROXY_AUTHZ,
                (int)offsetof(struct slap_control_ids, sc_proxyAuthz),
-               SLAP_CTRL_GLOBAL|SLAP_CTRL_ACCESS, proxy_authz_extops,
+               SLAP_CTRL_GLOBAL|SLAP_CTRL_ACCESS,
+               proxy_authz_extops, NULL,
                parseProxyAuthz, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { NULL, 0, 0, NULL, 0, LDAP_SLIST_ENTRY_INITIALIZER(next) }
 };
@@ -217,14 +236,24 @@ register_supported_control(const char *controloid,
        sc->sc_oid = ch_strdup( controloid );
        sc->sc_mask = controlmask;
        if ( controlexops != NULL ) {
-               sc->sc_extendedops = ldap_charray_dup( controlexops );
-               if ( sc->sc_extendedops == NULL ) {
+               int i;
+
+               for ( i = 0; controlexops[ i ]; i++ );
+
+               sc->sc_extendedopsbv = ber_memcalloc( i + 1, sizeof( struct berval ) );
+               if ( sc->sc_extendedopsbv == NULL ) {
                        ch_free( sc );
                        return LDAP_NO_MEMORY;
                }
+
+               for ( i = 0; controlexops[ i ]; i++ ) {
+                       ber_str2bv( controlexops[ i ], 0, 1, &sc->sc_extendedopsbv[ i ] );
+               }
+
        } else {
-               sc->sc_extendedops = NULL;
+               sc->sc_extendedopsbv = NULL;
        }
+       sc->sc_extendedops = NULL;
        sc->sc_parse = controlparsefn;
 
        if ( controlcid ) *controlcid = num_known_controls;
@@ -273,8 +302,8 @@ controls_destroy( void )
                LDAP_SLIST_REMOVE_HEAD(&controls_list, sc_next);
 
                ch_free( sc->sc_oid );
-               if ( sc->sc_extendedops != NULL ) {
-                       ldap_charray_free( sc->sc_extendedops );
+               if ( sc->sc_extendedopsbv != NULL ) {
+                       ber_bvarray_free( sc->sc_extendedopsbv );
                }
                ch_free( sc );
        }
@@ -475,11 +504,11 @@ int slap_parse_ctrl(
                case LDAP_REQ_EXTENDED:
                        tagmask=~0L;
                        assert( op->ore_reqoid.bv_val != NULL );
-                       if( sc->sc_extendedops != NULL ) {
+                       if( sc->sc_extendedopsbv != NULL ) {
                                int i;
-                               for( i=0; sc->sc_extendedops[i] != NULL; i++ ) {
-                                       if( strcmp( op->ore_reqoid.bv_val,
-                                               sc->sc_extendedops[i] ) == 0 )
+                               for( i=0; !BER_BVISNULL( &sc->sc_extendedopsbv[i] ); i++ ) {
+                                       if( bvmatch( &op->ore_reqoid,
+                                               &sc->sc_extendedopsbv[i] ) )
                                        {
                                                tagmask=0L;
                                                break;
@@ -706,7 +735,8 @@ slap_remove_control(
        switch ( op->o_ctrlflag[ ctrl ] ) {
        case SLAP_CONTROL_NONCRITICAL:
                for ( i = 0, j = -1; op->o_ctrls[ i ] != NULL; i++ ) {
-                       if ( strcmp( op->o_ctrls[ i ]->ldctl_oid, slap_known_controls[ ctrl - 1 ] ) == 0 )
+                       if ( strcmp( op->o_ctrls[ i ]->ldctl_oid,
+                               slap_known_controls[ ctrl - 1 ] ) == 0 )
                        {
                                j = i;
                        }
@@ -763,6 +793,30 @@ slap_remove_control(
 }
 
 #ifdef LDAP_DEVEL
+static int parseDontUseCopy (
+       Operation *op,
+       SlapReply *rs,
+       LDAPControl *ctrl )
+{
+       if ( op->o_dontUseCopy != SLAP_CONTROL_NONE ) {
+               rs->sr_text = "dontUseCopy control specified multiple times";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       if ( ctrl->ldctl_value.bv_len ) {
+               rs->sr_text = "dontUseCopy control value not empty";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       if ( ctrl->ldctl_iscritical != SLAP_CONTROL_CRITICAL ) {
+               rs->sr_text = "dontUseCopy criticality of FALSE not allowed";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       op->o_dontUseCopy = SLAP_CONTROL_CRITICAL;
+       return LDAP_SUCCESS;
+}
+
 static int parseManageDIT (
        Operation *op,
        SlapReply *rs,
@@ -1042,8 +1096,8 @@ static int parseAssert (
                return LDAP_OTHER;
        }
        
-       rs->sr_err = get_filter( op, ber, (Filter **)&(op->o_assertion), &rs->sr_text);
-
+       rs->sr_err = get_filter( op, ber, (Filter **)&(op->o_assertion),
+               &rs->sr_text);
        if( rs->sr_err != LDAP_SUCCESS ) {
                if( rs->sr_err == SLAPD_DISCONNECT ) {
                        rs->sr_err = LDAP_PROTOCOL_ERROR;
@@ -1214,7 +1268,8 @@ static int parseValuesReturnFilter (
                return LDAP_OTHER;
        }
        
-       rs->sr_err = get_vrFilter( op, ber, (ValuesReturnFilter **)&(op->o_vrFilter), &rs->sr_text);
+       rs->sr_err = get_vrFilter( op, ber,
+               (ValuesReturnFilter **)&(op->o_vrFilter), &rs->sr_text);
 
        if( rs->sr_err != LDAP_SUCCESS ) {
                if( rs->sr_err == SLAPD_DISCONNECT ) {
@@ -1244,7 +1299,6 @@ static int parseValuesReturnFilter (
        return LDAP_SUCCESS;
 }
 
-#ifdef LDAP_CONTROL_SUBENTRIES
 static int parseSubentries (
        Operation *op,
        SlapReply *rs,
@@ -1274,9 +1328,7 @@ static int parseSubentries (
 
        return LDAP_SUCCESS;
 }
-#endif
 
-#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
 static int parsePermissiveModify (
        Operation *op,
        SlapReply *rs,
@@ -1298,9 +1350,7 @@ static int parsePermissiveModify (
 
        return LDAP_SUCCESS;
 }
-#endif
 
-#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
 static int parseDomainScope (
        Operation *op,
        SlapReply *rs,
@@ -1322,7 +1372,6 @@ static int parseDomainScope (
 
        return LDAP_SUCCESS;
 }
-#endif
 
 #ifdef SLAP_CONTROL_X_TREE_DELETE
 static int parseTreeDelete (
@@ -1348,7 +1397,6 @@ static int parseTreeDelete (
 }
 #endif
 
-#ifdef LDAP_CONTROL_X_SEARCH_OPTIONS
 static int parseSearchOptions (
        Operation *op,
        SlapReply *rs,
@@ -1399,5 +1447,4 @@ static int parseSearchOptions (
 
        return LDAP_SUCCESS;
 }
-#endif