rodc: Allow local RODC changes with version 0
authorGarming Sam <garming@catalyst.net.nz>
Thu, 23 Mar 2017 21:24:21 +0000 (10:24 +1300)
committerGarming Sam <garming@samba.org>
Thu, 13 Apr 2017 05:29:17 +0000 (07:29 +0200)
These changes will get clobbered by RWDCs through replication. This
behaviour is required for lockoutTime to enforce the password lockout
locally on the RODC (and is consistent with Windows).

Signed-off-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/dsdb/samdb/ldb_modules/repl_meta_data.c
source4/dsdb/samdb/samdb.h
source4/setup/schema_samba4.ldif

index 44ec1d419129060f0d17ec2d42cda40674b43fae..851b4ad20aa568711372252701d9a3bc9cdb7c36 100644 (file)
@@ -235,7 +235,6 @@ static bool replmd_check_urgent_attribute(const struct ldb_message_element *el)
        return false;
 }
 
-
 static int replmd_replicated_apply_isDeleted(struct replmd_replicated_request *ar);
 
 /*
@@ -1506,6 +1505,7 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb,
        md1 = &omd->ctr.ctr1.array[i];
        md1->version++;
        md1->attid = attid;
+
        if (md1->attid == DRSUAPI_ATTID_isDeleted) {
                const struct ldb_val *rdn_val = ldb_dn_get_rdn_val(msg->dn);
                const char* rdn;
@@ -1532,6 +1532,15 @@ static int replmd_update_rpmd_element(struct ldb_context *ldb,
        md1->originating_usn           = *seq_num;
        md1->local_usn                 = *seq_num;
 
+       if (ldb_request_get_control(req, DSDB_CONTROL_FORCE_RODC_LOCAL_CHANGE) != NULL) {
+               /* Force version to 0 to be overriden later via replication */
+               bool am_rodc = false;
+               int ret = samdb_rodc(ldb, &am_rodc);
+               if (ret == LDB_SUCCESS && am_rodc) {
+                       md1->version = 0;
+               }
+       }
+
        return LDB_SUCCESS;
 }
 
@@ -1837,7 +1846,8 @@ static int replmd_update_rpmd(struct ldb_module *module,
 
                /*if we are RODC and this is a DRSR update then its ok*/
                if (!ldb_request_get_control(req, DSDB_CONTROL_REPLICATED_UPDATE_OID)
-                   && !ldb_request_get_control(req, DSDB_CONTROL_DBCHECK_MODIFY_RO_REPLICA)) {
+                   && !ldb_request_get_control(req, DSDB_CONTROL_DBCHECK_MODIFY_RO_REPLICA)
+                   && !ldb_request_get_control(req, DSDB_CONTROL_FORCE_RODC_LOCAL_CHANGE)) {
                        unsigned instanceType;
 
                        ret = samdb_rodc(ldb, rodc);
index 1e427d0e78a9a94202927604ab8eda8be0221e9b..5dce37e2e9c96a9ca4ae4c88804e54ca3c512008 100644 (file)
@@ -183,6 +183,12 @@ struct dsdb_control_password_user_account_control {
 /* passed when we want to thoroughly delete linked attributes */
 #define DSDB_CONTROL_REPLMD_VANISH_LINKS "1.3.6.1.4.1.7165.4.3.29"
 
+/*
+ * lockoutTime is a replicated attribute, but must be modified before
+ * connectivity occurs to allow password lockouts.
+ */
+#define DSDB_CONTROL_FORCE_RODC_LOCAL_CHANGE "1.3.6.1.4.1.7165.4.3.31"
+
 #define DSDB_EXTENDED_REPLICATED_OBJECTS_OID "1.3.6.1.4.1.7165.4.4.1"
 struct dsdb_extended_replicated_object {
        struct ldb_message *msg;
index 0189fb5934a4404fa5c41f79536caf05d8a852fc..d8bc2d994c329a7cd77f0ea7a1691262da7fc482 100644 (file)
 #Allocated: DSDB_CONTROL_SKIP_DUPLICATES_CHECK_OID 1.3.6.1.4.1.7165.4.3.28
 #Allocated: DSDB_CONTROL_REPLMD_VANISH_LINKS 1.3.6.1.4.1.7165.4.3.29
 #Allocated: LDB_CONTROL_RECALCULATE_RDN_OID 1.3.6.1.4.1.7165.4.3.30
+#Allocated: DSDB_CONTROL_FORCE_RODC_LOCAL_CHANGE 1.3.6.1.4.1.7165.4.3.31
+
 
 # Extended 1.3.6.1.4.1.7165.4.4.x
 #Allocated: DSDB_EXTENDED_REPLICATED_OBJECTS_OID 1.3.6.1.4.1.7165.4.4.1