.\" Copyright 1998-2007 The OpenLDAP Foundation All Rights Reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
.SH NAME
-ldap_create_control, ldap_find_control, ldap_control_free, ldap_controls_free \- LDAP control manipulation routines
+ldap_control_create, ldap_control_find, ldap_control_dup,
+ldap_controls_dup, ldap_control_free, ldap_controls_free
+\- LDAP control manipulation routines
.SH LIBRARY
OpenLDAP LDAP (libldap, -lldap)
.SH SYNOPSIS
.B #include <ldap.h>
.LP
-.BI "int ldap_create_control(LDAP_CONST char *" OID ", BerElement *" ber ", int " iscritical ", LDAPControl **" ctrlp ");"
+.BI "int ldap_control_create(const char *" oid ", int " iscritical ", struct berval *" value ", int " dupval ", LDAPControl **" ctrlp ");"
.LP
-.BI "LDAPControl *ldap_find_control(LDAP_CONST char *" OID ", LDAPControl **" ctrls ");"
+.BI "LDAPControl *ldap_control_find( const char *" oid ", LDAPControl **" ctrls ", LDAPControl ***" nextctrlp ");"
+.LP
+.BI "LDAPControl *ldap_control_dup(LDAPControl *" ctrl ");"
+.LP
+.BI "LDAPControl **ldap_controls_dup(LDAPControl **" ctrls ");"
.LP
.BI "void ldap_control_free(LDAPControl *" ctrl ");"
.LP
.BI "void ldap_controls_free(LDAPControl **" ctrls ");"
.SH DESCRIPTION
These routines are used to manipulate structures used for LDAP controls.
-.BR ldap_create_control ()
+
+.BR ldap_control_create ()
creates a control with the specified
.I OID
using the contents of the
-.I ber
-parameter for the control value, if any. The
+.I value
+parameter for the control value, if any. The content of
+.I value
+is duplicated if
+.I dupval
+is non-zero. The
.I iscritical
-parameter should be non-zero for a critical control. The created control
+parameter must be non-zero for a critical control. The created control
is returned in the
.I ctrlp
-parameter. The routine returns
+parameter. The routine returns
.B LDAP_SUCCESS
on success or some other error code on failure.
-.BR ldap_find_control ()
-searches the
+The content of
+.IR value ,
+for supported control types, can be prepared using helpers provided
+by this implementation of libldap, usually in the form
+.BR "ldap_create_<control name>_control_value" ().
+Otherwise, it can be BER-encoded using the functionalities of liblber.
+
+.BR ldap_control_find ()
+searches the NULL-terminated
.I ctrls
array for a control whose OID matches the
-.I OID
-parameter. The routine returns a pointer to the control if found,
+.I oid
+parameter. The routine returns a pointer to the control if found,
NULL otherwise.
+If the parameter
+.I nextctrlp
+is not NULL, on return it will point to the next control
+in the array, and can be passed to the
+.BR ldap_control_find ()
+routine for subsequent calls, to find further occurrences of the same
+control type.
+The use of this function is discouraged; the recommended way of handling
+controls in responses consists in going through the array of controls,
+dealing with each of them in the returned order, since it could matter.
+
+.BR ldap_control_dup ()
+duplicates an individual control structure, and
+.BR ldap_controls_dup ()
+duplicates a NULL-terminated array of controls.
+
.BR ldap_control_free ()
frees an individual control structure, and
.BR ldap_controls_free ()
-frees an array of controls.
+frees a NULL-terminated array of controls.
+
.SH SEE ALSO
.BR ldap (3),
.BR ldap_error (3)
-ldap_create_control.3
-ldap_find_control.3
+ldap_control_create.3
+ldap_control_find.3
+ldap_control_dup.3
+ldap_controls_dup.3
ldap_control_free.3
ldap_controls_free.3
/*
* in controls.c:
*/
+#if LDAP_DEPRECATED
LDAP_F( int )
-ldap_create_control LDAP_P((
+ldap_create_control LDAP_P(( /* deprecated, use ldap_control_create */
LDAP_CONST char *requestOID,
BerElement *ber,
int iscritical,
LDAPControl **ctrlp ));
LDAP_F( LDAPControl * )
-ldap_find_control LDAP_P((
+ldap_find_control LDAP_P(( /* deprecated, use ldap_control_find */
LDAP_CONST char *oid,
LDAPControl **ctrls ));
+#endif
+
+LDAP_F( int )
+ldap_control_create LDAP_P((
+ LDAP_CONST char *requestOID,
+ int iscritical,
+ struct berval *value,
+ int dupval,
+ LDAPControl **ctrlp ));
+
+LDAP_F( LDAPControl * )
+ldap_control_find LDAP_P((
+ LDAP_CONST char *oid,
+ LDAPControl **ctrls,
+ LDAPControl ***nextctrlp ));
LDAP_F( void )
ldap_control_free LDAP_P((
ldap_controls_free LDAP_P((
LDAPControl **ctrls ));
+LDAP_F( LDAPControl ** )
+ldap_controls_dup LDAP_P((
+ LDAPControl *LDAP_CONST *controls ));
+
+LDAP_F( LDAPControl * )
+ldap_control_dup LDAP_P((
+ LDAP_CONST LDAPControl *c ));
+
/*
* in dnssrv.c:
*/
return new;
}
-
+/*
+ * Find a LDAPControl - deprecated
+ */
LDAPControl *
ldap_find_control(
LDAP_CONST char *oid,
}
/*
- ldap_create_control
-
- 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.
----*/
+ * Find a LDAPControl
+ */
+LDAPControl *
+ldap_control_find(
+ LDAP_CONST char *oid,
+ LDAPControl **ctrls,
+ LDAPControl ***nextctrlp )
+{
+ if ( oid == NULL || ctrls == NULL || *ctrls == NULL ) {
+ return NULL;
+ }
+
+ for( ; *ctrls != NULL; ctrls++ ) {
+ if( strcmp( (*ctrls)->ldctl_oid, oid ) == 0 ) {
+ if ( nextctrlp != NULL ) {
+ *nextctrlp = ctrls + 1;
+ }
+
+ return *ctrls;
+ }
+ }
+
+ if ( nextctrlp != NULL ) {
+ *nextctrlp = NULL;
+ }
+
+ return NULL;
+}
+/*
+ * Create a LDAPControl, optionally from ber - deprecated
+ */
int
ldap_create_control(
LDAP_CONST char *requestOID,
return LDAP_NO_MEMORY;
}
- BER_BVZERO(&ctrl->ldctl_value);
+ BER_BVZERO(&ctrl->ldctl_value);
if ( ber && ( ber_flatten2( ber, &ctrl->ldctl_value, 1 ) == -1 )) {
LDAP_FREE( ctrl );
return LDAP_NO_MEMORY;
return LDAP_SUCCESS;
}
+/*
+ * Create a LDAPControl, optionally from value
+ */
+int
+ldap_control_create(
+ LDAP_CONST char *requestOID,
+ int iscritical,
+ struct berval *value,
+ int dupval,
+ LDAPControl **ctrlp )
+{
+ LDAPControl *ctrl;
+
+ assert( requestOID != NULL );
+ assert( ctrlp != NULL );
+
+ ctrl = (LDAPControl *) LDAP_CALLOC( sizeof(LDAPControl), 1 );
+ if ( ctrl == NULL ) {
+ return LDAP_NO_MEMORY;
+ }
+
+ ctrl->ldctl_iscritical = iscritical;
+ if ( requestOID != NULL ) {
+ ctrl->ldctl_oid = LDAP_STRDUP( requestOID );
+ if ( ctrl->ldctl_oid == NULL ) {
+ ldap_control_free( ctrl );
+ return LDAP_NO_MEMORY;
+ }
+ }
+
+ if ( value && !BER_BVISNULL( value ) ) {
+ if ( dupval ) {
+ ber_dupbv( &ctrl->ldctl_value, value );
+ if ( BER_BVISNULL( &ctrl->ldctl_value ) ) {
+ ldap_control_free( ctrl );
+ return LDAP_NO_MEMORY;
+ }
+
+ } else {
+ ctrl->ldctl_value = *value;
+ }
+ }
+
+ *ctrlp = ctrl;
+
+ return LDAP_SUCCESS;
+}
+
/*
* check for critical client controls and bitch if present
* if we ever support critical controls, we'll have to
LDAPControl **ctrlp )
{
struct berval value;
- BerElement *ber;
if ( ctrlp == NULL ) {
ld->ld_errno = LDAP_PARAM_ERROR;
ld->ld_errno = ldap_create_page_control_value( ld,
pagesize, cookie, &value );
if ( ld->ld_errno == LDAP_SUCCESS ) {
- if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
- ld->ld_errno = LDAP_NO_MEMORY;
- return LDAP_NO_MEMORY;
- }
-
- ld->ld_errno = ldap_create_control( LDAP_CONTROL_PAGEDRESULTS,
- ber, iscritical, ctrlp );
- if ( ld->ld_errno == LDAP_SUCCESS ) {
- (*ctrlp)->ldctl_value = value;
- } else {
+ ld->ld_errno = ldap_control_create( LDAP_CONTROL_PAGEDRESULTS,
+ iscritical, &value, 0, ctrlp );
+ if ( ld->ld_errno != LDAP_SUCCESS ) {
LDAP_FREE( value.bv_val );
}
- ber_free(ber, 1);
}
return ld->ld_errno;
return ld->ld_errno;
}
- c = ldap_find_control( LDAP_CONTROL_PAGEDRESULTS, ctrls );
+ c = ldap_control_find( LDAP_CONTROL_PAGEDRESULTS, ctrls, NULL );
if ( c == NULL ) {
/* No page control was found. */
ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
assert( LDAP_VALID( ld ) );
assert( ctrlp != NULL );
- ld->ld_errno = ldap_create_control( LDAP_CONTROL_PASSWORDPOLICYREQUEST,
- NULL, 0, ctrlp);
+ ld->ld_errno = ldap_control_create( LDAP_CONTROL_PASSWORDPOLICYREQUEST,
+ 0, NULL, 0, ctrlp );
- return(ld->ld_errno);
+ return ld->ld_errno;
}
ld (IN) An LDAP session handle.
ctrl (IN) The address of an
- LDAPControl structure, typically obtained
- by a call to ldap_find_control().
+ LDAPControl structure, either obtained
+ by running thorugh the list of response controls or
+ by a call to ldap_control_find().
exptimep (OUT) This result parameter is filled in with the number of seconds before
the password will expire, if expiration is imminent
LDAPControl **ctrlp )
{
struct berval value;
- BerElement *ber;
assert( ld != NULL );
assert( LDAP_VALID( ld ) );
- if ( ld == NULL ) return LDAP_PARAM_ERROR;
+ if ( ld == NULL ) {
+ return LDAP_PARAM_ERROR;
+ }
+
if ( ctrlp == NULL ) {
ld->ld_errno = LDAP_PARAM_ERROR;
return ld->ld_errno;
ld->ld_errno = ldap_create_sort_control_value( ld, keyList, &value );
if ( ld->ld_errno == LDAP_SUCCESS ) {
- if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
- ld->ld_errno = LDAP_NO_MEMORY;
- return LDAP_NO_MEMORY;
- }
-
- ld->ld_errno = ldap_create_control( LDAP_CONTROL_SORTREQUEST,
- ber, isCritical, ctrlp );
- if ( ld->ld_errno == LDAP_SUCCESS ) {
- (*ctrlp)->ldctl_value = value;
- } else {
+ ld->ld_errno = ldap_control_create( LDAP_CONTROL_SORTREQUEST,
+ isCritical, &value, 0, ctrlp );
+ if ( ld->ld_errno != LDAP_SUCCESS ) {
LDAP_FREE( value.bv_val );
}
- ber_free(ber, 1);
}
return ld->ld_errno;
LDAPControl **ctrlp )
{
struct berval value;
- BerElement *ber;
if ( ctrlp == NULL ) {
ld->ld_errno = LDAP_PARAM_ERROR;
sessionSourceIp, sessionSourceName, formatOID,
sessionTrackingIdentifier, &value );
if ( ld->ld_errno == LDAP_SUCCESS ) {
- ld->ld_errno = ldap_create_control( LDAP_CONTROL_X_SESSION_TRACKING,
- NULL, 0, ctrlp );
- if ( ld->ld_errno == LDAP_SUCCESS ) {
- (*ctrlp)->ldctl_value = value;
-
- } else {
+ ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_SESSION_TRACKING,
+ 0, &value, 0, ctrlp );
+ if ( ld->ld_errno != LDAP_SUCCESS ) {
LDAP_FREE( value.bv_val );
}
}
LDAPControl **ctrlp )
{
struct berval value;
- BerElement *ber;
if ( ctrlp == NULL ) {
ld->ld_errno = LDAP_PARAM_ERROR;
ld->ld_errno = ldap_create_vlv_control_value( ld, vlvinfop, &value );
if ( ld->ld_errno == LDAP_SUCCESS ) {
- if ((ber = ldap_alloc_ber_with_options(ld)) == NULL) {
- ld->ld_errno = LDAP_NO_MEMORY;
- return LDAP_NO_MEMORY;
- }
- ld->ld_errno = ldap_create_control( LDAP_CONTROL_VLVREQUEST,
- ber, 1, ctrlp );
- if ( ld->ld_errno == LDAP_SUCCESS ) {
- (*ctrlp)->ldctl_value = value;
- } else {
+ ld->ld_errno = ldap_control_create( LDAP_CONTROL_VLVREQUEST,
+ 1, &value, 0, ctrlp );
+ if ( ld->ld_errno != LDAP_SUCCESS ) {
LDAP_FREE( value.bv_val );
}
- ber_free(ber, 1);
}
return ld->ld_errno;
/* we can't work without the control */
rctrlp = NULL;
if ( rctrls ) {
+ LDAPControl **next;
/* NOTE: make sure we use the right one;
* a better approach would be to run thru
* the whole list and take care of all */
- rctrlp = ldap_find_control( LDAP_CONTROL_SYNC_STATE, rctrls );
+ rctrlp = ldap_control_find( LDAP_CONTROL_SYNC_STATE, rctrls, &next );
+ if ( next && ldap_control_find( LDAP_CONTROL_SYNC_STATE, next, NULL ) )
+ {
+ Debug( LDAP_DEBUG_ANY, "do_syncrep2: %s "
+ "got search entry with multiple "
+ "Sync State control\n", si->si_ridtxt, 0, 0 );
+ rc = -1;
+ goto done;
+ }
}
if ( rctrlp == NULL ) {
Debug( LDAP_DEBUG_ANY, "do_syncrep2: %s "