]> git.sur5r.net Git - openldap/commitdiff
minimal implementation of draft-wahl-ldap-session-03
authorPierangelo Masarati <ando@openldap.org>
Tue, 21 Aug 2007 22:47:54 +0000 (22:47 +0000)
committerPierangelo Masarati <ando@openldap.org>
Tue, 21 Aug 2007 22:47:54 +0000 (22:47 +0000)
servers/slapd/controls.c
servers/slapd/slap.h

index c89708dbf2fc537f60d8f931caf235c8f2e335d1..072777c69bf109e7ed5ca603a760eaa41926516e 100644 (file)
@@ -21,6 +21,7 @@
 #include <ac/socket.h>
 
 #include "slap.h"
+#include "lutil.h"
 
 #include "../../libraries/liblber/lber-int.h"
 
@@ -43,6 +44,9 @@ static SLAP_CTRL_PARSE_FN parseSubentries;
 static SLAP_CTRL_PARSE_FN parseTreeDelete;
 #endif
 static SLAP_CTRL_PARSE_FN parseValuesReturnFilter;
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+static SLAP_CTRL_PARSE_FN parseSessionTracking;
+#endif
 
 #undef sc_mask /* avoid conflict with Irix 6.5 <sys/signal.h> */
 
@@ -196,6 +200,13 @@ static struct slap_control control_defs[] = {
                SLAP_CTRL_GLOBAL|SLAP_CTRL_ACCESS,
                proxy_authz_extops, NULL,
                parseProxyAuthz, LDAP_SLIST_ENTRY_INITIALIZER(next) },
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+       { 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,
+               parseSessionTracking, LDAP_SLIST_ENTRY_INITIALIZER(next) },
+#endif
        { NULL, 0, 0, NULL, 0, NULL, LDAP_SLIST_ENTRY_INITIALIZER(next) }
 };
 
@@ -1585,3 +1596,207 @@ static int parseSearchOptions (
        return LDAP_SUCCESS;
 }
 
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+static int parseSessionTracking(
+       Operation *op,
+       SlapReply *rs,
+       LDAPControl *ctrl )
+{
+       BerElement              *ber;
+       ber_tag_t               tag;
+       ber_len_t               len;
+       int                     rc;
+
+       struct berval           sessionSourceIp = BER_BVNULL,
+                               sessionSourceName = BER_BVNULL,
+                               formatOID = BER_BVNULL,
+                               sessionTrackingIdentifier = BER_BVNULL;
+
+       size_t                  st_len, st_pos;
+
+       if ( ctrl->ldctl_iscritical ) {
+               rs->sr_text = "sessionTracking criticality is TRUE";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       if ( BER_BVISNULL( &ctrl->ldctl_value ) ) {
+               rs->sr_text = "sessionTracking control value is absent";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ) {
+               rs->sr_text = "sessionTracking control value is empty";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       ber = ber_init( &ctrl->ldctl_value );
+       if ( ber == NULL ) {
+               rs->sr_text = "internal error";
+               return LDAP_OTHER;
+       }
+
+       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 ) {
+               rs->sr_text = "sessionTracking.sessionSourceIp too long";
+               rs->sr_err = LDAP_PROTOCOL_ERROR;
+               goto error;
+
+       } else {
+               tag = ber_scanf( ber, "m", &sessionSourceIp );
+       }
+
+       if ( ldif_is_not_printable( sessionSourceIp.bv_val, sessionSourceIp.bv_len ) ) {
+               BER_BVZERO( &sessionSourceIp );
+       }
+
+       /* 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 ) {
+               rs->sr_text = "sessionTracking.sessionSourceName too long";
+               rs->sr_err = LDAP_PROTOCOL_ERROR;
+               goto error;
+
+       } else {
+               tag = ber_scanf( ber, "m", &sessionSourceName );
+       }
+
+       if ( ldif_is_not_printable( sessionSourceName.bv_val, sessionSourceName.bv_len ) ) {
+               BER_BVZERO( &sessionSourceName );
+       }
+
+       /* formatOID */
+       tag = ber_peek_tag( ber, &len );
+       if ( tag == LBER_DEFAULT ) {
+               tag = LBER_ERROR;
+               goto error;
+       }
+
+       if ( len == 0 ) {
+               rs->sr_text = "sessionTracking.formatOID empty";
+               rs->sr_err = LDAP_PROTOCOL_ERROR;
+               goto error;
+
+       } else if ( len > 1024 ) {
+               rs->sr_text = "sessionTracking.formatOID too long";
+               rs->sr_err = LDAP_PROTOCOL_ERROR;
+               goto error;
+
+       } else {
+               tag = ber_scanf( ber, "m", &formatOID );
+       }
+
+       rc = numericoidValidate( NULL, &formatOID );
+       if ( rc != LDAP_SUCCESS ) {
+               rs->sr_text = "sessionTracking.formatOID invalid";
+               goto error;
+       }
+
+       /* 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 {
+               /* 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 );
+       }
+
+       /* closure */
+       tag = ber_skip_tag( ber, &len );
+       if ( tag == LBER_DEFAULT && len == 0 ) {
+               tag = 0;
+       }
+
+       st_len = 0;
+       if ( !BER_BVISNULL( &sessionSourceIp ) ) {
+               st_len += STRLENOF( "IP=" ) + sessionSourceIp.bv_len;
+       }
+       if ( !BER_BVISNULL( &sessionSourceName ) ) {
+               if ( st_len ) st_len++;
+               st_len += STRLENOF( "NAME=" ) + sessionSourceName.bv_len;
+       }
+       if ( !BER_BVISNULL( &sessionTrackingIdentifier ) ) {
+               if ( st_len ) st_len++;
+               st_len += STRLENOF( "ID=" ) + sessionTrackingIdentifier.bv_len;
+       }
+
+       if ( st_len == 0 ) {
+               goto error;
+       }
+
+       st_len += STRLENOF( " []" );
+       st_pos = strlen( op->o_log_prefix );
+
+       if ( sizeof( op->o_log_prefix ) - st_pos > st_len ) {
+               char    *ptr = &op->o_log_prefix[ st_pos ];
+
+               ptr = lutil_strcopy( ptr, " [" /*]*/ );
+
+               st_len = 0;
+               if ( !BER_BVISNULL( &sessionSourceIp ) ) {
+                       ptr = lutil_strcopy( ptr, "IP=" );
+                       ptr = lutil_strcopy( ptr, sessionSourceIp.bv_val );
+                       st_len++;
+               }
+
+               if ( !BER_BVISNULL( &sessionSourceName ) ) {
+                       if ( st_len ) *ptr++ = ' ';
+                       ptr = lutil_strcopy( ptr, "NAME=" );
+                       ptr = lutil_strcopy( ptr, sessionSourceName.bv_val );
+                       st_len++;
+               }
+
+               if ( !BER_BVISNULL( &sessionTrackingIdentifier ) ) {
+                       if ( st_len ) *ptr++ = ' ';
+                       ptr = lutil_strcopy( ptr, "ID=" );
+                       ptr = lutil_strcopy( ptr, sessionTrackingIdentifier.bv_val );
+               }
+
+               *ptr++ = /*[*/ ']';
+               *ptr = '\0';
+       }
+
+error:;
+       (void)ber_free( ber, 1 );
+
+       if ( tag == LBER_ERROR ) {
+               rs->sr_text = "sessionTracking control decoding error";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+
+       return rs->sr_err;
+}
+#endif
index 4c001956eb1f5cf4b0a3cf8e526ae19c7478e4c0..818a36bbac5c6b51e4393abd0430472f42f855f8 100644 (file)
@@ -65,6 +65,7 @@ LDAP_BEGIN_DECL
 #define LDAP_COMP_MATCH
 #define LDAP_SYNC_TIMESTAMP
 #define SLAP_CONTROL_X_SORTEDRESULTS
+#define SLAP_CONTROL_X_SESSION_TRACKING
 #endif
 
 #define LDAP_DYNAMIC_OBJECTS
@@ -2356,6 +2357,9 @@ struct slap_control_ids {
 #endif
 #ifdef LDAP_X_TXN
        int sc_txnSpec;
+#endif
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+       int sc_sessionTracking;
 #endif
        int sc_valuesReturnFilter;
 };
@@ -2377,7 +2381,7 @@ typedef struct Opheader {
        void    *oh_tmpmemctx;          /* slab malloc context */
        BerMemoryFunctions *oh_tmpmfuncs;
 
-       char            oh_log_prefix[sizeof("conn=18446744073709551615 op=18446744073709551615")];
+       char            oh_log_prefix[ /* sizeof("conn=18446744073709551615 op=18446744073709551615") */ SLAP_TEXT_BUFLEN ];
 
 #ifdef LDAP_SLAPI
        void    *oh_extensions;         /* NS-SLAPI plugin */
@@ -2571,6 +2575,12 @@ struct Operation {
 #define o_txnSpec              o_ctrlflag[slap_cids.sc_txnSpec]
 #endif
 
+#ifdef SLAP_CONTROL_X_SESSION_TRACKING
+#define o_session_tracking     o_ctrlflag[slap_cids.sc_sessionTracking]
+#define o_tracked_sessions     o_controls[slap_cids.sc_sessionTracking]
+#define get_sessionTracking(op)                        ((int)(op)->o_session_tracking)
+#endif
+
 #define o_sync                 o_ctrlflag[slap_cids.sc_LDAPsync]
 
        AuthorizationInformation o_authz;