s4:schema Provide a way to reference a loaded schema between ldbs
authorAndrew Bartlett <abartlet@samba.org>
Wed, 12 Aug 2009 23:58:38 +0000 (09:58 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Sun, 16 Aug 2009 23:50:56 +0000 (09:50 +1000)
This allows us to load the schema against one ldb context, but apply
it to another.  This will be useful in the provision script, as we
need the schema before we start the LDAP server backend.

Adnrew Bartlett

source4/dsdb/schema/schema_set.c
source4/scripting/python/pyglue.c
source4/scripting/python/samba/samdb.py

index 5d78d0a0c687e64c38ac3dcc8992a5ea1c977c86..630c0ba184e2f99a79b9d5683d0cfb09cf285ae5 100644 (file)
@@ -370,34 +370,42 @@ int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema)
 static struct dsdb_schema *global_schema;
 
 /**
- * Make this ldb use the 'global' schema, setup to avoid having multiple copies in this process
+ * Make this ldb use a specified schema, already fully calculated and belonging to another ldb
  */
-int dsdb_set_global_schema(struct ldb_context *ldb)
+int dsdb_reference_schema(struct ldb_context *ldb, struct dsdb_schema *schema)
 {
        int ret;
-       if (!global_schema) {
-               return LDB_SUCCESS;
-       }
-
-       ret = ldb_set_opaque(ldb, "dsdb_schema", global_schema);
+       ret = ldb_set_opaque(ldb, "dsdb_schema", schema);
        if (ret != LDB_SUCCESS) {
                return ret;
        }
 
        /* Set the new attributes based on the new schema */
-       ret = dsdb_schema_set_attributes(ldb, global_schema, false);
+       ret = dsdb_schema_set_attributes(ldb, schema, false);
        if (ret != LDB_SUCCESS) {
                return ret;
        }
 
-       /* Keep a reference to this schema, just incase the global copy is replaced */
-       if (talloc_reference(ldb, global_schema) == NULL) {
+       /* Keep a reference to this schema, just incase the original copy is replaced */
+       if (talloc_reference(ldb, schema) == NULL) {
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
        return LDB_SUCCESS;
 }
 
+/**
+ * Make this ldb use the 'global' schema, setup to avoid having multiple copies in this process
+ */
+int dsdb_set_global_schema(struct ldb_context *ldb)
+{
+       if (!global_schema) {
+               return LDB_SUCCESS;
+       }
+
+       return dsdb_reference_schema(ldb, global_schema);
+}
+
 /**
  * Find the schema object for this ldb
  */
@@ -451,7 +459,7 @@ void dsdb_make_schema_global(struct ldb_context *ldb)
  * schema itself to the directory.
  */
 
-WERROR dsdb_attach_schema_from_ldif(struct ldb_context *ldb, const char *pf, const char *df)
+WERROR dsdb_set_schema_from_ldif(struct ldb_context *ldb, const char *pf, const char *df)
 {
        struct ldb_ldif *ldif;
        struct ldb_message *msg;
index 95255dc1f67678c4947fe411b1be5345acb301f7..36aae9ccef62b77d1728eb78cec85bcd3a3759fe 100644 (file)
@@ -286,7 +286,7 @@ static PyObject *py_dsdb_set_global_schema(PyObject *self, PyObject *args)
        Py_RETURN_NONE;
 }
 
-static PyObject *py_dsdb_attach_schema_from_ldif(PyObject *self, PyObject *args)
+static PyObject *py_dsdb_set_schema_from_ldif(PyObject *self, PyObject *args)
 {
        WERROR result;
        char *pf, *df;
@@ -298,7 +298,7 @@ static PyObject *py_dsdb_attach_schema_from_ldif(PyObject *self, PyObject *args)
 
        PyErr_LDB_OR_RAISE(py_ldb, ldb);
 
-       result = dsdb_attach_schema_from_ldif(ldb, pf, df);
+       result = dsdb_set_schema_from_ldif(ldb, pf, df);
        PyErr_WERROR_IS_ERR_RAISE(result);
 
        Py_RETURN_NONE;
@@ -327,6 +327,33 @@ static PyObject *py_dsdb_convert_schema_to_openldap(PyObject *self, PyObject *ar
        return ret;
 }
 
+static PyObject *py_dsdb_set_schema_from_ldb(PyObject *self, PyObject *args)
+{
+       PyObject *py_ldb;
+       struct ldb_context *ldb;
+       PyObject *py_from_ldb;
+       struct ldb_context *from_ldb;
+       struct dsdb_schema *schema;
+       int ret;
+       if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_from_ldb))
+               return NULL;
+
+       PyErr_LDB_OR_RAISE(py_ldb, ldb);
+
+       PyErr_LDB_OR_RAISE(py_from_ldb, from_ldb);
+
+       schema = dsdb_get_schema(from_ldb);
+       if (!schema) {
+               PyErr_SetString(PyExc_RuntimeError, "Failed to set find a schema on 'from' ldb!\n");
+               return NULL;
+       }
+
+       ret = dsdb_reference_schema(ldb, schema);
+       PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_get_exception(), ret, ldb);
+
+       Py_RETURN_NONE;
+}
+
 static PyObject *py_dom_sid_to_rid(PyLdbObject *self, PyObject *args)
 {
        PyObject *py_sid;
@@ -375,7 +402,9 @@ static PyMethodDef py_misc_methods[] = {
                NULL },
        { "dsdb_set_global_schema", (PyCFunction)py_dsdb_set_global_schema, METH_VARARGS,
                NULL },
-       { "dsdb_attach_schema_from_ldif", (PyCFunction)py_dsdb_attach_schema_from_ldif, METH_VARARGS,
+       { "dsdb_set_schema_from_ldif", (PyCFunction)py_dsdb_set_schema_from_ldif, METH_VARARGS,
+               NULL },
+       { "dsdb_set_schema_from_ldb", (PyCFunction)py_dsdb_set_schema_from_ldb, METH_VARARGS,
                NULL },
        { "dsdb_convert_schema_to_openldap", (PyCFunction)py_dsdb_convert_schema_to_openldap, METH_VARARGS,
                NULL },
index 508449a1c6473340539baf3471f065a68ce9a9f3..c7b42b612a4044015757836d93b458f33044a50f 100644 (file)
@@ -216,8 +216,11 @@ userPassword:: %s
         """
         glue.samdb_set_domain_sid(self, sid)
 
-    def attach_schema_from_ldif(self, pf, df):
-        glue.dsdb_attach_schema_from_ldif(self, pf, df)
+    def set_schema_from_ldif(self, pf, df):
+        glue.dsdb_set_schema_from_ldif(self, pf, df)
+
+    def set_schema_from_ldb(self, ldb):
+        glue.dsdb_set_schema_from_ldb(self, ldb)
 
     def convert_schema_to_openldap(self, target, mapping):
         return glue.dsdb_convert_schema_to_openldap(self, target, mapping)