X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fcontrols.c;h=7c26ff1c38fb4876cf072298de6dfbda2dcc92e7;hb=27cb98d28d60b1f258ea12852b22bfdfec6380f6;hp=b475dd1af44ef3789ebc49bfebbf9bf95934b67d;hpb=0be4d842bc2605d573d496d7485bdbe0ea66a31f;p=openldap diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index b475dd1af4..7c26ff1c38 100644 --- a/servers/slapd/controls.c +++ b/servers/slapd/controls.c @@ -19,18 +19,19 @@ #include "../../libraries/liblber/lber-int.h" -#define SLAP_CTRL_FRONTEND 0x80000000U - -#define SLAP_CTRL_OPFLAGS 0x0000FFFFU -#define SLAP_CTRL_ABANDON 0x00000001U -#define SLAP_CTRL_ADD 0x00002002U -#define SLAP_CTRL_BIND 0x00000004U -#define SLAP_CTRL_COMPARE 0x00001008U -#define SLAP_CTRL_DELETE 0x00002010U -#define SLAP_CTRL_MODIFY 0x00002020U -#define SLAP_CTRL_RENAME 0x00002040U -#define SLAP_CTRL_SEARCH 0x00001080U -#define SLAP_CTRL_UNBIND 0x00000100U +#define SLAP_CTRL_FRONTEND 0x80000000U +#define SLAP_CTRL_FRONTEND_SEARCH 0x01000000U /* for NOOP */ + +#define SLAP_CTRL_OPFLAGS 0x0000FFFFU +#define SLAP_CTRL_ABANDON 0x00000001U +#define SLAP_CTRL_ADD 0x00002002U +#define SLAP_CTRL_BIND 0x00000004U +#define SLAP_CTRL_COMPARE 0x00001008U +#define SLAP_CTRL_DELETE 0x00002010U +#define SLAP_CTRL_MODIFY 0x00002020U +#define SLAP_CTRL_RENAME 0x00002040U +#define SLAP_CTRL_SEARCH 0x00001080U +#define SLAP_CTRL_UNBIND 0x00000100U #define SLAP_CTRL_INTROGATE (SLAP_CTRL_COMPARE|SLAP_CTRL_SEARCH) #define SLAP_CTRL_UPDATE \ @@ -47,6 +48,13 @@ static SLAP_CTRL_PARSE_FN parseManageDSAit; static SLAP_CTRL_PARSE_FN parseSubentries; static SLAP_CTRL_PARSE_FN parseNoOp; static SLAP_CTRL_PARSE_FN parsePagedResults; +static SLAP_CTRL_PARSE_FN parseValuesReturnFilter; + +#ifdef LDAP_CLIENT_UPDATE +static SLAP_CTRL_PARSE_FN parseClientUpdate; +#endif /* LDAP_CLIENT_UPDATE */ + +#undef sc_mask /* avoid conflict with Irix 6.5 */ static struct slap_control { char *sc_oid; @@ -65,7 +73,7 @@ static struct slap_control { #endif #ifdef LDAP_CONTROL_NOOP { LDAP_CONTROL_NOOP, - SLAP_CTRL_UPDATE, NULL, + SLAP_CTRL_ACCESS, NULL, parseNoOp }, #endif #ifdef LDAP_CONTROL_PAGEDRESULTS_REQUEST @@ -73,6 +81,16 @@ static struct slap_control { SLAP_CTRL_SEARCH, NULL, parsePagedResults }, #endif +#ifdef LDAP_CONTROL_VALUESRETURNFILTER + { LDAP_CONTROL_VALUESRETURNFILTER, + SLAP_CTRL_SEARCH, NULL, + parseValuesReturnFilter }, +#endif +#ifdef LDAP_CLIENT_UPDATE + { LDAP_CONTROL_CLIENT_UPDATE, + SLAP_CTRL_SEARCH, NULL, + parseClientUpdate }, +#endif /* LDAP_CLIENT_UPDATE */ { NULL } }; @@ -126,8 +144,7 @@ int get_ctrls( } #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_ENTRY, - "get_ctrls: conn %lu\n", conn->c_connid )); + LDAP_LOG( OPERATION, ENTRY, "get_ctrls: conn %lu\n", conn->c_connid, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "=> get_ctrls\n", 0, 0, 0 ); #endif @@ -197,9 +214,8 @@ int get_ctrls( if( tag == LBER_ERROR ) { #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_INFO, - "get_ctrls: conn %lu get OID failed.\n", - conn->c_connid )); + LDAP_LOG( OPERATION, INFO, "get_ctrls: conn %lu get OID failed.\n", + conn->c_connid, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get oid failed.\n", 0, 0, 0 ); @@ -219,9 +235,9 @@ int get_ctrls( if( tag == LBER_ERROR ) { #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_INFO, - "get_ctrls: conn %lu get crit failed.\n", - conn->c_connid )); + LDAP_LOG( OPERATION, INFO, + "get_ctrls: conn %lu get crit failed.\n", + conn->c_connid, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: get crit failed.\n", 0, 0, 0 ); @@ -242,11 +258,10 @@ int get_ctrls( if( tag == LBER_ERROR ) { #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_INFO, "get_ctrls: conn %lu: " + LDAP_LOG( OPERATION, INFO, "get_ctrls: conn %lu: " "%s (%scritical): get value failed.\n", - conn->c_connid, - c->ldctl_oid ? c->ldctl_oid : "(NULL)", - c->ldctl_iscritical ? "" : "non" )); + conn->c_connid, c->ldctl_oid ? c->ldctl_oid : "(NULL)", + c->ldctl_iscritical ? "" : "non" ); #else Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: conn %lu: " "%s (%scritical): get value failed.\n", @@ -263,11 +278,10 @@ int get_ctrls( } #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_INFO, + LDAP_LOG( OPERATION, INFO, "get_ctrls: conn %lu oid=\"%s\" (%scritical)\n", - conn->c_connid, - c->ldctl_oid ? c->ldctl_oid : "(NULL)", - c->ldctl_iscritical ? "" : "non" )); + conn->c_connid, c->ldctl_oid ? c->ldctl_oid : "(NULL)", + c->ldctl_iscritical ? "" : "non" ); #else Debug( LDAP_DEBUG_TRACE, "=> get_ctrls: oid=\"%s\" (%scritical)\n", c->ldctl_oid ? c->ldctl_oid : "(NULL)", @@ -327,7 +341,13 @@ int get_ctrls( if( rc != LDAP_SUCCESS ) goto return_results; - if( sc->sc_mask & SLAP_CTRL_FRONTEND ) { + if ( sc->sc_mask & SLAP_CTRL_FRONTEND ) { + /* kludge to disable backend_control() check */ + c->ldctl_iscritical = 0; + + } else if ( tagmask == SLAP_CTRL_SEARCH && + sc->sc_mask & SLAP_CTRL_FRONTEND_SEARCH ) + { /* kludge to disable backend_control() check */ c->ldctl_iscritical = 0; } @@ -349,9 +369,8 @@ int get_ctrls( return_results: #ifdef NEW_LOGGING - LDAP_LOG(( "operation", LDAP_LEVEL_RESULTS, - "get_ctrls: conn=%lu n=%d rc=%d err=%s\n", - conn->c_connid, nctrls, rc, errmsg ? errmsg : "" )); + LDAP_LOG( OPERATION, RESULTS, + "get_ctrls: n=%d rc=%d err=%s\n", nctrls, rc, errmsg ? errmsg : "" ); #else Debug( LDAP_DEBUG_TRACE, "<= get_ctrls: n=%d rc=%d err=%s\n", nctrls, rc, errmsg ? errmsg : ""); @@ -527,3 +546,185 @@ static int parsePagedResults ( return LDAP_SUCCESS; } #endif + +#ifdef LDAP_CONTROL_VALUESRETURNFILTER +int parseValuesReturnFilter ( + Connection *conn, + Operation *op, + LDAPControl *ctrl, + const char **text ) +{ + int rc; + BerElement *ber; + struct berval fstr = { 0, NULL }; + const char *err_msg = ""; + + if ( op->o_valuesreturnfilter != SLAP_NO_CONTROL ) { + *text = "valuesreturnfilter control specified multiple times"; + return LDAP_PROTOCOL_ERROR; + } + + ber = ber_init( &(ctrl->ldctl_value) ); + if (ber == NULL) { + *text = "internal error"; + return LDAP_OTHER; + } + + rc = get_vrFilter( conn, ber, &(op->vrFilter), &err_msg); + + if( rc != LDAP_SUCCESS ) { + text = &err_msg; + if( rc == SLAPD_DISCONNECT ) { + send_ldap_disconnect( conn, op, + LDAP_PROTOCOL_ERROR, *text ); + } else { + send_ldap_result( conn, op, rc, + NULL, *text, NULL, NULL ); + } + if( fstr.bv_val != NULL) free( fstr.bv_val ); + if( op->vrFilter != NULL) vrFilter_free( op->vrFilter ); + + } else { + vrFilter2bv( op->vrFilter, &fstr ); + } + +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, ARGS, + "parseValuesReturnFilter: conn %d vrFilter: %s\n", + conn->c_connid, fstr.bv_len ? fstr.bv_val : "empty" , 0 ); +#else + Debug( LDAP_DEBUG_ARGS, " vrFilter: %s\n", + fstr.bv_len ? fstr.bv_val : "empty", 0, 0 ); +#endif + + op->o_valuesreturnfilter = ctrl->ldctl_iscritical + ? SLAP_CRITICAL_CONTROL + : SLAP_NONCRITICAL_CONTROL; + + return LDAP_SUCCESS; +} +#endif + +#ifdef LDAP_CLIENT_UPDATE +static int parseClientUpdate ( + Connection *conn, + Operation *op, + LDAPControl *ctrl, + const char **text ) +{ + ber_tag_t tag; + BerElement *ber; + ber_int_t type; + ber_int_t interval; + ber_len_t len; + struct berval scheme = { 0, NULL }; + struct berval cookie = { 0, NULL }; + + if ( op->o_clientupdate != SLAP_NO_CONTROL ) { + *text = "LCUP client update control specified multiple times"; + return LDAP_PROTOCOL_ERROR; + } + + if ( ctrl->ldctl_value.bv_len == 0 ) { + *text = "LCUP client update control value is empty"; + return LDAP_PROTOCOL_ERROR; + } + + /* Parse the control value + * ClientUpdateControlValue ::= SEQUENCE { + * updateType ENUMERATED { + * synchronizeOnly {0}, + * synchronizeAndPersist {1}, + * persistOnly {2} }, + * sendCookieInterval INTEGER OPTIONAL, + * cookie LCUPCookie OPTIONAL + * } + */ + + ber = ber_init( &ctrl->ldctl_value ); + if( ber == NULL ) { + *text = "internal error"; + return LDAP_OTHER; + } + + if ( (tag = ber_scanf( ber, "{i" /*}*/, &type )) == LBER_ERROR ) { + *text = "LCUP client update control : decoding error"; + return LDAP_PROTOCOL_ERROR; + } + + switch( type ) { + case LDAP_CUP_SYNC_ONLY: + type = SLAP_LCUP_SYNC; + break; + case LDAP_CUP_SYNC_AND_PERSIST: + type = SLAP_LCUP_SYNC_AND_PERSIST; + break; + case LDAP_CUP_PERSIST_ONLY: + type = SLAP_LCUP_PERSIST; + break; + default: + *text = "LCUP client update control : unknown update type"; + return LDAP_PROTOCOL_ERROR; + } + + if ( (tag = ber_peek_tag( ber, &len )) == LBER_DEFAULT ) { + *text = "LCUP client update control : decoding error"; + return LDAP_PROTOCOL_ERROR; + } + + if ( tag == LDAP_TAG_INTERVAL ) { + if ( (tag = ber_scanf( ber, "i", &interval )) == LBER_ERROR ) { + *text = "LCUP client update control : decoding error"; + return LDAP_PROTOCOL_ERROR; + } + + if ( interval <= 0 ) { + /* server chooses interval */ + interval = LDAP_CUP_DEFAULT_SEND_COOKIE_INTERVAL; + } + + } else { + /* server chooses interval */ + interval = LDAP_CUP_DEFAULT_SEND_COOKIE_INTERVAL; + } + + if ( (tag = ber_peek_tag( ber, &len )) == LBER_DEFAULT ) { + *text = "LCUP client update control : decoding error"; + return LDAP_PROTOCOL_ERROR; + } + + if ( tag == LDAP_TAG_COOKIE ) { + if ( (tag = ber_scanf( ber, /*{*/ "{mm}}", + &scheme, &cookie )) == LBER_ERROR ) { + *text = "LCUP client update control : decoding error"; + return LDAP_PROTOCOL_ERROR; + } + } + + /* TODO : Cookie Scheme Validation */ +#if 0 + if ( lcup_cookie_scheme_validate(scheme) != LDAP_SUCCESS ) { + *text = "Unsupported LCUP cookie scheme"; + return LCUP_UNSUPPORTED_SCHEME; + } + + if ( lcup_cookie_validate(scheme, cookie) != LDAP_SUCCESS ) { + *text = "Invalid LCUP cookie"; + return LCUP_INVALID_COOKIE; + } +#endif + + ber_dupbv( &op->o_clientupdate_state, &cookie ); + + (void) ber_free( ber, 1 ); + + op->o_clientupdate_type = (char) type; + op->o_clientupdate_interval = interval; + + op->o_clientupdate = ctrl->ldctl_iscritical + ? SLAP_CRITICAL_CONTROL + : SLAP_NONCRITICAL_CONTROL; + + return LDAP_SUCCESS; +} +#endif /* LDAP_CLIENT_UPDATE */