X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fcontrols.c;h=b7f66eeab2faa2a1aa441295f814b7f40bc1a65b;hb=c8d5bcf0c713a372327a686639da6aaa983570b2;hp=072777c69bf109e7ed5ca603a760eaa41926516e;hpb=1a59d091bc974a2e2d5bb2697168e9c830d6bcf6;p=openldap diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index 072777c69b..b7f66eeab2 100644 --- a/servers/slapd/controls.c +++ b/servers/slapd/controls.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * 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 @@ -21,6 +21,7 @@ #include #include "slap.h" +#include "ldif.h" #include "lutil.h" #include "../../libraries/liblber/lber-int.h" @@ -107,6 +108,15 @@ static char *manageDSAit_extops[] = { NULL }; +#ifdef SLAP_CONTROL_X_SESSION_TRACKING +static char *session_tracking_extops[] = { + LDAP_EXOP_MODIFY_PASSWD, + LDAP_EXOP_WHO_AM_I, + LDAP_EXOP_REFRESH, + NULL +}; +#endif + static struct slap_control control_defs[] = { { LDAP_CONTROL_ASSERT, (int)offsetof(struct slap_control_ids, sc_assert), @@ -204,7 +214,7 @@ static struct slap_control control_defs[] = { { LDAP_CONTROL_X_SESSION_TRACKING, (int)offsetof(struct slap_control_ids, sc_sessionTracking), SLAP_CTRL_GLOBAL|SLAP_CTRL_ACCESS|SLAP_CTRL_BIND|SLAP_CTRL_HIDE, - NULL, NULL, + session_tracking_extops, NULL, parseSessionTracking, LDAP_SLIST_ENTRY_INITIALIZER(next) }, #endif { NULL, 0, 0, NULL, 0, NULL, LDAP_SLIST_ENTRY_INITIALIZER(next) } @@ -1040,12 +1050,13 @@ static int parsePagedResults ( 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"; @@ -1070,11 +1081,7 @@ static int parsePagedResults ( * 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 ); @@ -1093,6 +1100,7 @@ static int parsePagedResults ( 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; /* NOTE: according to RFC 2696 3.: @@ -1116,7 +1124,6 @@ static int parsePagedResults ( } done:; - (void)ber_free( ber, 1 ); return rc; } @@ -1597,6 +1604,17 @@ static int parseSearchOptions ( } #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, @@ -1605,7 +1623,7 @@ static int parseSessionTracking( BerElement *ber; ber_tag_t tag; ber_len_t len; - int rc; + int i, rc; struct berval sessionSourceIp = BER_BVNULL, sessionSourceName = BER_BVNULL, @@ -1629,6 +1647,9 @@ static int parseSessionTracking( 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"; @@ -1714,6 +1735,14 @@ static int parseSessionTracking( 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 ) { @@ -1727,17 +1756,19 @@ static int parseSessionTracking( } 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 ) ) { @@ -1749,7 +1780,8 @@ static int parseSessionTracking( } 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 ) { @@ -1780,7 +1812,8 @@ static int parseSessionTracking( 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 ); } @@ -1799,4 +1832,73 @@ error:; 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