diff --git a/doc/man/man5/slapd-config.5 b/doc/man/man5/slapd-config.5 index 4c22b3eef233544da9e3c6efac6bd71a555864d4..41e7da2cf27551051c71c236280855282534504c 100644 --- a/doc/man/man5/slapd-config.5 +++ b/doc/man/man5/slapd-config.5 @@ -1204,7 +1204,7 @@ See .BR olcLimits for an explanation of the different flags. .TP -.B olcSortVals <attr> [...] +.B olcSortVals: <attr> [...] Specify a list of multi-valued attributes whose values will always be maintained in sorted order. Using this option will allow Modify, Compare, and filter evaluations on these attributes to be performed @@ -1234,6 +1234,14 @@ which they are defined. They are supported by every type of backend. All of the Global Database Options may also be used here. .TP +.B olcAddContentAcl: TRUE | FALSE +Controls whether Add operations will perform ACL checks on +the content of the entry being added. This check is off +by default. See the +.BR slapd.access (5) +manual page for more details on ACL requirements for +Add operations. +.TP .B olcHidden: TRUE | FALSE Controls whether the database will be used to answer queries. A database that is hidden will never be diff --git a/doc/man/man5/slapd.access.5 b/doc/man/man5/slapd.access.5 index 5fe76f684e63213addb35006667491b9cb0a3edb..dd24af2018187883e165b65f637c9ec3ef046707 100644 --- a/doc/man/man5/slapd.access.5 +++ b/doc/man/man5/slapd.access.5 @@ -911,7 +911,15 @@ When adding the suffix entry of a database, .B add access to .B children -of the empty DN ("") is required. +of the empty DN ("") is required. Also if +Add content ACL checking has been configured on +the database (see the +.BR slapd.conf (5) +or +.BR slapd-config (5) +manual page), +.B add (=a) +will be required on all of the attributes being added. .LP The diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5 index 8a7f8e8477e4b5887d4f1253e04e1c32e31505a5..3e2ab714d26bb4c7db5bb59617be39f3c060afa8 100644 --- a/doc/man/man5/slapd.conf.5 +++ b/doc/man/man5/slapd.conf.5 @@ -1162,6 +1162,14 @@ or .BR sql , depending on which backend will serve the database. .TP +.B add_content_acl on | off +Controls whether Add operations will perform ACL checks on +the content of the entry being added. This check is off +by default. See the +.BR slapd.access (5) +manual page for more details on ACL requirements for +Add operations. +.TP .B hidden on | off Controls whether the database will be used to answer queries. A database that is hidden will never be diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index dcb0844aa35319593d498bae9373f66324fc3d81..a9c2a791550d483972226bd8fa82edb8df7d7b3e 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 974f2fd53fb92fb384835a46dc295c5d440194ed..0d1431923b1127e26f1cb7c8152ba167a12d9592 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] ); @@ -6193,6 +6209,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 8822e1f02ba4f1ace9f88f252ee94087d86de45b..3e0fb9a91d4062b97be2a4d78d369581939a7403 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1789,6 +1789,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) @@ -1814,6 +1815,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 diff --git a/tests/data/slapd-acl.conf b/tests/data/slapd-acl.conf index 64cde948c73521677ea45d1c0cbe403cce2d69ee..fca529b0820a9c17b625655eb9ecc7f919ad778b 100644 --- a/tests/data/slapd-acl.conf +++ b/tests/data/slapd-acl.conf @@ -52,7 +52,7 @@ rootpw secret #hdb#index cn,sn,uid pres,eq,sub #ndb#dbname db_1 #ndb#include @DATADIR@/ndb.conf - +add_content_acl on #access to attrs=objectclass dn.subtree="dc=example,dc=com" access to attrs=objectclass by dn.exact="cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com" add diff --git a/tests/data/slapd-dds.conf b/tests/data/slapd-dds.conf index bb9ebbf10d75948753c1e6af6780bb52757ee610..955a23734ae17552013244842a7ccab147c8c846 100644 --- a/tests/data/slapd-dds.conf +++ b/tests/data/slapd-dds.conf @@ -48,6 +48,7 @@ rootpw secret #hdb#index entryExpireTimestamp eq #ndb#dbname db_1 #ndb#include @DATADIR@/ndb.conf +add_content_acl on overlay dds dds-max-ttl 1d