]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/controls.c
ITS#4550 don't overwrite remote server's err msg
[openldap] / servers / slapd / controls.c
index 050f0ac7e14aa0ebda16ae63e23ae58d1f8ed143..6c610008843c31b338fc641248afa79b879c20a7 100644 (file)
@@ -96,7 +96,7 @@ static int num_known_controls = 1;
 
 static char *proxy_authz_extops[] = {
        LDAP_EXOP_MODIFY_PASSWD,
-       LDAP_EXOP_X_WHO_AM_I,
+       LDAP_EXOP_WHO_AM_I,
        LDAP_EXOP_REFRESH,
        NULL
 };
@@ -128,13 +128,6 @@ static struct slap_control control_defs[] = {
                SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH,
                NULL, NULL,
                parseValuesReturnFilter, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-#ifdef LDAP_CONTROL_X_VALUESRETURNFILTER
-       { LDAP_CONTROL_X_VALUESRETURNFILTER /* bad OID */,
-               (int)offsetof(struct slap_control_ids, sc_valuesReturnFilter),
-               SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE,
-               NULL, NULL,
-               parseValuesReturnFilter, LDAP_SLIST_ENTRY_INITIALIZER(next) },
-#endif
        { LDAP_CONTROL_PAGEDRESULTS,
                (int)offsetof(struct slap_control_ids, sc_pagedResults),
                SLAP_CTRL_SEARCH,
@@ -190,6 +183,13 @@ static struct slap_control control_defs[] = {
                SLAP_CTRL_GLOBAL|SLAP_CTRL_UPDATE|SLAP_CTRL_HIDE,
                NULL, NULL,
                parseManageDIT, LDAP_SLIST_ENTRY_INITIALIZER(next) },
+#endif
+#ifdef LDAP_X_TXN
+       { LDAP_CONTROL_X_TXN_SPEC,
+               (int)offsetof(struct slap_control_ids, sc_txnSpec),
+               SLAP_CTRL_UPDATE|SLAP_CTRL_HIDE,
+               NULL, NULL,
+               txn_spec_ctrl, LDAP_SLIST_ENTRY_INITIALIZER(next) },
 #endif
        { LDAP_CONTROL_MANAGEDSAIT,
                (int)offsetof(struct slap_control_ids, sc_manageDSAit),
@@ -420,7 +420,7 @@ get_supported_controls(char ***ctrloidsp,
        }
        masks = (slap_mask_t *)SLAP_MALLOC( (n + 1) * sizeof(slap_mask_t) );
        if  ( masks == NULL ) {
-               ch_free( oids );
+               SLAP_FREE( oids );
                return LDAP_NO_MEMORY;
        }
 
@@ -492,9 +492,11 @@ slap_global_control( Operation *op, const char *oid, int *cid )
                return LDAP_COMPARE_TRUE;
        }
 
+#if 0
        Debug( LDAP_DEBUG_TRACE,
                "slap_global_control: unavailable control: %s\n",      
                oid, 0, 0 );
+#endif
 
        return LDAP_COMPARE_FALSE;
 }
@@ -1159,6 +1161,7 @@ static int parseAssert (
        
        rs->sr_err = get_filter( op, ber, (Filter **)&(op->o_assertion),
                &rs->sr_text);
+       (void) ber_free( ber, 1 );
        if( rs->sr_err != LDAP_SUCCESS ) {
                if( rs->sr_err == SLAPD_DISCONNECT ) {
                        rs->sr_err = LDAP_PROTOCOL_ERROR;
@@ -1208,32 +1211,41 @@ static int parsePreRead (
                return LDAP_PROTOCOL_ERROR;
        }
 
+#ifdef LDAP_X_TXN
+       if ( op->o_txnSpec ) { /* temporary limitation */
+               rs->sr_text = "cannot perform pre-read in transaction";
+               return LDAP_UNWILLING_TO_PERFORM;
+       }
+#endif
+
        ber = ber_init( &(ctrl->ldctl_value) );
        if (ber == NULL) {
                rs->sr_text = "preread control: internal error";
                return LDAP_OTHER;
        }
 
+       rs->sr_err = LDAP_SUCCESS;
+
        siz = sizeof( AttributeName );
        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;
+               rs->sr_err = LDAP_PROTOCOL_ERROR;
+               goto done;
        }
 
        for( i=0; i<siz; i++ ) {
-               int             rc = LDAP_SUCCESS;
                const char      *dummy = NULL;
 
                an[i].an_desc = NULL;
                an[i].an_oc = NULL;
                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_err = slap_bv2ad( &an[i].an_name, &an[i].an_desc, &dummy );
+               if ( rs->sr_err != LDAP_SUCCESS && ctrl->ldctl_iscritical ) {
                        rs->sr_text = dummy
                                ? dummy
                                : "postread control: unknown attributeType";
-                       return rc;
+                       goto done;
                }
        }
 
@@ -1243,8 +1255,9 @@ static int parsePreRead (
 
        op->o_preread_attrs = an;
 
-       rs->sr_err = LDAP_SUCCESS;
-       return LDAP_SUCCESS;
+done:
+       (void) ber_free( ber, 1 );
+       return rs->sr_err;
 }
 
 static int parsePostRead (
@@ -1266,32 +1279,40 @@ static int parsePostRead (
                return LDAP_PROTOCOL_ERROR;
        }
 
+#ifdef LDAP_X_TXN
+       if ( op->o_txnSpec ) { /* temporary limitation */
+               rs->sr_text = "cannot perform post-read in transaction";
+               return LDAP_UNWILLING_TO_PERFORM;
+       }
+#endif
+
        ber = ber_init( &(ctrl->ldctl_value) );
        if (ber == NULL) {
                rs->sr_text = "postread control: internal error";
                return LDAP_OTHER;
        }
 
+       rs->sr_err = LDAP_SUCCESS;
        siz = sizeof( AttributeName );
        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;
+               rs->sr_err = LDAP_PROTOCOL_ERROR;
+               goto done;
        }
 
        for( i=0; i<siz; i++ ) {
-               int             rc = LDAP_SUCCESS;
                const char      *dummy = NULL;
 
                an[i].an_desc = NULL;
                an[i].an_oc = NULL;
                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_err = slap_bv2ad( &an[i].an_name, &an[i].an_desc, &dummy );
+               if ( rs->sr_err != LDAP_SUCCESS && ctrl->ldctl_iscritical ) {
                        rs->sr_text = dummy
                                ? dummy
                                : "postread control: unknown attributeType";
-                       return rc;
+                       goto done;
                }
        }
 
@@ -1301,8 +1322,9 @@ static int parsePostRead (
 
        op->o_postread_attrs = an;
 
-       rs->sr_err = LDAP_SUCCESS;
-       return LDAP_SUCCESS;
+done:
+       (void) ber_free( ber, 1 );
+       return rs->sr_err;
 }
 
 static int parseValuesReturnFilter (
@@ -1332,6 +1354,8 @@ static int parseValuesReturnFilter (
        rs->sr_err = get_vrFilter( op, ber,
                (ValuesReturnFilter **)&(op->o_vrFilter), &rs->sr_text);
 
+       (void) ber_free( ber, 1 );
+
        if( rs->sr_err != LDAP_SUCCESS ) {
                if( rs->sr_err == SLAPD_DISCONNECT ) {
                        rs->sr_err = LDAP_PROTOCOL_ERROR;
@@ -1478,13 +1502,14 @@ static int parseSearchOptions (
                return LDAP_OTHER;
        }
 
-       if ( (tag = ber_scanf( ber, "{i}", &search_flags )) == LBER_ERROR ) {
+       tag = ber_scanf( ber, "{i}", &search_flags );
+       (void) ber_free( ber, 1 );
+
+       if ( tag == 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_CONTROL_NONE ) {
                        rs->sr_text = "searchOptions control specified multiple times "