X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fcontrols.c;h=280b4f14b0db6b47a1720cf9fc56539c807c42b7;hb=543c588772b22a029b60e72e45e68032935ecd54;hp=94d37d7a40e7a526ad37f195115cc03c14b0f8f0;hpb=7dec65ee109f296347b7e95a858ea52fe24da3e3;p=openldap diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index 94d37d7a40..280b4f14b0 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-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,12 +29,10 @@ 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; -#ifdef LDAP_CONTROL_MODIFY_INCREMENT -static SLAP_CTRL_PARSE_FN parseModifyIncrement; -#endif static SLAP_CTRL_PARSE_FN parseNoOp; static SLAP_CTRL_PARSE_FN parsePagedResults; #ifdef LDAP_DEVEL @@ -67,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,89 +97,102 @@ static int num_known_controls = 1; static char *proxy_authz_extops[] = { LDAP_EXOP_MODIFY_PASSWD, LDAP_EXOP_X_WHO_AM_I, + LDAP_EXOP_REFRESH, + NULL +}; + +static char *manageDSAit_extops[] = { + LDAP_EXOP_REFRESH, 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_CONTROL_MODIFY_INCREMENT - { LDAP_CONTROL_MODIFY_INCREMENT, - (int)offsetof(struct slap_control_ids, sc_modifyIncrement), - SLAP_CTRL_HIDE|SLAP_CTRL_MODIFY, NULL, - parseModifyIncrement, LDAP_SLIST_ENTRY_INITIALIZER(next) }, -#endif #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) } }; @@ -226,14 +238,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; @@ -282,8 +304,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 ); } @@ -484,11 +506,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; @@ -703,35 +725,100 @@ return_results: return rs->sr_err; } -#ifdef LDAP_CONTROL_MODIFY_INCREMENT -static int parseModifyIncrement ( +int +slap_remove_control( + Operation *op, + SlapReply *rs, + int ctrl, + BI_chk_controls fnc ) +{ + int i, j; + + 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 ) + { + j = i; + } + } + + if ( j == -1 ) { + rs->sr_err = LDAP_OTHER; + break; + } + + if ( fnc ) { + (void)fnc( op, rs ); + } + + op->o_tmpfree( op->o_ctrls[ j ], op->o_tmpmemctx ); + + if ( i > 1 ) { + AC_MEMCPY( &op->o_ctrls[ j ], &op->o_ctrls[ j + 1 ], + ( i - j ) * sizeof( LDAPControl * ) ); + + } else { + op->o_tmpfree( op->o_ctrls, op->o_tmpmemctx ); + op->o_ctrls = NULL; + } + + op->o_ctrlflag[ ctrl ] = SLAP_CONTROL_IGNORED; + + Debug( LDAP_DEBUG_ANY, "%s: " + "non-critical control \"%s\" not supported; stripped.\n", + op->o_log_prefix, slap_known_controls[ ctrl ], 0 ); + /* fall thru */ + + case SLAP_CONTROL_IGNORED: + case SLAP_CONTROL_NONE: + rs->sr_err = SLAP_CB_CONTINUE; + break; + + case SLAP_CONTROL_CRITICAL: + rs->sr_err = LDAP_UNAVAILABLE_CRITICAL_EXTENSION; + if ( fnc ) { + (void)fnc( op, rs ); + } + Debug( LDAP_DEBUG_ANY, "%s: " + "critical control \"%s\" not supported.\n", + op->o_log_prefix, slap_known_controls[ ctrl ], 0 ); + break; + + default: + /* handle all cases! */ + assert( 0 ); + } + + return rs->sr_err; +} + +#ifdef LDAP_DEVEL +static int parseDontUseCopy ( Operation *op, SlapReply *rs, LDAPControl *ctrl ) { -#if 0 - if ( op->o_modifyIncrement != SLAP_CONTROL_NONE ) { - rs->sr_text = "modifyIncrement control specified multiple times"; + if ( op->o_dontUseCopy != SLAP_CONTROL_NONE ) { + rs->sr_text = "dontUseCopy control specified multiple times"; return LDAP_PROTOCOL_ERROR; } -#endif if ( ctrl->ldctl_value.bv_len ) { - rs->sr_text = "modifyIncrement control value not empty"; + rs->sr_text = "dontUseCopy control value not empty"; return LDAP_PROTOCOL_ERROR; } -#if 0 - op->o_modifyIncrement = ctrl->ldctl_iscritical - ? SLAP_CONTROL_CRITICAL - : SLAP_CONTROL_NONCRITICAL; -#endif + 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; } -#endif -#ifdef LDAP_DEVEL static int parseManageDIT ( Operation *op, SlapReply *rs, @@ -929,48 +1016,6 @@ static int parsePagedResults ( goto done; } -#if 0 - /* defer cookie decoding/checks to backend... */ - if ( cookie.bv_len ) { - PagedResultsCookie reqcookie; - if( cookie.bv_len != sizeof( reqcookie ) ) { - /* bad cookie */ - rs->sr_text = "paged results cookie is invalid"; - rc = LDAP_PROTOCOL_ERROR; - goto done; - } - - AC_MEMCPY( &reqcookie, cookie.bv_val, sizeof( reqcookie )); - - if ( reqcookie > op->o_pagedresults_state.ps_cookie ) { - /* bad cookie */ - rs->sr_text = "paged results cookie is invalid"; - rc = LDAP_PROTOCOL_ERROR; - goto done; - - } else if ( reqcookie < op->o_pagedresults_state.ps_cookie ) { - rs->sr_text = "paged results cookie is invalid or old"; - rc = LDAP_UNWILLING_TO_PERFORM; - goto done; - } - - } else { - /* Initial request. Initialize state. */ -#if 0 - if ( op->o_conn->c_pagedresults_state.ps_cookie != 0 ) { - /* There's another pagedResults control on the - * same connection; reject new pagedResults controls - * (allowed by RFC2696) */ - rs->sr_text = "paged results cookie unavailable; try later"; - rc = LDAP_UNWILLING_TO_PERFORM; - goto done; - } -#endif - op->o_pagedresults_state.ps_cookie = 0; - op->o_pagedresults_state.ps_count = 0; - } -#endif - ps = op->o_tmpalloc( sizeof(PagedResultsState), op->o_tmpmemctx ); *ps = op->o_conn->c_pagedresults_state; ps->ps_size = size; @@ -1053,8 +1098,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; @@ -1225,7 +1270,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 ) { @@ -1255,7 +1301,6 @@ static int parseValuesReturnFilter ( return LDAP_SUCCESS; } -#ifdef LDAP_CONTROL_SUBENTRIES static int parseSubentries ( Operation *op, SlapReply *rs, @@ -1285,9 +1330,7 @@ static int parseSubentries ( return LDAP_SUCCESS; } -#endif -#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY static int parsePermissiveModify ( Operation *op, SlapReply *rs, @@ -1309,9 +1352,7 @@ static int parsePermissiveModify ( return LDAP_SUCCESS; } -#endif -#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE static int parseDomainScope ( Operation *op, SlapReply *rs, @@ -1333,7 +1374,6 @@ static int parseDomainScope ( return LDAP_SUCCESS; } -#endif #ifdef SLAP_CONTROL_X_TREE_DELETE static int parseTreeDelete ( @@ -1359,7 +1399,6 @@ static int parseTreeDelete ( } #endif -#ifdef LDAP_CONTROL_X_SEARCH_OPTIONS static int parseSearchOptions ( Operation *op, SlapReply *rs, @@ -1370,7 +1409,7 @@ static int parseSearchOptions ( ber_tag_t tag; if ( ctrl->ldctl_value.bv_len == 0 ) { - rs->sr_text = "searchOptions control value not empty"; + rs->sr_text = "searchOptions control value is empty (or absent)"; return LDAP_PROTOCOL_ERROR; } @@ -1404,11 +1443,10 @@ static int parseSearchOptions ( * including: * LDAP_SEARCH_FLAG_PHANTOM_ROOM */ - rs->sr_text = "searchOptions contained unrecongized flag"; + rs->sr_text = "searchOptions contained unrecognized flag"; return LDAP_UNWILLING_TO_PERFORM; } return LDAP_SUCCESS; } -#endif