Back to index

openldap  2.4.31
deref.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 1998-2012 The OpenLDAP Foundation.
00005  * Portions Copyright 2008 Pierangelo Masarati.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in the file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 /* ACKNOWLEDGEMENTS:
00017  * This work was initially developed by Pierangelo Masarati
00018  * for inclusion in OpenLDAP Software.
00019  */
00020 
00021 #include "portable.h"
00022 
00023 #include <stdio.h>
00024 #include <ac/stdlib.h>
00025 #include <ac/string.h>
00026 #include <ac/time.h>
00027 
00028 #include "ldap-int.h"
00029 
00030 int
00031 ldap_create_deref_control_value(
00032        LDAP          *ld,
00033        LDAPDerefSpec *ds,
00034        struct berval *value )
00035 {
00036        BerElement    *ber = NULL;
00037        ber_tag_t     tag;
00038        int           i;
00039 
00040        if ( ld == NULL || value == NULL || ds == NULL )
00041        {
00042               if ( ld )
00043                      ld->ld_errno = LDAP_PARAM_ERROR;
00044               return LDAP_PARAM_ERROR;
00045        }
00046 
00047        assert( LDAP_VALID( ld ) );
00048 
00049        value->bv_val = NULL;
00050        value->bv_len = 0;
00051        ld->ld_errno = LDAP_SUCCESS;
00052 
00053        ber = ldap_alloc_ber_with_options( ld );
00054        if ( ber == NULL ) {
00055               ld->ld_errno = LDAP_NO_MEMORY;
00056               return ld->ld_errno;
00057        }
00058 
00059        tag = ber_printf( ber, "{" /*}*/ );
00060        if ( tag == LBER_ERROR ) {
00061               ld->ld_errno = LDAP_ENCODING_ERROR;
00062               goto done;
00063        }
00064 
00065        for ( i = 0; ds[i].derefAttr != NULL; i++ ) {
00066               int j;
00067 
00068               tag = ber_printf( ber, "{s{" /*}}*/ , ds[i].derefAttr );
00069               if ( tag == LBER_ERROR ) {
00070                      ld->ld_errno = LDAP_ENCODING_ERROR;
00071                      goto done;
00072               }
00073 
00074               for ( j = 0; ds[i].attributes[j] != NULL; j++ ) {
00075                      tag = ber_printf( ber, "s", ds[i].attributes[ j ] );
00076                      if ( tag == LBER_ERROR ) {
00077                             ld->ld_errno = LDAP_ENCODING_ERROR;
00078                             goto done;
00079                      }
00080               }
00081 
00082               tag = ber_printf( ber, /*{{*/ "}N}" );
00083               if ( tag == LBER_ERROR ) {
00084                      ld->ld_errno = LDAP_ENCODING_ERROR;
00085                      goto done;
00086               }
00087        }
00088 
00089        tag = ber_printf( ber, /*{*/ "}" );
00090        if ( tag == LBER_ERROR ) {
00091               ld->ld_errno = LDAP_ENCODING_ERROR;
00092               goto done;
00093        }
00094 
00095        if ( ber_flatten2( ber, value, 1 ) == -1 ) {
00096               ld->ld_errno = LDAP_NO_MEMORY;
00097        }
00098 
00099 done:;
00100        if ( ber != NULL ) {
00101               ber_free( ber, 1 );
00102        }
00103 
00104        return ld->ld_errno;
00105 }
00106 
00107 int
00108 ldap_create_deref_control(
00109        LDAP          *ld,
00110        LDAPDerefSpec *ds,
00111        int           iscritical,
00112        LDAPControl   **ctrlp )
00113 {
00114        struct berval value;
00115 
00116        if ( ctrlp == NULL ) {
00117               ld->ld_errno = LDAP_PARAM_ERROR;
00118               return ld->ld_errno;
00119        }
00120 
00121        ld->ld_errno = ldap_create_deref_control_value( ld, ds, &value );
00122        if ( ld->ld_errno == LDAP_SUCCESS ) {
00123               ld->ld_errno = ldap_control_create( LDAP_CONTROL_PAGEDRESULTS,
00124                      iscritical, &value, 0, ctrlp );
00125               if ( ld->ld_errno != LDAP_SUCCESS ) {
00126                      LDAP_FREE( value.bv_val );
00127               }
00128        }
00129 
00130        return ld->ld_errno;
00131 }
00132 
00133 void
00134 ldap_derefresponse_free( LDAPDerefRes *dr )
00135 {
00136        for ( ; dr; ) {
00137               LDAPDerefRes *drnext = dr->next;
00138               LDAPDerefVal *dv;
00139 
00140               LDAP_FREE( dr->derefAttr );
00141               LDAP_FREE( dr->derefVal.bv_val );
00142 
00143               for ( dv = dr->attrVals; dv; ) {
00144                      LDAPDerefVal *dvnext = dv->next;
00145                      LDAP_FREE( dv->type );
00146                      ber_bvarray_free( dv->vals );
00147                      LDAP_FREE( dv );
00148                      dv = dvnext;
00149               }
00150 
00151               LDAP_FREE( dr );
00152 
00153               dr = drnext;
00154        }
00155 }
00156 
00157 int
00158 ldap_parse_derefresponse_control(
00159        LDAP          *ld,
00160        LDAPControl   *ctrl,
00161        LDAPDerefRes  **drp2 )
00162 {
00163        BerElement *ber;
00164        ber_tag_t tag;
00165        ber_len_t len;
00166        char *last;
00167        LDAPDerefRes *drhead = NULL, **drp;
00168 
00169        if ( ld == NULL || ctrl == NULL || drp2 == NULL ) {
00170               if ( ld )
00171                      ld->ld_errno = LDAP_PARAM_ERROR;
00172               return LDAP_PARAM_ERROR;
00173        }
00174 
00175        /* Create a BerElement from the berval returned in the control. */
00176        ber = ber_init( &ctrl->ldctl_value );
00177 
00178        if ( ber == NULL ) {
00179               ld->ld_errno = LDAP_NO_MEMORY;
00180               return ld->ld_errno;
00181        }
00182 
00183        /* Extract the count and cookie from the control. */
00184        drp = &drhead;
00185        for ( tag = ber_first_element( ber, &len, &last );
00186               tag != LBER_DEFAULT;
00187               tag = ber_next_element( ber, &len, last ) )
00188        {
00189               LDAPDerefRes *dr;
00190               LDAPDerefVal **dvp;
00191               char *last2;
00192 
00193               dr = LDAP_CALLOC( 1, sizeof(LDAPDerefRes) );
00194               dvp = &dr->attrVals;
00195 
00196               tag = ber_scanf( ber, "{ao", &dr->derefAttr, &dr->derefVal );
00197               if ( tag == LBER_ERROR ) {
00198                      goto done;
00199               }
00200 
00201               tag = ber_peek_tag( ber, &len );
00202               if ( tag == (LBER_CONSTRUCTED|LBER_CLASS_CONTEXT) ) {
00203                      for ( tag = ber_first_element( ber, &len, &last2 );
00204                             tag != LBER_DEFAULT;
00205                             tag = ber_next_element( ber, &len, last2 ) )
00206                      {
00207                             LDAPDerefVal *dv;
00208 
00209                             dv = LDAP_CALLOC( 1, sizeof(LDAPDerefVal) );
00210 
00211                             tag = ber_scanf( ber, "{a[W]}", &dv->type, &dv->vals );
00212                             if ( tag == LBER_ERROR ) {
00213                                    goto done;
00214                             }
00215 
00216                             *dvp = dv;
00217                             dvp = &dv->next;
00218                      }
00219               }
00220 
00221               tag = ber_scanf( ber, "}" );
00222               if ( tag == LBER_ERROR ) {
00223                      goto done;
00224               }
00225 
00226               *drp = dr;
00227               drp = &dr->next;
00228        }
00229 
00230        tag = 0;
00231 
00232 done:;
00233         ber_free( ber, 1 );
00234 
00235        if ( tag == LBER_ERROR ) {
00236               if ( drhead != NULL ) {
00237                      ldap_derefresponse_free( drhead );
00238               }
00239 
00240               *drp2 = NULL;
00241               ld->ld_errno = LDAP_DECODING_ERROR;
00242 
00243        } else {
00244               *drp2 = drhead;
00245               ld->ld_errno = LDAP_SUCCESS;
00246        }
00247 
00248        return ld->ld_errno;
00249 }
00250 
00251 int
00252 ldap_parse_deref_control(
00253        LDAP          *ld,
00254        LDAPControl   **ctrls,
00255        LDAPDerefRes  **drp )
00256 {
00257        LDAPControl *c;
00258 
00259        if ( drp == NULL ) {
00260               ld->ld_errno = LDAP_PARAM_ERROR;
00261               return ld->ld_errno;
00262        }
00263 
00264        *drp = NULL;
00265 
00266        if ( ctrls == NULL ) {
00267               ld->ld_errno =  LDAP_CONTROL_NOT_FOUND;
00268               return ld->ld_errno;
00269        }
00270 
00271        c = ldap_control_find( LDAP_CONTROL_X_DEREF, ctrls, NULL );
00272        if ( c == NULL ) {
00273               /* No deref control was found. */
00274               ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
00275               return ld->ld_errno;
00276        }
00277 
00278        ld->ld_errno = ldap_parse_derefresponse_control( ld, c, drp );
00279 
00280        return ld->ld_errno;
00281 }
00282