2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1998-2014 The OpenLDAP Foundation.
5 * Portions Copyright 2007 Pierangelo Masarati.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
17 * This work was developed by Pierangelo Masarati for inclusion in
24 #include <ac/stdlib.h>
25 #include <ac/string.h>
30 #ifdef LDAP_CONTROL_X_SESSION_TRACKING
33 * Client-side of <draft-wahl-ldap-session-03>
37 ldap_create_session_tracking_value(
39 char *sessionSourceIp,
40 char *sessionSourceName,
42 struct berval *sessionTrackingIdentifier,
43 struct berval *value )
45 BerElement *ber = NULL;
48 struct berval ip, name, oid, id;
56 ld->ld_errno = LDAP_PARAM_ERROR;
59 return LDAP_PARAM_ERROR;
62 assert( LDAP_VALID( ld ) );
63 ld->ld_errno = LDAP_SUCCESS;
65 /* check sizes according to I.D. */
66 if ( sessionSourceIp == NULL ) {
70 ber_str2bv( sessionSourceIp, 0, 0, &ip );
71 /* NOTE: we're strict because we don't want
72 * to send out bad data */
73 if ( ip.bv_len > 128 ) goto param_error;
76 if ( sessionSourceName == NULL ) {
77 BER_BVSTR( &name, "" );
80 ber_str2bv( sessionSourceName, 0, 0, &name );
81 /* NOTE: we're strict because we don't want
82 * to send out bad data */
83 if ( name.bv_len > 65536 ) goto param_error;
86 ber_str2bv( formatOID, 0, 0, &oid );
87 /* NOTE: we're strict because we don't want
88 * to send out bad data */
89 if ( oid.bv_len > 1024 ) goto param_error;
91 if ( sessionTrackingIdentifier == NULL ||
92 sessionTrackingIdentifier->bv_val == NULL )
97 id = *sessionTrackingIdentifier;
101 value->bv_val = NULL;
104 ber = ldap_alloc_ber_with_options( ld );
106 ld->ld_errno = LDAP_NO_MEMORY;
110 tag = ber_printf( ber, "{OOOO}", &ip, &name, &oid, &id );
111 if ( tag == LBER_ERROR ) {
112 ld->ld_errno = LDAP_ENCODING_ERROR;
116 if ( ber_flatten2( ber, value, 1 ) == -1 ) {
117 ld->ld_errno = LDAP_NO_MEMORY;
129 * NOTE: this API is bad; it could be much more efficient...
132 ldap_create_session_tracking_control(
134 char *sessionSourceIp,
135 char *sessionSourceName,
137 struct berval *sessionTrackingIdentifier,
138 LDAPControl **ctrlp )
142 if ( ctrlp == NULL ) {
143 ld->ld_errno = LDAP_PARAM_ERROR;
147 ld->ld_errno = ldap_create_session_tracking_value( ld,
148 sessionSourceIp, sessionSourceName, formatOID,
149 sessionTrackingIdentifier, &value );
150 if ( ld->ld_errno == LDAP_SUCCESS ) {
151 ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_SESSION_TRACKING,
152 0, &value, 0, ctrlp );
153 if ( ld->ld_errno != LDAP_SUCCESS ) {
154 LDAP_FREE( value.bv_val );
162 ldap_parse_session_tracking_control(
182 ld->ld_errno = LDAP_PARAM_ERROR;
185 /* NOTE: we want the caller to get all or nothing;
186 * we could allow some of the pointers to be NULL,
187 * if one does not want part of the data */
188 return LDAP_PARAM_ERROR;
196 ber = ber_init( &ctrl->ldctl_value );
199 ld->ld_errno = LDAP_NO_MEMORY;
203 tag = ber_skip_tag( ber, &len );
204 if ( tag != LBER_SEQUENCE ) {
209 /* sessionSourceIp */
210 tag = ber_peek_tag( ber, &len );
211 if ( tag == LBER_DEFAULT ) {
217 tag = ber_skip_tag( ber, &len );
221 /* should be LDAP_DECODING_ERROR,
222 * but we're liberal in what we accept */
224 tag = ber_scanf( ber, "o", ip );
227 /* sessionSourceName */
228 tag = ber_peek_tag( ber, &len );
229 if ( tag == LBER_DEFAULT ) {
235 tag = ber_skip_tag( ber, &len );
239 /* should be LDAP_DECODING_ERROR,
240 * but we're liberal in what we accept */
242 tag = ber_scanf( ber, "o", name );
246 tag = ber_peek_tag( ber, &len );
247 if ( tag == LBER_DEFAULT ) {
253 ld->ld_errno = LDAP_DECODING_ERROR;
258 /* should be LDAP_DECODING_ERROR,
259 * but we're liberal in what we accept */
261 tag = ber_scanf( ber, "o", oid );
264 /* FIXME: should check if it is an OID... leave it to the caller */
266 /* sessionTrackingIdentifier */
267 tag = ber_peek_tag( ber, &len );
268 if ( tag == LBER_DEFAULT ) {
274 tag = ber_skip_tag( ber, &len );
279 /* should be LDAP_DECODING_ERROR,
280 * but we're liberal in what we accept */
283 tag = ber_scanf( ber, "o", id );
287 tag = ber_skip_tag( ber, &len );
288 if ( tag == LBER_DEFAULT && len == 0 ) {
293 (void)ber_free( ber, 1 );
295 if ( tag == LBER_ERROR ) {
296 return LDAP_DECODING_ERROR;
302 #endif /* LDAP_CONTROL_X_SESSION_TRACKING */