/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1998-2004 The OpenLDAP Foundation.
+ * Copyright 1998-2005 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
if (( sc->sc_mask & tagmask ) == tagmask ) {
/* available extension */
+ int rc;
if( !sc->sc_parse ) {
rs->sr_err = LDAP_OTHER;
goto return_results;
}
- rs->sr_err = sc->sc_parse( op, rs, c );
- assert( rs->sr_err != LDAP_UNAVAILABLE_CRITICAL_EXTENSION );
- if( rs->sr_err != LDAP_SUCCESS ) goto return_results;
+ rc = sc->sc_parse( op, rs, c );
+ assert( rc != LDAP_UNAVAILABLE_CRITICAL_EXTENSION );
+ if ( rc ) {
+ rs->sr_err = rc;
+ goto return_results;
+ }
if ( sc->sc_mask & SLAP_CTRL_FRONTEND ) {
/* kludge to disable backend_control() check */
rs->sr_text = "critical extension is not recognized";
goto return_results;
}
+next_ctrl:;
}
return_results:
SlapReply *rs,
LDAPControl *ctrl )
{
- ber_tag_t tag;
- ber_int_t size;
- BerElement *ber;
- struct berval cookie = BER_BVNULL;
+ int rc = LDAP_SUCCESS;
+ ber_tag_t tag;
+ ber_int_t size;
+ BerElement *ber;
+ struct berval cookie = BER_BVNULL;
if ( op->o_pagedresults != SLAP_NO_CONTROL ) {
rs->sr_text = "paged results control specified multiple times";
}
tag = ber_scanf( ber, "{im}", &size, &cookie );
- (void) ber_free( ber, 1 );
if( tag == LBER_ERROR ) {
rs->sr_text = "paged results control could not be decoded";
- return LDAP_PROTOCOL_ERROR;
+ rc = LDAP_PROTOCOL_ERROR;
+ goto done;
}
if( size < 0 ) {
rs->sr_text = "paged results control size invalid";
- return LDAP_PROTOCOL_ERROR;
+ rc = LDAP_PROTOCOL_ERROR;
+ goto done;
}
if( cookie.bv_len ) {
if( cookie.bv_len != sizeof( reqcookie ) ) {
/* bad cookie */
rs->sr_text = "paged results cookie is invalid";
- return LDAP_PROTOCOL_ERROR;
+ 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";
- return LDAP_PROTOCOL_ERROR;
+ 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";
- return LDAP_UNWILLING_TO_PERFORM;
+ 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_id = NOID;
op->o_pagedresults_state.ps_count = 0;
}
op->o_pagedresults_size = size;
- op->o_pagedresults = ctrl->ldctl_iscritical
- ? SLAP_CRITICAL_CONTROL
- : SLAP_NONCRITICAL_CONTROL;
+ /* NOTE: according to RFC 2696 3.:
- return LDAP_SUCCESS;
+ If the page size is greater than or equal to the sizeLimit value, the
+ server should ignore the control as the request can be satisfied in a
+ single page.
+
+ * NOTE: this assumes that the op->ors_slimit be set
+ * before the controls are parsed.
+ */
+ if ( op->ors_slimit > 0 && size >= op->ors_slimit ) {
+ op->o_pagedresults = SLAP_IGNORED_CONTROL;
+
+ } else if ( ctrl->ldctl_iscritical ) {
+ op->o_pagedresults = SLAP_CRITICAL_CONTROL;
+
+ } else {
+ op->o_pagedresults = SLAP_NONCRITICAL_CONTROL;
+ }
+
+done:;
+ (void)ber_free( ber, 1 );
+ return rc;
}
static int parseAssert (
/* FIXME: should use BER library */
if( ( ctrl->ldctl_value.bv_len != 3 )
- && ( ctrl->ldctl_value.bv_val[0] != 0x01 )
- && ( ctrl->ldctl_value.bv_val[1] != 0x01 ))
+ || ( ctrl->ldctl_value.bv_val[0] != 0x01 )
+ || ( ctrl->ldctl_value.bv_val[1] != 0x01 ))
{
rs->sr_text = "subentries control value encoding is bogus";
return LDAP_PROTOCOL_ERROR;