X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fcontrols.c;h=7c26ff1c38fb4876cf072298de6dfbda2dcc92e7;hb=27cb98d28d60b1f258ea12852b22bfdfec6380f6;hp=3450172de731121279228db648140f0235a03fcc;hpb=132506e13c858d29a002d520246c1e6b1496ded4;p=openldap diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index 3450172de7..7c26ff1c38 100644 --- a/servers/slapd/controls.c +++ b/servers/slapd/controls.c @@ -50,6 +50,10 @@ 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 { @@ -82,6 +86,11 @@ static struct slap_control { SLAP_CTRL_SEARCH, NULL, parseValuesReturnFilter }, #endif +#ifdef LDAP_CLIENT_UPDATE + { LDAP_CONTROL_CLIENT_UPDATE, + SLAP_CTRL_SEARCH, NULL, + parseClientUpdate }, +#endif /* LDAP_CLIENT_UPDATE */ { NULL } }; @@ -595,3 +604,127 @@ int parseValuesReturnFilter ( 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 */