]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/controls.c
fix ITS#3753
[openldap] / servers / slapd / controls.c
index c201273eb579f44430bcba861f4e04fab2ad8d58..7360e06fcb7fb0dca7440aaeee86fd8442f3ccf7 100644 (file)
@@ -28,10 +28,14 @@ static SLAP_CTRL_PARSE_FN parseAssert;
 static SLAP_CTRL_PARSE_FN parsePreRead;
 static SLAP_CTRL_PARSE_FN parsePostRead;
 static SLAP_CTRL_PARSE_FN parseProxyAuthz;
+static SLAP_CTRL_PARSE_FN parseManageDIT;
 static SLAP_CTRL_PARSE_FN parseManageDSAit;
 static SLAP_CTRL_PARSE_FN parseModifyIncrement;
 static SLAP_CTRL_PARSE_FN parseNoOp;
 static SLAP_CTRL_PARSE_FN parsePagedResults;
+#ifdef LDAP_DEVEL
+static SLAP_CTRL_PARSE_FN parseSortedResults;
+#endif
 static SLAP_CTRL_PARSE_FN parseValuesReturnFilter;
 static SLAP_CTRL_PARSE_FN parsePermissiveModify;
 static SLAP_CTRL_PARSE_FN parseDomainScope;
@@ -106,12 +110,18 @@ 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),
                SLAP_CTRL_SEARCH, 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,
+               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),
@@ -130,8 +140,8 @@ static struct slap_control control_defs[] = {
                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,
+#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,
                parseSearchOptions, LDAP_SLIST_ENTRY_INITIALIZER(next) },
@@ -152,6 +162,10 @@ static struct slap_control control_defs[] = {
                SLAP_CTRL_HIDE|SLAP_CTRL_MODIFY, NULL,
                parseModifyIncrement, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #endif
+       { LDAP_CONTROL_MANAGEDIT,
+               (int)offsetof(struct slap_control_ids, sc_manageDIT),
+               SLAP_CTRL_GLOBAL|SLAP_CTRL_UPDATE, NULL,
+               parseManageDIT, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { LDAP_CONTROL_MANAGEDSAIT,
                (int)offsetof(struct slap_control_ids, sc_manageDSAit),
                SLAP_CTRL_ACCESS, NULL,
@@ -381,7 +395,7 @@ slap_find_control_id(
 }
 
 int
-slap_global_control( Operation *op, const char *oid )
+slap_global_control( Operation *op, const char *oid, int *cid )
 {
        struct slap_control *ctrl = find_ctrl( oid );
 
@@ -390,22 +404,23 @@ slap_global_control( Operation *op, const char *oid )
                Debug( LDAP_DEBUG_ANY,
                        "slap_global_control: unrecognized control: %s\n",      
                        oid, 0, 0 );
-               assert( 0 );
-               return 0;
+               return LDAP_CONTROL_NOT_FOUND;
        }
 
-       if ( ctrl->sc_mask & SLAP_CTRL_GLOBAL ) return 1;
+       if ( cid ) *cid = ctrl->sc_cid;
 
-       if (( op->o_tag & LDAP_REQ_SEARCH ) &&
-               ( ctrl->sc_mask & SLAP_CTRL_GLOBAL_SEARCH ))
+       if ( ( ctrl->sc_mask & SLAP_CTRL_GLOBAL ) ||
+               ( ( op->o_tag & LDAP_REQ_SEARCH ) &&
+               ( ctrl->sc_mask & SLAP_CTRL_GLOBAL_SEARCH ) ) )
        {
-               return 1;
+               return LDAP_COMPARE_TRUE;
        }
 
-       Debug( LDAP_DEBUG_ANY,
+       Debug( LDAP_DEBUG_TRACE,
                "slap_global_control: unavailable control: %s\n",      
                oid, 0, 0 );
-       return 0;
+
+       return LDAP_COMPARE_FALSE;
 }
 
 void slap_free_ctrls(
@@ -700,6 +715,28 @@ static int parseModifyIncrement (
        return LDAP_SUCCESS;
 }
 
+static int parseManageDIT (
+       Operation *op,
+       SlapReply *rs,
+       LDAPControl *ctrl )
+{
+       if ( op->o_managedit != SLAP_CONTROL_NONE ) {
+               rs->sr_text = "manageDIT control specified multiple times";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       if ( ctrl->ldctl_value.bv_len ) {
+               rs->sr_text = "manageDIT control value not empty";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       op->o_managedit = ctrl->ldctl_iscritical
+               ? SLAP_CONTROL_CRITICAL
+               : SLAP_CONTROL_NONCRITICAL;
+
+       return LDAP_SUCCESS;
+}
+
 static int parseManageDSAit (
        Operation *op,
        SlapReply *rs,
@@ -745,19 +782,17 @@ static int parseProxyAuthz (
                ctrl->ldctl_value.bv_len ?  ctrl->ldctl_value.bv_val : "anonymous",
                0 );
 
-       if( ctrl->ldctl_value.bv_len == 0 ) {
+       if ( ctrl->ldctl_value.bv_len == 0 ) {
                Debug( LDAP_DEBUG_TRACE,
                        "parseProxyAuthz: conn=%lu anonymous\n", 
                        op->o_connid, 0, 0 );
 
                /* anonymous */
-               free( op->o_dn.bv_val );
-               op->o_dn.bv_len = 0;
-               op->o_dn.bv_val = ch_strdup( "" );
-
-               free( op->o_ndn.bv_val );
+               op->o_ndn.bv_val[ 0 ] = '\0';
                op->o_ndn.bv_len = 0;
-               op->o_ndn.bv_val = ch_strdup( "" );
+
+               op->o_dn.bv_val[ 0 ] = '\0';
+               op->o_dn.bv_len = 0;
 
                return LDAP_SUCCESS;
        }
@@ -781,27 +816,26 @@ static int parseProxyAuthz (
 
        rc = slap_sasl_authorized( op, &op->o_ndn, &dn );
 
-       if( rc ) {
+       if ( rc ) {
                ch_free( dn.bv_val );
                rs->sr_text = "not authorized to assume identity";
                return LDAP_PROXY_AUTHZ_FAILURE;
        }
 
-       ch_free( op->o_dn.bv_val );
        ch_free( op->o_ndn.bv_val );
-
-       op->o_dn.bv_val = NULL;
-       op->o_ndn = dn;
-
-       Statslog( LDAP_DEBUG_STATS, "%s PROXYAUTHZ dn=\"%s\"\n",
-           op->o_log_prefix, dn.bv_val, 0, 0, 0 );
+       ch_free( op->o_dn.bv_val );
 
        /*
         * NOTE: since slap_sasl_getdn() returns a normalized dn,
         * from now on op->o_dn is normalized
         */
+       op->o_ndn = dn;
        ber_dupbv( &op->o_dn, &dn );
 
+
+       Statslog( LDAP_DEBUG_STATS, "%s PROXYAUTHZ dn=\"%s\"\n",
+           op->o_log_prefix, dn.bv_val, 0, 0, 0 );
+
        return LDAP_SUCCESS;
 }
 
@@ -949,6 +983,34 @@ done:;
        return rc;
 }
 
+#ifdef LDAP_DEVEL
+static int parseSortedResults (
+       Operation *op,
+       SlapReply *rs,
+       LDAPControl *ctrl )
+{
+       int             rc = LDAP_SUCCESS;
+
+       if ( op->o_sortedresults != SLAP_CONTROL_NONE ) {
+               rs->sr_text = "sorted results control specified multiple times";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ) {
+               rs->sr_text = "sorted results control value is empty (or absent)";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       /* blow off parsing the value */
+
+       op->o_sortedresults = ctrl->ldctl_iscritical
+               ? SLAP_CONTROL_CRITICAL
+               : SLAP_CONTROL_NONCRITICAL;
+
+       return rc;
+}
+#endif
+
 static int parseAssert (
        Operation *op,
        SlapReply *rs,
@@ -1190,8 +1252,8 @@ static int parseSubentries (
 
        /* 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 ))
+               || ( ctrl->ldctl_value.bv_val[0] != 0x01 )
+               || ( ctrl->ldctl_value.bv_val[1] != 0x01 ))
        {
                rs->sr_text = "subentries control value encoding is bogus";
                return LDAP_PROTOCOL_ERROR;
@@ -1201,8 +1263,9 @@ static int parseSubentries (
                ? SLAP_CONTROL_CRITICAL
                : SLAP_CONTROL_NONCRITICAL;
 
-       if ( (void *)(ctrl->ldctl_value.bv_val[2] != 0x00))
+       if (ctrl->ldctl_value.bv_val[2]) {
                set_subentries_visibility( op );
+       }
 
        return LDAP_SUCCESS;
 }
@@ -1280,7 +1343,7 @@ static int parseTreeDelete (
 }
 #endif
 
-#ifdef LDAP_CONTORL_X_SEARCH_OPTIONS
+#ifdef LDAP_CONTROL_X_SEARCH_OPTIONS
 static int parseSearchOptions (
        Operation *op,
        SlapReply *rs,
@@ -1288,6 +1351,7 @@ static int parseSearchOptions (
 {
        BerElement *ber;
        ber_int_t search_flags;
+       ber_tag_t tag;
 
        if ( ctrl->ldctl_value.bv_len == 0 ) {
                rs->sr_text = "searchOptions control value not empty";