From b613ab25b0f684377062a381dbc432ea126f5b6f Mon Sep 17 00:00:00 2001
From: Howard Chu <hyc@openldap.org>
Date: Mon, 10 Nov 2008 22:10:19 +0000
Subject: [PATCH] ITS#4556 allow Add content checking to be configured per-DB

---
 servers/slapd/acl.c     |  4 ++++
 servers/slapd/bconfig.c | 21 ++++++++++++++++++++-
 servers/slapd/slap.h    |  2 ++
 3 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c
index dcb0844aa3..a9c2a79155 100644
--- a/servers/slapd/acl.c
+++ b/servers/slapd/acl.c
@@ -1843,6 +1843,10 @@ acl_check_modlist(
 	}
 	assert( be != NULL );
 
+	/* If ADD attribute checking is not enabled, just allow it */
+	if ( op->o_tag == LDAP_REQ_ADD && !SLAP_DBACL_ADD( be ))
+		return 1;
+
 	/* short circuit root database access */
 	if ( be_isroot( op ) ) {
 		Debug( LDAP_DEBUG_ACL,
diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c
index e0d26e7000..5493d9811b 100644
--- a/servers/slapd/bconfig.c
+++ b/servers/slapd/bconfig.c
@@ -184,6 +184,7 @@ enum {
 	CFG_SORTVALS,
 	CFG_IX_INTLEN,
 	CFG_SYNTAX,
+	CFG_ACL_ADD,
 
 	CFG_LAST
 };
@@ -280,6 +281,10 @@ static ConfigTable config_back_cf_table[] = {
 			"DESC 'Access Control List' "
 			"EQUALITY caseIgnoreMatch "
 			"SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )", NULL, NULL },
+	{ "add_content_acl",	NULL, 0, 0, 0, ARG_MAY_DB|ARG_ON_OFF|ARG_MAGIC|CFG_ACL_ADD,
+		&config_generic, "( OLcfgGlAt:86 NAME 'olcAddContentAcl' "
+			"DESC 'Check ACLs against content of Add ops' "
+			"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
 	{ "allows",	"features", 2, 0, 5, ARG_PRE_DB|ARG_MAGIC,
 		&config_allows, "( OLcfgGlAt:2 NAME 'olcAllows' "
 			"DESC 'Allowed set of deprecated features' "
@@ -771,7 +776,7 @@ static ConfigOCs cf_ocs[] = {
 		"SUP olcConfig STRUCTURAL "
 		"MUST olcDatabase "
 		"MAY ( olcHidden $ olcSuffix $ olcSubordinate $ olcAccess $ "
-		 "olcLastMod $ olcLimits $ "
+		 "olcAddContentAcl $ olcLastMod $ olcLimits $ "
 		 "olcMaxDerefDepth $ olcPlugin $ olcReadOnly $ olcReplica $ "
 		 "olcReplicaArgsFile $ olcReplicaPidFile $ olcReplicationInterval $ "
 		 "olcReplogFile $ olcRequires $ olcRestrict $ olcRootDN $ olcRootPW $ "
@@ -1006,6 +1011,9 @@ config_generic(ConfigArgs *c) {
 			rc = (!i);
 			break;
 		}
+		case CFG_ACL_ADD:
+			c->value_int = (SLAP_DBACL_ADD(c->be) != 0);
+			break;
 		case CFG_ROOTDSE: {
 			ConfigFile *cf = c->ca_private;
 			if ( cf->c_dseFiles ) {
@@ -1159,6 +1167,7 @@ config_generic(ConfigArgs *c) {
 		case CFG_SASLSECP:
 		case CFG_SSTR_IF_MAX:
 		case CFG_SSTR_IF_MIN:
+		case CFG_ACL_ADD:
 			break;
 
 		/* no-ops, requires slapd restart */
@@ -1694,6 +1703,13 @@ sortval_reject:
 			}
 			break;
 
+		case CFG_ACL_ADD:
+			if(c->value_int)
+				SLAP_DBFLAGS(c->be) |= SLAP_DBFLAG_ACL_ADD;
+			else
+				SLAP_DBFLAGS(c->be) &= ~SLAP_DBFLAG_ACL_ADD;
+			break;
+
 		case CFG_ROOTDSE:
 			if(root_dse_read_file(c->argv[1])) {
 				snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> could not read file", c->argv[0] );
@@ -6207,6 +6223,9 @@ config_back_db_init( BackendDB *be, ConfigReply* cr )
 	/* Hide from namingContexts */
 	SLAP_BFLAGS(be) |= SLAP_BFLAG_CONFIG;
 
+	/* Check ACLs on content of Adds by default */
+	SLAP_DBFLAGS(be) |= SLAP_DBFLAG_ACL_ADD;
+
 	return 0;
 }
 
diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h
index cfe52274e2..ae7d51b8d6 100644
--- a/servers/slapd/slap.h
+++ b/servers/slapd/slap.h
@@ -1791,6 +1791,7 @@ struct BackendDB {
 #define SLAP_DBFLAG_SYNC_SHADOW		0x1000U /* a sync shadow */
 #define SLAP_DBFLAG_SLURP_SHADOW	0x2000U /* a slurp shadow */
 #define SLAP_DBFLAG_CLEAN		0x10000U /* was cleanly shutdown */
+#define SLAP_DBFLAG_ACL_ADD		0x20000U /* check attr ACLs on adds */
 	slap_mask_t	be_flags;
 #define SLAP_DBFLAGS(be)			((be)->be_flags)
 #define SLAP_NOLASTMOD(be)			(SLAP_DBFLAGS(be) & SLAP_DBFLAG_NOLASTMOD)
@@ -1816,6 +1817,7 @@ struct BackendDB {
 #define SLAP_SINGLE_SHADOW(be)			(SLAP_DBFLAGS(be) & SLAP_DBFLAG_SINGLE_SHADOW)
 #define SLAP_MULTIMASTER(be)			(!SLAP_SINGLE_SHADOW(be))
 #define SLAP_DBCLEAN(be)			(SLAP_DBFLAGS(be) & SLAP_DBFLAG_CLEAN)
+#define SLAP_DBACL_ADD(be)			(SLAP_DBFLAGS(be) & SLAP_DBFLAG_ACL_ADD)
 
 	slap_mask_t	be_restrictops;		/* restriction operations */
 #define SLAP_RESTRICT_OP_ADD		0x0001U
-- 
GitLab