Back to index

lightning-sunbird  0.9+nobinonly
vlistctrl.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Mozilla Communicator client code, released
00015  * March 31, 1998.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /* vlistctrl.c - virtual list control implementation. */
00039 #include "ldap-int.h"
00040 
00041 
00042 
00043 /*
00044  * function to create a VirtualListViewRequest control that can be passed
00045  * to ldap_search_ext() or ldap_search_ext_s().  *ctrlp will be set to a
00046  * freshly allocated LDAPControl structure.  Returns an LDAP error code
00047  * (LDAP_SUCCESS if all goes well).
00048  * 
00049  *  Parameters
00050  *   ld              LDAP pointer to the desired connection 
00051  *
00052  *   ldvlistp        the control structure.
00053  *
00054  *   ctrlp           the address of a place to put the constructed control 
00055 
00056   The controlValue is an OCTET STRING
00057   whose value is the BER-encoding of the following SEQUENCE:
00058   
00059        VirtualListViewRequest ::= SEQUENCE {
00060                beforeCount    INTEGER (0 .. maxInt),
00061                afterCount     INTEGER (0 .. maxInt),
00062                CHOICE {
00063                        byIndex [0] SEQUENCE {
00064                        index           INTEGER (0 .. maxInt),
00065                        contentCount    INTEGER (0 .. maxInt) }
00066                        byValue [1] greaterThanOrEqual assertionValue }
00067   
00068   beforeCount indicates how many  entries  before  the  target  entry  the
00069   client  wants  the  server  to  send. afterCount indicates the number of
00070   entries after the target entry the client  wants  the  server  to  send.
00071   index  and contentCount identify the target entry
00072   greaterThanOrEqual  is  an  attribute  assertion  value  defined  in
00073   [LDAPv3].  If  present, the value supplied in greaterThanOrEqual is used
00074   to determine the target entry by  comparison  with  the  values  of  the
00075   attribute  specified as the primary sort key. The first list entry who's
00076   value is no less than the supplied value is the target entry.
00077 
00078  */
00079 
00080 int 
00081 LDAP_CALL
00082 ldap_create_virtuallist_control( 
00083     LDAP *ld, 
00084     LDAPVirtualList *ldvlistp,
00085     LDAPControl **ctrlp 
00086 )
00087 {
00088     BerElement *ber;
00089     int rc;
00090     
00091     if (!NSLDAPI_VALID_LDAP_POINTER( ld )) {
00092        return( LDAP_PARAM_ERROR );
00093     }
00094 
00095 
00096     if ( NULL == ctrlp || NULL == ldvlistp ) {
00097         LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
00098         return ( LDAP_PARAM_ERROR );
00099     }
00100 
00101     /* create a ber package to hold the controlValue */
00102     if ( LDAP_SUCCESS != nsldapi_alloc_ber_with_options( ld, &ber )  ) 
00103     {
00104         LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
00105         return( LDAP_NO_MEMORY );
00106     }
00107 
00108     if ( LBER_ERROR == ber_printf( ber, 
00109                                    "{ii", 
00110                                    (int)ldvlistp->ldvlist_before_count,
00111                                    (int)ldvlistp->ldvlist_after_count )) 
00112                                 /* XXX lossy casts */
00113     {
00114         LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
00115         ber_free( ber, 1 );
00116         return( LDAP_ENCODING_ERROR );
00117     }
00118 
00119     if (NULL == ldvlistp->ldvlist_attrvalue)
00120     {
00121         if ( LBER_ERROR == ber_printf( ber, 
00122                                        "t{ii}}", 
00123                                    LDAP_TAG_VLV_BY_INDEX,
00124                                        (int)ldvlistp->ldvlist_index, 
00125                                        (int)ldvlistp->ldvlist_size ) ) 
00126                                    /* XXX lossy casts */
00127         {
00128             LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
00129             ber_free( ber, 1 );
00130             return( LDAP_ENCODING_ERROR );
00131         }
00132     } 
00133     else 
00134     {
00135         if ( LBER_ERROR == ber_printf( ber, 
00136                                       "to}", 
00137                                    LDAP_TAG_VLV_BY_VALUE,
00138                                       ldvlistp->ldvlist_attrvalue,
00139                                    (int)strlen( ldvlistp->ldvlist_attrvalue )) ) {
00140             LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
00141             ber_free( ber, 1 );
00142             return( LDAP_ENCODING_ERROR );
00143         }
00144     }
00145 
00146 
00147     rc = nsldapi_build_control( LDAP_CONTROL_VLVREQUEST , 
00148                                 ber, 
00149                                 1,
00150                                 1, 
00151                                 ctrlp );
00152 
00153     LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
00154     return( rc );
00155 
00156 }
00157 
00158 
00159 /*
00160  * function to find and parse a VirtualListViewResponse control contained in
00161  * "ctrls"  *target_posp, *list_sizep, and *errcodep are set based on its
00162  * contents.  Returns an LDAP error code that indicates whether the parsing
00163  * itself was successful (LDAP_SUCCESS if all goes well).
00164 
00165   The controlValue is an OCTET STRING, whose value
00166   is the BER encoding of a value of the following SEQUENCE:
00167   
00168        VirtualListViewResponse ::= SEQUENCE {
00169                targetPosition    INTEGER (0 .. maxInt),
00170                contentCount     INTEGER (0 .. maxInt),
00171                virtualListViewResult ENUMERATED {
00172                        success (0),
00173                        operatonsError (1),
00174                        unwillingToPerform (53),
00175                        insufficientAccessRights (50),
00176                        busy (51),
00177                        timeLimitExceeded (3),
00178                        adminLimitExceeded (11),
00179                        sortControlMissing (60),
00180                        indexRangeError (61),
00181                        other (80) }  }
00182 
00183  */
00184 int 
00185 LDAP_CALL
00186 ldap_parse_virtuallist_control
00187 ( 
00188     LDAP *ld, 
00189     LDAPControl **ctrls,
00190     unsigned long *target_posp, 
00191     unsigned long *list_sizep, 
00192     int *errcodep
00193 )
00194 {
00195     BerElement              *ber;
00196     int                     i, foundListControl, errcode;
00197     LDAPControl             *listCtrlp;
00198     unsigned long    target_pos, list_size;
00199 
00200     if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
00201         return( LDAP_PARAM_ERROR );
00202     }
00203 
00204     /* only ldapv3 or higher can do virtual lists. */
00205     if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) {
00206         LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
00207         return( LDAP_NOT_SUPPORTED );
00208     }
00209 
00210     /* find the listControl in the list of controls if it exists */
00211     if ( ctrls == NULL ) {
00212         LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
00213         return ( LDAP_CONTROL_NOT_FOUND );
00214     } 
00215     
00216     foundListControl = 0;
00217     for ( i = 0; (( ctrls[i] != NULL ) && ( !foundListControl )); i++ ) {
00218         foundListControl = !strcmp( ctrls[i]->ldctl_oid, 
00219                                     LDAP_CONTROL_VLVRESPONSE );
00220     }
00221     if ( !foundListControl ) {
00222         LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
00223         return ( LDAP_CONTROL_NOT_FOUND );
00224     } else {
00225         /* let local var point to the listControl */
00226         listCtrlp = ctrls[i-1];                 
00227     }
00228 
00229     /*  allocate a Ber element with the contents of the list_control's struct berval */
00230     if ( ( ber = ber_init( &listCtrlp->ldctl_value ) ) == NULL ) {
00231         LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
00232         return( LDAP_NO_MEMORY );
00233     }           
00234 
00235     /* decode the result from the Berelement */
00236     if (  LBER_ERROR == ber_scanf( ber, "{iie}", &target_pos, &list_size,
00237            &errcode ) ) {
00238         LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
00239         ber_free( ber, 1 );
00240         return( LDAP_DECODING_ERROR );
00241     }
00242 
00243     if ( target_posp != NULL ) {
00244        *target_posp = target_pos;
00245     }
00246     if ( list_sizep != NULL ) {
00247        *list_sizep = list_size;
00248     }
00249     if ( errcodep != NULL ) {
00250        *errcodep = errcode;
00251     }
00252 
00253     /* the ber encoding is no longer needed */
00254     ber_free(ber,1);
00255 
00256     return(LDAP_SUCCESS);
00257 
00258 }