mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
152 lines
2.9 KiB
C
152 lines
2.9 KiB
C
/*
|
|
* Copyright 1999 The OpenLDAP Foundation.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms are permitted only
|
|
* as authorized by the OpenLDAP Public License. A copy of this
|
|
* license is available at http://www.OpenLDAP.org/license.html or
|
|
* in file LICENSE in the top-level directory of the distribution.
|
|
*/
|
|
#include "portable.h"
|
|
|
|
#include <stdio.h>
|
|
#include <ac/socket.h>
|
|
|
|
#include "slap.h"
|
|
|
|
#include "../../libraries/liblber/lber-int.h"
|
|
|
|
char *supportedControls[] = {
|
|
NULL
|
|
};
|
|
|
|
int get_ctrls(
|
|
Connection *conn,
|
|
Operation *op,
|
|
int sendres )
|
|
{
|
|
int nctrls;
|
|
ber_tag_t tag;
|
|
ber_len_t len;
|
|
char *opaque;
|
|
BerElement *ber = op->o_ber;
|
|
LDAPControl ***ctrls = &op->o_ctrls;
|
|
int rc = LDAP_SUCCESS;
|
|
|
|
len = ber_pvt_ber_remaining(ber);
|
|
|
|
if( len == 0) {
|
|
/* no controls */
|
|
rc = LDAP_SUCCESS;
|
|
goto return_results;
|
|
}
|
|
|
|
if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
|
|
if( tag == LBER_ERROR ) {
|
|
rc = LDAP_PROTOCOL_ERROR;
|
|
}
|
|
|
|
goto return_results;
|
|
}
|
|
|
|
if( op->o_protocol < LDAP_VERSION3 ) {
|
|
rc = LDAP_PROTOCOL_ERROR;
|
|
goto return_results;
|
|
}
|
|
|
|
/* set through each element */
|
|
nctrls = 0;
|
|
*ctrls = ch_malloc( 1 * sizeof(LDAPControl *) );
|
|
|
|
#if 0
|
|
if( *ctrls == NULL ) {
|
|
rc = LDAP_NO_MEMORY;
|
|
goto return_results;
|
|
}
|
|
#endif
|
|
|
|
ctrls[nctrls] = NULL;
|
|
|
|
for( tag = ber_first_element( ber, &len, &opaque );
|
|
tag != LBER_ERROR;
|
|
tag = ber_next_element( ber, &len, opaque ) )
|
|
{
|
|
LDAPControl *tctrl;
|
|
LDAPControl **tctrls;
|
|
|
|
tctrl = ch_calloc( 1, sizeof(LDAPControl) );
|
|
|
|
/* allocate pointer space for current controls (nctrls)
|
|
* + this control + extra NULL
|
|
*/
|
|
tctrls = (tctrl == NULL) ? NULL :
|
|
ch_realloc(*ctrls, (nctrls+2) * sizeof(LDAPControl *));
|
|
|
|
#if 0
|
|
if( tctrls == NULL ) {
|
|
/* one of the above allocation failed */
|
|
|
|
if( tctrl != NULL ) {
|
|
ch_free( tctrl );
|
|
}
|
|
|
|
ldap_controls_free(*ctrls);
|
|
*ctrls = NULL;
|
|
|
|
rc = LDAP_NO_MEMORY;
|
|
goto return_results;
|
|
}
|
|
#endif
|
|
|
|
|
|
tctrls[nctrls++] = tctrl;
|
|
tctrls[nctrls] = NULL;
|
|
|
|
tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid );
|
|
|
|
if( tag != LBER_ERROR ) {
|
|
tag = ber_peek_tag( ber, &len );
|
|
}
|
|
|
|
if( tag == LBER_BOOLEAN ) {
|
|
ber_int_t crit;
|
|
tag = ber_scanf( ber, "b", &crit );
|
|
tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0;
|
|
}
|
|
|
|
if( tag != LBER_ERROR ) {
|
|
tag = ber_peek_tag( ber, &len );
|
|
}
|
|
|
|
if( tag == LBER_OCTETSTRING ) {
|
|
tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
|
|
|
|
} else {
|
|
tctrl->ldctl_value.bv_val = NULL;
|
|
}
|
|
|
|
if( tag == LBER_ERROR ) {
|
|
*ctrls = NULL;
|
|
ldap_controls_free( tctrls );
|
|
rc = LDAP_DECODING_ERROR;
|
|
goto return_results;
|
|
}
|
|
|
|
if( tctrl->ldctl_iscritical &&
|
|
!charray_inlist( supportedControls, tctrl->ldctl_oid ) )
|
|
{
|
|
rc = LDAP_UNAVAILABLE_CRITICIAL_EXTENSION;
|
|
goto return_results;
|
|
}
|
|
|
|
*ctrls = tctrls;
|
|
}
|
|
|
|
return_results:
|
|
if( sendres && rc != LDAP_SUCCESS ) {
|
|
send_ldap_result( conn, op, rc, NULL, NULL );
|
|
}
|
|
|
|
return rc;
|
|
}
|