mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-20 22:59:34 -05:00
client side of draft-wahl-ldap-session
This commit is contained in:
parent
1a59d091bc
commit
b0d2063d92
4 changed files with 397 additions and 5 deletions
|
|
@ -33,6 +33,7 @@
|
|||
#include <ac/unistd.h>
|
||||
#include <ac/errno.h>
|
||||
#include <ac/time.h>
|
||||
#include <ac/socket.h>
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
#ifdef HAVE_SASL_SASL_H
|
||||
|
|
@ -113,6 +114,10 @@ int chaining = 0;
|
|||
static int chainingResolve = -1;
|
||||
static int chainingContinuation = -1;
|
||||
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
|
||||
#ifdef LDAP_CONTROL_X_SESSION_TRACKING
|
||||
static int sessionTracking = 0;
|
||||
struct berval stValue;
|
||||
#endif /* LDAP_CONTROL_X_SESSION_TRACKING */
|
||||
|
||||
LDAPControl *unknown_ctrls = NULL;
|
||||
int unknown_ctrls_num = 0;
|
||||
|
|
@ -204,6 +209,9 @@ N_(" [!]preread[=<attrs>] (a comma-separated attribute list)\n")
|
|||
#ifdef LDAP_DEVEL
|
||||
N_(" [!]relax\n")
|
||||
#endif
|
||||
#ifdef LDAP_CONTROL_X_SESSION_TRACKING
|
||||
N_(" [!]sessiontracking\n")
|
||||
#endif /* LDAP_CONTROL_X_SESSION_TRACKING */
|
||||
N_(" abandon, cancel, ignore (SIGINT sends abandon/cancel,\n"
|
||||
" or ignores response; if critical, doesn't wait for SIGINT.\n"
|
||||
" not really controls)\n")
|
||||
|
|
@ -522,6 +530,15 @@ tool_args( int argc, char **argv )
|
|||
gotintr = abcan;
|
||||
}
|
||||
|
||||
#ifdef LDAP_CONTROL_X_SESSION_TRACKING
|
||||
} else if ( strcasecmp( control, "sessiontracking" ) == 0 ) {
|
||||
if ( sessionTracking ) {
|
||||
fprintf( stderr, "%s: session tracking can be only specified once\n", prog );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
sessionTracking = 1;
|
||||
#endif /* LDAP_CONTROL_X_SESSION_TRACKING */
|
||||
|
||||
} else if ( tool_is_oid( control ) ) {
|
||||
LDAPControl *tmpctrls, ctrl;
|
||||
|
||||
|
|
@ -935,6 +952,9 @@ tool_args( int argc, char **argv )
|
|||
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
|
||||
chaining ||
|
||||
#endif
|
||||
#ifdef LDAP_CONTROL_X_SESSION_TRACKING
|
||||
sessionTracking ||
|
||||
#endif /* LDAP_CONTROL_X_SESSION_TRACKING */
|
||||
noop || ppolicy || preread || postread )
|
||||
{
|
||||
fprintf( stderr, "%s: -e/-M incompatible with LDAPv2\n", prog );
|
||||
|
|
@ -1355,7 +1375,7 @@ void
|
|||
tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
|
||||
{
|
||||
int i = 0, j, crit = 0, err;
|
||||
LDAPControl c[12], **ctrls;
|
||||
LDAPControl c[16], **ctrls;
|
||||
|
||||
if ( ! ( assertctl
|
||||
|| authzid
|
||||
|
|
@ -1373,6 +1393,9 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
|
|||
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
|
||||
|| chaining
|
||||
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
|
||||
#ifdef LDAP_CONTROL_X_SESSION_TRACKING
|
||||
|| sessionTracking
|
||||
#endif /* LDAP_CONTROL_X_SESSION_TRACKING */
|
||||
|| count
|
||||
|| unknown_ctrls_num ) )
|
||||
{
|
||||
|
|
@ -1587,6 +1610,59 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
|
|||
}
|
||||
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
|
||||
|
||||
#ifdef LDAP_CONTROL_X_SESSION_TRACKING
|
||||
if ( sessionTracking ) {
|
||||
if ( stValue.bv_val == NULL ) {
|
||||
char *ip = NULL, *name = NULL;
|
||||
struct berval id = { 0 };
|
||||
char namebuf[ HOST_NAME_MAX ];
|
||||
|
||||
if ( gethostname( namebuf, sizeof( namebuf ) ) == 0 ) {
|
||||
struct hostent *h;
|
||||
struct in_addr addr;
|
||||
|
||||
name = namebuf;
|
||||
|
||||
h = gethostbyname( name );
|
||||
if ( h != NULL ) {
|
||||
AC_MEMCPY( &addr, h->h_addr, sizeof( addr ) );
|
||||
ip = inet_ntoa( addr );
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
if ( sasl_authz_id != NULL ) {
|
||||
ber_str2bv( sasl_authz_id, 0, 0, &id );
|
||||
|
||||
} else if ( sasl_authc_id != NULL ) {
|
||||
ber_str2bv( sasl_authc_id, 0, 0, &id );
|
||||
|
||||
} else
|
||||
#endif /* HAVE_CYRUS_SASL */
|
||||
if ( binddn != NULL ) {
|
||||
ber_str2bv( binddn, 0, 0, &id );
|
||||
|
||||
} else {
|
||||
ber_str2bv( "anonymous", 0, 0, &id );
|
||||
}
|
||||
|
||||
if ( ldap_create_session_tracking_value( ld,
|
||||
ip, name, "1.3.6.1.4.1.21008.108.63.1.3", &id,
|
||||
&stValue ) )
|
||||
{
|
||||
fprintf( stderr, _("Session tracking control encoding error!\n") );
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
|
||||
c[i].ldctl_oid = LDAP_CONTROL_X_SESSION_TRACKING;
|
||||
c[i].ldctl_iscritical = 0;
|
||||
ber_dupbv( &c[i].ldctl_value, &stValue );
|
||||
ctrls[i] = &c[i];
|
||||
i++;
|
||||
}
|
||||
#endif /* LDAP_CONTROL_X_SESSION_TRACKING */
|
||||
|
||||
while ( count-- ) {
|
||||
ctrls[i++] = extra_c++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ SRCS = bind.c open.c result.c error.c compare.c search.c \
|
|||
request.c os-ip.c url.c pagectrl.c sortctrl.c vlvctrl.c \
|
||||
init.c options.c print.c string.c util-int.c schema.c \
|
||||
charray.c tls.c os-local.c dnssrv.c utf-8.c utf-8-conv.c \
|
||||
turn.c ppolicy.c dds.c txn.c ldap_sync.c
|
||||
turn.c ppolicy.c dds.c txn.c ldap_sync.c stctrl.c
|
||||
|
||||
OBJS = bind.lo open.lo result.lo error.lo compare.lo search.lo \
|
||||
controls.lo messages.lo references.lo extended.lo cyrus.lo \
|
||||
|
|
@ -37,7 +37,7 @@ OBJS = bind.lo open.lo result.lo error.lo compare.lo search.lo \
|
|||
request.lo os-ip.lo url.lo pagectrl.lo sortctrl.lo vlvctrl.lo \
|
||||
init.lo options.lo print.lo string.lo util-int.lo schema.lo \
|
||||
charray.lo tls.lo os-local.lo dnssrv.lo utf-8.lo utf-8-conv.lo \
|
||||
turn.lo ppolicy.lo dds.lo txn.lo ldap_sync.lo
|
||||
turn.lo ppolicy.lo dds.lo txn.lo ldap_sync.lo stctrl.lo
|
||||
|
||||
LDAP_INCDIR= ../../include
|
||||
LDAP_LIBDIR= ../../libraries
|
||||
|
|
|
|||
316
libraries/libldap/stctrl.c
Normal file
316
libraries/libldap/stctrl.c
Normal file
|
|
@ -0,0 +1,316 @@
|
|||
/* $OpenLDAP$ */
|
||||
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
*
|
||||
* Copyright 1998-2007 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 ) );
|
||||
|
||||
/* 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(
|
||||
LDAP *ld,
|
||||
char *sessionSourceIp,
|
||||
char *sessionSourceName,
|
||||
char *formatOID,
|
||||
struct berval *sessionTrackingIdentifier,
|
||||
LDAPControl **ctrlp )
|
||||
{
|
||||
struct berval value;
|
||||
BerElement *ber;
|
||||
|
||||
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 ) {
|
||||
ber = ldap_alloc_ber_with_options( ld );
|
||||
if ( ber == NULL ) {
|
||||
ld->ld_errno = LDAP_NO_MEMORY;
|
||||
return LDAP_NO_MEMORY;
|
||||
}
|
||||
|
||||
ld->ld_errno = ldap_create_control( LDAP_CONTROL_X_SESSION_TRACKING,
|
||||
ber, 0, ctrlp );
|
||||
if ( ld->ld_errno == LDAP_SUCCESS ) {
|
||||
(*ctrlp)->ldctl_value = value;
|
||||
|
||||
} else {
|
||||
LDAP_FREE( value.bv_val );
|
||||
}
|
||||
ber_free( ber, 1 );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ip->bv_val = NULL;
|
||||
ip->bv_len = 0;
|
||||
name->bv_val = NULL;
|
||||
name->bv_len = 0;
|
||||
oid->bv_val = NULL;
|
||||
oid->bv_len = 0;
|
||||
id->bv_val = NULL;
|
||||
id->bv_len = 0;
|
||||
|
||||
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 */
|
||||
|
|
@ -28,7 +28,7 @@ XXSRCS = apitest.c test.c \
|
|||
request.c os-ip.c url.c pagectrl.c sortctrl.c vlvctrl.c \
|
||||
init.c options.c print.c string.c util-int.c schema.c \
|
||||
charray.c tls.c os-local.c dnssrv.c utf-8.c utf-8-conv.c \
|
||||
turn.c ppolicy.c dds.c txn.c ldap_sync.c
|
||||
turn.c ppolicy.c dds.c txn.c ldap_sync.c stctrl.c
|
||||
SRCS = threads.c rdwr.c rmutex.c tpool.c rq.c \
|
||||
thr_posix.c thr_cthreads.c thr_thr.c thr_lwp.c thr_nt.c \
|
||||
thr_pth.c thr_stub.c thr_debug.c
|
||||
|
|
@ -44,7 +44,7 @@ OBJS = threads.lo rdwr.lo rmutex.lo tpool.lo rq.lo \
|
|||
request.lo os-ip.lo url.lo pagectrl.lo sortctrl.lo vlvctrl.lo \
|
||||
init.lo options.lo print.lo string.lo util-int.lo schema.lo \
|
||||
charray.lo tls.lo os-local.lo dnssrv.lo utf-8.lo utf-8-conv.lo \
|
||||
turn.lo ppolicy.lo dds.lo txn.lo ldap_sync.lo
|
||||
turn.lo ppolicy.lo dds.lo txn.lo ldap_sync.lo stctrl.lo
|
||||
|
||||
LDAP_INCDIR= ../../include
|
||||
LDAP_LIBDIR= ../../libraries
|
||||
|
|
|
|||
Loading…
Reference in a new issue