X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fcontrols.c;h=ea2ecba0ec2edea11f055924a6459c27ad792789;hb=eb6b2650091656bde96fbbdb87a5b8154cdc319b;hp=5d9d73f4123a509b18a9a05c52ed01f33c8f3b79;hpb=8788a2af3663988d71c57b6c0e39622299b823fc;p=openldap diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index 5d9d73f412..ea2ecba0ec 100644 --- a/servers/slapd/controls.c +++ b/servers/slapd/controls.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2006 The OpenLDAP Foundation. + * Copyright 1998-2007 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,27 +25,24 @@ #include "../../libraries/liblber/lber-int.h" static SLAP_CTRL_PARSE_FN parseAssert; -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 parseDomainScope; static SLAP_CTRL_PARSE_FN parseDontUseCopy; -static SLAP_CTRL_PARSE_FN parseManageDIT; -#endif static SLAP_CTRL_PARSE_FN parseManageDSAit; static SLAP_CTRL_PARSE_FN parseNoOp; static SLAP_CTRL_PARSE_FN parsePagedResults; -#ifdef LDAP_DEVEL +static SLAP_CTRL_PARSE_FN parsePermissiveModify; +static SLAP_CTRL_PARSE_FN parsePreRead, parsePostRead; +static SLAP_CTRL_PARSE_FN parseProxyAuthz; +static SLAP_CTRL_PARSE_FN parseRelax; +static SLAP_CTRL_PARSE_FN parseSearchOptions; +#ifdef SLAP_SORTEDRESULTS 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; +static SLAP_CTRL_PARSE_FN parseSubentries; #ifdef SLAP_CONTROL_X_TREE_DELETE static SLAP_CTRL_PARSE_FN parseTreeDelete; #endif -static SLAP_CTRL_PARSE_FN parseSearchOptions; -static SLAP_CTRL_PARSE_FN parseSubentries; +static SLAP_CTRL_PARSE_FN parseValuesReturnFilter; #undef sc_mask /* avoid conflict with Irix 6.5 */ @@ -133,7 +130,7 @@ static struct slap_control control_defs[] = { SLAP_CTRL_SEARCH, NULL, NULL, parsePagedResults, LDAP_SLIST_ENTRY_INITIALIZER(next) }, -#ifdef LDAP_DEVEL +#ifdef SLAP_SORTEDRESULTS { LDAP_CONTROL_SORTREQUEST, (int)offsetof(struct slap_control_ids, sc_sortedResults), SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE, @@ -145,6 +142,11 @@ static struct slap_control control_defs[] = { SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE, NULL, NULL, parseDomainScope, LDAP_SLIST_ENTRY_INITIALIZER(next) }, + { LDAP_CONTROL_DONTUSECOPY, + (int)offsetof(struct slap_control_ids, sc_dontUseCopy), + SLAP_CTRL_GLOBAL|SLAP_CTRL_INTROGATE|SLAP_CTRL_HIDE, + NULL, NULL, + parseDontUseCopy, LDAP_SLIST_ENTRY_INITIALIZER(next) }, { LDAP_CONTROL_X_PERMISSIVE_MODIFY, (int)offsetof(struct slap_control_ids, sc_permissiveModify), SLAP_CTRL_MODIFY|SLAP_CTRL_HIDE, @@ -172,18 +174,11 @@ static struct slap_control control_defs[] = { 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), + { LDAP_CONTROL_RELAX, + (int)offsetof(struct slap_control_ids, sc_relax), SLAP_CTRL_GLOBAL|SLAP_CTRL_UPDATE|SLAP_CTRL_HIDE, NULL, NULL, - parseManageDIT, LDAP_SLIST_ENTRY_INITIALIZER(next) }, -#endif + parseRelax, LDAP_SLIST_ENTRY_INITIALIZER(next) }, #ifdef LDAP_X_TXN { LDAP_CONTROL_X_TXN_SPEC, (int)offsetof(struct slap_control_ids, sc_txnSpec), @@ -420,7 +415,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 +487,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; } @@ -842,7 +839,6 @@ slap_remove_control( return rs->sr_err; } -#ifdef LDAP_DEVEL static int parseDontUseCopy ( Operation *op, SlapReply *rs, @@ -853,12 +849,12 @@ static int parseDontUseCopy ( return LDAP_PROTOCOL_ERROR; } - if ( ctrl->ldctl_value.bv_len ) { - rs->sr_text = "dontUseCopy control value not empty"; + if ( !BER_BVISNULL( &ctrl->ldctl_value )) { + rs->sr_text = "dontUseCopy control value not absent"; return LDAP_PROTOCOL_ERROR; } - if ( ctrl->ldctl_iscritical != SLAP_CONTROL_CRITICAL ) { + if ( !ctrl->ldctl_iscritical ) { rs->sr_text = "dontUseCopy criticality of FALSE not allowed"; return LDAP_PROTOCOL_ERROR; } @@ -867,28 +863,27 @@ static int parseDontUseCopy ( return LDAP_SUCCESS; } -static int parseManageDIT ( +static int parseRelax ( Operation *op, SlapReply *rs, LDAPControl *ctrl ) { - if ( op->o_managedit != SLAP_CONTROL_NONE ) { - rs->sr_text = "manageDIT control specified multiple times"; + if ( op->o_relax != SLAP_CONTROL_NONE ) { + rs->sr_text = "relax control specified multiple times"; return LDAP_PROTOCOL_ERROR; } - if ( ctrl->ldctl_value.bv_len ) { - rs->sr_text = "manageDIT control value not empty"; + if ( !BER_BVISNULL( &ctrl->ldctl_value )) { + rs->sr_text = "relax control value not absent"; return LDAP_PROTOCOL_ERROR; } - op->o_managedit = ctrl->ldctl_iscritical + op->o_relax = ctrl->ldctl_iscritical ? SLAP_CONTROL_CRITICAL : SLAP_CONTROL_NONCRITICAL; return LDAP_SUCCESS; } -#endif static int parseManageDSAit ( Operation *op, @@ -900,8 +895,8 @@ static int parseManageDSAit ( return LDAP_PROTOCOL_ERROR; } - if ( ctrl->ldctl_value.bv_len ) { - rs->sr_text = "manageDSAit control value not empty"; + if ( !BER_BVISNULL( &ctrl->ldctl_value )) { + rs->sr_text = "manageDSAit control value not absent"; return LDAP_PROTOCOL_ERROR; } @@ -925,6 +920,11 @@ static int parseProxyAuthz ( return LDAP_PROTOCOL_ERROR; } + if ( BER_BVISNULL( &ctrl->ldctl_value )) { + rs->sr_text = "proxy authorization control value absent"; + return LDAP_PROTOCOL_ERROR; + } + if ( !( global_allows & SLAP_ALLOW_PROXY_AUTHZ_ANON ) && BER_BVISEMPTY( &op->o_ndn ) ) { @@ -942,7 +942,7 @@ static int parseProxyAuthz ( ctrl->ldctl_value.bv_len ? ctrl->ldctl_value.bv_val : "anonymous", 0 ); - if ( ctrl->ldctl_value.bv_len == 0 ) { + if ( BER_BVISEMPTY( &ctrl->ldctl_value )) { Debug( LDAP_DEBUG_TRACE, "parseProxyAuthz: conn=%lu anonymous\n", op->o_connid, 0, 0 ); @@ -996,7 +996,6 @@ static int parseProxyAuthz ( 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 ); @@ -1042,8 +1041,13 @@ static int parsePagedResults ( return LDAP_PROTOCOL_ERROR; } + if ( BER_BVISNULL( &ctrl->ldctl_value ) ) { + rs->sr_text = "paged results control value is absent"; + return LDAP_PROTOCOL_ERROR; + } + if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ) { - rs->sr_text = "paged results control value is empty (or absent)"; + rs->sr_text = "paged results control value is empty"; return LDAP_PROTOCOL_ERROR; } @@ -1105,7 +1109,7 @@ done:; return rc; } -#ifdef LDAP_DEVEL +#ifdef SLAP_SORTEDRESULTS static int parseSortedResults ( Operation *op, SlapReply *rs, @@ -1118,8 +1122,13 @@ static int parseSortedResults ( return LDAP_PROTOCOL_ERROR; } + if ( BER_BVISNULL( &ctrl->ldctl_value ) ) { + rs->sr_text = "sorted results control value is absent"; + return LDAP_PROTOCOL_ERROR; + } + if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ) { - rs->sr_text = "sorted results control value is empty (or absent)"; + rs->sr_text = "sorted results control value is empty"; return LDAP_PROTOCOL_ERROR; } @@ -1146,8 +1155,13 @@ static int parseAssert ( return LDAP_PROTOCOL_ERROR; } - if ( ctrl->ldctl_value.bv_len == 0 ) { - rs->sr_text = "assert control value is empty (or absent)"; + if ( BER_BVISNULL( &ctrl->ldctl_value )) { + rs->sr_text = "assert control value is absent"; + return LDAP_PROTOCOL_ERROR; + } + + if ( BER_BVISEMPTY( &ctrl->ldctl_value )) { + rs->sr_text = "assert control value is empty"; return LDAP_PROTOCOL_ERROR; } @@ -1159,6 +1173,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; @@ -1203,15 +1218,22 @@ static int parsePreRead ( return LDAP_PROTOCOL_ERROR; } - if ( ctrl->ldctl_value.bv_len == 0 ) { - rs->sr_text = "preread control value is empty (or absent)"; + if ( BER_BVISNULL( &ctrl->ldctl_value )) { + rs->sr_text = "preread control value is absent"; return LDAP_PROTOCOL_ERROR; } + if ( BER_BVISEMPTY( &ctrl->ldctl_value )) { + rs->sr_text = "preread control value is empty"; + 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) { @@ -1219,26 +1241,28 @@ static int parsePreRead ( 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; ildctl_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; } } @@ -1248,8 +1272,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,15 +1291,22 @@ static int parsePostRead ( return LDAP_PROTOCOL_ERROR; } - if ( ctrl->ldctl_value.bv_len == 0 ) { - rs->sr_text = "postread control value is empty (or absent)"; + if ( BER_BVISNULL( &ctrl->ldctl_value )) { + rs->sr_text = "postread control value is absent"; return LDAP_PROTOCOL_ERROR; } + if ( BER_BVISEMPTY( &ctrl->ldctl_value )) { + rs->sr_text = "postread control value is empty"; + 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) { @@ -1282,26 +1314,46 @@ static int parsePostRead ( 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; ildctl_iscritical ) { - rs->sr_text = dummy - ? dummy - : "postread control: unknown attributeType"; - return rc; + if ( rc != LDAP_SUCCESS ) { + int i; + static struct berval special_attrs[] = { + BER_BVC( LDAP_NO_ATTRS ), + BER_BVC( LDAP_ALL_USER_ATTRIBUTES ), + BER_BVC( LDAP_ALL_OPERATIONAL_ATTRIBUTES ), + BER_BVNULL + }; + + /* deal with special attribute types */ + for ( i = 0; !BER_BVISNULL( &special_attrs[ i ] ); i++ ) { + if ( bvmatch( &an[i].an_name, &special_attrs[ i ] ) ) { + break; + } + } + + if ( BER_BVISNULL( &special_attrs[ i ] ) && ctrl->ldctl_iscritical ) { + rs->sr_err = rc; + rs->sr_text = dummy + ? dummy + : "postread control: unknown attributeType"; + goto done; + } } } @@ -1311,8 +1363,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 ( @@ -1328,8 +1381,13 @@ static int parseValuesReturnFilter ( return LDAP_PROTOCOL_ERROR; } - if ( ctrl->ldctl_value.bv_len == 0 ) { - rs->sr_text = "valuesReturnFilter control value is empty (or absent)"; + if ( BER_BVISNULL( &ctrl->ldctl_value )) { + rs->sr_text = "valuesReturnFilter control value is absent"; + return LDAP_PROTOCOL_ERROR; + } + + if ( BER_BVISEMPTY( &ctrl->ldctl_value )) { + rs->sr_text = "valuesReturnFilter control value is empty"; return LDAP_PROTOCOL_ERROR; } @@ -1342,6 +1400,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; @@ -1410,8 +1470,8 @@ static int parsePermissiveModify ( return LDAP_PROTOCOL_ERROR; } - if ( ctrl->ldctl_value.bv_len ) { - rs->sr_text = "permissiveModify control value not empty"; + if ( BER_BVISNULL( &ctrl->ldctl_value )) { + rs->sr_text = "permissiveModify control value not absent"; return LDAP_PROTOCOL_ERROR; } @@ -1432,7 +1492,7 @@ static int parseDomainScope ( return LDAP_PROTOCOL_ERROR; } - if ( ctrl->ldctl_value.bv_len ) { + if ( BER_BVISNULL( &ctrl->ldctl_value )) { rs->sr_text = "domainScope control value not empty"; return LDAP_PROTOCOL_ERROR; } @@ -1455,8 +1515,8 @@ static int parseTreeDelete ( return LDAP_PROTOCOL_ERROR; } - if ( ctrl->ldctl_value.bv_len ) { - rs->sr_text = "treeDelete control value not empty"; + if ( BER_BVISNULL( &ctrl->ldctl_value )) { + rs->sr_text = "treeDelete control value not absent"; return LDAP_PROTOCOL_ERROR; } @@ -1477,8 +1537,13 @@ static int parseSearchOptions ( ber_int_t search_flags; ber_tag_t tag; - if ( ctrl->ldctl_value.bv_len == 0 ) { - rs->sr_text = "searchOptions control value is empty (or absent)"; + if ( BER_BVISNULL( &ctrl->ldctl_value )) { + rs->sr_text = "searchOptions control value is absent"; + return LDAP_PROTOCOL_ERROR; + } + + if ( BER_BVISEMPTY( &ctrl->ldctl_value )) { + rs->sr_text = "searchOptions control value is empty"; return LDAP_PROTOCOL_ERROR; } @@ -1488,13 +1553,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 "