The branch, master has been updated via 85ebc49... s4-devel: added a getncchanges developer script via f0803de... s4-pyrpc: use s4_event_context_init() via 470d877... s4-pyregistry: use s4_event_context_init() via 68fe347... s4-event: event_context_find() should use s4_event_context_init() via b4a048d... s4-net: role should be case insensitive for join via 635c41a... s4-drs: show the user sid that does the GetNCChanges call via 826177b... s4-drs: removed the warning on WRIT_REP being set via bd7f981... s4-net: added initial implemention of RODC join via 1337f58... libnet-s4: added replicate() command in pynet via bdc1639... s4-libnet: split libnet_Vampire() into two parts via 2d2a0cb... s4-libnet: show the DN when DsAddEntry() fails via a2cb6ef... s4-net: moved the net join command to python via 8a442b0... s4-libnet: added join type constants to python interface via 10813bd... s4-python: added ndr_print() method in ndr via 8950640... pidl-python: fixed the docstrings for ndr_print, ndr_pack and ndr_unpack via 0d7557e... libreplace: fixed the strptime() waf test from 6cf29b3... s4:security Change struct security_token->sids from struct dom_sid * to struct dom_sid
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 85ebc495f68ae7dca4eecc48b1e2f37325185271 Author: Andrew Tridgell <tri...@samba.org> Date: Mon Aug 23 12:47:51 2010 +1000 s4-devel: added a getncchanges developer script this allows for command line access to getncchanges it also provides a good example of calling DRSUAPI interfaces from python Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit f0803de830d4f1a009b5ef2a06fd94e0f25b3ea8 Author: Andrew Tridgell <tri...@samba.org> Date: Mon Aug 23 12:07:56 2010 +1000 s4-pyrpc: use s4_event_context_init() This fixes a crash when using kerberos and the python dcercpc interface, which requires event nesting Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit 470d87701bfc4d3d58b9cf0c6e5f240bc24707d9 Author: Andrew Tridgell <tri...@samba.org> Date: Mon Aug 23 12:07:19 2010 +1000 s4-pyregistry: use s4_event_context_init() Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit 68fe347592d455638a30a87eace0ba9ebb9a7707 Author: Andrew Tridgell <tri...@samba.org> Date: Mon Aug 23 12:07:00 2010 +1000 s4-event: event_context_find() should use s4_event_context_init() Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit b4a048d763e6bf2202392343946568b311c1708b Author: Andrew Tridgell <tri...@samba.org> Date: Mon Aug 23 11:36:29 2010 +1000 s4-net: role should be case insensitive for join Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit 635c41ab822d12cf3bb8172fdfab28c6c8ac3597 Author: Andrew Tridgell <tri...@samba.org> Date: Mon Aug 23 11:33:19 2010 +1000 s4-drs: show the user sid that does the GetNCChanges call this is useful when debugging replication Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit 826177bd2427a6fdf32c2466040de73a7f286d35 Author: Andrew Tridgell <tri...@samba.org> Date: Mon Aug 23 11:32:28 2010 +1000 s4-drs: removed the warning on WRIT_REP being set we just need to clear this flag commit bd7f9813de5d4f7832342f607d8308e916f0c14d Author: Andrew Tridgell <tri...@samba.org> Date: Mon Aug 23 11:31:48 2010 +1000 s4-net: added initial implemention of RODC join This does the join using python code Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit 1337f5875c2adbb594d421e457f9e6ed5dd4071a Author: Andrew Tridgell <tri...@samba.org> Date: Mon Aug 23 11:30:22 2010 +1000 libnet-s4: added replicate() command in pynet Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit bdc1639642de79aa08e839f77be210683e6361f6 Author: Andrew Tridgell <tri...@samba.org> Date: Mon Aug 23 11:13:22 2010 +1000 s4-libnet: split libnet_Vampire() into two parts libnet_Replicate() will do just the replication portion of libnet_Vampire(). This will be used by the RODC join, where the join part of the operation happens in python, and behaves quite differently to the libnet_Join() code. Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit 2d2a0cb5823080694df0ba161017a83876048d93 Author: Andrew Tridgell <tri...@samba.org> Date: Mon Aug 23 11:11:35 2010 +1000 s4-libnet: show the DN when DsAddEntry() fails Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit a2cb6ef017402e16d2012ffa165b66eb3dafe10b Author: Andrew Tridgell <tri...@samba.org> Date: Mon Aug 23 08:52:19 2010 +1000 s4-net: moved the net join command to python Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit 8a442b082284782987237a0ecf77213c43ed5dae Author: Andrew Tridgell <tri...@samba.org> Date: Mon Aug 23 08:50:04 2010 +1000 s4-libnet: added join type constants to python interface Pair-Programmed-With: Andrew Bartlett <abart...@samba.org> commit 10813bdd852f63eb48dc8ca63a312a80b3897489 Author: Andrew Tridgell <tri...@samba.org> Date: Mon Aug 23 07:52:25 2010 +1000 s4-python: added ndr_print() method in ndr commit 895064000d9a4764e5f8d007d6eb2ab761ce2eca Author: Andrew Tridgell <tri...@samba.org> Date: Mon Aug 23 07:51:55 2010 +1000 pidl-python: fixed the docstrings for ndr_print, ndr_pack and ndr_unpack commit 0d7557e2dc489a16949451fa2372a206ffa055a6 Author: Andrew Tridgell <tri...@samba.org> Date: Mon Aug 23 07:28:09 2010 +1000 libreplace: fixed the strptime() waf test Thanks to Jelmer for pointing this out ----------------------------------------------------------------------- Summary of changes: lib/replace/wscript | 10 +- pidl/lib/Parse/Pidl/Samba4/Python.pm | 6 +- source4/lib/events/tevent_s4.c | 2 +- source4/lib/registry/pyregistry.c | 4 +- source4/libnet/libnet_become_dc.c | 3 +- source4/libnet/libnet_vampire.c | 92 +++++-- source4/libnet/libnet_vampire.h | 16 ++ source4/libnet/py_net.c | 64 +++++ source4/librpc/rpc/pyrpc.c | 2 +- source4/rpc_server/drsuapi/getncchanges.c | 11 +- source4/scripting/devel/getncchanges | 120 +++++++++ source4/scripting/python/samba/join.py | 289 +++++++++++++++++++++ source4/scripting/python/samba/ndr.py | 3 + source4/scripting/python/samba/netcmd/__init__.py | 2 + source4/scripting/python/samba/netcmd/join.py | 35 ++- source4/utils/net/net.c | 1 - source4/utils/net/net_join.c | 104 -------- source4/utils/net/wscript_build | 2 +- 18 files changed, 604 insertions(+), 162 deletions(-) create mode 100755 source4/scripting/devel/getncchanges create mode 100644 source4/scripting/python/samba/join.py delete mode 100644 source4/utils/net/net_join.c Changeset truncated at 500 lines: diff --git a/lib/replace/wscript b/lib/replace/wscript index 9cdfd7f..66b0e87 100644 --- a/lib/replace/wscript +++ b/lib/replace/wscript @@ -202,8 +202,9 @@ def configure(conf): conf.DEFINE('HAVE_EPOLL', 1) if not conf.CHECK_CODE('''#define LIBREPLACE_CONFIGURE_TEST_STRPTIME - #include "$libreplacedir/test/strptime.c"''', + #include "test/strptime.c"''', define='HAVE_STRPTIME', + addmain=False, msg='Checking for working strptime'): conf.DEFINE('REPLACE_STRPTIME', 1) @@ -288,13 +289,6 @@ def configure(conf): cflags=conf.env.VISIBILITY_CFLAGS, define='HAVE_VISIBILITY_ATTR') - if not conf.CHECK_CODE('''#define LIBREPLACE_CONFIGURE_TEST_STRPTIME - #include "$libreplacedir/test/strptime.c"''', - define='HAVE_STRPTIME', - msg='Checking for working strptime'): - conf.DEFINE('REPLACE_STRPTIME', 1) - - # look for a method of finding the list of network interfaces for method in ['HAVE_IFACE_GETIFADDRS', 'HAVE_IFACE_AIX', 'HAVE_IFACE_IFCONF', 'HAVE_IFACE_IFREQ']: if conf.CHECK_CODE(''' diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm index f7968b4..6adc60c 100644 --- a/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -303,9 +303,9 @@ sub PythonStruct($$$$$$) $py_methods = "py_$name\_methods"; $self->pidl("static PyMethodDef $py_methods\[] = {"); $self->indent; - $self->pidl("{ \"__ndr_pack__\", (PyCFunction)py_$name\_ndr_pack, METH_NOARGS, \"S.pack() -> blob\\nNDR pack\" },"); - $self->pidl("{ \"__ndr_unpack__\", (PyCFunction)py_$name\_ndr_unpack, METH_VARARGS, \"S.unpack(blob) -> None\\nNDR unpack\" },"); - $self->pidl("{ \"__ndr_print__\", (PyCFunction)py_$name\_ndr_print, METH_VARARGS, \"S.print(blob) -> None\\nNDR print\" },"); + $self->pidl("{ \"__ndr_pack__\", (PyCFunction)py_$name\_ndr_pack, METH_NOARGS, \"S.ndr_pack(object) -> blob\\nNDR pack\" },"); + $self->pidl("{ \"__ndr_unpack__\", (PyCFunction)py_$name\_ndr_unpack, METH_VARARGS, \"S.ndr_unpack(class, blob) -> None\\nNDR unpack\" },"); + $self->pidl("{ \"__ndr_print__\", (PyCFunction)py_$name\_ndr_print, METH_VARARGS, \"S.ndr_print(object) -> None\\nNDR print\" },"); $self->pidl("{ NULL, NULL, 0, NULL }"); $self->deindent; $self->pidl("};"); diff --git a/source4/lib/events/tevent_s4.c b/source4/lib/events/tevent_s4.c index 838f20d..ecedf84 100644 --- a/source4/lib/events/tevent_s4.c +++ b/source4/lib/events/tevent_s4.c @@ -97,7 +97,7 @@ struct tevent_context *event_context_find(TALLOC_CTX *mem_ctx) ev = default_tevent_context; } if (ev == NULL) { - ev = tevent_context_init(mem_ctx); + ev = s4_event_context_init(mem_ctx); } return ev; } diff --git a/source4/lib/registry/pyregistry.c b/source4/lib/registry/pyregistry.c index a3ba6c5..7f4f833 100644 --- a/source4/lib/registry/pyregistry.c +++ b/source4/lib/registry/pyregistry.c @@ -19,10 +19,10 @@ #include <Python.h> #include "includes.h" -#include <tevent.h> #include "libcli/util/pyerrors.h" #include "lib/registry/registry.h" #include "lib/talloc/pytalloc.h" +#include "lib/events/events.h" #include "auth/credentials/pycredentials.h" #include "param/pyparam.h" @@ -361,7 +361,7 @@ static PyObject *py_open_ldb_file(PyObject *self, PyObject *args, PyObject *kwar session_info = NULL; /* FIXME */ result = reg_open_ldb_file(NULL, location, session_info, credentials, - tevent_context_init(NULL), lp_ctx, &key); + s4_event_context_init(NULL), lp_ctx, &key); PyErr_WERROR_IS_ERR_RAISE(result); return py_talloc_steal(&PyHiveKey, key); diff --git a/source4/libnet/libnet_become_dc.c b/source4/libnet/libnet_become_dc.c index 828fd52..fc7faa4 100644 --- a/source4/libnet/libnet_become_dc.c +++ b/source4/libnet/libnet_become_dc.c @@ -2287,8 +2287,9 @@ static void becomeDC_drsuapi1_add_entry_recv(struct tevent_req *subreq) return; } - DEBUG(0,("DsAddEntry (R3) failed: " + DEBUG(0,("DsAddEntry (R3) of '%s' failed: " "Errors: dir_err = %d, status = %s;\n", + r->in.req->req3.first_object.object.identifier->dn, err_data->v1.dir_err, win_errstr(err_data->v1.status))); diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 5a5f126..1847890 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -757,13 +757,7 @@ NTSTATUS libnet_Vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_Vampire *r) { struct libnet_JoinDomain *join; - struct provision_store_self_join_settings *set_secrets; - struct libnet_BecomeDC b; - struct libnet_vampire_cb_state *s; - struct ldb_message *msg; - const char *error_string; - int ldb_ret; - uint32_t i; + struct libnet_Replicate rep; NTSTATUS status; const char *account_name; @@ -811,14 +805,64 @@ NTSTATUS libnet_Vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, talloc_free(join); return status; } + + rep.in.domain_name = join->out.domain_name; + rep.in.netbios_name = netbios_name; + rep.in.targetdir = r->in.targetdir; + rep.in.domain_sid = join->out.domain_sid; + rep.in.realm = join->out.realm; + rep.in.server = join->out.samr_binding->host; + rep.in.join_password = join->out.join_password; + rep.in.kvno = join->out.kvno; + + status = libnet_Replicate(ctx, mem_ctx, &rep); + + r->out.domain_sid = join->out.domain_sid; + r->out.domain_name = join->out.domain_name; + r->out.error_string = rep.out.error_string; + + return status; +} + + + +NTSTATUS libnet_Replicate(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, + struct libnet_Replicate *r) +{ + struct provision_store_self_join_settings *set_secrets; + struct libnet_BecomeDC b; + struct libnet_vampire_cb_state *s; + struct ldb_message *msg; + const char *error_string; + int ldb_ret; + uint32_t i; + NTSTATUS status; + TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); + const char *account_name; + const char *netbios_name; + + r->out.error_string = NULL; + + netbios_name = r->in.netbios_name; + account_name = talloc_asprintf(tmp_ctx, "%s$", netbios_name); + if (!account_name) { + talloc_free(tmp_ctx); + r->out.error_string = NULL; + return NT_STATUS_NO_MEMORY; + } + /* Re-use the domain we are joining as the domain for the user + * to be authenticated with, unless they specified + * otherwise */ + cli_credentials_set_domain(ctx->cred, r->in.domain_name, CRED_GUESS_ENV); + s = libnet_vampire_cb_state_init(mem_ctx, ctx->lp_ctx, ctx->event_ctx, - netbios_name, join->out.domain_name, join->out.realm, + netbios_name, r->in.domain_name, r->in.realm, r->in.targetdir); if (!s) { return NT_STATUS_NO_MEMORY; } - talloc_steal(s, join); + talloc_steal(s, tmp_ctx); ZERO_STRUCT(b); @@ -826,19 +870,19 @@ NTSTATUS libnet_Vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, * We now know the domain and realm for sure - if they didn't * put one on the command line, use this for the rest of the * join */ - cli_credentials_set_realm(ctx->cred, join->out.realm, CRED_GUESS_ENV); - cli_credentials_set_domain(ctx->cred, join->out.domain_name, CRED_GUESS_ENV); + cli_credentials_set_realm(ctx->cred, r->in.realm, CRED_GUESS_ENV); + cli_credentials_set_domain(ctx->cred, r->in.domain_name, CRED_GUESS_ENV); /* Now set these values into the smb.conf - we probably had * empty or useless defaults here from whatever smb.conf we * started with */ - lpcfg_set_cmdline(s->lp_ctx, "realm", join->out.realm); - lpcfg_set_cmdline(s->lp_ctx, "workgroup", join->out.domain_name); + lpcfg_set_cmdline(s->lp_ctx, "realm", r->in.realm); + lpcfg_set_cmdline(s->lp_ctx, "workgroup", r->in.domain_name); - b.in.domain_dns_name = join->out.realm; - b.in.domain_netbios_name = join->out.domain_name; - b.in.domain_sid = join->out.domain_sid; - b.in.source_dsa_address = join->out.samr_binding->host; + b.in.domain_dns_name = r->in.realm; + b.in.domain_netbios_name = r->in.domain_name; + b.in.domain_sid = r->in.domain_sid; + b.in.source_dsa_address = r->in.server; b.in.dest_dsa_netbios_name = netbios_name; b.in.callbacks.private_data = s; @@ -914,13 +958,13 @@ NTSTATUS libnet_Vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, } ZERO_STRUCTP(set_secrets); - set_secrets->domain_name = join->out.domain_name; - set_secrets->realm = join->out.realm; + set_secrets->domain_name = r->in.domain_name; + set_secrets->realm = r->in.realm; set_secrets->netbios_name = netbios_name; set_secrets->secure_channel_type = SEC_CHAN_BDC; - set_secrets->machine_password = join->out.join_password; - set_secrets->key_version_number = join->out.kvno; - set_secrets->domain_sid = join->out.domain_sid; + set_secrets->machine_password = r->in.join_password; + set_secrets->key_version_number = r->in.kvno; + set_secrets->domain_sid = r->in.domain_sid; status = provision_store_self_join(ctx, s->lp_ctx, ctx->event_ctx, set_secrets, &error_string); if (!NT_STATUS_IS_OK(status)) { @@ -929,9 +973,6 @@ NTSTATUS libnet_Vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, return status; } - r->out.domain_name = talloc_steal(mem_ctx, join->out.domain_name); - r->out.domain_sid = dom_sid_dup(mem_ctx, join->out.domain_sid); - /* commit the transaction now we know the secrets were written * out properly */ @@ -943,5 +984,4 @@ NTSTATUS libnet_Vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, talloc_free(s); return NT_STATUS_OK; - } diff --git a/source4/libnet/libnet_vampire.h b/source4/libnet/libnet_vampire.h index 9bf64d3..ea616ab 100644 --- a/source4/libnet/libnet_vampire.h +++ b/source4/libnet/libnet_vampire.h @@ -36,6 +36,22 @@ struct libnet_Vampire { } out; }; +struct libnet_Replicate { + struct { + const char *domain_name; + const char *netbios_name; + const char *targetdir; /* optional, may be NULL */ + struct dom_sid *domain_sid; + const char *realm; + const char *server; + const char *join_password; + uint32_t kvno; + } in; + struct { + const char *error_string; + } out; +}; + /* Private context for the default callbacks */ struct libnet_vampire_cb_state; diff --git a/source4/libnet/py_net.c b/source4/libnet/py_net.c index f5eea22..d4a4670 100644 --- a/source4/libnet/py_net.c +++ b/source4/libnet/py_net.c @@ -306,9 +306,68 @@ static PyObject *py_net_vampire(py_net_Object *self, PyObject *args, PyObject *k return ret; } + +static PyObject *py_net_replicate(py_net_Object *self, PyObject *args, PyObject *kwargs) +{ + const char *kwnames[] = { "domain", "netbios_name", + "domain_sid", "realm", "server", "join_password", + "kvno", "target_dir", NULL }; + NTSTATUS status; + TALLOC_CTX *mem_ctx; + struct libnet_Replicate r; + unsigned kvno; + const char *sidstr; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ssssssI|z", + discard_const_p(char *, kwnames), + &r.in.domain_name, + &r.in.netbios_name, + &sidstr, + &r.in.realm, + &r.in.server, + &r.in.join_password, + &kvno, + &r.in.targetdir)) { + return NULL; + } + + r.out.error_string = NULL; + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + r.in.kvno = kvno; + r.in.domain_sid = dom_sid_parse_talloc(mem_ctx, sidstr); + + if (!r.in.domain_sid) { + PyErr_Format(PyExc_RuntimeError, "Bad domain_sid %s", sidstr); + talloc_free(mem_ctx); + return NULL; + } + + status = libnet_Replicate(self->libnet_ctx, mem_ctx, &r); + + if (!NT_STATUS_IS_OK(status)) { + PyErr_SetString(PyExc_RuntimeError, + r.out.error_string ? r.out.error_string : nt_errstr(status)); + talloc_free(mem_ctx); + return NULL; + } + + talloc_free(mem_ctx); + + return Py_None; +} + static const char py_net_vampire_doc[] = "vampire(domain, target_dir=None)\n" "Vampire a domain."; +static const char py_net_replicate_doc[] = "replicate(domain, netbios_name, domain_sid, realm, server, join_password, kvno, target_dir=None)\n" + "Replicate a domain."; + static PyMethodDef net_obj_methods[] = { {"join", (PyCFunction)py_net_join, METH_VARARGS|METH_KEYWORDS, py_net_join_doc}, {"set_password", (PyCFunction)py_net_set_password, METH_VARARGS|METH_KEYWORDS, py_net_set_password_doc}, @@ -317,6 +376,7 @@ static PyMethodDef net_obj_methods[] = { {"create_user", (PyCFunction)py_net_user_create, METH_VARARGS|METH_KEYWORDS, py_net_create_user_doc}, {"delete_user", (PyCFunction)py_net_user_delete, METH_VARARGS|METH_KEYWORDS, py_net_delete_user_doc}, {"vampire", (PyCFunction)py_net_vampire, METH_VARARGS|METH_KEYWORDS, py_net_vampire_doc}, + {"replicate", (PyCFunction)py_net_replicate, METH_VARARGS|METH_KEYWORDS, py_net_replicate_doc}, { NULL } }; @@ -392,4 +452,8 @@ void initnet(void) Py_INCREF(&py_net_Type); PyModule_AddObject(m, "Net", (PyObject *)&py_net_Type); + PyModule_AddObject(m, "LIBNET_JOINDOMAIN_AUTOMATIC", PyInt_FromLong(LIBNET_JOINDOMAIN_AUTOMATIC)); + PyModule_AddObject(m, "LIBNET_JOINDOMAIN_SPECIFIED", PyInt_FromLong(LIBNET_JOINDOMAIN_SPECIFIED)); + PyModule_AddObject(m, "LIBNET_JOIN_AUTOMATIC", PyInt_FromLong(LIBNET_JOIN_AUTOMATIC)); + PyModule_AddObject(m, "LIBNET_JOIN_SPECIFIED", PyInt_FromLong(LIBNET_JOIN_SPECIFIED)); } diff --git a/source4/librpc/rpc/pyrpc.c b/source4/librpc/rpc/pyrpc.c index 258e458..bcfe8cf 100644 --- a/source4/librpc/rpc/pyrpc.c +++ b/source4/librpc/rpc/pyrpc.c @@ -339,7 +339,7 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py ret = PyObject_New(dcerpc_InterfaceObject, type); ret->mem_ctx = mem_ctx; - event_ctx = event_context_init(ret->mem_ctx); + event_ctx = s4_event_context_init(ret->mem_ctx); if (py_basis != Py_None) { struct dcerpc_pipe *base_pipe; diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index 7a1ccd9..7eb5ee0 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -1027,10 +1027,8 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ security_level = security_session_user_level(dce_call->conn->auth_state.session_info, samdb_domain_sid(sam_ctx)); if (security_level == SECURITY_RO_DOMAIN_CONTROLLER && - (req8->replica_flags & DRSUAPI_DRS_WRIT_REP) && - req8->extended_op != DRSUAPI_EXOP_REPL_SECRET) { - DEBUG(3,(__location__ ": Removing WRIT_REP flag for replication by RODC %s\n", - dom_sid_string(mem_ctx, user_sid))); + req8->replica_flags & DRSUAPI_DRS_WRIT_REP) { + /* we rely on this flag being unset for RODC requests */ req8->replica_flags &= ~DRSUAPI_DRS_WRIT_REP; } @@ -1368,13 +1366,14 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ } DEBUG(r->out.ctr->ctr6.more_data?2:1, - ("DsGetNCChanges with uSNChanged >= %llu flags 0x%08x on %s gave %u objects (done %u/%u) %u links (done %u/%u)\n", + ("DsGetNCChanges with uSNChanged >= %llu flags 0x%08x on %s gave %u objects (done %u/%u) %u links (done %u/%u (as %s))\n", (unsigned long long)(req8->highwatermark.highest_usn+1), req8->replica_flags, ncRoot->dn, r->out.ctr->ctr6.object_count, i, r->out.ctr->ctr6.more_data?getnc_state->site_res->count:i, r->out.ctr->ctr6.linked_attributes_count, - link_given, link_total)); + link_given, link_total, + dom_sid_string(mem_ctx, user_sid))); #if 0 if (!r->out.ctr->ctr6.more_data && req8->extended_op != DRSUAPI_EXOP_NONE) { diff --git a/source4/scripting/devel/getncchanges b/source4/scripting/devel/getncchanges new file mode 100755 index 0000000..7656c22 --- /dev/null +++ b/source4/scripting/devel/getncchanges @@ -0,0 +1,120 @@ +#!/usr/bin/env python + +# script to call a DRS GetNCChanges from the command line +# this is useful for plugfest testing + +import sys +from optparse import OptionParser + +sys.path.insert(0, "bin/python") + +import samba +import samba.getopt as options +from samba.dcerpc import drsuapi, misc +from samba.samdb import SamDB +from samba.auth import system_session + +def do_DsBind(drs): + '''make a DsBind call, returning the binding handle''' + bind_info = drsuapi.DsBindInfoCtr() + bind_info.length = 28 + bind_info.info = drsuapi.DsBindInfo28() + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_BASE + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2 + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1 + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2 + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2 + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01 + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3 + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2 + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6 + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8 + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5 + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6 + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3 + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7 + bind_info.info.supported_extensions |= drsuapi.DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT + (info, handle) = drs.DsBind(misc.GUID(drsuapi.DRSUAPI_DS_BIND_GUID), bind_info) + return handle + +########### main code ########### +if __name__ == "__main__": + parser = OptionParser("getncchanges [options] server") + sambaopts = options.SambaOptions(parser) + credopts = options.CredentialsOptionsDouble(parser) + parser.add_option_group(credopts) + + parser.add_option("", "--dn", dest="dn", help="DN to replicate",) + parser.add_option("", "--exop", dest="exop", help="extended operation",) + + (opts, args) = parser.parse_args() + + lp = sambaopts.get_loadparm() + creds = credopts.get_credentials(lp) + + if len(args) != 1: + parser.error("You must supply a server") + + if creds.is_anonymous(): + parser.error("You must supply credentials") + + server = args[0] + + binding_str = "ncacn_ip_tcp:%s[seal,print]" % server + + drs = drsuapi.drsuapi(binding_str, lp, creds) + drs_handle = do_DsBind(drs) + print "DRS Handle: %s" % drs_handle + + req8 = drsuapi.DsGetNCChangesRequest8() -- Samba Shared Repository