| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689 |
- /** BEGIN COPYRIGHT BLOCK
- * This Program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; version 2 of the License.
- *
- * This Program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * In addition, as a special exception, Red Hat, Inc. gives You the additional
- * right to link the code of this Program with code not covered under the GNU
- * General Public License ("Non-GPL Code") and to distribute linked combinations
- * including the two, subject to the limitations in this paragraph. Non-GPL Code
- * permitted under this exception must only link to the code of this Program
- * through those well defined interfaces identified in the file named EXCEPTION
- * found in the source code files (the "Approved Interfaces"). The files of
- * Non-GPL Code may instantiate templates or use macros or inline functions from
- * the Approved Interfaces without causing the resulting work to be covered by
- * the GNU General Public License. Only Red Hat, Inc. may make changes or
- * additions to the list of Approved Interfaces. You must obey the GNU General
- * Public License in all respects for all of the Program code and other code used
- * in conjunction with the Program except the Non-GPL Code covered by this
- * exception. If you modify this file, you may extend this exception to your
- * version of the file, but you are not obligated to do so. If you do not wish to
- * provide this exception without modification, you must delete this exception
- * statement from your version and license this file solely under the GPL without
- * exception.
- *
- *
- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- * END COPYRIGHT BLOCK **/
- #ifdef HAVE_CONFIG_H
- # include <config.h>
- #endif
- /* control.c - routines for dealing with LDAPMessage controls */
- #include <stdio.h>
- #include "slap.h"
- /*
- * static variables used to track information about supported controls.
- * supported_controls is a NULL-terminated array of OIDs.
- * supported_controls_ops is an array of bitmaps that hold SLAPI_OPERATION_*
- * flags that specify the operation(s) for which a control is supported.
- * The elements in the supported_controls_ops array align with the ones
- * in the supported_controls array.
- */
- static char **supported_controls = NULL;
- static unsigned long *supported_controls_ops = NULL;
- static int supported_controls_count = 0;
- static PRRWLock *supported_controls_lock = NULL;
- /*
- * Register all of the LDAPv3 controls we know about "out of the box."
- */
- void
- init_controls( void )
- {
- supported_controls_lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE,
- "supported controls rwlock");
- if (NULL == supported_controls_lock) {
- /* Out of resources */
- slapi_log_error(SLAPI_LOG_FATAL, "startup",
- "init_controls: failed to create lock.\n");
- exit (1);
- }
- slapi_register_supported_control( LDAP_CONTROL_MANAGEDSAIT,
- SLAPI_OPERATION_SEARCH | SLAPI_OPERATION_COMPARE
- | SLAPI_OPERATION_ADD | SLAPI_OPERATION_DELETE
- | SLAPI_OPERATION_MODIFY | SLAPI_OPERATION_MODDN );
- slapi_register_supported_control( LDAP_CONTROL_PERSISTENTSEARCH,
- SLAPI_OPERATION_SEARCH );
- slapi_register_supported_control( LDAP_CONTROL_PWEXPIRED,
- SLAPI_OPERATION_NONE );
- slapi_register_supported_control( LDAP_CONTROL_PWEXPIRING,
- SLAPI_OPERATION_NONE );
- slapi_register_supported_control( LDAP_CONTROL_SORTREQUEST,
- SLAPI_OPERATION_SEARCH );
- slapi_register_supported_control( LDAP_CONTROL_VLVREQUEST,
- SLAPI_OPERATION_SEARCH );
- slapi_register_supported_control( LDAP_CONTROL_AUTH_REQUEST,
- SLAPI_OPERATION_BIND );
- slapi_register_supported_control( LDAP_CONTROL_AUTH_RESPONSE,
- SLAPI_OPERATION_NONE );
- slapi_register_supported_control( LDAP_CONTROL_REAL_ATTRS_ONLY,
- SLAPI_OPERATION_SEARCH );
- slapi_register_supported_control( LDAP_CONTROL_VIRT_ATTRS_ONLY,
- SLAPI_OPERATION_SEARCH );
- slapi_register_supported_control( LDAP_X_CONTROL_PWPOLICY_REQUEST,
- SLAPI_OPERATION_SEARCH | SLAPI_OPERATION_COMPARE
- | SLAPI_OPERATION_ADD | SLAPI_OPERATION_DELETE
- | SLAPI_OPERATION_MODIFY | SLAPI_OPERATION_MODDN );
- /*
- We do not register the password policy response because it has
- the same oid as the request (and it was being reported twice in
- in the root DSE supportedControls attribute)
- slapi_register_supported_control( LDAP_X_CONTROL_PWPOLICY_RESPONSE,
- SLAPI_OPERATION_SEARCH | SLAPI_OPERATION_COMPARE
- | SLAPI_OPERATION_ADD | SLAPI_OPERATION_DELETE
- | SLAPI_OPERATION_MODIFY | SLAPI_OPERATION_MODDN );
- */
- slapi_register_supported_control( LDAP_CONTROL_GET_EFFECTIVE_RIGHTS,
- SLAPI_OPERATION_SEARCH );
- /* LDAP_CONTROL_PAGEDRESULTS is shared by request and response */
- slapi_register_supported_control( LDAP_CONTROL_PAGEDRESULTS,
- SLAPI_OPERATION_SEARCH );
- }
- /*
- * register a supported control so it can be returned as part of the root DSE.
- */
- void
- slapi_register_supported_control( char *controloid, unsigned long controlops )
- {
- if ( controloid != NULL ) {
- PR_RWLock_Wlock(supported_controls_lock);
- ++supported_controls_count;
- charray_add( &supported_controls, slapi_ch_strdup( controloid ));
- supported_controls_ops = (unsigned long *)slapi_ch_realloc(
- (char *)supported_controls_ops,
- supported_controls_count * sizeof( unsigned long ));
- supported_controls_ops[ supported_controls_count - 1 ] =
- controlops;
- PR_RWLock_Unlock(supported_controls_lock);
- }
- }
- /*
- * retrieve supported controls OID and/or operations arrays.
- * return 0 if successful and -1 if not.
- * This function is not MTSafe and should be deprecated.
- * slapi_get_supported_controls_copy should be used instead.
- */
- int
- slapi_get_supported_controls( char ***ctrloidsp, unsigned long **ctrlopsp )
- {
- if ( ctrloidsp != NULL ) {
- *ctrloidsp = supported_controls;
- }
- if ( ctrlopsp != NULL ) {
- *ctrlopsp = supported_controls_ops;
- }
- return( 0 );
- }
- static
- unsigned long *supported_controls_ops_dup(unsigned long *ctrlops)
- {
- int i;
- unsigned long *dup_ops = (unsigned long *)slapi_ch_calloc(
- supported_controls_count + 1, sizeof( unsigned long ));
- if (NULL != dup_ops) {
- for (i=0; i < supported_controls_count; i++)
- dup_ops[i] = supported_controls_ops[i];
- }
- return dup_ops;
- }
- int slapi_get_supported_controls_copy( char ***ctrloidsp, unsigned long **ctrlopsp )
- {
- PR_RWLock_Rlock(supported_controls_lock);
- if ( ctrloidsp != NULL ) {
- *ctrloidsp = charray_dup(supported_controls);
- }
- if ( ctrlopsp != NULL ) {
- *ctrlopsp = supported_controls_ops_dup(supported_controls_ops);
- }
- PR_RWLock_Unlock(supported_controls_lock);
- return (0);
- }
- /*
- * RFC 4511 section 4.1.11. Controls says that the UnbindRequest
- * MUST ignore the criticality field of controls
- */
- int
- get_ldapmessage_controls_ext(
- Slapi_PBlock *pb,
- BerElement *ber,
- LDAPControl ***controlsp, /* can be NULL if no need to return */
- int ignore_criticality /* some requests must ignore criticality */
- )
- {
- LDAPControl **ctrls, *new;
- ber_tag_t tag;
- ber_len_t len = -1;
- int rc, maxcontrols, curcontrols;
- char *last;
- int managedsait, pwpolicy_ctrl;
- /*
- * Each LDAPMessage can have a set of controls appended
- * to it. Controls are used to extend the functionality
- * of an LDAP operation (e.g., add an attribute size limit
- * to the search operation). These controls look like this:
- *
- * Controls ::= SEQUENCE OF Control
- *
- * Control ::= SEQUENCE {
- * controlType LDAPOID,
- * criticality BOOLEAN DEFAULT FALSE,
- * controlValue OCTET STRING
- * }
- */
- LDAPDebug( LDAP_DEBUG_TRACE, "=> get_ldapmessage_controls\n", 0, 0, 0 );
- ctrls = NULL;
- slapi_pblock_set( pb, SLAPI_REQCONTROLS, ctrls );
- if ( controlsp != NULL ) {
- *controlsp = NULL;
- }
- rc = LDAP_PROTOCOL_ERROR; /* most popular error we may return */
- /*
- * check to see if controls were included
- */
- if ( ber_get_option( ber, LBER_OPT_REMAINING_BYTES, &len ) != 0 ) {
- LDAPDebug( LDAP_DEBUG_TRACE,
- "<= get_ldapmessage_controls LDAP_OPERATIONS_ERROR\n",
- 0, 0, 0 );
- return( LDAP_OPERATIONS_ERROR ); /* unexpected error */
- }
- if ( len == 0 ) {
- LDAPDebug( LDAP_DEBUG_TRACE,
- "<= get_ldapmessage_controls no controls\n", 0, 0, 0 );
- return( LDAP_SUCCESS ); /* no controls */
- }
- if (( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
- if ( tag == LBER_ERROR ) {
- LDAPDebug( LDAP_DEBUG_TRACE,
- "<= get_ldapmessage_controls LDAP_PROTOCOL_ERROR\n",
- 0, 0, 0 );
- return( LDAP_PROTOCOL_ERROR ); /* decoding error */
- }
- /*
- * We found something other than controls. This should never
- * happen in LDAPv3, but we don't treat this is a hard error --
- * we just ignore the extra stuff.
- */
- LDAPDebug( LDAP_DEBUG_TRACE,
- "<= get_ldapmessage_controls ignoring unrecognized data in request (tag 0x%x)\n",
- tag, 0, 0 );
- return( LDAP_SUCCESS );
- }
- /*
- * A sequence of controls is present. If connection is not LDAPv3
- * or better, return a protocol error. Otherwise, parse the controls.
- */
- if ( pb != NULL && pb->pb_conn != NULL
- && pb->pb_conn->c_ldapversion < LDAP_VERSION3 ) {
- slapi_log_error( SLAPI_LOG_FATAL, "connection",
- "received control(s) on an LDAPv%d connection\n",
- pb->pb_conn->c_ldapversion );
- return( LDAP_PROTOCOL_ERROR );
- }
- maxcontrols = curcontrols = 0;
- for ( tag = ber_first_element( ber, &len, &last );
- tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET;
- tag = ber_next_element( ber, &len, last ) ) {
- len = -1; /* reset */
- if ( curcontrols >= maxcontrols - 1 ) {
- #define CONTROL_GRABSIZE 6
- maxcontrols += CONTROL_GRABSIZE;
- ctrls = (LDAPControl **) slapi_ch_realloc( (char *)ctrls,
- maxcontrols * sizeof(LDAPControl *) );
- }
- new = (LDAPControl *) slapi_ch_calloc( 1, sizeof(LDAPControl) );
- ctrls[curcontrols++] = new;
- ctrls[curcontrols] = NULL;
- if ( ber_scanf( ber, "{a", &new->ldctl_oid ) == LBER_ERROR ) {
- goto free_and_return;
- }
- /* the criticality is optional */
- if ( ber_peek_tag( ber, &len ) == LBER_BOOLEAN ) {
- if ( ber_scanf( ber, "b", &new->ldctl_iscritical )
- == LBER_ERROR ) {
- goto free_and_return;
- }
- } else {
- /* absent is synonomous with FALSE */
- new->ldctl_iscritical = 0;
- }
- len = -1; /* reset */
- /* if we are ignoring criticality, treat as FALSE */
- if (ignore_criticality) {
- new->ldctl_iscritical = 0;
- }
- /*
- * return an appropriate error if this control is marked
- * critical and either:
- * a) we do not support it at all OR
- * b) it is not supported for this operation
- */
- if ( new->ldctl_iscritical ) {
- int i;
- PR_RWLock_Rlock(supported_controls_lock);
- for ( i = 0; supported_controls != NULL
- && supported_controls[i] != NULL; ++i ) {
- if ( strcmp( supported_controls[i],
- new->ldctl_oid ) == 0 ) {
- break;
- }
- }
- if ( supported_controls == NULL ||
- supported_controls[i] == NULL ||
- ( 0 == ( supported_controls_ops[i] &
- operation_get_type(pb->pb_op) ))) {
- rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
- PR_RWLock_Unlock(supported_controls_lock);
- goto free_and_return;
- }
- PR_RWLock_Unlock(supported_controls_lock);
- }
- /* the control value is optional */
- if ( ber_peek_tag( ber, &len ) == LBER_OCTETSTRING ) {
- if ( ber_scanf( ber, "o", &new->ldctl_value )
- == LBER_ERROR ) {
- goto free_and_return;
- }
- } else {
- (new->ldctl_value).bv_val = NULL;
- (new->ldctl_value).bv_len = 0;
- }
- len = -1; /* reset for next loop iter */
- }
- if ( (tag != LBER_END_OF_SEQORSET) && (len != -1) ) {
- goto free_and_return;
- }
- slapi_pblock_set( pb, SLAPI_REQCONTROLS, ctrls );
- managedsait = slapi_control_present( ctrls,
- LDAP_CONTROL_MANAGEDSAIT, NULL, NULL );
- slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, &managedsait );
- pwpolicy_ctrl = slapi_control_present( ctrls,
- LDAP_X_CONTROL_PWPOLICY_REQUEST, NULL, NULL );
- slapi_pblock_set( pb, SLAPI_PWPOLICY, &pwpolicy_ctrl );
- if ( controlsp != NULL ) {
- *controlsp = ctrls;
- }
- #ifdef SLAPD_ECHO_CONTROL
- /*
- * XXXmcs: Start of hack: if a control with OID "1.1" was sent by
- * the client, echo all controls back to the client unchanged. Note
- * that this is just a hack to test control handling in libldap and
- * should be removed once we support all interesting controls.
- */
- if ( slapi_control_present( ctrls, "1.1", NULL, NULL )) {
- int i;
- for ( i = 0; ctrls[i] != NULL; ++i ) {
- slapi_pblock_set( pb, SLAPI_ADD_RESCONTROL,
- (void *)ctrls[i] );
- }
- }
- #endif /* SLAPD_ECHO_CONTROL */
- LDAPDebug( LDAP_DEBUG_TRACE,
- "<= get_ldapmessage_controls %d controls\n", curcontrols, 0, 0 );
- return( LDAP_SUCCESS );
- free_and_return:;
- ldap_controls_free( ctrls );
- LDAPDebug( LDAP_DEBUG_TRACE,
- "<= get_ldapmessage_controls %i\n", rc, 0, 0 );
- return( rc );
- }
- int
- get_ldapmessage_controls(
- Slapi_PBlock *pb,
- BerElement *ber,
- LDAPControl ***controlsp /* can be NULL if no need to return */
- )
- {
- return get_ldapmessage_controls_ext(pb, ber, controlsp, 0 /* do not ignore criticality */);
- }
- int
- slapi_control_present( LDAPControl **controls, char *oid, struct berval **val, int *iscritical )
- {
- int i;
- LDAPDebug( LDAP_DEBUG_TRACE,
- "=> slapi_control_present (looking for %s)\n", oid, 0, 0 );
- if ( val != NULL ) {
- *val = NULL;
- }
- if ( controls == NULL ) {
- LDAPDebug( LDAP_DEBUG_TRACE,
- "<= slapi_control_present 0 (NO CONTROLS)\n", 0, 0, 0 );
- return( 0 );
- }
- for ( i = 0; controls[i] != NULL; i++ ) {
- if ( strcmp( controls[i]->ldctl_oid, oid ) == 0 ) {
- if (NULL != val) {
- *val = &controls[i]->ldctl_value;
- if (NULL != iscritical) {
- *iscritical = (int) controls[i]->ldctl_iscritical;
- }
- }
- LDAPDebug( LDAP_DEBUG_TRACE,
- "<= slapi_control_present 1 (FOUND)\n", 0, 0, 0 );
- return( 1 );
- }
- }
- LDAPDebug( LDAP_DEBUG_TRACE,
- "<= slapi_control_present 0 (NOT FOUND)\n", 0, 0, 0 );
- return( 0 );
- }
- /*
- * Write sequence of controls in "ctrls" to "ber".
- * Return zero on success and -1 if an error occurs.
- */
- int
- write_controls( BerElement *ber, LDAPControl **ctrls )
- {
- int i;
- unsigned long rc;
- rc= ber_start_seq( ber, LDAP_TAG_CONTROLS );
- if ( rc == LBER_ERROR ) {
- return( -1 );
- }
- /* if the criticality is false, it should be absent from the encoding */
- for ( i = 0; ctrls[ i ] != NULL; ++i ) {
- if ( ctrls[ i ]->ldctl_value.bv_val == 0 ) {
- if ( ctrls[ i ]->ldctl_iscritical ) {
- rc = ber_printf( ber, "{sb}", ctrls[ i ]->ldctl_oid,
- ctrls[ i ]->ldctl_iscritical );
- } else {
- rc = ber_printf( ber, "{s}", ctrls[ i ]->ldctl_oid );
- }
- } else {
- if ( ctrls[ i ]->ldctl_iscritical ) {
- rc = ber_printf( ber, "{sbo}", ctrls[ i ]->ldctl_oid,
- ctrls[ i ]->ldctl_iscritical,
- ctrls[ i ]->ldctl_value.bv_val,
- ctrls[ i ]->ldctl_value.bv_len );
- } else {
- rc = ber_printf( ber, "{so}", ctrls[ i ]->ldctl_oid,
- ctrls[ i ]->ldctl_value.bv_val,
- ctrls[ i ]->ldctl_value.bv_len );
- }
- }
- if ( rc == LBER_ERROR ) {
- return( -1 );
- }
- }
- rc= ber_put_seq( ber );
- if ( rc == LBER_ERROR ) {
- return( -1 );
- }
- return( 0 );
- }
- /*
- * duplicate "newctrl" and add it to the array of controls "*ctrlsp"
- * note that *ctrlsp may be reset and that it is okay to pass NULL for it.
- * IF copy is true, a copy of the passed in control will be added - copy
- * made with slapi_dup_control - if copy is false, the control
- * will be used directly and may be free'd by ldap_controls_free - so
- * make sure it is ok for the control array to own the pointer you
- * pass in
- */
- void
- add_control_ext( LDAPControl ***ctrlsp, LDAPControl *newctrl, int copy )
- {
- int count;
- if ( *ctrlsp == NULL ) {
- count = 0;
- } else {
- for ( count = 0; (*ctrlsp)[count] != NULL; ++count ) {
- ;
- }
- }
- *ctrlsp = (LDAPControl **)slapi_ch_realloc( (char *)*ctrlsp,
- ( count + 2 ) * sizeof(LDAPControl *));
- if (copy) {
- (*ctrlsp)[ count ] = slapi_dup_control( newctrl );
- } else {
- (*ctrlsp)[ count ] = newctrl;
- }
- (*ctrlsp)[ ++count ] = NULL;
- }
- /*
- * duplicate "newctrl" and add it to the array of controls "*ctrlsp"
- * note that *ctrlsp may be reset and that it is okay to pass NULL for it.
- */
- void
- add_control( LDAPControl ***ctrlsp, LDAPControl *newctrl )
- {
- add_control_ext(ctrlsp, newctrl, 1 /* copy */);
- }
- void
- slapi_add_control_ext( LDAPControl ***ctrlsp, LDAPControl *newctrl, int copy )
- {
- add_control_ext(ctrlsp, newctrl, copy);
- }
- /*
- * return a malloc'd copy of "ctrl"
- */
- LDAPControl *
- slapi_dup_control( LDAPControl *ctrl )
- {
- LDAPControl *rctrl;
- rctrl = (LDAPControl *)slapi_ch_malloc( sizeof( LDAPControl ));
- rctrl->ldctl_oid = slapi_ch_strdup( ctrl->ldctl_oid );
- rctrl->ldctl_iscritical = ctrl->ldctl_iscritical;
- if ( ctrl->ldctl_value.bv_val == NULL ) { /* no value */
- rctrl->ldctl_value.bv_len = 0;
- rctrl->ldctl_value.bv_val = NULL;
- } else if ( ctrl->ldctl_value.bv_len <= 0 ) { /* zero length value */
- rctrl->ldctl_value.bv_len = 0;
- rctrl->ldctl_value.bv_val = slapi_ch_malloc( 1 );
- rctrl->ldctl_value.bv_val[0] = '\0';
- } else { /* value with content */
- rctrl->ldctl_value.bv_len = ctrl->ldctl_value.bv_len;
- rctrl->ldctl_value.bv_val =
- slapi_ch_malloc( ctrl->ldctl_value.bv_len );
- memcpy( rctrl->ldctl_value.bv_val, ctrl->ldctl_value.bv_val,
- ctrl->ldctl_value.bv_len );
- }
- return( rctrl );
- }
- void
- slapi_add_controls( LDAPControl ***ctrlsp, LDAPControl **newctrls, int copy )
- {
- int ii;
- for (ii = 0; newctrls && newctrls[ii]; ++ii) {
- slapi_add_control_ext(ctrlsp, newctrls[ii], copy);
- }
- }
- int
- slapi_build_control( char *oid, BerElement *ber,
- char iscritical, LDAPControl **ctrlp )
- {
- int rc = 0;
- int return_value = LDAP_SUCCESS;
- struct berval *bvp = NULL;
- PR_ASSERT( NULL != oid && NULL != ctrlp );
- if ( NULL == ber ) {
- bvp = NULL;
- } else {
- /* allocate struct berval with contents of the BER encoding */
- rc = ber_flatten( ber, &bvp );
- if ( -1 == rc ) {
- return_value = LDAP_NO_MEMORY;
- goto loser;
- }
- }
- /* allocate the new control structure */
- *ctrlp = (LDAPControl *)slapi_ch_calloc( 1, sizeof(LDAPControl));
- /* fill in the fields of this new control */
- (*ctrlp)->ldctl_iscritical = iscritical;
- (*ctrlp)->ldctl_oid = slapi_ch_strdup( oid );
- if ( NULL == bvp ) {
- (*ctrlp)->ldctl_value.bv_len = 0;
- (*ctrlp)->ldctl_value.bv_val = NULL;
- } else {
- (*ctrlp)->ldctl_value = *bvp; /* struct copy */
- ldap_memfree(bvp); /* free container, but not contents */
- bvp = NULL;
- }
- loser:
- return return_value;
- }
- #if 0
- /*
- * rbyrne: This is version of the above using the slapi_build_control_from_berval()
- * I'll enable this afterwards.
- * Build an allocated LDAPv3 control from a BerElement.
- * Returns an LDAP error code.
- */
- int
- slapi_build_control( char *oid, BerElement *ber,
- char iscritical, LDAPControl **ctrlp )
- {
- int rc = 0;
- int return_value = LDAP_SUCCESS;
- struct berval *bvp = NULL;
- PR_ASSERT( NULL != oid && NULL != ctrlp );
- if ( NULL == ber ) {
- bvp = NULL;
- } else {
- /* allocate struct berval with contents of the BER encoding */
- rc = ber_flatten( ber, &bvp );
- if ( -1 == rc ) {
- return_value = LDAP_NO_MEMORY;
- goto loser;
- }
- }
- return_value = slapi_build_control_from_berval( oid, bvp, iscritical,
- ctrlp);
- if ( bvp != NULL ) {
- ldap_memfree(bvp); /* free container, but not contents */
- bvp = NULL;
- }
-
- loser:
- return return_value;
- }
- #endif
- /*
- * Build an allocated LDAPv3 control from a berval. Returns an LDAP error code.
- */
- int
- slapi_build_control_from_berval( char *oid, struct berval *bvp,
- char iscritical, LDAPControl **ctrlp )
- {
- int return_value = LDAP_SUCCESS;
- /* allocate the new control structure */
- *ctrlp = (LDAPControl *)slapi_ch_calloc( 1, sizeof(LDAPControl));
- /* fill in the fields of this new control */
- (*ctrlp)->ldctl_iscritical = iscritical;
- (*ctrlp)->ldctl_oid = slapi_ch_strdup( oid );
- if ( NULL == bvp ) {
- (*ctrlp)->ldctl_value.bv_len = 0;
- (*ctrlp)->ldctl_value.bv_val = NULL;
- } else {
- (*ctrlp)->ldctl_value = *bvp; /* struct copy */
- }
- return return_value;
- }
|