1999-09-09 03:06:24 +08:00
|
|
|
/* $OpenLDAP$ */
|
2003-11-26 15:16:36 +08:00
|
|
|
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
|
|
|
*
|
2007-01-03 04:00:42 +08:00
|
|
|
* Copyright 1998-2007 The OpenLDAP Foundation.
|
2003-11-26 15:16:36 +08:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted only as authorized by the OpenLDAP
|
|
|
|
* Public License.
|
|
|
|
*
|
|
|
|
* A copy of this license is available in the file LICENSE in the
|
|
|
|
* top-level directory of the distribution or, alternatively, at
|
|
|
|
* <http://www.OpenLDAP.org/license.html>.
|
1998-12-29 04:53:15 +08:00
|
|
|
*/
|
2003-11-26 15:16:36 +08:00
|
|
|
/* This notice applies to changes, created by or for Novell, Inc.,
|
|
|
|
* to preexisting works for which notices appear elsewhere in this file.
|
|
|
|
*
|
|
|
|
* Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
|
|
|
|
* USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO VERSION
|
|
|
|
* 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS AVAILABLE AT
|
|
|
|
* HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE" IN THE
|
|
|
|
* TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION OF THIS
|
|
|
|
* WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP PUBLIC
|
|
|
|
* LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT THE
|
|
|
|
* PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
|
|
|
|
*---
|
|
|
|
* Note: A verbatim copy of version 2.0.1 of the OpenLDAP Public License
|
|
|
|
* can be found in the file "build/LICENSE-2.0.1" in this distribution
|
|
|
|
* of OpenLDAP Software.
|
|
|
|
*/
|
2006-10-28 03:37:04 +08:00
|
|
|
|
|
|
|
#include "portable.h"
|
|
|
|
|
|
|
|
#include <ac/stdlib.h>
|
|
|
|
|
|
|
|
#include <ac/time.h>
|
|
|
|
#include <ac/string.h>
|
|
|
|
|
|
|
|
#include "ldap-int.h"
|
1999-06-04 03:22:33 +08:00
|
|
|
|
2006-06-15 13:18:06 +08:00
|
|
|
/* LDAPv3 Controls (RFC 4511)
|
1999-06-04 03:22:33 +08:00
|
|
|
*
|
2006-06-15 13:18:06 +08:00
|
|
|
* Controls ::= SEQUENCE OF control Control
|
1999-06-04 03:22:33 +08:00
|
|
|
*
|
|
|
|
* Control ::= SEQUENCE {
|
|
|
|
* controlType LDAPOID,
|
|
|
|
* criticality BOOLEAN DEFAULT FALSE,
|
|
|
|
* controlValue OCTET STRING OPTIONAL
|
|
|
|
* }
|
1998-12-23 10:31:35 +08:00
|
|
|
*/
|
|
|
|
|
1999-05-19 09:12:33 +08:00
|
|
|
/*
|
|
|
|
* ldap_int_put_controls
|
|
|
|
*/
|
|
|
|
|
1999-07-13 13:13:33 +08:00
|
|
|
int
|
|
|
|
ldap_int_put_controls(
|
1999-05-19 09:12:33 +08:00
|
|
|
LDAP *ld,
|
1999-07-13 13:13:33 +08:00
|
|
|
LDAPControl *const *ctrls,
|
1999-05-19 09:12:33 +08:00
|
|
|
BerElement *ber )
|
|
|
|
{
|
1999-07-13 13:13:33 +08:00
|
|
|
LDAPControl *const *c;
|
1999-05-19 09:12:33 +08:00
|
|
|
|
|
|
|
assert( ld != NULL );
|
2005-12-13 23:53:10 +08:00
|
|
|
assert( LDAP_VALID( ld ) );
|
1999-05-19 09:12:33 +08:00
|
|
|
assert( ber != NULL );
|
|
|
|
|
|
|
|
if( ctrls == NULL ) {
|
|
|
|
/* use default server controls */
|
|
|
|
ctrls = ld->ld_sctrls;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( ctrls == NULL || *ctrls == NULL ) {
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ld->ld_version < LDAP_VERSION3 ) {
|
|
|
|
/* LDAPv2 doesn't support controls,
|
|
|
|
* error if any control is critical
|
|
|
|
*/
|
|
|
|
for( c = ctrls ; *c != NULL; c++ ) {
|
|
|
|
if( (*c)->ldctl_iscritical ) {
|
|
|
|
ld->ld_errno = LDAP_NOT_SUPPORTED;
|
|
|
|
return ld->ld_errno;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Controls are encoded as a sequence of sequences */
|
1999-06-19 07:53:05 +08:00
|
|
|
if( ber_printf( ber, "t{"/*}*/, LDAP_TAG_CONTROLS ) == -1 ) {
|
1999-05-19 09:12:33 +08:00
|
|
|
ld->ld_errno = LDAP_ENCODING_ERROR;
|
|
|
|
return ld->ld_errno;
|
|
|
|
}
|
|
|
|
|
|
|
|
for( c = ctrls ; *c != NULL; c++ ) {
|
1999-06-19 07:53:05 +08:00
|
|
|
if ( ber_printf( ber, "{s" /*}*/,
|
1999-05-19 09:12:33 +08:00
|
|
|
(*c)->ldctl_oid ) == -1 )
|
|
|
|
{
|
|
|
|
ld->ld_errno = LDAP_ENCODING_ERROR;
|
|
|
|
return ld->ld_errno;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( (*c)->ldctl_iscritical /* only if true */
|
|
|
|
&& ( ber_printf( ber, "b",
|
1999-06-19 07:53:05 +08:00
|
|
|
(ber_int_t) (*c)->ldctl_iscritical ) == -1 ) )
|
1999-05-19 09:12:33 +08:00
|
|
|
{
|
|
|
|
ld->ld_errno = LDAP_ENCODING_ERROR;
|
|
|
|
return ld->ld_errno;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( (*c)->ldctl_value.bv_val != NULL /* only if we have a value */
|
|
|
|
&& ( ber_printf( ber, "O",
|
|
|
|
&((*c)->ldctl_value) ) == -1 ) )
|
|
|
|
{
|
|
|
|
ld->ld_errno = LDAP_ENCODING_ERROR;
|
|
|
|
return ld->ld_errno;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-24 09:40:39 +08:00
|
|
|
if( ber_printf( ber, /*{*/"N}" ) == -1 ) {
|
1999-05-19 09:12:33 +08:00
|
|
|
ld->ld_errno = LDAP_ENCODING_ERROR;
|
|
|
|
return ld->ld_errno;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-24 09:40:39 +08:00
|
|
|
if( ber_printf( ber, /*{*/ "}" ) == -1 ) {
|
1999-05-19 09:12:33 +08:00
|
|
|
ld->ld_errno = LDAP_ENCODING_ERROR;
|
|
|
|
return ld->ld_errno;
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2003-10-12 16:14:28 +08:00
|
|
|
int ldap_pvt_get_controls(
|
1999-05-28 10:15:57 +08:00
|
|
|
BerElement *ber,
|
1999-06-17 01:11:14 +08:00
|
|
|
LDAPControl ***ctrls )
|
1999-05-19 09:12:33 +08:00
|
|
|
{
|
1999-05-28 10:15:57 +08:00
|
|
|
int nctrls;
|
1999-06-19 07:53:05 +08:00
|
|
|
ber_tag_t tag;
|
|
|
|
ber_len_t len;
|
1999-05-28 10:15:57 +08:00
|
|
|
char *opaque;
|
|
|
|
|
|
|
|
assert( ber != NULL );
|
1999-05-19 09:12:33 +08:00
|
|
|
|
1999-06-29 06:47:20 +08:00
|
|
|
if( ctrls == NULL ) {
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
1999-05-28 10:15:57 +08:00
|
|
|
*ctrls = NULL;
|
|
|
|
|
2000-09-15 13:56:37 +08:00
|
|
|
len = ber_pvt_ber_remaining( ber );
|
1999-05-28 10:15:57 +08:00
|
|
|
|
|
|
|
if( len == 0) {
|
|
|
|
/* no controls */
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
|
|
|
|
if( tag == LBER_ERROR ) {
|
|
|
|
/* decoding error */
|
|
|
|
return LDAP_DECODING_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ignore unexpected input */
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set through each element */
|
|
|
|
nctrls = 0;
|
1999-05-29 09:19:14 +08:00
|
|
|
*ctrls = LDAP_MALLOC( 1 * sizeof(LDAPControl *) );
|
1999-05-28 10:15:57 +08:00
|
|
|
|
|
|
|
if( *ctrls == NULL ) {
|
|
|
|
return LDAP_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
1999-12-03 08:21:32 +08:00
|
|
|
*ctrls[nctrls] = NULL;
|
1999-05-28 10:15:57 +08:00
|
|
|
|
|
|
|
for( tag = ber_first_element( ber, &len, &opaque );
|
1999-05-28 11:24:41 +08:00
|
|
|
tag != LBER_ERROR;
|
1999-05-28 10:15:57 +08:00
|
|
|
tag = ber_next_element( ber, &len, opaque ) )
|
|
|
|
{
|
|
|
|
LDAPControl *tctrl;
|
|
|
|
LDAPControl **tctrls;
|
|
|
|
|
1999-05-29 09:19:14 +08:00
|
|
|
tctrl = LDAP_CALLOC( 1, sizeof(LDAPControl) );
|
1999-05-28 10:15:57 +08:00
|
|
|
|
|
|
|
/* allocate pointer space for current controls (nctrls)
|
|
|
|
* + this control + extra NULL
|
|
|
|
*/
|
|
|
|
tctrls = (tctrl == NULL) ? NULL :
|
1999-05-29 09:19:14 +08:00
|
|
|
LDAP_REALLOC(*ctrls, (nctrls+2) * sizeof(LDAPControl *));
|
1999-05-28 10:15:57 +08:00
|
|
|
|
|
|
|
if( tctrls == NULL ) {
|
|
|
|
/* one of the above allocation failed */
|
|
|
|
|
|
|
|
if( tctrl != NULL ) {
|
1999-05-29 09:19:14 +08:00
|
|
|
LDAP_FREE( tctrl );
|
1999-05-28 10:15:57 +08:00
|
|
|
}
|
1999-05-19 09:12:33 +08:00
|
|
|
|
1999-05-28 10:15:57 +08:00
|
|
|
ldap_controls_free(*ctrls);
|
|
|
|
*ctrls = NULL;
|
|
|
|
|
|
|
|
return LDAP_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
tctrls[nctrls++] = tctrl;
|
|
|
|
tctrls[nctrls] = NULL;
|
|
|
|
|
1999-06-19 07:53:05 +08:00
|
|
|
tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid );
|
1999-05-28 10:15:57 +08:00
|
|
|
|
2002-10-08 03:58:10 +08:00
|
|
|
if( tag == LBER_ERROR ) {
|
|
|
|
*ctrls = NULL;
|
|
|
|
ldap_controls_free( tctrls );
|
|
|
|
return LDAP_DECODING_ERROR;
|
1999-05-28 10:15:57 +08:00
|
|
|
}
|
|
|
|
|
2002-10-08 03:58:10 +08:00
|
|
|
tag = ber_peek_tag( ber, &len );
|
|
|
|
|
1999-05-28 10:15:57 +08:00
|
|
|
if( tag == LBER_BOOLEAN ) {
|
1999-06-19 07:53:05 +08:00
|
|
|
ber_int_t crit;
|
|
|
|
tag = ber_scanf( ber, "b", &crit );
|
|
|
|
tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0;
|
1999-05-28 10:15:57 +08:00
|
|
|
tag = ber_peek_tag( ber, &len );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( tag == LBER_OCTETSTRING ) {
|
|
|
|
tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
|
|
|
|
} else {
|
2007-08-21 18:52:16 +08:00
|
|
|
BER_BVZERO( &tctrl->ldctl_value );
|
1999-05-28 10:15:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
*ctrls = tctrls;
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
1999-05-19 09:12:33 +08:00
|
|
|
}
|
|
|
|
|
1998-12-23 10:31:35 +08:00
|
|
|
/*
|
|
|
|
* Free a LDAPControl
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
ldap_control_free( LDAPControl *c )
|
|
|
|
{
|
2007-07-25 04:53:23 +08:00
|
|
|
LDAP_MEMORY_DEBUG_ASSERT( c != NULL );
|
1999-06-06 04:18:32 +08:00
|
|
|
|
1998-12-23 10:31:35 +08:00
|
|
|
if ( c != NULL ) {
|
|
|
|
if( c->ldctl_oid != NULL) {
|
1999-05-29 09:19:14 +08:00
|
|
|
LDAP_FREE( c->ldctl_oid );
|
1998-12-23 10:31:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if( c->ldctl_value.bv_val != NULL ) {
|
1999-05-29 09:19:14 +08:00
|
|
|
LDAP_FREE( c->ldctl_value.bv_val );
|
1998-12-23 10:31:35 +08:00
|
|
|
}
|
|
|
|
|
1999-05-29 09:19:14 +08:00
|
|
|
LDAP_FREE( c );
|
1998-12-23 10:31:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Free an array of LDAPControl's
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
ldap_controls_free( LDAPControl **controls )
|
|
|
|
{
|
2007-07-25 04:53:23 +08:00
|
|
|
LDAP_MEMORY_DEBUG_ASSERT( controls != NULL );
|
1999-06-06 04:18:32 +08:00
|
|
|
|
1998-12-23 10:31:35 +08:00
|
|
|
if ( controls != NULL ) {
|
1999-07-22 12:47:58 +08:00
|
|
|
int i;
|
1998-12-23 10:31:35 +08:00
|
|
|
|
1999-07-22 12:47:58 +08:00
|
|
|
for( i=0; controls[i] != NULL; i++) {
|
|
|
|
ldap_control_free( controls[i] );
|
1998-12-23 10:31:35 +08:00
|
|
|
}
|
|
|
|
|
1999-05-29 09:19:14 +08:00
|
|
|
LDAP_FREE( controls );
|
1998-12-23 10:31:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Duplicate an array of LDAPControl
|
|
|
|
*/
|
1999-07-13 13:13:33 +08:00
|
|
|
LDAPControl **
|
|
|
|
ldap_controls_dup( LDAPControl *const *controls )
|
1998-12-23 10:31:35 +08:00
|
|
|
{
|
|
|
|
LDAPControl **new;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if ( controls == NULL ) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* count the controls */
|
|
|
|
for(i=0; controls[i] != NULL; i++) /* empty */ ;
|
|
|
|
|
|
|
|
if( i < 1 ) {
|
|
|
|
/* no controls to duplicate */
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2002-06-22 03:14:37 +08:00
|
|
|
new = (LDAPControl **) LDAP_MALLOC( (i+1) * sizeof(LDAPControl *) );
|
1998-12-23 10:31:35 +08:00
|
|
|
|
|
|
|
if( new == NULL ) {
|
|
|
|
/* memory allocation failure */
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* duplicate the controls */
|
|
|
|
for(i=0; controls[i] != NULL; i++) {
|
|
|
|
new[i] = ldap_control_dup( controls[i] );
|
|
|
|
|
|
|
|
if( new[i] == NULL ) {
|
|
|
|
ldap_controls_free( new );
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
new[i] = NULL;
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Duplicate a LDAPControl
|
|
|
|
*/
|
1999-07-13 13:13:33 +08:00
|
|
|
LDAPControl *
|
|
|
|
ldap_control_dup( const LDAPControl *c )
|
1998-12-23 10:31:35 +08:00
|
|
|
{
|
|
|
|
LDAPControl *new;
|
|
|
|
|
|
|
|
if ( c == NULL ) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
1999-05-29 09:19:14 +08:00
|
|
|
new = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
|
1998-12-23 10:31:35 +08:00
|
|
|
|
|
|
|
if( new == NULL ) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( c->ldctl_oid != NULL ) {
|
1999-06-03 06:28:22 +08:00
|
|
|
new->ldctl_oid = LDAP_STRDUP( c->ldctl_oid );
|
1998-12-23 10:31:35 +08:00
|
|
|
|
|
|
|
if(new->ldctl_oid == NULL) {
|
1999-05-29 09:19:14 +08:00
|
|
|
LDAP_FREE( new );
|
1998-12-23 10:31:35 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
2007-08-21 18:52:16 +08:00
|
|
|
/* FIXME: how can a control have null OID? */
|
1998-12-23 10:31:35 +08:00
|
|
|
new->ldctl_oid = NULL;
|
|
|
|
}
|
|
|
|
|
2000-10-14 10:13:53 +08:00
|
|
|
if( c->ldctl_value.bv_val != NULL ) {
|
|
|
|
new->ldctl_value.bv_val =
|
|
|
|
(char *) LDAP_MALLOC( c->ldctl_value.bv_len + 1 );
|
1998-12-23 10:31:35 +08:00
|
|
|
|
|
|
|
if(new->ldctl_value.bv_val == NULL) {
|
|
|
|
if(new->ldctl_oid != NULL) {
|
1999-05-29 09:19:14 +08:00
|
|
|
LDAP_FREE( new->ldctl_oid );
|
1998-12-23 10:31:35 +08:00
|
|
|
}
|
1999-05-29 09:19:14 +08:00
|
|
|
LDAP_FREE( new );
|
1998-12-23 10:31:35 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2000-10-14 10:13:53 +08:00
|
|
|
new->ldctl_value.bv_len = c->ldctl_value.bv_len;
|
|
|
|
|
2000-07-28 09:07:07 +08:00
|
|
|
AC_MEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val,
|
1998-12-23 10:31:35 +08:00
|
|
|
c->ldctl_value.bv_len );
|
|
|
|
|
2000-10-14 10:13:53 +08:00
|
|
|
new->ldctl_value.bv_val[new->ldctl_value.bv_len] = '\0';
|
1998-12-23 10:31:35 +08:00
|
|
|
|
|
|
|
} else {
|
|
|
|
new->ldctl_value.bv_len = 0;
|
|
|
|
new->ldctl_value.bv_val = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
new->ldctl_iscritical = c->ldctl_iscritical;
|
|
|
|
return new;
|
1999-05-28 10:15:57 +08:00
|
|
|
}
|
2000-06-08 03:39:49 +08:00
|
|
|
|
2004-03-14 08:57:44 +08:00
|
|
|
|
|
|
|
LDAPControl *
|
|
|
|
ldap_find_control(
|
|
|
|
LDAP_CONST char *oid,
|
|
|
|
LDAPControl **ctrls )
|
|
|
|
{
|
|
|
|
if( ctrls == NULL || *ctrls == NULL ) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
for( ; *ctrls != NULL; ctrls++ ) {
|
|
|
|
if( strcmp( (*ctrls)->ldctl_oid, oid ) == 0 ) {
|
|
|
|
return *ctrls;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2000-06-08 03:39:49 +08:00
|
|
|
/*
|
2000-07-23 01:29:54 +08:00
|
|
|
ldap_create_control
|
2000-06-08 03:39:49 +08:00
|
|
|
|
|
|
|
Internal function to create an LDAP control from the encoded BerElement.
|
|
|
|
|
|
|
|
requestOID (IN) The OID to use in creating the control.
|
|
|
|
|
|
|
|
ber (IN) The encoded BerElement to use in creating the control.
|
|
|
|
|
|
|
|
iscritical (IN) 0 - Indicates the control is not critical to the operation.
|
|
|
|
non-zero - The control is critical to the operation.
|
|
|
|
|
|
|
|
ctrlp (OUT) Returns a pointer to the LDAPControl created. This control
|
|
|
|
SHOULD be freed by calling ldap_control_free() when done.
|
|
|
|
---*/
|
|
|
|
|
2000-06-19 03:48:07 +08:00
|
|
|
int
|
2000-07-23 01:29:54 +08:00
|
|
|
ldap_create_control(
|
|
|
|
LDAP_CONST char *requestOID,
|
2000-06-08 03:39:49 +08:00
|
|
|
BerElement *ber,
|
|
|
|
int iscritical,
|
|
|
|
LDAPControl **ctrlp )
|
|
|
|
{
|
|
|
|
LDAPControl *ctrl;
|
|
|
|
|
2002-06-05 23:46:26 +08:00
|
|
|
assert( requestOID != NULL );
|
|
|
|
assert( ctrlp != NULL );
|
2000-06-08 03:39:49 +08:00
|
|
|
|
2000-07-23 01:29:54 +08:00
|
|
|
ctrl = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
|
|
|
|
if ( ctrl == NULL ) {
|
2000-06-08 03:39:49 +08:00
|
|
|
return LDAP_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
2007-08-23 03:33:28 +08:00
|
|
|
BER_BVZERO(&ctrl->ldctl_value);
|
2007-08-23 03:26:55 +08:00
|
|
|
if ( ber && ( ber_flatten2( ber, &ctrl->ldctl_value, 1 ) == -1 )) {
|
2000-07-23 01:29:54 +08:00
|
|
|
LDAP_FREE( ctrl );
|
2000-06-08 03:39:49 +08:00
|
|
|
return LDAP_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctrl->ldctl_oid = LDAP_STRDUP( requestOID );
|
|
|
|
ctrl->ldctl_iscritical = iscritical;
|
|
|
|
|
2000-07-23 01:29:54 +08:00
|
|
|
if ( requestOID != NULL && ctrl->ldctl_oid == NULL ) {
|
|
|
|
ldap_control_free( ctrl );
|
2000-06-08 03:39:49 +08:00
|
|
|
return LDAP_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
*ctrlp = ctrl;
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
2001-07-06 11:13:42 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* check for critical client controls and bitch if present
|
|
|
|
* if we ever support critical controls, we'll have to
|
|
|
|
* find a means for maintaining per API call control
|
|
|
|
* information.
|
|
|
|
*/
|
|
|
|
int ldap_int_client_controls( LDAP *ld, LDAPControl **ctrls )
|
|
|
|
{
|
|
|
|
LDAPControl *const *c;
|
|
|
|
|
|
|
|
assert( ld != NULL );
|
2005-12-13 23:53:10 +08:00
|
|
|
assert( LDAP_VALID( ld ) );
|
2001-07-06 11:13:42 +08:00
|
|
|
|
|
|
|
if( ctrls == NULL ) {
|
|
|
|
/* use default server controls */
|
|
|
|
ctrls = ld->ld_cctrls;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( ctrls == NULL || *ctrls == NULL ) {
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
for( c = ctrls ; *c != NULL; c++ ) {
|
|
|
|
if( (*c)->ldctl_iscritical ) {
|
|
|
|
ld->ld_errno = LDAP_NOT_SUPPORTED;
|
|
|
|
return ld->ld_errno;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return LDAP_SUCCESS;
|
|
|
|
}
|