]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/controls.c
Fix prev commit
[openldap] / servers / slapd / controls.c
index 47916031656c9f1a62b7e37cc028ab59165d76e3..7818eab0745d7143806d9a03918fc71e5fc24def 100644 (file)
@@ -1,13 +1,18 @@
 /* $OpenLDAP$ */
-/* 
- * Copyright 1999-2003 The OpenLDAP Foundation.
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2004 The OpenLDAP Foundation.
  * All rights reserved.
  *
- * Redistribution and use in source and binary forms are permitted only
- * as authorized by the OpenLDAP Public License.  A copy of this
- * license is available at http://www.OpenLDAP.org/license.html or
- * in file LICENSE in the top-level directory of the distribution.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
  */
+
 #include "portable.h"
 
 #include <stdio.h>
@@ -30,6 +35,8 @@ static SLAP_CTRL_PARSE_FN parsePagedResults;
 static SLAP_CTRL_PARSE_FN parseValuesReturnFilter;
 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;
@@ -84,11 +91,9 @@ static struct slap_control control_defs[] = {
        { LDAP_CONTROL_VALUESRETURNFILTER,
                SLAP_CTRL_SEARCH, NULL,
                parseValuesReturnFilter, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-#ifdef LDAP_CONTROL_PAGEDRESULTS
        { LDAP_CONTROL_PAGEDRESULTS,
                SLAP_CTRL_SEARCH, NULL,
                parsePagedResults, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-#endif
 #ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
        { LDAP_CONTROL_X_DOMAIN_SCOPE,
                SLAP_CTRL_FRONTEND|SLAP_CTRL_SEARCH, NULL,
@@ -99,6 +104,16 @@ static struct slap_control control_defs[] = {
                SLAP_CTRL_MODIFY, NULL,
                parsePermissiveModify, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #endif
+#ifdef LDAP_CONTROL_X_TREE_DELETE
+       { LDAP_CONTROL_X_TREE_DELETE,
+               SLAP_CTRL_DELETE, NULL,
+               parseTreeDelete, LDAP_SLIST_ENTRY_INITIALIZER(next) },
+#endif
+#ifdef LDAP_CONTORL_X_SEARCH_OPTIONS
+       { LDAP_CONTORL_X_SEARCH_OPTIONS,
+               SLAP_CTRL_FRONTEND|SLAP_CTRL_SEARCH, NULL,
+               parseSearchOptions, LDAP_SLIST_ENTRY_INITIALIZER(next) },
+#endif
 #ifdef LDAP_CONTROL_SUBENTRIES
        { LDAP_CONTROL_SUBENTRIES,
                SLAP_CTRL_SEARCH, NULL,
@@ -110,9 +125,11 @@ static struct slap_control control_defs[] = {
        { LDAP_CONTROL_SYNC,
                SLAP_CTRL_HIDE|SLAP_CTRL_SEARCH, NULL,
                parseLDAPsync, LDAP_SLIST_ENTRY_INITIALIZER(next) },
+#ifdef LDAP_CONTROL_MODIFY_INCREMENT
        { LDAP_CONTROL_MODIFY_INCREMENT,
                SLAP_CTRL_HIDE|SLAP_CTRL_MODIFY, NULL,
                parseModifyIncrement, LDAP_SLIST_ENTRY_INITIALIZER(next) },
+#endif
        { LDAP_CONTROL_MANAGEDSAIT,
                SLAP_CTRL_ACCESS, NULL,
                parseManageDSAit, LDAP_SLIST_ENTRY_INITIALIZER(next) },
@@ -696,8 +713,8 @@ static int parseProxyAuthz (
        SlapReply *rs,
        LDAPControl *ctrl )
 {
-       int rc;
-       struct berval dn = { 0, NULL };
+       int             rc;
+       struct berval   dn = { 0, NULL };
 
        if ( op->o_proxy_authz != SLAP_NO_CONTROL ) {
                rs->sr_text = "proxy authorization control specified multiple times";
@@ -746,8 +763,8 @@ static int parseProxyAuthz (
        }
 
        rc = slap_sasl_getdn( op->o_conn, op,
-               ctrl->ldctl_value.bv_val, ctrl->ldctl_value.bv_len,
-               NULL, &dn, SLAP_GETDN_AUTHZID );
+                       ctrl->ldctl_value.bv_val, ctrl->ldctl_value.bv_len,
+                       NULL, &dn, SLAP_GETDN_AUTHZID );
 
        if( rc != LDAP_SUCCESS || !dn.bv_len ) {
                if ( dn.bv_val ) {
@@ -755,6 +772,7 @@ static int parseProxyAuthz (
                }
                rs->sr_text = "authzId mapping failed";
                return LDAP_PROXY_AUTHZ_FAILURE;
+
        }
 
 #ifdef NEW_LOGGING
@@ -814,7 +832,6 @@ static int parseNoOp (
        return LDAP_SUCCESS;
 }
 
-#ifdef LDAP_CONTROL_PAGEDRESULTS
 static int parsePagedResults (
        Operation *op,
        SlapReply *rs,
@@ -895,7 +912,6 @@ static int parsePagedResults (
 
        return LDAP_SUCCESS;
 }
-#endif
 
 static int parseAssert (
        Operation *op,
@@ -986,17 +1002,24 @@ static int parsePreRead (
        }
 
        siz = sizeof( AttributeName );
-       off = 0;
+       off = offsetof( AttributeName, an_name );
        if ( ber_scanf( ber, "{M}", &an, &siz, off ) == LBER_ERROR ) {
                rs->sr_text = "preread control: decoding error";
                return LDAP_PROTOCOL_ERROR;
        }
 
        for( i=0; i<siz; i++ ) {
-               const char *dummy;
+               int             rc = LDAP_SUCCESS;
+               const char      *dummy = NULL;
+
                an[i].an_desc = NULL;
                an[i].an_oc = NULL;
-               slap_bv2ad( &an[i].an_name, &an[i].an_desc, &dummy );
+               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";
+                       return rc;
+               }
        }
 
        op->o_preread = ctrl->ldctl_iscritical
@@ -1035,17 +1058,24 @@ static int parsePostRead (
        }
 
        siz = sizeof( AttributeName );
-       off = 0;
+       off = offsetof( AttributeName, an_name );
        if ( ber_scanf( ber, "{M}", &an, &siz, off ) == LBER_ERROR ) {
                rs->sr_text = "postread control: decoding error";
                return LDAP_PROTOCOL_ERROR;
        }
 
        for( i=0; i<siz; i++ ) {
-               const char *dummy;
+               int             rc = LDAP_SUCCESS;
+               const char      *dummy = NULL;
+
                an[i].an_desc = NULL;
                an[i].an_oc = NULL;
-               slap_bv2ad( &an[i].an_name, &an[i].an_desc, &dummy );
+               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";
+                       return rc;
+               }
        }
 
        op->o_postread = ctrl->ldctl_iscritical
@@ -1197,6 +1227,78 @@ static int parseDomainScope (
 }
 #endif
 
+#ifdef LDAP_CONTROL_X_TREE_DELETE
+static int parseTreeDelete (
+       Operation *op,
+       SlapReply *rs,
+       LDAPControl *ctrl )
+{
+       if ( op->o_tree_delete != SLAP_NO_CONTROL ) {
+               rs->sr_text = "treeDelete control specified multiple times";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       if ( ctrl->ldctl_value.bv_len ) {
+               rs->sr_text = "treeDelete control value not empty";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       op->o_tree_delete = ctrl->ldctl_iscritical
+               ? SLAP_CRITICAL_CONTROL
+               : SLAP_NONCRITICAL_CONTROL;
+
+       return LDAP_SUCCESS;
+}
+#endif
+
+#ifdef LDAP_CONTORL_X_SEARCH_OPTIONS
+static int parseSearchOptions (
+       Operation *op,
+       SlapReply *rs,
+       LDAPControl *ctrl )
+{
+       BerElement *ber;
+       ber_int_t search_flags;
+
+       if ( ctrl->ldctl_value.bv_len == 0 ) {
+               rs->sr_text = "searchOptions control value not empty";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       ber = ber_init( &ctrl->ldctl_value );
+       if( ber == NULL ) {
+               rs->sr_text = "internal error";
+               return LDAP_OTHER;
+       }
+
+       if ( (tag = ber_scanf( ber, "{i}", &search_flags )) == LBER_ERROR ) {
+               rs->sr_text = "searchOptions control decoding error";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       (void) ber_free( ber, 1 );
+
+       if ( search_flags & LDAP_SEARCH_FLAG_DOMAIN_SCOPE ) {
+               if ( op->o_domain_scope != SLAP_NO_CONTROL ) {
+                       rs->sr_text = "searchOptions control specified multiple times or with domainScope control";
+                       return LDAP_PROTOCOL_ERROR;
+               }
+
+               op->o_domain_scope = ctrl->ldctl_iscritical
+                       ? SLAP_CRITICAL_CONTROL
+                       : SLAP_NONCRITICAL_CONTROL;
+       }
+
+       if ( search_flags & ~(LDAP_SEARCH_FLAG_DOMAIN_SCOPE) ) {
+               /* Other search flags not recognised so far */
+               rs->sr_text = "searchOptions contained invalid flag";
+               return LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
+       }
+
+       return LDAP_SUCCESS;
+}
+#endif
+
 static int parseLDAPsync (
        Operation *op,
        SlapReply *rs,
@@ -1255,20 +1357,25 @@ static int parseLDAPsync (
 
        tag = ber_peek_tag( ber, &len );
 
-       if ( tag == LDAP_SYNC_TAG_COOKIE ) {
+       if ( tag == LDAP_TAG_SYNC_COOKIE ) {
                struct berval tmp_bv;   
-               if (( ber_scanf( ber, /*{*/ "o}", &tmp_bv )) == LBER_ERROR ) {
+               if (( ber_scanf( ber, /*{*/ "o", &tmp_bv )) == LBER_ERROR ) {
                        rs->sr_text = "LDAP 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 );
-       } else {
-               if (( ber_scanf( ber, /*{*/ "}")) == LBER_ERROR ) {
-                       rs->sr_text = "LDAP Sync control : decoding error";
+       }
+       if ( tag == LDAP_TAG_RELOAD_HINT ) {
+               if (( ber_scanf( ber, /*{*/ "b", &op->o_sync_rhint )) == LBER_ERROR ) {
+                       rs->sr_text = "LDAP Sync control : rhint decoding error";
                        return LDAP_PROTOCOL_ERROR;
                }
        }
+       if (( ber_scanf( ber, /*{*/ "}")) == LBER_ERROR ) {
+                       rs->sr_text = "LDAP Sync control : decoding error";
+                       return LDAP_PROTOCOL_ERROR;
+       }
 
        (void) ber_free( ber, 1 );