dsdb/repl: Ensure we use the LOCAL attid value, not the remote one
authorAndrew Bartlett <abartlet@samba.org>
Thu, 10 Mar 2016 00:43:15 +0000 (13:43 +1300)
committerStefan Metzmacher <metze@samba.org>
Sun, 13 Mar 2016 22:29:14 +0000 (23:29 +0100)
The key here is that while this never was an issue for builtin schema,
nor for objects with an msDS-IntID used outside the schema partition,
additional attributes added and used in the schema partition were
incorrectly using the wrong attributeID value in the replPropertyMetaData.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11783

Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Sun Mar 13 23:29:14 CET 2016 on sn-devel-144

source4/dsdb/repl/replicated_objects.c
source4/dsdb/schema/schema_syntax.c

index e9225f586c0492965058843a9072b69e8ce6ed3e..a112e18e076fb9ba8311a1de2352bf45ecf111e4 100644 (file)
@@ -455,7 +455,7 @@ WERROR dsdb_convert_object_ex(struct ldb_context *ldb,
                }
                if (W_ERROR_EQUAL(status, WERR_TOO_MANY_SECRETS)) {
                        WERROR get_name_status = dsdb_attribute_drsuapi_to_ldb(ldb, schema, pfm_remote,
-                                                                              a, msg->elements, e);
+                                                                              a, msg->elements, e, NULL);
                        if (W_ERROR_IS_OK(get_name_status)) {
                                DEBUG(0, ("Unxpectedly got secret value %s on %s from DRS server\n",
                                          e->name, ldb_dn_get_linearized(msg->dn)));
@@ -467,11 +467,21 @@ WERROR dsdb_convert_object_ex(struct ldb_context *ldb,
                        return status;
                }
 
+               /*
+                * This function also fills in the local attid value,
+                * based on comparing the remote and local prefixMap
+                * tables.  If we don't convert the value, then we can
+                * have invalid values in the replPropertyMetaData we
+                * store on disk, as the prefixMap is per host, not
+                * per-domain.  This may be why Microsoft added the
+                * msDS-IntID feature, however this is not used for
+                * extra attributes in the schema partition itself.
+                */
                status = dsdb_attribute_drsuapi_to_ldb(ldb, schema, pfm_remote,
-                                                      a, msg->elements, e);
+                                                      a, msg->elements, e,
+                                                      &m->attid);
                W_ERROR_NOT_OK_RETURN(status);
 
-               m->attid                        = a->attid;
                m->version                      = d->version;
                m->originating_change_time      = d->originating_change_time;
                m->originating_invocation_id    = d->originating_invocation_id;
@@ -1038,7 +1048,7 @@ static WERROR dsdb_origin_object_convert(struct ldb_context *ldb,
                e = &msg->elements[i];
 
                status = dsdb_attribute_drsuapi_to_ldb(ldb, schema, schema->prefixmap,
-                                                      a, msg->elements, e);
+                                                      a, msg->elements, e, NULL);
                W_ERROR_NOT_OK_RETURN(status);
        }
 
index 94e319c11f39e8d5eba2cf1ea6b9007ce294890a..5b7c8b13d807e8c90d1af3a9309916e5de718fd3 100644 (file)
@@ -2702,7 +2702,8 @@ WERROR dsdb_attribute_drsuapi_to_ldb(struct ldb_context *ldb,
                                     const struct dsdb_schema_prefixmap *pfm_remote,
                                     const struct drsuapi_DsReplicaAttribute *in,
                                     TALLOC_CTX *mem_ctx,
-                                    struct ldb_message_element *out)
+                                    struct ldb_message_element *out,
+                                    enum drsuapi_DsAttributeId *local_attid_as_enum)
 {
        const struct dsdb_attribute *sa;
        struct dsdb_syntax_ctx syntax_ctx;
@@ -2738,6 +2739,15 @@ WERROR dsdb_attribute_drsuapi_to_ldb(struct ldb_context *ldb,
                return WERR_DS_ATT_NOT_DEF_IN_SCHEMA;
        }
 
+       /*
+        * We return the same class of attid as we were given.  That
+        * is, we trust the remote server not to use an
+        * msDS-IntId value in the schema partition
+        */
+       if (local_attid_as_enum != NULL) {
+               *local_attid_as_enum = (enum drsuapi_DsAttributeId)attid_local;
+       }
+
        return sa->syntax->drsuapi_to_ldb(&syntax_ctx, sa, in, mem_ctx, out);
 }