home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ldapsdk.zip / libraries / libldap / controls.c < prev    next >
C/C++ Source or Header  |  2001-07-22  |  10KB  |  475 lines

  1. /* $OpenLDAP: pkg/ldap/libraries/libldap/controls.c,v 1.19.2.9 2001/07/21 19:01:39 kurt Exp $ */
  2. /*
  3.  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  4.  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  5.  */
  6.  
  7. /* LDAPv3 Controls (RFC2251)
  8.  *
  9.  *    Controls ::= SEQUENCE OF Control  
  10.  *
  11.  *    Control ::= SEQUENCE { 
  12.  *        controlType        LDAPOID,
  13.  *        criticality        BOOLEAN DEFAULT FALSE,
  14.  *        controlValue    OCTET STRING OPTIONAL
  15.  *    }
  16.  */
  17.  
  18. #include "portable.h"
  19.  
  20. #include <ac/stdlib.h>
  21.  
  22. #include <ac/time.h>
  23. #include <ac/string.h>
  24.  
  25. #include "ldap-int.h"
  26.  
  27.  
  28. /*
  29.  * ldap_int_put_controls
  30.  */
  31.  
  32. int
  33. ldap_int_put_controls(
  34.     LDAP *ld,
  35.     LDAPControl *const *ctrls,
  36.     BerElement *ber )
  37. {
  38.     LDAPControl *const *c;
  39.  
  40.     assert( ld != NULL );
  41.     assert( ber != NULL );
  42.  
  43.     if( ctrls == NULL ) {
  44.         /* use default server controls */
  45.         ctrls = ld->ld_sctrls;
  46.     }
  47.  
  48.     if( ctrls == NULL || *ctrls == NULL ) {
  49.         return LDAP_SUCCESS;
  50.     }
  51.  
  52.     if ( ld->ld_version < LDAP_VERSION3 ) {
  53.         /* LDAPv2 doesn't support controls,
  54.          * error if any control is critical
  55.          */
  56.         for( c = ctrls ; *c != NULL; c++ ) {
  57.             if( (*c)->ldctl_iscritical ) {
  58.                 ld->ld_errno = LDAP_NOT_SUPPORTED;
  59.                 return ld->ld_errno;
  60.             }
  61.         }
  62.  
  63.         return LDAP_SUCCESS;
  64.     }
  65.  
  66.     /* Controls are encoded as a sequence of sequences */
  67.     if( ber_printf( ber, "t{"/*}*/, LDAP_TAG_CONTROLS ) == -1 ) {
  68.         ld->ld_errno = LDAP_ENCODING_ERROR;
  69.         return ld->ld_errno;
  70.     }
  71.  
  72.     for( c = ctrls ; *c != NULL; c++ ) {
  73.         if ( ber_printf( ber, "{s" /*}*/,
  74.             (*c)->ldctl_oid ) == -1 )
  75.         {
  76.             ld->ld_errno = LDAP_ENCODING_ERROR;
  77.             return ld->ld_errno;
  78.         }
  79.  
  80.         if( (*c)->ldctl_iscritical /* only if true */
  81.             &&  ( ber_printf( ber, "b",
  82.                 (ber_int_t) (*c)->ldctl_iscritical ) == -1 ) )
  83.         {
  84.             ld->ld_errno = LDAP_ENCODING_ERROR;
  85.             return ld->ld_errno;
  86.         }
  87.  
  88.         if( (*c)->ldctl_value.bv_val != NULL /* only if we have a value */
  89.             &&  ( ber_printf( ber, "O",
  90.                 &((*c)->ldctl_value) ) == -1 ) )
  91.         {
  92.             ld->ld_errno = LDAP_ENCODING_ERROR;
  93.             return ld->ld_errno;
  94.         }
  95.  
  96.  
  97.         if( ber_printf( ber, /*{*/"N}" ) == -1 ) {
  98.             ld->ld_errno = LDAP_ENCODING_ERROR;
  99.             return ld->ld_errno;
  100.         }
  101.     }
  102.  
  103.  
  104.     if( ber_printf( ber, /*{*/ "}" ) == -1 ) {
  105.         ld->ld_errno = LDAP_ENCODING_ERROR;
  106.         return ld->ld_errno;
  107.     }
  108.  
  109.     return LDAP_SUCCESS;
  110. }
  111.  
  112. int ldap_int_get_controls(
  113.     BerElement *ber,
  114.     LDAPControl ***ctrls )
  115. {
  116.     int nctrls;
  117.     ber_tag_t tag;
  118.     ber_len_t len;
  119.     char *opaque;
  120.  
  121.     assert( ber != NULL );
  122.  
  123.     if( ctrls == NULL ) {
  124.         return LDAP_SUCCESS;
  125.     }
  126.     *ctrls = NULL;
  127.  
  128.     len = ber_pvt_ber_remaining( ber );
  129.  
  130.     if( len == 0) {
  131.         /* no controls */
  132.         return LDAP_SUCCESS;
  133.     }
  134.  
  135.     if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
  136.         if( tag == LBER_ERROR ) {
  137.             /* decoding error */
  138.             return LDAP_DECODING_ERROR;
  139.         }
  140.  
  141.         /* ignore unexpected input */
  142.         return LDAP_SUCCESS;
  143.     }
  144.  
  145.     /* set through each element */
  146.     nctrls = 0;
  147.     *ctrls = LDAP_MALLOC( 1 * sizeof(LDAPControl *) );
  148.  
  149.     if( *ctrls == NULL ) {
  150.         return LDAP_NO_MEMORY;
  151.     }
  152.  
  153.     *ctrls[nctrls] = NULL;
  154.  
  155.     for( tag = ber_first_element( ber, &len, &opaque );
  156.         tag != LBER_ERROR;
  157.         tag = ber_next_element( ber, &len, opaque ) )
  158.     {
  159.         LDAPControl *tctrl;
  160.         LDAPControl **tctrls;
  161.  
  162.         tctrl = LDAP_CALLOC( 1, sizeof(LDAPControl) );
  163.  
  164.         /* allocate pointer space for current controls (nctrls)
  165.          * + this control + extra NULL
  166.          */
  167.         tctrls = (tctrl == NULL) ? NULL :
  168.             LDAP_REALLOC(*ctrls, (nctrls+2) * sizeof(LDAPControl *));
  169.  
  170.         if( tctrls == NULL ) {
  171.             /* one of the above allocation failed */
  172.  
  173.             if( tctrl != NULL ) {
  174.                 LDAP_FREE( tctrl );
  175.             }
  176.  
  177.             ldap_controls_free(*ctrls);
  178.             *ctrls = NULL;
  179.  
  180.             return LDAP_NO_MEMORY;
  181.         }
  182.  
  183.  
  184.         tctrls[nctrls++] = tctrl;
  185.         tctrls[nctrls] = NULL;
  186.  
  187.         tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid );
  188.  
  189.         if( tag != LBER_ERROR ) {
  190.             tag = ber_peek_tag( ber, &len );
  191.         }
  192.  
  193.         if( tag == LBER_BOOLEAN ) {
  194.             ber_int_t crit;
  195.             tag = ber_scanf( ber, "b", &crit );
  196.             tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0;
  197.         }
  198.  
  199.         if( tag != LBER_ERROR ) {
  200.             tag = ber_peek_tag( ber, &len );
  201.         }
  202.  
  203.         if( tag == LBER_OCTETSTRING ) {
  204.             tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
  205.  
  206.         } else {
  207.             tctrl->ldctl_value.bv_val = NULL;
  208.         }
  209.  
  210.         if( tag == LBER_ERROR ) {
  211.             *ctrls = NULL;
  212.             ldap_controls_free( tctrls );
  213.             return LDAP_DECODING_ERROR;
  214.         }
  215.  
  216.         *ctrls = tctrls;
  217.     }
  218.         
  219.     return LDAP_SUCCESS;
  220. }
  221.  
  222. /*
  223.  * Free a LDAPControl
  224.  */
  225. void
  226. ldap_control_free( LDAPControl *c )
  227. {
  228. #ifdef LDAP_MEMORY_DEBUG
  229.     assert( c != NULL );
  230. #endif
  231.  
  232.     if ( c != NULL ) {
  233.         if( c->ldctl_oid != NULL) {
  234.             LDAP_FREE( c->ldctl_oid );
  235.         }
  236.  
  237.         if( c->ldctl_value.bv_val != NULL ) {
  238.             LDAP_FREE( c->ldctl_value.bv_val );
  239.         }
  240.  
  241.         LDAP_FREE( c );
  242.     }
  243. }
  244.  
  245. /*
  246.  * Free an array of LDAPControl's
  247.  */
  248. void
  249. ldap_controls_free( LDAPControl **controls )
  250. {
  251. #ifdef LDAP_MEMORY_DEBUG
  252.     assert( controls != NULL );
  253. #endif
  254.  
  255.     if ( controls != NULL ) {
  256.         int i;
  257.  
  258.         for( i=0; controls[i] != NULL; i++) {
  259.             ldap_control_free( controls[i] );
  260.         }
  261.  
  262.         LDAP_FREE( controls );
  263.     }
  264. }
  265.  
  266. /*
  267.  * Duplicate an array of LDAPControl
  268.  */
  269. LDAPControl **
  270. ldap_controls_dup( LDAPControl *const *controls )
  271. {
  272.     LDAPControl **new;
  273.     int i;
  274.  
  275.     if ( controls == NULL ) {
  276.         return NULL;
  277.     }
  278.  
  279.     /* count the controls */
  280.     for(i=0; controls[i] != NULL; i++) /* empty */ ;
  281.  
  282.     if( i < 1 ) {
  283.         /* no controls to duplicate */
  284.         return NULL;
  285.     }
  286.  
  287.     new = (LDAPControl **) LDAP_MALLOC( i * sizeof(LDAPControl *) );
  288.  
  289.     if( new == NULL ) {
  290.         /* memory allocation failure */
  291.         return NULL;
  292.     }
  293.  
  294.     /* duplicate the controls */
  295.     for(i=0; controls[i] != NULL; i++) {
  296.         new[i] = ldap_control_dup( controls[i] );
  297.  
  298.         if( new[i] == NULL ) {
  299.             ldap_controls_free( new );
  300.             return NULL;
  301.         }
  302.     }
  303.  
  304.     new[i] = NULL;
  305.  
  306.     return new;
  307. }
  308.  
  309. /*
  310.  * Duplicate a LDAPControl
  311.  */
  312. LDAPControl *
  313. ldap_control_dup( const LDAPControl *c )
  314. {
  315.     LDAPControl *new;
  316.  
  317.     if ( c == NULL ) {
  318.         return NULL;
  319.     }
  320.  
  321.     new = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
  322.  
  323.     if( new == NULL ) {
  324.         return NULL;
  325.     }
  326.  
  327.     if( c->ldctl_oid != NULL ) {
  328.         new->ldctl_oid = LDAP_STRDUP( c->ldctl_oid );
  329.  
  330.         if(new->ldctl_oid == NULL) {
  331.             LDAP_FREE( new );
  332.             return NULL;
  333.         }
  334.  
  335.     } else {
  336.         new->ldctl_oid = NULL;
  337.     }
  338.  
  339.     if( c->ldctl_value.bv_val != NULL ) {
  340.         new->ldctl_value.bv_val =
  341.             (char *) LDAP_MALLOC( c->ldctl_value.bv_len + 1 );
  342.  
  343.         if(new->ldctl_value.bv_val == NULL) {
  344.             if(new->ldctl_oid != NULL) {
  345.                 LDAP_FREE( new->ldctl_oid );
  346.             }
  347.             LDAP_FREE( new );
  348.             return NULL;
  349.         }
  350.         
  351.         new->ldctl_value.bv_len = c->ldctl_value.bv_len;
  352.  
  353.         AC_MEMCPY( new->ldctl_value.bv_val, c->ldctl_value.bv_val, 
  354.             c->ldctl_value.bv_len );
  355.  
  356.         new->ldctl_value.bv_val[new->ldctl_value.bv_len] = '\0';
  357.  
  358.     } else {
  359.         new->ldctl_value.bv_len = 0;
  360.         new->ldctl_value.bv_val = NULL;
  361.     }
  362.  
  363.     new->ldctl_iscritical = c->ldctl_iscritical;
  364.     return new;
  365. }
  366.  
  367. /*
  368.  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
  369.  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
  370.  */
  371. /* Adapted for inclusion into OpenLDAP by Kurt D. Zeilenga */
  372. /*---
  373.  * This notice applies to changes, created by or for Novell, Inc.,
  374.  * to preexisting works for which notices appear elsewhere in this file.
  375.  *
  376.  * Copyright (C) 1999, 2000 Novell, Inc. All Rights Reserved.
  377.  *
  378.  * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
  379.  * USE, MODIFICATION, AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO VERSION
  380.  * 2.0.1 OF THE OPENLDAP PUBLIC LICENSE, A COPY OF WHICH IS AVAILABLE AT
  381.  * HTTP://WWW.OPENLDAP.ORG/LICENSE.HTML OR IN THE FILE "LICENSE" IN THE
  382.  * TOP-LEVEL DIRECTORY OF THE DISTRIBUTION. ANY USE OR EXPLOITATION OF THIS
  383.  * WORK OTHER THAN AS AUTHORIZED IN VERSION 2.0.1 OF THE OPENLDAP PUBLIC
  384.  * LICENSE, OR OTHER PRIOR WRITTEN CONSENT FROM NOVELL, COULD SUBJECT THE
  385.  * PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY. 
  386.  *---
  387.  * Modification to OpenLDAP source by Novell, Inc.
  388.  * June 2000 sfs  Added control utilities
  389.  */
  390. /*---
  391.    ldap_create_control
  392.    
  393.    Internal function to create an LDAP control from the encoded BerElement.
  394.  
  395.    requestOID  (IN) The OID to use in creating the control.
  396.    
  397.    ber         (IN) The encoded BerElement to use in creating the control.
  398.    
  399.    iscritical  (IN) 0 - Indicates the control is not critical to the operation.
  400.                     non-zero - The control is critical to the operation.
  401.                   
  402.    ctrlp      (OUT) Returns a pointer to the LDAPControl created.  This control
  403.                     SHOULD be freed by calling ldap_control_free() when done.
  404. ---*/
  405.  
  406. int
  407. ldap_create_control(
  408.     LDAP_CONST char *requestOID,
  409.     BerElement *ber,
  410.     int iscritical,
  411.     LDAPControl **ctrlp )
  412. {
  413.     LDAPControl *ctrl;
  414.     struct berval *bvalp;
  415.  
  416.     if ( requestOID == NULL || ctrlp == NULL ) {
  417.         return LDAP_PARAM_ERROR;
  418.     }
  419.  
  420.     ctrl = (LDAPControl *) LDAP_MALLOC( sizeof(LDAPControl) );
  421.     if ( ctrl == NULL ) {
  422.         return LDAP_NO_MEMORY;
  423.     }
  424.  
  425.     if ( ber_flatten( ber, &bvalp ) == LBER_ERROR ) {
  426.         LDAP_FREE( ctrl );
  427.         return LDAP_NO_MEMORY;
  428.     }
  429.  
  430.     ctrl->ldctl_value = *bvalp;
  431.     ber_memfree( bvalp );
  432.  
  433.     ctrl->ldctl_oid = LDAP_STRDUP( requestOID );
  434.     ctrl->ldctl_iscritical = iscritical;
  435.  
  436.     if ( requestOID != NULL && ctrl->ldctl_oid == NULL ) {
  437.         ldap_control_free( ctrl );
  438.         return LDAP_NO_MEMORY;
  439.     }
  440.  
  441.     *ctrlp = ctrl;
  442.     return LDAP_SUCCESS;
  443. }
  444.  
  445. /*
  446.  * check for critical client controls and bitch if present
  447.  * if we ever support critical controls, we'll have to
  448.  * find a means for maintaining per API call control
  449.  * information.
  450.  */
  451. int ldap_int_client_controls( LDAP *ld, LDAPControl **ctrls )
  452. {
  453.     LDAPControl *const *c;
  454.  
  455.     assert( ld != NULL );
  456.  
  457.     if( ctrls == NULL ) {
  458.         /* use default server controls */
  459.         ctrls = ld->ld_cctrls;
  460.     }
  461.  
  462.     if( ctrls == NULL || *ctrls == NULL ) {
  463.         return LDAP_SUCCESS;
  464.     }
  465.  
  466.     for( c = ctrls ; *c != NULL; c++ ) {
  467.         if( (*c)->ldctl_iscritical ) {
  468.             ld->ld_errno = LDAP_NOT_SUPPORTED;
  469.             return ld->ld_errno;
  470.         }
  471.     }
  472.  
  473.     return LDAP_SUCCESS;
  474. }
  475.