summaryrefslogtreecommitdiffstats
path: root/ldap
diff options
context:
space:
mode:
authorNathan Kinder <nkinder@redhat.com>2009-10-02 13:47:38 -0700
committerNathan Kinder <nkinder@redhat.com>2009-10-02 13:47:38 -0700
commit5593a5f7da88ae37ae032b95c7a3a369e8d61a1a (patch)
treeee0802fd37f211498a7fe5c462c97dbf7cbff9ad /ldap
parentab6e5a77de769f55d55e70d7754ec732385e7067 (diff)
downloadds-5593a5f7da88ae37ae032b95c7a3a369e8d61a1a.tar.gz
ds-5593a5f7da88ae37ae032b95c7a3a369e8d61a1a.tar.xz
ds-5593a5f7da88ae37ae032b95c7a3a369e8d61a1a.zip
Add ssf bind rule to access control plug-in.
This patch adds a new ssf bind rule keyword to the access control plug-in. This allows you to write ACIs that require a specific level of encryption for the rule to apply. The new keyword can be used with '=', '!=', '<', '>', '<=' and '>=' comparators. I added code that stores the SSF in effect for an operation into the operation struct. The value that we store is the higher of the two between the SASL SSF and the SSL/TLS SSF.
Diffstat (limited to 'ldap')
-rw-r--r--ldap/servers/plugins/acl/acl.h12
-rw-r--r--ldap/servers/plugins/acl/acl_ext.c15
-rw-r--r--ldap/servers/plugins/acl/aclinit.c7
-rw-r--r--ldap/servers/plugins/acl/acllas.c176
-rw-r--r--ldap/servers/plugins/acl/aclparse.c5
-rw-r--r--ldap/servers/plugins/acl/aclutil.c4
-rw-r--r--ldap/servers/slapd/connection.c17
-rw-r--r--ldap/servers/slapd/pblock.c6
-rw-r--r--ldap/servers/slapd/slap.h1
-rw-r--r--ldap/servers/slapd/slapi-plugin.h1
10 files changed, 225 insertions, 19 deletions
diff --git a/ldap/servers/plugins/acl/acl.h b/ldap/servers/plugins/acl/acl.h
index bccf4c54..d8bc5070 100644
--- a/ldap/servers/plugins/acl/acl.h
+++ b/ldap/servers/plugins/acl/acl.h
@@ -68,6 +68,7 @@
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
+#include <limits.h>
#ifndef _WIN32
#include <sys/socket.h>
#include <netinet/in.h>
@@ -147,6 +148,7 @@ static char* const access_str_proxy = "proxy";
#define DS_LAS_USERATTR "userattr"
#define DS_LAS_ROLEDN "roledn"
#define DS_LAS_ROLEDNATTR "rolednattr"
+#define DS_LAS_SSF "ssf"
/* These define the things that aclutil_evaluate_macro() supports */
@@ -203,6 +205,7 @@ typedef enum
#define DS_PROP_ACLPB "aclblock"
#define DS_ATTR_AUTHTYPE "authtype"
#define DS_ATTR_CERT "clientcert"
+#define DS_ATTR_SSF "ssf"
#define ACL_ANOM_MAX_ACL 40
struct scoped_entry_anominfo {
@@ -294,6 +297,7 @@ typedef struct aci {
#define ACI_PARAM_ATTRRULE (short) 0x0800
#define ACI_USERDN_SELFRULE (short) 0x1000
#define ACI_ROLEDN_RULE (short) 0x2000
+#define ACI_SSF_RULE (short) 0x4000
@@ -645,7 +649,7 @@ typedef struct {
int anomUser;
Acl_PBlock *aclpb;
Slapi_Entry *resourceEntry;
-
+ int ssf;
}lasInfo;
@@ -759,6 +763,12 @@ extern int DS_LASUserAttrEval(NSErr_t *errp, char *attribute,
PList_t subject, PList_t resource, PList_t auth_info,
PList_t global_auth);
+extern int DS_LASSSFEval(NSErr_t *errp, char *attribute,
+ CmpOp_t comparator,
+ char *pattern, int *cachable, void **las_cookie,
+ PList_t subject, PList_t resource, PList_t auth_info,
+ PList_t global_auth);
+
/* other function declaration */
int aclinit_main();
int acl_match_substring (struct slapi_filter *f, char *str, int match);
diff --git a/ldap/servers/plugins/acl/acl_ext.c b/ldap/servers/plugins/acl/acl_ext.c
index 1b473770..d400c9c7 100644
--- a/ldap/servers/plugins/acl/acl_ext.c
+++ b/ldap/servers/plugins/acl/acl_ext.c
@@ -580,11 +580,16 @@ acl__malloc_aclpb ( )
"Unable to set the AUTH TYPE in the Plist\n");
return NULL;
}
- if (PListInitProp(aclpb->aclpb_proplist, 0, DS_ATTR_ENTRY, aclpb, 0) < 0) {
+ if (PListInitProp(aclpb->aclpb_proplist, 0, DS_ATTR_ENTRY, aclpb, 0) < 0) {
slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
"Unable to set the ENTRY TYPE in the Plist\n");
return NULL;
}
+ if (PListInitProp(aclpb->aclpb_proplist, 0, DS_ATTR_SSF, aclpb, 0) < 0) {
+ slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
+ "Unable to set the SSF in the Plist\n");
+ return NULL;
+ }
/*
* ACL_ATTR_IP and ACL_ATTR_DNS are initialized lazily in the
@@ -648,6 +653,7 @@ acl_init_aclpb ( Slapi_PBlock *pb , Acl_PBlock *aclpb, const char *dn, int copy_
char *authType;
void *conn;
int op_type;
+ int ssf = 0;
if ( NULL == aclpb ) {
@@ -688,6 +694,13 @@ acl_init_aclpb ( Slapi_PBlock *pb , Acl_PBlock *aclpb, const char *dn, int copy_
"Unable to set the AUTH TYPE in the Plist\n");
return;
}
+ slapi_pblock_get ( pb, SLAPI_OPERATION_SSF, &ssf);
+ if (PListAssignValue(aclpb->aclpb_proplist, DS_ATTR_SSF, ssf, 0) < 0) {
+ slapi_log_error(SLAPI_LOG_FATAL, plugin_name,
+ "Unable to set the SSF in the Plist\n");
+ return;
+ }
+
/* PKBxxx: We should be getting it from the OP struct */
slapi_pblock_get ( pb, SLAPI_CONN_CERT, &aclpb->aclpb_clientcert );
diff --git a/ldap/servers/plugins/acl/aclinit.c b/ldap/servers/plugins/acl/aclinit.c
index 46095925..e99e57fc 100644
--- a/ldap/servers/plugins/acl/aclinit.c
+++ b/ldap/servers/plugins/acl/aclinit.c
@@ -567,5 +567,12 @@ __aclinit__RegisterLases(void)
"Unable to register USERATTR Las\n");
return ACL_ERR;
}
+ if (ACL_LasRegister(NULL, DS_LAS_SSF,
+ (LASEvalFunc_t)DS_LASSSFEval,
+ (LASFlushFunc_t)NULL) < 0) {
+ slapi_log_error (SLAPI_LOG_FATAL, plugin_name,
+ "Unable to register SSF Las\n");
+ return ACL_ERR;
+ }
return ACL_OK;
}
diff --git a/ldap/servers/plugins/acl/acllas.c b/ldap/servers/plugins/acl/acllas.c
index d2205968..53620e4b 100644
--- a/ldap/servers/plugins/acl/acllas.c
+++ b/ldap/servers/plugins/acl/acllas.c
@@ -254,7 +254,7 @@ static int acllas__get_members (Slapi_Entry* e, void *callback_data);
static int acllas__client_match_URL (struct acl_pblock *aclpb,
char *n_dn, char *url );
static int acllas__handle_client_search (Slapi_Entry *e, void *callback_data);
-static int __acllas_setup ( NSErr_t *errp, char *attr_name, CmpOp_t comparator,
+static int __acllas_setup ( NSErr_t *errp, char *attr_name, CmpOp_t comparator, int allow_range,
char *attr_pattern, int *cachable, void **LAS_cookie,
PList_t subject, PList_t resource, PList_t auth_info,
PList_t global_auth, char *lasType, char *lasName, lasInfo *linfo);
@@ -483,7 +483,7 @@ DS_LASUserDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
lasInfo lasinfo;
int got_undefined = 0;
- if ( 0 != (rc = __acllas_setup (errp, attr_name, comparator,
+ if ( 0 != (rc = __acllas_setup (errp, attr_name, comparator, 0, /* Don't allow range comparators */
attr_pattern,cachable,LAS_cookie,
subject, resource, auth_info,global_auth,
DS_LAS_USERDN, "DS_LASUserDnEval", &lasinfo )) ) {
@@ -761,7 +761,7 @@ DS_LASGroupDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
int got_undefined = 0;
/* the setup should not fail under normal operation */
- if ( 0 != (rc = __acllas_setup (errp, attr_name, comparator,
+ if ( 0 != (rc = __acllas_setup (errp, attr_name, comparator, 0, /* Don't allow range comparators */
attr_pattern,cachable,LAS_cookie,
subject, resource, auth_info,global_auth,
DS_LAS_GROUPDN, "DS_LASGroupDnEval", &lasinfo )) ) {
@@ -979,7 +979,7 @@ DS_LASRoleDnEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
lasInfo lasinfo;
int got_undefined = 0;
- if ( 0 != (rc = __acllas_setup (errp, attr_name, comparator,
+ if ( 0 != (rc = __acllas_setup (errp, attr_name, comparator, 0, /* Don't allow range comparators */
attr_pattern,cachable,LAS_cookie,
subject, resource, auth_info,global_auth,
DS_LAS_ROLEDN, "DS_LASRoleDnEval",
@@ -1154,7 +1154,7 @@ DS_LASUserDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
lasInfo lasinfo;
int got_undefined = 0;
- if ( 0 != (rc = __acllas_setup (errp, attr_name, comparator,
+ if ( 0 != (rc = __acllas_setup (errp, attr_name, comparator, 0, /* Don't allow range comparators */
attr_pattern,cachable,LAS_cookie,
subject, resource, auth_info,global_auth,
DS_LAS_USERDNATTR, "DS_LASUserDnAttrEval",
@@ -1629,7 +1629,7 @@ DS_LASAuthMethodEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
char *s = NULL;
lasInfo lasinfo;
- if ( 0 != (rc = __acllas_setup (errp, attr_name, comparator,
+ if ( 0 != (rc = __acllas_setup (errp, attr_name, comparator, 0, /* Don't allow range comparators */
attr_pattern,cachable,LAS_cookie,
subject, resource, auth_info,global_auth,
DS_LAS_AUTHMETHOD, "DS_LASAuthMethodEval",
@@ -1679,6 +1679,143 @@ DS_LASAuthMethodEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
return rc;
}
+
+/***************************************************************************
+*
+* DS_LASSSFEval
+*
+*
+* Input:
+* attr_name The string "ssf" - in lower case.
+* comparator CMP_OP_EQ, CMP_OP_NE, CMP_OP_GT, CMP_OP_LT, CMP_OP_GE, CMP_OP_LE
+* attr_pattern An integer representing the SSF
+* cachable Always set to FALSE.
+* subject Subject property list
+* resource Resource property list
+* auth_info Authentication info, if any
+*
+* Returns:
+* retcode The usual LAS return codes.
+*
+* Error Handling:
+* None.
+*
+**************************************************************************/
+int
+DS_LASSSFEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
+ char *attr_pattern, int *cachable, void **LAS_cookie,
+ PList_t subject, PList_t resource, PList_t auth_info,
+ PList_t global_auth)
+{
+ char *attr;
+ char *ptr;
+ int len;
+ int rc;
+ char *s = NULL;
+ lasInfo lasinfo;
+ int aclssf;
+
+ if ( 0 != (rc = __acllas_setup (errp, attr_name, comparator, 1, /* Allow range comparators */
+ attr_pattern,cachable,LAS_cookie,
+ subject, resource, auth_info,global_auth,
+ DS_LAS_SSF, "DS_LASSSFEval",
+ &lasinfo )) ) {
+ return LAS_EVAL_FAIL;
+ }
+
+ attr = attr_pattern;
+
+ /* ignore leading and trailing whitespace */
+ while(ldap_utf8isspace(attr)) LDAP_UTF8INC(attr);
+ len = strlen(attr);
+ ptr = attr+len-1;
+ while(ptr >= attr && ldap_utf8isspace(ptr)) {
+ *ptr = '\0';
+ LDAP_UTF8DEC(ptr);
+ }
+
+ /* Convert SSF from bind rule to an int. */
+ aclssf = (int) strtol(attr, &ptr, 10);
+ if (*ptr != '\0') {
+ rc = LAS_EVAL_FAIL;
+ slapi_log_error( SLAPI_LOG_ACL, plugin_name,
+ "Error parsing numeric SSF from bind rule.\n");
+ slapi_log_error( SLAPI_LOG_ACL, plugin_name,
+ "Returning UNDEFINED for ssf evaluation.\n");
+ }
+
+ /* Check for negative values or a value overflow. */
+ if ((aclssf < 0) || (((aclssf == INT_MAX) || (aclssf == INT_MIN)) && (errno == ERANGE))){
+ rc = LAS_EVAL_FAIL;
+ slapi_log_error( SLAPI_LOG_ACL, plugin_name,
+ "SSF \"%s\" is invalid. Value must range from 0 to %d",
+ attr, INT_MAX);
+ slapi_log_error( SLAPI_LOG_ACL, plugin_name,
+ "Returning UNDEFINED for ssf evaluation.\n");
+ }
+
+ slapi_log_error( SLAPI_LOG_ACL, plugin_name,
+ "DS_LASSSFEval: aclssf:%d, ssf:%d\n",
+ aclssf, lasinfo.ssf);
+
+ switch ((int)comparator) {
+ case CMP_OP_EQ:
+ if (lasinfo.ssf == aclssf) {
+ rc = LAS_EVAL_TRUE;
+ } else {
+ rc = LAS_EVAL_FALSE;
+ }
+ break;
+ case CMP_OP_NE:
+ if (lasinfo.ssf != aclssf) {
+ rc = LAS_EVAL_TRUE;
+ } else {
+ rc = LAS_EVAL_FALSE;
+ }
+ break;
+ case CMP_OP_GT:
+ if (lasinfo.ssf > aclssf) {
+ rc = LAS_EVAL_TRUE;
+ } else {
+ rc = LAS_EVAL_FALSE;
+ }
+ break;
+ case CMP_OP_LT:
+ if (lasinfo.ssf < aclssf) {
+ rc = LAS_EVAL_TRUE;
+ } else {
+ rc = LAS_EVAL_FALSE;
+ }
+ break;
+ case CMP_OP_GE:
+ if (lasinfo.ssf >= aclssf) {
+ rc = LAS_EVAL_TRUE;
+ } else {
+ rc = LAS_EVAL_FALSE;
+ }
+ break;
+ case CMP_OP_LE:
+ if (lasinfo.ssf <= aclssf) {
+ rc = LAS_EVAL_TRUE;
+ } else {
+ rc = LAS_EVAL_FALSE;
+ }
+ break;
+ default:
+ /* This should never happen since the comparator is
+ * validated by __acllas_setup(), but better safe
+ * than sorry. */
+ rc = LAS_EVAL_FAIL;
+ slapi_log_error( SLAPI_LOG_ACL, plugin_name,
+ "Invalid comparator \"%d\" evaluating SSF.\n",
+ (int)comparator);
+ slapi_log_error( SLAPI_LOG_ACL, plugin_name,
+ "Returning UNDEFINED for ssf evaluation.\n");
+ }
+
+ return rc;
+}
+
/****************************************************************************
* Struct to evaluate and keep the current members being evaluated
@@ -2394,7 +2531,7 @@ DS_LASGroupDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
lasInfo lasinfo;
int got_undefined = 0;
- if ( 0 != (rc = __acllas_setup (errp, attr_name, comparator,
+ if ( 0 != (rc = __acllas_setup (errp, attr_name, comparator, 0, /* Don't allow range comparators */
attr_pattern,cachable,LAS_cookie,
subject, resource, auth_info,global_auth,
DS_LAS_GROUPDNATTR, "DS_LASGroupDnAttrEval",
@@ -3145,7 +3282,7 @@ DS_LASUserAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
lasInfo lasinfo;
int got_undefined = 0;
- if ( 0 != (rc = __acllas_setup (errp, attr_name, comparator,
+ if ( 0 != (rc = __acllas_setup (errp, attr_name, comparator, 0, /* Don't allow range comparators */
attr_pattern,cachable,LAS_cookie,
subject, resource, auth_info,global_auth,
DS_LAS_USERATTR, "DS_LASUserAttrEval",
@@ -3414,7 +3551,7 @@ acllas__handle_client_search ( Slapi_Entry *e, void *callback_data )
static int
__acllas_setup ( NSErr_t *errp, char *attr_name, CmpOp_t comparator,
- char *attr_pattern, int *cachable, void **LAS_cookie,
+ int allow_range, char *attr_pattern, int *cachable, void **LAS_cookie,
PList_t subject, PList_t resource, PList_t auth_info,
PList_t global_auth, char *lasType, char*lasName, lasInfo *linfo)
{
@@ -3431,9 +3568,16 @@ __acllas_setup ( NSErr_t *errp, char *attr_name, CmpOp_t comparator,
return LAS_EVAL_INVALID;
}
- if ((comparator != CMP_OP_EQ) && (comparator != CMP_OP_NE)) {
+ /* Validate the comparator */
+ if (allow_range && (comparator != CMP_OP_EQ) && (comparator != CMP_OP_NE) &&
+ (comparator != CMP_OP_GT) && (comparator != CMP_OP_LT) &&
+ (comparator != CMP_OP_GE) && (comparator != CMP_OP_LE)) {
+ slapi_log_error( SLAPI_LOG_ACL, plugin_name,
+ "%s:Invalid comparator(%d)\n", lasName, (int)comparator);
+ return LAS_EVAL_INVALID;
+ } else if (!allow_range && (comparator != CMP_OP_EQ) && (comparator != CMP_OP_NE)) {
slapi_log_error( SLAPI_LOG_ACL, plugin_name,
- "%s:Invalid comparator(%d)\n", lasName, (int)comparator);
+ "%s:Invalid comparator(%d)\n", lasName, (int)comparator);
return LAS_EVAL_INVALID;
}
@@ -3491,6 +3635,14 @@ __acllas_setup ( NSErr_t *errp, char *attr_name, CmpOp_t comparator,
"%s:Unable to get the auth type(%d)\n", lasName, rc);
return LAS_EVAL_FAIL;
}
+
+ /* get the SSF */
+ if ((rc = PListFindValue(subject, DS_ATTR_SSF,
+ (void **)&linfo->ssf, NULL)) < 0) {
+ acl_print_acllib_err(errp, NULL);
+ slapi_log_error( SLAPI_LOG_ACL, plugin_name,
+ "%s:Unable to get the ssf(%d)\n", lasName, rc);
+ }
return 0;
}
@@ -3568,7 +3720,7 @@ DS_LASRoleDnAttrEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
int k=0;
int got_undefined = 0;
- if ( 0 != (rc = __acllas_setup (errp, attr_name, comparator,
+ if ( 0 != (rc = __acllas_setup (errp, attr_name, comparator, 0, /* Don't allow range comparators */
attr_pattern,cachable,LAS_cookie,
subject, resource, auth_info,global_auth,
DS_LAS_ROLEDN, "DS_LASRoleDnAttrEval",
diff --git a/ldap/servers/plugins/acl/aclparse.c b/ldap/servers/plugins/acl/aclparse.c
index 57fd5ae7..8d4a21a0 100644
--- a/ldap/servers/plugins/acl/aclparse.c
+++ b/ldap/servers/plugins/acl/aclparse.c
@@ -927,7 +927,10 @@ __aclp__getNextLASRule (aci_t *aci_item, char *original_str , char **endOfCurrRu
} else if ((ruleStart = strstr(word, ACL_ATTR_DNS)) != NULL) {
ruleType = ACI_DNS_RULE;
ruleLen = strlen ( ACL_ATTR_DNS) ;
- }
+ } else if ((ruleStart = strstr(word, DS_LAS_SSF)) != NULL) {
+ ruleType = ACI_SSF_RULE;
+ ruleLen = strlen ( DS_LAS_SSF) ;
+ }
/* Here, we've found a space...if we were in in_dn_expr mode
* and we'vve found a closure for that ie.a '"' or a ')'
* eg. "'ldap:///all"' or 'ldap:///all")' then exit in_dn_expr mode.
diff --git a/ldap/servers/plugins/acl/aclutil.c b/ldap/servers/plugins/acl/aclutil.c
index a93a53a3..4aebd477 100644
--- a/ldap/servers/plugins/acl/aclutil.c
+++ b/ldap/servers/plugins/acl/aclutil.c
@@ -409,6 +409,10 @@ aclutil__Ruletypestr (int type , char str[])
strcpy (p, "paramAttr ");
p = strchr (p, '\0');
}
+ if ( type & ACI_SSF_RULE) {
+ strcpy (p, "ssf ");
+ p = strchr (p, '\0');
+ }
}
/*
** acl_gen_err_msg
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
index 70990c68..57028de2 100644
--- a/ldap/servers/slapd/connection.c
+++ b/ldap/servers/slapd/connection.c
@@ -484,12 +484,12 @@ connection_dispatch_operation(Connection *conn, Operation *op, Slapi_PBlock *pb)
{
int minssf = config_get_minssf();
- /* Copy the Connection DN into the operation struct */
- op_copy_identity( conn, op );
-
/* Get the effective key length now since the first SSL handshake should be complete */
connection_set_ssl_ssf( conn );
+ /* Copy the Connection DN and SSF into the operation struct */
+ op_copy_identity( conn, op );
+
/* If the minimum SSF requirements are not met, only allow
* bind and extended operations through. The bind and extop
* code will ensure that only SASL binds and startTLS are
@@ -2538,7 +2538,7 @@ connection_operations_pending( Connection *conn, Operation *op2ignore,
* that is, after the first few bytes of the request are received.
* In particular, we want the first request from an LDAPS client
* to have an authorization identity derived from the initial SSL
- * handshake.
+ * handshake. We also copy the SSF at this time.
*/
static void
op_copy_identity(Connection *conn, Operation *op)
@@ -2570,6 +2570,15 @@ op_copy_identity(Connection *conn, Operation *op)
/* copy isroot flag as well so root DN privileges are preserved */
op->o_isroot = conn->c_isroot;
+
+ /* copy the highest SSF (between SASL and SSL/TLS) into the
+ * operation for use by access control. */
+ if (conn->c_sasl_ssf >= conn->c_ssl_ssf) {
+ op->o_ssf = conn->c_sasl_ssf;
+ } else {
+ op->o_ssf = conn->c_ssl_ssf;
+ }
+
PR_Unlock( conn->c_mutex );
}
diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c
index d8cd876a..21195ea3 100644
--- a/ldap/servers/slapd/pblock.c
+++ b/ldap/servers/slapd/pblock.c
@@ -1544,6 +1544,12 @@ slapi_pblock_get( Slapi_PBlock *pblock, int arg, void *value )
(*( char **)value ) = pblock->pb_op->o_authtype;
break;
+ case SLAPI_OPERATION_SSF:
+ if (pblock->pb_op!=NULL) {
+ * ((int *) value) = pblock->pb_op->o_ssf;
+ }
+ break;
+
case SLAPI_CLIENT_DNS:
if (pblock->pb_conn == NULL) {
LDAPDebug( LDAP_DEBUG_ANY,
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index 01848172..ec030bc6 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1197,6 +1197,7 @@ typedef struct op {
int o_isroot; /* requestor is manager */
Slapi_DN o_sdn; /* dn bound when op was initiated */
char *o_authtype; /* auth method used to bind dn */
+ int o_ssf; /* ssf for this operation (highest between SASL and TLS/SSL) */
int o_opid; /* id of this operation */
PRUint64 o_connid; /* id of conn initiating this op; for logging only */
void *o_handler_data;
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 5ed054d9..1d545a0a 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -3052,6 +3052,7 @@ int slapi_reslimit_get_integer_limit( Slapi_Connection *conn, int handle,
#define SLAPI_OPERATION_TYPE 590
#define SLAPI_OPERATION_AUTHTYPE 741
#define SLAPI_OPERATION_ID 744
+#define SLAPI_OPERATION_SSF 750
#define SLAPI_IS_REPLICATED_OPERATION 142
#define SLAPI_IS_MMR_REPLICATED_OPERATION 153
#define SLAPI_IS_LEGACY_REPLICATED_OPERATION 154