summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/common/util.c39
-rw-r--r--source4/dsdb/pydsdb.c36
-rw-r--r--source4/dsdb/samdb/ldb_modules/samba_dsdb.c2
-rw-r--r--source4/scripting/python/samba/provision.py10
-rw-r--r--source4/scripting/python/samba/samdb.py20
-rw-r--r--source4/scripting/python/samba/schema.py12
6 files changed, 106 insertions, 13 deletions
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 66a0b0f87d..30cb5c5c99 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -1173,6 +1173,43 @@ failed:
return false;
}
+bool samdb_set_ntds_settings_dn(struct ldb_context *ldb, struct ldb_dn *ntds_settings_dn_in)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_dn *ntds_settings_dn_new;
+ struct ldb_dn *ntds_settings_dn_old;
+
+ /* see if we have a cached copy */
+ ntds_settings_dn_old = talloc_get_type(ldb_get_opaque(ldb,
+ "cache.ntds_settings_dn"), struct ldb_dn);
+
+ tmp_ctx = talloc_new(ldb);
+ if (tmp_ctx == NULL) {
+ goto failed;
+ }
+
+ ntds_settings_dn_new = ldb_dn_copy(tmp_ctx, ntds_settings_dn_in);
+ if (!ntds_settings_dn_new) {
+ goto failed;
+ }
+
+ /* cache the domain_sid in the ldb */
+ if (ldb_set_opaque(ldb, "cache.ntds_settings_dn", ntds_settings_dn_new) != LDB_SUCCESS) {
+ goto failed;
+ }
+
+ talloc_steal(ldb, ntds_settings_dn_new);
+ talloc_free(tmp_ctx);
+ talloc_free(ntds_settings_dn_old);
+
+ return true;
+
+failed:
+ DEBUG(1,("Failed to set our NTDS Settings DN in the ldb!\n"));
+ talloc_free(tmp_ctx);
+ return false;
+}
+
/* Obtain the short name of the flexible single master operator
* (FSMO), such as the PDC Emulator */
const char *samdb_result_fsmo_name(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_message *msg,
@@ -1207,7 +1244,7 @@ struct ldb_dn *samdb_ntds_settings_dn(struct ldb_context *ldb)
struct ldb_dn *settings_dn;
/* see if we have a cached copy */
- settings_dn = (struct ldb_dn *)ldb_get_opaque(ldb, "cache.settings_dn");
+ settings_dn = (struct ldb_dn *)ldb_get_opaque(ldb, "cache.ntds_settings_dn");
if (settings_dn) {
return settings_dn;
}
diff --git a/source4/dsdb/pydsdb.c b/source4/dsdb/pydsdb.c
index 88c62086f3..45f8b6e1ca 100644
--- a/source4/dsdb/pydsdb.c
+++ b/source4/dsdb/pydsdb.c
@@ -127,6 +127,38 @@ static PyObject *py_samdb_set_domain_sid(PyLdbObject *self, PyObject *args)
Py_RETURN_NONE;
}
+static PyObject *py_samdb_set_ntds_settings_dn(PyLdbObject *self, PyObject *args)
+{
+ PyObject *py_ldb, *py_ntds_settings_dn;
+ struct ldb_context *ldb;
+ struct ldb_dn *ntds_settings_dn;
+ TALLOC_CTX *tmp_ctx;
+ bool ret;
+
+ if (!PyArg_ParseTuple(args, "OO", &py_ldb, &py_ntds_settings_dn))
+ return NULL;
+
+ PyErr_LDB_OR_RAISE(py_ldb, ldb);
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ if (!PyObject_AsDn(tmp_ctx, py_ntds_settings_dn, ldb, &ntds_settings_dn)) {
+ return NULL;
+ }
+
+ ret = samdb_set_ntds_settings_dn(ldb, ntds_settings_dn);
+ talloc_free(tmp_ctx);
+ if (!ret) {
+ PyErr_SetString(PyExc_RuntimeError, "set_ntds_settings_dn failed");
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
static PyObject *py_samdb_get_domain_sid(PyLdbObject *self, PyObject *args)
{
PyObject *py_ldb;
@@ -356,6 +388,10 @@ static PyMethodDef py_dsdb_methods[] = {
"Get SID of domain in use." },
{ "samdb_ntds_invocation_id", (PyCFunction)py_samdb_ntds_invocation_id,
METH_VARARGS, "get the NTDS invocation ID GUID as a string"},
+ { "samdb_set_ntds_settings_dn", (PyCFunction)py_samdb_set_ntds_settings_dn,
+ METH_VARARGS,
+ "samdb_set_ntds_settings_dn(samdb, ntds_settings_dn)\n"
+ "Set NTDS Settings DN for this LDB (allows it to be set before the DB fully exists)." },
{ "dsdb_get_oid_from_attid", (PyCFunction)py_dsdb_get_oid_from_attid,
METH_VARARGS, NULL },
{ "dsdb_set_ntds_invocation_id",
diff --git a/source4/dsdb/samdb/ldb_modules/samba_dsdb.c b/source4/dsdb/samdb/ldb_modules/samba_dsdb.c
index 8f7e5407c7..0e635de8ed 100644
--- a/source4/dsdb/samdb/ldb_modules/samba_dsdb.c
+++ b/source4/dsdb/samdb/ldb_modules/samba_dsdb.c
@@ -185,11 +185,11 @@ static int samba_dsdb_init(struct ldb_module *module)
"kludge_acl",
"schema_load",
"instancetype",
- "rdn_name",
NULL };
const char **link_modules;
static const char *tdb_modules_list[] = {
+ "rdn_name",
"subtree_delete",
"repl_meta_data",
"subtree_rename",
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index f2004878c1..0757a72556 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -871,10 +871,9 @@ def setup_samdb(path, setup_path, session_info, provision_backend, lp,
if schema is None:
schema = Schema(setup_path, domainsid, schemadn=names.schemadn, serverdn=names.serverdn)
- # Load the database, but importantly, use Ldb not SamDB as we don't want to
- # load the global schema
- samdb = Ldb(session_info=session_info,
- credentials=provision_backend.credentials, lp=lp)
+ # Load the database, but don's load the global schema and don't connect quite yet
+ samdb = SamDB(session_info=session_info, url=None, auto_connect=False,
+ credentials=provision_backend.credentials, lp=lp, global_schema=False)
message("Pre-loading the Samba 4 and AD schema")
@@ -901,6 +900,7 @@ def setup_samdb(path, setup_path, session_info, provision_backend, lp,
samdb.set_domain_sid(str(domainsid))
samdb.set_invocation_id(invocationid)
+ samdb.set_ntds_settings_dn("CN=NTDS Settings,%s" % names.serverdn)
message("Adding DomainDN: %s" % names.domaindn)
@@ -1236,7 +1236,7 @@ def provision(setup_dir, message, session_info,
ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="")
- schema = Schema(setup_path, domainsid, schemadn=names.schemadn,
+ schema = Schema(setup_path, domainsid, invocationid=invocationid, schemadn=names.schemadn,
serverdn=names.serverdn)
if backend_type == "ldb":
diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py
index d41b3ec637..dd3824db0c 100644
--- a/source4/scripting/python/samba/samdb.py
+++ b/source4/scripting/python/samba/samdb.py
@@ -37,9 +37,11 @@ class SamDB(samba.Ldb):
"""The SAM database."""
def __init__(self, url=None, lp=None, modules_dir=None, session_info=None,
- credentials=None, flags=0, options=None, global_schema=True):
+ credentials=None, flags=0, options=None, global_schema=True, auto_connect=True):
self.lp = lp
- if url is None:
+ if not auto_connect:
+ url = None
+ elif url is None and lp is not None:
url = lp.get("sam database")
super(SamDB, self).__init__(url=url, lp=lp, modules_dir=modules_dir,
@@ -50,7 +52,10 @@ class SamDB(samba.Ldb):
dsdb.dsdb_set_global_schema(self)
def connect(self, url=None, flags=0, options=None):
- super(SamDB, self).connect(url=self.lp.private_path(url), flags=flags,
+ if self.lp is not None:
+ url = self.lp.private_path(url)
+
+ super(SamDB, self).connect(url=url, flags=flags,
options=options)
def domain_dn(self):
@@ -261,6 +266,15 @@ accountExpires: %u
"Get the invocation_id id"
return dsdb.samdb_ntds_invocation_id(self)
+ def set_ntds_settings_dn(self, ntds_settings_dn):
+ """Set the NTDS Settings DN, as would be returned on the dsServiceName rootDSE attribute
+
+ This allows the DN to be set before the database fully exists
+
+ :param ntds_settings_dn: The new DN to use
+ """
+ dsdb.samdb_set_ntds_settings_dn(self, ntds_settings_dn)
+
invocation_id = property(get_invocation_id, set_invocation_id)
domain_sid = property(get_domain_sid, set_domain_sid)
diff --git a/source4/scripting/python/samba/schema.py b/source4/scripting/python/samba/schema.py
index 092dfe6719..1777c6559c 100644
--- a/source4/scripting/python/samba/schema.py
+++ b/source4/scripting/python/samba/schema.py
@@ -26,6 +26,7 @@ from base64 import b64encode
from ms_schema import read_ms_schema
from samba.dcerpc import security
from samba import read_and_sub_file, substitute_var, check_all_substituted
+from samba.samdb import SamDB
from samba import Ldb
from samba.ndr import ndr_pack
from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL
@@ -52,7 +53,7 @@ def get_schema_descriptor(domain_sid):
class Schema(object):
- def __init__(self, setup_path, domain_sid, schemadn=None,
+ def __init__(self, setup_path, domain_sid, invocationid=None, schemadn=None,
serverdn=None, files=None, prefixmap=None):
"""Load schema for the SamDB from the AD schema files and samba4_schema.ldif
@@ -65,7 +66,12 @@ class Schema(object):
"""
self.schemadn = schemadn
- self.ldb = Ldb()
+ self.ldb = SamDB(global_schema=False)
+ if serverdn is not None:
+ self.ldb.set_ntds_settings_dn("CN=NTDS Settings,%s" % serverdn)
+ if invocationid is not None:
+ self.ldb.set_invocation_id(invocationid)
+
self.schema_data = read_ms_schema(
setup_path('ad-schema/MS-AD_Schema_2K8_R2_Attributes.txt'),
setup_path('ad-schema/MS-AD_Schema_2K8_R2_Classes.txt'))
@@ -100,7 +106,7 @@ class Schema(object):
self.ldb.set_schema_from_ldif(prefixmap_ldif, self.schema_data)
def write_to_tmp_ldb(self, schemadb_path):
- self.ldb.connect(schemadb_path)
+ self.ldb.connect(url=schemadb_path)
self.ldb.transaction_start()
try:
self.ldb.add_ldif("""dn: @ATTRIBUTES