]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap/controls.c
Add ftest (filter test) to the mix, needs work.
[openldap] / libraries / libldap / controls.c
index b609b7bc5660cd0c180fe2df01663248bda74c69..6dcf7364ecbc63d34f64d9e463107875f4a7e150 100644 (file)
@@ -1,5 +1,6 @@
+/* $OpenLDAP$ */
 /*
- * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  */
 
  * ldap_int_put_controls
  */
 
-int ldap_int_put_controls(
+int
+ldap_int_put_controls(
        LDAP *ld,
-       LDAPControl **ctrls,
+       LDAPControl *const *ctrls,
        BerElement *ber )
 {
-       LDAPControl **c;
+       LDAPControl *const *c;
 
        assert( ld != NULL );
        assert( ber != NULL );
@@ -92,14 +94,14 @@ int ldap_int_put_controls(
                }
 
 
-               if( ber_printf( ber, /*{*/"}" ) == -1 ) {
+               if( ber_printf( ber, /*{*/"N}" ) == -1 ) {
                        ld->ld_errno = LDAP_ENCODING_ERROR;
                        return ld->ld_errno;
                }
        }
 
 
-       if( ber_printf( ber, /*{*/"}" ) == -1 ) {
+       if( ber_printf( ber, /*{*/ "}" ) == -1 ) {
                ld->ld_errno = LDAP_ENCODING_ERROR;
                return ld->ld_errno;
        }
@@ -117,11 +119,13 @@ int ldap_int_get_controls(
        char *opaque;
 
        assert( ber != NULL );
-       assert( ctrls != NULL );
 
+       if( ctrls == NULL ) {
+               return LDAP_SUCCESS;
+       }
        *ctrls = NULL;
 
-       len = ber_pvt_ber_remaining(ber);
+       len = ber_pvt_ber_remaining( ber );
 
        if( len == 0) {
                /* no controls */
@@ -146,7 +150,7 @@ int ldap_int_get_controls(
                return LDAP_NO_MEMORY;
        }
 
-       ctrls[nctrls] = NULL;
+       *ctrls[nctrls] = NULL;
 
        for( tag = ber_first_element( ber, &len, &opaque );
                tag != LBER_ERROR;
@@ -221,7 +225,9 @@ int ldap_int_get_controls(
 void
 ldap_control_free( LDAPControl *c )
 {
+#ifdef LDAP_MEMORY_DEBUG
        assert( c != NULL );
+#endif
 
        if ( c != NULL ) {
                if( c->ldctl_oid != NULL) {
@@ -242,13 +248,15 @@ ldap_control_free( LDAPControl *c )
 void
 ldap_controls_free( LDAPControl **controls )
 {
+#ifdef LDAP_MEMORY_DEBUG
        assert( controls != NULL );
+#endif
 
        if ( controls != NULL ) {
-               LDAPControl *c;
+               int i;
 
-               for(c = *controls; c != NULL; c++) {
-                       ldap_control_free( c );
+               for( i=0; controls[i] != NULL; i++) {
+                       ldap_control_free( controls[i] );
                }
 
                LDAP_FREE( controls );
@@ -258,7 +266,8 @@ ldap_controls_free( LDAPControl **controls )
 /*
  * Duplicate an array of LDAPControl
  */
-LDAPControl **ldap_controls_dup( LDAPControl **controls )
+LDAPControl **
+ldap_controls_dup( LDAPControl *const *controls )
 {
        LDAPControl **new;
        int i;
@@ -300,7 +309,8 @@ LDAPControl **ldap_controls_dup( LDAPControl **controls )
 /*
  * Duplicate a LDAPControl
  */
-LDAPControl *ldap_control_dup( LDAPControl *c )
+LDAPControl *
+ldap_control_dup( const LDAPControl *c )
 {
        LDAPControl *new;
 
@@ -326,8 +336,9 @@ LDAPControl *ldap_control_dup( LDAPControl *c )
                new->ldctl_oid = NULL;
        }
 
-       if( c->ldctl_value.bv_len > 0 ) {
-               new->ldctl_value.bv_val = (char *) LDAP_MALLOC( c->ldctl_value.bv_len );
+       if( c->ldctl_value.bv_val != NULL ) {
+               new->ldctl_value.bv_val =
+                       (char *) LDAP_MALLOC( c->ldctl_value.bv_len + 1 );
 
                if(new->ldctl_value.bv_val == NULL) {
                        if(new->ldctl_oid != NULL) {
@@ -337,10 +348,12 @@ LDAPControl *ldap_control_dup( LDAPControl *c )
                        return NULL;
                }
                
-               SAFEMEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val, 
+               new->ldctl_value.bv_len = c->ldctl_value.bv_len;
+
+               AC_MEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val, 
                        c->ldctl_value.bv_len );
 
-               new->ldctl_value.bv_len = c->ldctl_value.bv_len;
+               new->ldctl_value.bv_val[new->ldctl_value.bv_len] = '\0';
 
        } else {
                new->ldctl_value.bv_len = 0;
@@ -350,3 +363,112 @@ LDAPControl *ldap_control_dup( LDAPControl *c )
        new->ldctl_iscritical = c->ldctl_iscritical;
        return new;
 }
+
+/*
+ * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+/* Adapted for inclusion into OpenLDAP by Kurt D. Zeilenga */
+/*---
+ * 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. 
+ *---
+ * Modification to OpenLDAP source by Novell, Inc.
+ * June 2000 sfs  Added control utilities
+ */
+/*---
+   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.
+---*/
+
+int
+ldap_create_control(
+       LDAP_CONST char *requestOID,
+       BerElement *ber,
+       int iscritical,
+       LDAPControl **ctrlp )
+{
+       LDAPControl *ctrl;
+       struct berval *bvalp;
+
+       if ( requestOID == NULL || ctrlp == NULL ) {
+               return LDAP_PARAM_ERROR;
+       }
+
+       ctrl = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
+       if ( ctrl == NULL ) {
+               return LDAP_NO_MEMORY;
+       }
+
+       if ( ber_flatten( ber, &bvalp ) == LBER_ERROR ) {
+               LDAP_FREE( ctrl );
+               return LDAP_NO_MEMORY;
+       }
+
+       ctrl->ldctl_value = *bvalp;
+       ber_memfree( bvalp );
+
+       ctrl->ldctl_oid = LDAP_STRDUP( requestOID );
+       ctrl->ldctl_iscritical = iscritical;
+
+       if ( requestOID != NULL && ctrl->ldctl_oid == NULL ) {
+               ldap_control_free( ctrl );
+               return LDAP_NO_MEMORY;
+       }
+
+       *ctrlp = ctrl;
+       return LDAP_SUCCESS;
+}
+
+/*
+ * 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 );
+
+       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;
+}