mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
python/drs: Ensure to pass in the local invocationID during the domain join
This ensures (and asserts) that we never write an all-zero GUID as an invocationID to the database in replPropertyMetaData. Andrew Bartlett Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
This commit is contained in:
parent
6965f918c0
commit
a623359fb8
@ -147,12 +147,16 @@ def drs_DsBind(drs):
|
|||||||
class drs_Replicate(object):
|
class drs_Replicate(object):
|
||||||
'''DRS replication calls'''
|
'''DRS replication calls'''
|
||||||
|
|
||||||
def __init__(self, binding_string, lp, creds, samdb):
|
def __init__(self, binding_string, lp, creds, samdb, invocation_id):
|
||||||
self.drs = drsuapi.drsuapi(binding_string, lp, creds)
|
self.drs = drsuapi.drsuapi(binding_string, lp, creds)
|
||||||
(self.drs_handle, self.supported_extensions) = drs_DsBind(self.drs)
|
(self.drs_handle, self.supported_extensions) = drs_DsBind(self.drs)
|
||||||
self.net = Net(creds=creds, lp=lp)
|
self.net = Net(creds=creds, lp=lp)
|
||||||
self.samdb = samdb
|
self.samdb = samdb
|
||||||
self.replication_state = self.net.replicate_init(self.samdb, lp, self.drs)
|
if not isinstance(invocation_id, misc.GUID):
|
||||||
|
raise RuntimeError("Must supply GUID for invocation_id")
|
||||||
|
if invocation_id == misc.GUID("00000000-0000-0000-0000-000000000000"):
|
||||||
|
raise RuntimeError("Must not set GUID 00000000-0000-0000-0000-000000000000 as invocation_id")
|
||||||
|
self.replication_state = self.net.replicate_init(self.samdb, lp, self.drs, invocation_id)
|
||||||
|
|
||||||
def drs_get_rodc_partial_attribute_set(self):
|
def drs_get_rodc_partial_attribute_set(self):
|
||||||
'''get a list of attributes for RODC replication'''
|
'''get a list of attributes for RODC replication'''
|
||||||
|
@ -799,7 +799,7 @@ class dc_join(object):
|
|||||||
binding_options += ",print"
|
binding_options += ",print"
|
||||||
repl = drs_utils.drs_Replicate(
|
repl = drs_utils.drs_Replicate(
|
||||||
"ncacn_ip_tcp:%s[%s]" % (ctx.server, binding_options),
|
"ncacn_ip_tcp:%s[%s]" % (ctx.server, binding_options),
|
||||||
ctx.lp, repl_creds, ctx.local_samdb)
|
ctx.lp, repl_creds, ctx.local_samdb, ctx.invocation_id)
|
||||||
|
|
||||||
repl.replicate(ctx.schema_dn, source_dsa_invocation_id,
|
repl.replicate(ctx.schema_dn, source_dsa_invocation_id,
|
||||||
destination_dsa_guid, schema=True, rodc=ctx.RODC,
|
destination_dsa_guid, schema=True, rodc=ctx.RODC,
|
||||||
|
@ -258,11 +258,13 @@ def drs_local_replicate(self, SOURCE_DC, NC):
|
|||||||
|
|
||||||
|
|
||||||
source_dsa_invocation_id = misc.GUID(self.samdb.get_invocation_id())
|
source_dsa_invocation_id = misc.GUID(self.samdb.get_invocation_id())
|
||||||
|
dest_dsa_invocation_id = misc.GUID(self.local_samdb.get_invocation_id())
|
||||||
destination_dsa_guid = self.ntds_guid
|
destination_dsa_guid = self.ntds_guid
|
||||||
|
|
||||||
self.samdb.transaction_start()
|
self.samdb.transaction_start()
|
||||||
repl = drs_utils.drs_Replicate("ncacn_ip_tcp:%s[seal]" % self.server, self.lp,
|
repl = drs_utils.drs_Replicate("ncacn_ip_tcp:%s[seal]" % self.server, self.lp,
|
||||||
self.creds, self.local_samdb)
|
self.creds, self.local_samdb, dest_dsa_invocation_id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
repl.replicate(NC, source_dsa_invocation_id, destination_dsa_guid)
|
repl.replicate(NC, source_dsa_invocation_id, destination_dsa_guid)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
|
@ -1302,6 +1302,7 @@ const struct GUID *samdb_ntds_invocation_id(struct ldb_context *ldb)
|
|||||||
/* see if we have a cached copy */
|
/* see if we have a cached copy */
|
||||||
invocation_id = (struct GUID *)ldb_get_opaque(ldb, "cache.invocation_id");
|
invocation_id = (struct GUID *)ldb_get_opaque(ldb, "cache.invocation_id");
|
||||||
if (invocation_id) {
|
if (invocation_id) {
|
||||||
|
SMB_ASSERT(!GUID_all_zero(invocation_id));
|
||||||
return invocation_id;
|
return invocation_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1362,6 +1363,7 @@ bool samdb_set_ntds_invocation_id(struct ldb_context *ldb, const struct GUID *in
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SMB_ASSERT(!GUID_all_zero(invocation_id_in));
|
||||||
*invocation_id_new = *invocation_id_in;
|
*invocation_id_new = *invocation_id_in;
|
||||||
|
|
||||||
/* cache the domain_sid in the ldb */
|
/* cache the domain_sid in the ldb */
|
||||||
|
@ -727,6 +727,11 @@ static PyObject *py_dsdb_set_ntds_invocation_id(PyObject *self, PyObject *args)
|
|||||||
PyErr_LDB_OR_RAISE(py_ldb, ldb);
|
PyErr_LDB_OR_RAISE(py_ldb, ldb);
|
||||||
GUID_from_string(PyString_AsString(py_guid), &guid);
|
GUID_from_string(PyString_AsString(py_guid), &guid);
|
||||||
|
|
||||||
|
if (GUID_all_zero(&guid)) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "set_ntds_invocation_id rejected due to all-zero invocation ID");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ret = samdb_set_ntds_invocation_id(ldb, &guid);
|
ret = samdb_set_ntds_invocation_id(ldb, &guid);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
PyErr_SetString(PyExc_RuntimeError, "set_ntds_invocation_id failed");
|
PyErr_SetString(PyExc_RuntimeError, "set_ntds_invocation_id failed");
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include <pyldb.h>
|
#include <pyldb.h>
|
||||||
|
#include <pytalloc.h>
|
||||||
#include "libnet.h"
|
#include "libnet.h"
|
||||||
#include "auth/credentials/pycredentials.h"
|
#include "auth/credentials/pycredentials.h"
|
||||||
#include "libcli/security/security.h"
|
#include "libcli/security/security.h"
|
||||||
@ -33,6 +34,7 @@
|
|||||||
#include "libcli/finddc.h"
|
#include "libcli/finddc.h"
|
||||||
#include "dsdb/samdb/samdb.h"
|
#include "dsdb/samdb/samdb.h"
|
||||||
#include "py_net.h"
|
#include "py_net.h"
|
||||||
|
#include "librpc/rpc/pyrpc_util.h"
|
||||||
|
|
||||||
void initnet(void);
|
void initnet(void);
|
||||||
|
|
||||||
@ -363,16 +365,17 @@ struct replicate_state {
|
|||||||
*/
|
*/
|
||||||
static PyObject *py_net_replicate_init(py_net_Object *self, PyObject *args, PyObject *kwargs)
|
static PyObject *py_net_replicate_init(py_net_Object *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
const char *kwnames[] = { "samdb", "lp", "drspipe", NULL };
|
const char *kwnames[] = { "samdb", "lp", "drspipe", "invocation_id", NULL };
|
||||||
PyObject *py_ldb, *py_lp, *py_drspipe;
|
PyObject *py_ldb, *py_lp, *py_drspipe, *py_invocation_id;
|
||||||
struct ldb_context *samdb;
|
struct ldb_context *samdb;
|
||||||
struct loadparm_context *lp;
|
struct loadparm_context *lp;
|
||||||
struct replicate_state *s;
|
struct replicate_state *s;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOO",
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOOO",
|
||||||
discard_const_p(char *, kwnames),
|
discard_const_p(char *, kwnames),
|
||||||
&py_ldb, &py_lp, &py_drspipe)) {
|
&py_ldb, &py_lp, &py_drspipe,
|
||||||
|
&py_invocation_id)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,6 +395,12 @@ static PyObject *py_net_replicate_init(py_net_Object *self, PyObject *args, PyOb
|
|||||||
talloc_free(s);
|
talloc_free(s);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (!py_check_dcerpc_type(py_invocation_id, "samba.dcerpc.misc", "GUID")) {
|
||||||
|
|
||||||
|
talloc_free(s);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
s->dest_dsa.invocation_id = *pytalloc_get_type(py_invocation_id, struct GUID);
|
||||||
|
|
||||||
s->drs_pipe = (dcerpc_InterfaceObject *)(py_drspipe);
|
s->drs_pipe = (dcerpc_InterfaceObject *)(py_drspipe);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user