Back to index

openldap  2.4.31
stctrl.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 2007 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 developed by Pierangelo Masarati for inclusion in
00018  * 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 #ifdef LDAP_CONTROL_X_SESSION_TRACKING
00031 
00032 /*
00033  * Client-side of <draft-wahl-ldap-session-03>
00034  */
00035 
00036 int
00037 ldap_create_session_tracking_value(
00038        LDAP          *ld,
00039        char          *sessionSourceIp,
00040        char          *sessionSourceName,
00041        char          *formatOID,
00042        struct berval *sessionTrackingIdentifier,
00043        struct berval *value )
00044 {
00045        BerElement    *ber = NULL;
00046        ber_tag_t     tag;
00047 
00048        struct berval ip, name, oid, id;
00049 
00050        if ( ld == NULL ||
00051               formatOID == NULL ||
00052               value == NULL )
00053        {
00054 param_error:;
00055               if ( ld ) {
00056                      ld->ld_errno = LDAP_PARAM_ERROR;
00057               }
00058 
00059               return LDAP_PARAM_ERROR;
00060        }
00061 
00062        assert( LDAP_VALID( ld ) );
00063        ld->ld_errno = LDAP_SUCCESS;
00064 
00065        /* check sizes according to I.D. */
00066        if ( sessionSourceIp == NULL ) {
00067               BER_BVSTR( &ip, "" );
00068 
00069        } else {
00070               ber_str2bv( sessionSourceIp, 0, 0, &ip );
00071               /* NOTE: we're strict because we don't want
00072                * to send out bad data */
00073               if ( ip.bv_len > 128 ) goto param_error;
00074        }
00075 
00076        if ( sessionSourceName == NULL ) {
00077               BER_BVSTR( &name, "" );
00078 
00079        } else {
00080               ber_str2bv( sessionSourceName, 0, 0, &name );
00081               /* NOTE: we're strict because we don't want
00082                * to send out bad data */
00083               if ( name.bv_len > 65536 ) goto param_error;
00084        }
00085 
00086        ber_str2bv( formatOID, 0, 0, &oid );
00087        /* NOTE: we're strict because we don't want
00088         * to send out bad data */
00089        if ( oid.bv_len > 1024 ) goto param_error;
00090 
00091        if ( sessionTrackingIdentifier == NULL ||
00092               sessionTrackingIdentifier->bv_val == NULL )
00093        {
00094               BER_BVSTR( &id, "" );
00095 
00096        } else {
00097               id = *sessionTrackingIdentifier;
00098        }
00099 
00100        /* prepare value */
00101        value->bv_val = NULL;
00102        value->bv_len = 0;
00103 
00104        ber = ldap_alloc_ber_with_options( ld );
00105        if ( ber == NULL ) {
00106               ld->ld_errno = LDAP_NO_MEMORY;
00107               return ld->ld_errno;
00108        }
00109 
00110        tag = ber_printf( ber, "{OOOO}", &ip, &name, &oid, &id );
00111        if ( tag == LBER_ERROR ) {
00112               ld->ld_errno = LDAP_ENCODING_ERROR;
00113               goto done;
00114        }
00115 
00116        if ( ber_flatten2( ber, value, 1 ) == -1 ) {
00117               ld->ld_errno = LDAP_NO_MEMORY;
00118        }
00119 
00120 done:;
00121        if ( ber != NULL ) {
00122               ber_free( ber, 1 );
00123        }
00124 
00125        return ld->ld_errno;
00126 }
00127 
00128 /*
00129  * NOTE: this API is bad; it could be much more efficient...
00130  */
00131 int
00132 ldap_create_session_tracking_control(
00133        LDAP          *ld,
00134        char          *sessionSourceIp,
00135        char          *sessionSourceName,
00136        char          *formatOID,
00137        struct berval *sessionTrackingIdentifier,
00138        LDAPControl   **ctrlp )
00139 {
00140        struct berval value;
00141 
00142        if ( ctrlp == NULL ) {
00143               ld->ld_errno = LDAP_PARAM_ERROR;
00144               return ld->ld_errno;
00145        }
00146 
00147        ld->ld_errno = ldap_create_session_tracking_value( ld,
00148               sessionSourceIp, sessionSourceName, formatOID,
00149               sessionTrackingIdentifier, &value );
00150        if ( ld->ld_errno == LDAP_SUCCESS ) {
00151               ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_SESSION_TRACKING,
00152                      0, &value, 0, ctrlp );
00153               if ( ld->ld_errno != LDAP_SUCCESS ) {
00154                      LDAP_FREE( value.bv_val );
00155               }
00156        }
00157 
00158        return ld->ld_errno;
00159 }
00160 
00161 int
00162 ldap_parse_session_tracking_control(
00163        LDAP *ld,
00164        LDAPControl *ctrl,
00165        struct berval *ip,
00166        struct berval *name,
00167        struct berval *oid,
00168        struct berval *id )
00169 {
00170        BerElement    *ber;
00171        ber_tag_t     tag;
00172        ber_len_t     len;
00173 
00174        if ( ld == NULL || 
00175               ctrl == NULL || 
00176               ip == NULL ||
00177               name == NULL ||
00178               oid == NULL ||
00179               id == NULL )
00180        {
00181               if ( ld ) {
00182                      ld->ld_errno = LDAP_PARAM_ERROR;
00183               }
00184 
00185               /* NOTE: we want the caller to get all or nothing;
00186                * we could allow some of the pointers to be NULL,
00187                * if one does not want part of the data */
00188               return LDAP_PARAM_ERROR;
00189        }
00190 
00191        BER_BVZERO( ip );
00192        BER_BVZERO( name );
00193        BER_BVZERO( oid );
00194        BER_BVZERO( id );
00195 
00196        ber = ber_init( &ctrl->ldctl_value );
00197 
00198        if ( ber == NULL ) {
00199               ld->ld_errno = LDAP_NO_MEMORY;
00200               return ld->ld_errno;
00201        }
00202 
00203        tag = ber_skip_tag( ber, &len );
00204        if ( tag != LBER_SEQUENCE ) {
00205               tag = LBER_ERROR;
00206               goto error;
00207        }
00208 
00209        /* sessionSourceIp */
00210        tag = ber_peek_tag( ber, &len );
00211        if ( tag == LBER_DEFAULT ) {
00212               tag = LBER_ERROR;
00213               goto error;
00214        }
00215 
00216        if ( len == 0 ) {
00217               tag = ber_skip_tag( ber, &len );
00218 
00219        } else {
00220               if ( len > 128 ) {
00221                      /* should be LDAP_DECODING_ERROR,
00222                       * but we're liberal in what we accept */
00223               }
00224               tag = ber_scanf( ber, "o", ip );
00225        }
00226 
00227        /* sessionSourceName */
00228        tag = ber_peek_tag( ber, &len );
00229        if ( tag == LBER_DEFAULT ) {
00230               tag = LBER_ERROR;
00231               goto error;
00232        }
00233 
00234        if ( len == 0 ) {
00235               tag = ber_skip_tag( ber, &len );
00236 
00237        } else {
00238               if ( len > 65536 ) {
00239                      /* should be LDAP_DECODING_ERROR,
00240                       * but we're liberal in what we accept */
00241               }
00242               tag = ber_scanf( ber, "o", name );
00243        }
00244 
00245        /* formatOID */
00246        tag = ber_peek_tag( ber, &len );
00247        if ( tag == LBER_DEFAULT ) {
00248               tag = LBER_ERROR;
00249               goto error;
00250        }
00251 
00252        if ( len == 0 ) {
00253               ld->ld_errno = LDAP_DECODING_ERROR;
00254               goto error;
00255 
00256        } else {
00257               if ( len > 1024 ) {
00258                      /* should be LDAP_DECODING_ERROR,
00259                       * but we're liberal in what we accept */
00260               }
00261               tag = ber_scanf( ber, "o", oid );
00262        }
00263 
00264        /* FIXME: should check if it is an OID... leave it to the caller */
00265 
00266        /* sessionTrackingIdentifier */
00267        tag = ber_peek_tag( ber, &len );
00268        if ( tag == LBER_DEFAULT ) {
00269               tag = LBER_ERROR;
00270               goto error;
00271        }
00272 
00273        if ( len == 0 ) {
00274               tag = ber_skip_tag( ber, &len );
00275 
00276        } else {
00277 #if 0
00278               if ( len > 65536 ) {
00279                      /* should be LDAP_DECODING_ERROR,
00280                       * but we're liberal in what we accept */
00281               }
00282 #endif
00283               tag = ber_scanf( ber, "o", id );
00284        }
00285 
00286        /* closure */
00287        tag = ber_skip_tag( ber, &len );
00288        if ( tag == LBER_DEFAULT && len == 0 ) {
00289               tag = 0;
00290        }
00291 
00292 error:;
00293        (void)ber_free( ber, 1 );
00294 
00295        if ( tag == LBER_ERROR ) {
00296               return LDAP_DECODING_ERROR;
00297        }
00298 
00299        return ld->ld_errno;
00300 }
00301 
00302 #endif /* LDAP_CONTROL_X_SESSION_TRACKING */