s4:provision Allow a specific prefix map to be loaded into a new schema provision
authorAndrew Bartlett <abartlet@samba.org>
Thu, 10 Jun 2010 11:33:45 +0000 (21:33 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 15 Jun 2010 00:51:34 +0000 (10:51 +1000)
This allows the prefixMap from a DRS server to be used when loading
the schema from the local files.  This helps us then import other
schema with this map in place.

Andrew Bartlett

Signed-off-by: Kamen Mazdrashki <kamenim@samba.org>
source4/dsdb/schema/tests/schema_syntax.c
source4/libnet/libnet_vampire.c
source4/param/provision.c
source4/param/provision.h
source4/scripting/python/samba/schema.py

index efbaf5684c8edba946b138dd79a6c487f0b54f32..5dae097583677b6ce112694eae6daf03593570b1 100644 (file)
@@ -201,7 +201,7 @@ static bool torture_dsdb_syntax_tcase_setup(struct torture_context *tctx, void *
        priv = talloc_zero(tctx, struct torture_dsdb_syntax);
        torture_assert(tctx, priv, "No memory");
 
-       priv->ldb = provision_get_schema(priv, tctx->lp_ctx);
+       priv->ldb = provision_get_schema(priv, tctx->lp_ctx, NULL);
        torture_assert(tctx, priv->ldb, "Failed to load schema from disk");
 
        priv->schema = dsdb_get_schema(priv->ldb, NULL);
index 3b0b5a78b301f347f2273691e784d0a6f22ab6c4..84fe2944e0b5ecf4cefb8ebae82f5b7206a2bfb2 100644 (file)
@@ -198,6 +198,7 @@ static NTSTATUS libnet_vampire_cb_apply_schema(struct libnet_vampire_cb_state *s
        struct dsdb_extended_replicated_objects *schema_objs_1, *schema_objs_2;
        struct repsFromTo1 *s_dsa;
        char *tmp_dns_name;
+       struct ldb_context *schema_ldb;
        struct ldb_message *msg;
        struct ldb_val prefixMap_val;
        struct ldb_message_element *prefixMap_el;
@@ -252,6 +253,20 @@ static NTSTATUS libnet_vampire_cb_apply_schema(struct libnet_vampire_cb_state *s
        NT_STATUS_HAVE_NO_MEMORY(tmp_dns_name);
        s_dsa->other_info->dns_name = tmp_dns_name;
 
+       schema_ldb = provision_get_schema(s, s->lp_ctx, &s->prefixmap_blob);
+       if (!schema_ldb) {
+               DEBUG(0,("Failed to re-load from local provision using remote prefixMap.  Will continue with local prefixMap\n"));
+               s->provision_schema = dsdb_get_schema(s->ldb, s);
+       } else {
+               s->provision_schema = dsdb_get_schema(schema_ldb, s);
+               ret = dsdb_reference_schema(s->ldb, s->provision_schema, false);
+               if (ret != LDB_SUCCESS) {
+                       DEBUG(0,("Failed to attach schema from local provision using remote prefixMap."));
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
+               talloc_free(schema_ldb);
+       }
+
        s->provision_schema->relax_OID_conversions = true;
 
        /* Now convert the schema elements again, using the schema we just imported */
@@ -425,11 +440,19 @@ NTSTATUS libnet_vampire_cb_schema_chunk(void *private_data,
 
        if (!s->schema) {
                WERROR werr;
+               struct drsuapi_DsReplicaOIDMapping_Ctr mapping_ctr_without_schema_info;
                /* Put the DRS prefixmap aside for the schema we are
                 * about to load in the provision, and into the one we
                 * are making with the help of DRS */
 
-               werr = dsdb_get_drsuapi_prefixmap_as_blob(mapping_ctr, s, &s->prefixmap_blob);
+               mapping_ctr_without_schema_info = *mapping_ctr;
+
+               /* This strips off the 0xFF schema info from the end,
+                * because we don't want it in the blob */
+               if (mapping_ctr_without_schema_info.num_mappings > 0) {
+                       mapping_ctr_without_schema_info.num_mappings--;
+               }
+               werr = dsdb_get_drsuapi_prefixmap_as_blob(&mapping_ctr_without_schema_info, s, &s->prefixmap_blob);
                if (!W_ERROR_IS_OK(werr)) {
                        return werror_to_ntstatus(werr);
                }
index 28869e0a72be7fb6666aafcfeed4d945b9525280..81c4fb16a50f6a0035b371df4ba0ea35d53ae1fc 100644 (file)
@@ -339,7 +339,8 @@ failure:
 }
 
 
-struct ldb_context *provision_get_schema(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
+struct ldb_context *provision_get_schema(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx,
+                                        DATA_BLOB *override_prefixmap)
 {
        const char *setupdir;
        PyObject *schema_mod, *schema_dict, *schema_fn, *py_result, *parameters;
@@ -376,6 +377,11 @@ struct ldb_context *provision_get_schema(TALLOC_CTX *mem_ctx, struct loadparm_co
        setupdir = lp_setupdir(lp_ctx);
        PyDict_SetItemString(parameters, "setup_dir", 
                             PyString_FromString(setupdir));
+       if (override_prefixmap) {
+               PyDict_SetItemString(parameters, "override_prefixmap",
+                                    PyString_FromStringAndSize((const char *)override_prefixmap->data,
+                                                               override_prefixmap->length));
+       }
 
        py_result = PyEval_CallObjectWithKeywords(schema_fn, NULL, parameters);
 
index 516a9dea5fa80a5b37deae4bc85917d9f82030d4..36758b97070f8c2b44dc2c71be8014e016ff5195 100644 (file)
@@ -63,6 +63,7 @@ NTSTATUS provision_store_self_join(TALLOC_CTX *mem_ctx, struct loadparm_context
                                   struct provision_store_self_join_settings *settings,
                                   const char **error_string);
 
-struct ldb_context *provision_get_schema(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx);
+struct ldb_context *provision_get_schema(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx,
+                                        DATA_BLOB *override_prefixmap);
 
 #endif /* _PROVISION_H_ */
index bdc09cfd3a17e0f1062cd99f9622053fa90d3d37..bffb0e53da1df3cf4a2c70e80a0c9bc00e36f5a2 100644 (file)
@@ -166,7 +166,8 @@ def get_dnsyntax_attributes(schemadn,schemaldb):
 def ldb_with_schema(setup_dir=None,
         schemadn="cn=schema,cn=configuration,dc=example,dc=com", 
         serverdn="cn=server,cn=servers,cn=default-first-site-name,cn=sites,cn=cn=configuration,dc=example,dc=com",
-        domainsid=None):
+        domainsid=None,
+        override_prefixmap=None):
     """Load schema for the SamDB from the AD schema files and samba4_schema.ldif
     
     :param setup_dir: Setup path
@@ -185,4 +186,4 @@ def ldb_with_schema(setup_dir=None,
         domainsid = security.random_sid()
     else:
         domainsid = security.dom_sid(domainsid)
-    return Schema(setup_path, domainsid, schemadn=schemadn, serverdn=serverdn)
+    return Schema(setup_path, domainsid, schemadn=schemadn, serverdn=serverdn, override_prefixmap=override_prefixmap)