123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- /* $OpenLDAP$ */
- /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2022 The OpenLDAP Foundation.
- * Portions Copyright 2007 Pierangelo Masarati.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the OpenLDAP
- * Public License.
- *
- * A copy of this license is available in the file LICENSE in the
- * top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
- /* ACKNOWLEDGEMENTS:
- * This work was developed by Pierangelo Masarati for inclusion in
- * OpenLDAP Software.
- */
- #include "portable.h"
- #include <stdio.h>
- #include <ac/stdlib.h>
- #include <ac/string.h>
- #include <ac/time.h>
- #include "ldap-int.h"
- #ifdef LDAP_CONTROL_X_SESSION_TRACKING
- /*
- * Client-side of <draft-wahl-ldap-session-03>
- */
- int
- ldap_create_session_tracking_value(
- LDAP *ld,
- char *sessionSourceIp,
- char *sessionSourceName,
- char *formatOID,
- struct berval *sessionTrackingIdentifier,
- struct berval *value )
- {
- BerElement *ber = NULL;
- ber_tag_t tag;
- struct berval ip, name, oid, id;
- if ( ld == NULL ||
- formatOID == NULL ||
- value == NULL )
- {
- param_error:;
- if ( ld ) {
- ld->ld_errno = LDAP_PARAM_ERROR;
- }
- return LDAP_PARAM_ERROR;
- }
- assert( LDAP_VALID( ld ) );
- ld->ld_errno = LDAP_SUCCESS;
- /* check sizes according to I.D. */
- if ( sessionSourceIp == NULL ) {
- BER_BVSTR( &ip, "" );
- } else {
- ber_str2bv( sessionSourceIp, 0, 0, &ip );
- /* NOTE: we're strict because we don't want
- * to send out bad data */
- if ( ip.bv_len > 128 ) goto param_error;
- }
- if ( sessionSourceName == NULL ) {
- BER_BVSTR( &name, "" );
- } else {
- ber_str2bv( sessionSourceName, 0, 0, &name );
- /* NOTE: we're strict because we don't want
- * to send out bad data */
- if ( name.bv_len > 65536 ) goto param_error;
- }
- ber_str2bv( formatOID, 0, 0, &oid );
- /* NOTE: we're strict because we don't want
- * to send out bad data */
- if ( oid.bv_len > 1024 ) goto param_error;
- if ( sessionTrackingIdentifier == NULL ||
- sessionTrackingIdentifier->bv_val == NULL )
- {
- BER_BVSTR( &id, "" );
- } else {
- id = *sessionTrackingIdentifier;
- }
- /* prepare value */
- value->bv_val = NULL;
- value->bv_len = 0;
- ber = ldap_alloc_ber_with_options( ld );
- if ( ber == NULL ) {
- ld->ld_errno = LDAP_NO_MEMORY;
- return ld->ld_errno;
- }
- tag = ber_printf( ber, "{OOOO}", &ip, &name, &oid, &id );
- if ( tag == LBER_ERROR ) {
- ld->ld_errno = LDAP_ENCODING_ERROR;
- goto done;
- }
- if ( ber_flatten2( ber, value, 1 ) == -1 ) {
- ld->ld_errno = LDAP_NO_MEMORY;
- }
- done:;
- if ( ber != NULL ) {
- ber_free( ber, 1 );
- }
- return ld->ld_errno;
- }
- /*
- * NOTE: this API is bad; it could be much more efficient...
- */
- int
- ldap_create_session_tracking_control(
- LDAP *ld,
- char *sessionSourceIp,
- char *sessionSourceName,
- char *formatOID,
- struct berval *sessionTrackingIdentifier,
- LDAPControl **ctrlp )
- {
- struct berval value;
- if ( ctrlp == NULL ) {
- ld->ld_errno = LDAP_PARAM_ERROR;
- return ld->ld_errno;
- }
- ld->ld_errno = ldap_create_session_tracking_value( ld,
- sessionSourceIp, sessionSourceName, formatOID,
- sessionTrackingIdentifier, &value );
- if ( ld->ld_errno == LDAP_SUCCESS ) {
- ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_SESSION_TRACKING,
- 0, &value, 0, ctrlp );
- if ( ld->ld_errno != LDAP_SUCCESS ) {
- LDAP_FREE( value.bv_val );
- }
- }
- return ld->ld_errno;
- }
- int
- ldap_parse_session_tracking_control(
- LDAP *ld,
- LDAPControl *ctrl,
- struct berval *ip,
- struct berval *name,
- struct berval *oid,
- struct berval *id )
- {
- BerElement *ber;
- ber_tag_t tag;
- ber_len_t len;
- if ( ld == NULL ||
- ctrl == NULL ||
- ip == NULL ||
- name == NULL ||
- oid == NULL ||
- id == NULL )
- {
- if ( ld ) {
- ld->ld_errno = LDAP_PARAM_ERROR;
- }
- /* NOTE: we want the caller to get all or nothing;
- * we could allow some of the pointers to be NULL,
- * if one does not want part of the data */
- return LDAP_PARAM_ERROR;
- }
- BER_BVZERO( ip );
- BER_BVZERO( name );
- BER_BVZERO( oid );
- BER_BVZERO( id );
- ber = ber_init( &ctrl->ldctl_value );
- if ( ber == NULL ) {
- ld->ld_errno = LDAP_NO_MEMORY;
- return ld->ld_errno;
- }
- tag = ber_skip_tag( ber, &len );
- if ( tag != LBER_SEQUENCE ) {
- tag = LBER_ERROR;
- goto error;
- }
- /* sessionSourceIp */
- tag = ber_peek_tag( ber, &len );
- if ( tag == LBER_DEFAULT ) {
- tag = LBER_ERROR;
- goto error;
- }
- if ( len == 0 ) {
- tag = ber_skip_tag( ber, &len );
- } else {
- if ( len > 128 ) {
- /* should be LDAP_DECODING_ERROR,
- * but we're liberal in what we accept */
- }
- tag = ber_scanf( ber, "o", ip );
- }
- /* sessionSourceName */
- tag = ber_peek_tag( ber, &len );
- if ( tag == LBER_DEFAULT ) {
- tag = LBER_ERROR;
- goto error;
- }
- if ( len == 0 ) {
- tag = ber_skip_tag( ber, &len );
- } else {
- if ( len > 65536 ) {
- /* should be LDAP_DECODING_ERROR,
- * but we're liberal in what we accept */
- }
- tag = ber_scanf( ber, "o", name );
- }
- /* formatOID */
- tag = ber_peek_tag( ber, &len );
- if ( tag == LBER_DEFAULT ) {
- tag = LBER_ERROR;
- goto error;
- }
- if ( len == 0 ) {
- ld->ld_errno = LDAP_DECODING_ERROR;
- goto error;
- } else {
- if ( len > 1024 ) {
- /* should be LDAP_DECODING_ERROR,
- * but we're liberal in what we accept */
- }
- tag = ber_scanf( ber, "o", oid );
- }
- /* FIXME: should check if it is an OID... leave it to the caller */
- /* sessionTrackingIdentifier */
- tag = ber_peek_tag( ber, &len );
- if ( tag == LBER_DEFAULT ) {
- tag = LBER_ERROR;
- goto error;
- }
- if ( len == 0 ) {
- tag = ber_skip_tag( ber, &len );
- } else {
- #if 0
- if ( len > 65536 ) {
- /* should be LDAP_DECODING_ERROR,
- * but we're liberal in what we accept */
- }
- #endif
- tag = ber_scanf( ber, "o", id );
- }
- /* closure */
- tag = ber_skip_tag( ber, &len );
- if ( tag == LBER_DEFAULT && len == 0 ) {
- tag = 0;
- }
- error:;
- (void)ber_free( ber, 1 );
- if ( tag == LBER_ERROR ) {
- return LDAP_DECODING_ERROR;
- }
- return ld->ld_errno;
- }
- #endif /* LDAP_CONTROL_X_SESSION_TRACKING */
|