/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1998-2007 The OpenLDAP Foundation.
+ * Copyright 1998-2008 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include <ac/socket.h>
#include "slap.h"
+#include "ldif.h"
#include "lutil.h"
#include "../../libraries/liblber/lber-int.h"
SlapReply *rs,
LDAPControl *ctrl )
{
+ BerElementBuffer berbuf;
+ BerElement *ber = (BerElement *)&berbuf;
+ struct berval cookie;
+ PagedResultsState *ps;
int rc = LDAP_SUCCESS;
ber_tag_t tag;
ber_int_t size;
- BerElement *ber;
- struct berval cookie = BER_BVNULL;
- PagedResultsState *ps;
if ( op->o_pagedresults != SLAP_CONTROL_NONE ) {
rs->sr_text = "paged results control specified multiple times";
* cookie OCTET STRING
* }
*/
- ber = ber_init( &ctrl->ldctl_value );
- if ( ber == NULL ) {
- rs->sr_text = "internal error";
- return LDAP_OTHER;
- }
+ ber_init2( ber, &ctrl->ldctl_value, LBER_USE_DER );
tag = ber_scanf( ber, "{im}", &size, &cookie );
ps = op->o_tmpalloc( sizeof(PagedResultsState), op->o_tmpmemctx );
*ps = op->o_conn->c_pagedresults_state;
ps->ps_size = size;
+ ps->ps_cookieval = cookie;
op->o_pagedresults_state = ps;
+ if ( !cookie.bv_len ) {
+ ps->ps_count = 0;
+ ps->ps_cookie = 0;
+ }
/* NOTE: according to RFC 2696 3.:
}
done:;
- (void)ber_free( ber, 1 );
return rc;
}
}
#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+struct berval session_tracking_formats[] = {
+ BER_BVC( LDAP_CONTROL_X_SESSION_TRACKING_RADIUS_ACCT_SESSION_ID ),
+ BER_BVC( "RADIUS-Acct-Session-Id" ),
+ BER_BVC( LDAP_CONTROL_X_SESSION_TRACKING_RADIUS_ACCT_MULTI_SESSION_ID ),
+ BER_BVC( "RADIUS-Acct-Multi-Session-Id" ),
+ BER_BVC( LDAP_CONTROL_X_SESSION_TRACKING_USERNAME ),
+ BER_BVC( "USERNAME" ),
+
+ BER_BVNULL
+};
+
static int parseSessionTracking(
Operation *op,
SlapReply *rs,
BerElement *ber;
ber_tag_t tag;
ber_len_t len;
- int rc;
+ int i, rc;
struct berval sessionSourceIp = BER_BVNULL,
sessionSourceName = BER_BVNULL,
return LDAP_PROTOCOL_ERROR;
}
+ /* TODO: add the capability to determine if a client is allowed
+ * to use this control, based on identity, ip and so */
+
ber = ber_init( &ctrl->ldctl_value );
if ( ber == NULL ) {
rs->sr_text = "internal error";
goto error;
}
+ for ( i = 0; !BER_BVISNULL( &session_tracking_formats[ i ] ); i += 2 )
+ {
+ if ( bvmatch( &formatOID, &session_tracking_formats[ i ] ) ) {
+ formatOID = session_tracking_formats[ i + 1 ];
+ break;
+ }
+ }
+
/* sessionTrackingIdentifier */
tag = ber_peek_tag( ber, &len );
if ( tag == LBER_DEFAULT ) {
} else {
/* note: should not be more than 65536... */
tag = ber_scanf( ber, "m", &sessionTrackingIdentifier );
- }
-
- if ( ldif_is_not_printable( sessionTrackingIdentifier.bv_val, sessionTrackingIdentifier.bv_len ) ) {
- BER_BVZERO( &sessionTrackingIdentifier );
+ if ( ldif_is_not_printable( sessionTrackingIdentifier.bv_val, sessionTrackingIdentifier.bv_len ) ) {
+ /* we want the OID printed, at least */
+ BER_BVSTR( &sessionTrackingIdentifier, "" );
+ }
}
/* closure */
tag = ber_skip_tag( ber, &len );
- if ( tag == LBER_DEFAULT && len == 0 ) {
- tag = 0;
+ if ( tag != LBER_DEFAULT || len != 0 ) {
+ tag = LBER_ERROR;
+ goto error;
}
+ tag = 0;
st_len = 0;
if ( !BER_BVISNULL( &sessionSourceIp ) ) {
}
if ( !BER_BVISNULL( &sessionTrackingIdentifier ) ) {
if ( st_len ) st_len++;
- st_len += STRLENOF( "ID=" ) + sessionTrackingIdentifier.bv_len;
+ st_len += formatOID.bv_len + STRLENOF( "=" )
+ + sessionTrackingIdentifier.bv_len;
}
if ( st_len == 0 ) {
if ( !BER_BVISNULL( &sessionTrackingIdentifier ) ) {
if ( st_len ) *ptr++ = ' ';
- ptr = lutil_strcopy( ptr, "ID=" );
+ ptr = lutil_strcopy( ptr, formatOID.bv_val );
+ *ptr++ = '=';
ptr = lutil_strcopy( ptr, sessionTrackingIdentifier.bv_val );
}
return rs->sr_err;
}
+
+int
+slap_ctrl_session_tracking_add(
+ Operation *op,
+ SlapReply *rs,
+ struct berval *ip,
+ struct berval *name,
+ struct berval *id,
+ LDAPControl *ctrl )
+{
+ BerElementBuffer berbuf;
+ BerElement *ber = (BerElement *)&berbuf;
+
+ static struct berval oid = BER_BVC( LDAP_CONTROL_X_SESSION_TRACKING_USERNAME );
+
+ assert( ctrl != NULL );
+
+ ber_init2( ber, NULL, LBER_USE_DER );
+
+ ber_printf( ber, "{OOOO}", ip, name, &oid, id );
+
+ if ( ber_flatten2( ber, &ctrl->ldctl_value, 0 ) == -1 ) {
+ rs->sr_err = LDAP_OTHER;
+ goto done;
+ }
+
+ ctrl->ldctl_oid = LDAP_CONTROL_X_SESSION_TRACKING;
+ ctrl->ldctl_iscritical = 0;
+
+ rs->sr_err = LDAP_SUCCESS;
+
+done:;
+ return rs->sr_err;
+}
+
+int
+slap_ctrl_session_tracking_request_add( Operation *op, SlapReply *rs, LDAPControl *ctrl )
+{
+ static struct berval bv_unknown = BER_BVC( SLAP_STRING_UNKNOWN );
+ struct berval ip = BER_BVNULL,
+ name = BER_BVNULL,
+ id = BER_BVNULL;
+
+ if ( !BER_BVISNULL( &op->o_conn->c_peer_name ) &&
+ memcmp( op->o_conn->c_peer_name.bv_val, "IP=", STRLENOF( "IP=" ) ) == 0 )
+ {
+ char *ptr;
+
+ ip.bv_val = op->o_conn->c_peer_name.bv_val + STRLENOF( "IP=" );
+ ip.bv_len = op->o_conn->c_peer_name.bv_len - STRLENOF( "IP=" );
+
+ ptr = ber_bvchr( &ip, ':' );
+ if ( ptr ) {
+ ip.bv_len = ptr - ip.bv_val;
+ }
+ }
+
+ if ( !BER_BVISNULL( &op->o_conn->c_peer_domain ) &&
+ !bvmatch( &op->o_conn->c_peer_domain, &bv_unknown ) )
+ {
+ name = op->o_conn->c_peer_domain;
+ }
+
+ if ( !BER_BVISNULL( &op->o_dn ) && !BER_BVISEMPTY( &op->o_dn ) ) {
+ id = op->o_dn;
+ }
+
+ return slap_ctrl_session_tracking_add( op, rs, &ip, &name, &id, ctrl );
+}
#endif