From 5a522b31003d50cf476ead83fb322abeb1525957 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 25 Sep 2005 12:26:07 +0000 Subject: r10486: This is a merge of Brad Henry's 'net join' rework, to better perform an ADS join, particularly as a DC. This represents the bulk of his Google SOC work, and I'm very pleased to intergrate it into the tree. (Metze will intergrate the DRSUAPI work later). Both metze and myself have also put a lot of time into this patch, and in mentoring Brad in general. In return, Brad has been a very good student, and has taken the comments well. Since it's last appearance on samba-technical@, I have made correctness and valgrind fixups, as well as adding a new 'BINDING' mode to the libnet_rpc routines. This allows the exact binding string to be passed down from the torture code, including options and exact target host. Andrew Bartlett (This used to be commit d6fa105fdabbeb83a9b0e50dad49d1649afdb2a4) --- source4/torture/rpc/netlogon.c | 2 +- source4/torture/rpc/testjoin.c | 149 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 136 insertions(+), 15 deletions(-) (limited to 'source4/torture/rpc') diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index a8d881f665..966a0f2e5b 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -1361,7 +1361,7 @@ BOOL torture_rpc_netlogon(void) mem_ctx = talloc_init("torture_rpc_netlogon"); - join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_SVRTRUST, + join_ctx = torture_join_domain(TEST_MACHINE_NAME, ACB_SVRTRUST, &machine_password); if (!join_ctx) { talloc_free(mem_ctx); diff --git a/source4/torture/rpc/testjoin.c b/source4/torture/rpc/testjoin.c index 1f5c9f3270..2c2eca74e7 100644 --- a/source4/torture/rpc/testjoin.c +++ b/source4/torture/rpc/testjoin.c @@ -29,10 +29,15 @@ #include "librpc/gen_ndr/ndr_samr.h" #include "system/time.h" #include "lib/crypto/crypto.h" +#include "libnet/libnet.h" +#include "lib/cmdline/popt_common.h" +#include "lib/ldb/include/ldb.h" + struct test_join { struct dcerpc_pipe *p; struct policy_handle user_handle; + struct libnet_JoinDomain *libnet_r; const char *dom_sid; }; @@ -272,13 +277,59 @@ failed: struct test_join *torture_join_domain(const char *machine_name, - const char *domain, - uint16_t acct_flags, + uint32_t acct_flags, const char **machine_password) { - char *username = talloc_asprintf(NULL, "%s$", machine_name); - struct test_join *tj = torture_create_testuser(username, domain, acct_flags, machine_password); - talloc_free(username); + NTSTATUS status; + struct libnet_context *libnet_ctx; + struct libnet_JoinDomain *libnet_r; + struct test_join *tj; + + tj = talloc(NULL, struct test_join); + if (!tj) return NULL; + + libnet_r = talloc(tj, struct libnet_JoinDomain); + if (!libnet_r) { + talloc_free(tj); + return NULL; + } + + libnet_ctx = libnet_context_init(NULL); + if (!libnet_ctx) { + talloc_free(tj); + return NULL; + } + + tj->libnet_r = libnet_r; + + libnet_ctx->cred = cmdline_credentials; + libnet_r->in.binding = lp_parm_string(-1, "torture", "binding"); + libnet_r->in.level = LIBNET_JOINDOMAIN_SPECIFIED; + libnet_r->in.netbios_name = machine_name; + libnet_r->in.account_name = talloc_asprintf(libnet_r, "%s$", machine_name); + if (!libnet_r->in.account_name) { + talloc_free(tj); + return NULL; + } + + libnet_r->in.acct_type = acct_flags; + + status = libnet_JoinDomain(libnet_ctx, libnet_r, libnet_r); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Domain join failed - %s.\n", nt_errstr(status))); + talloc_free(tj); + return NULL; + } + tj->p = libnet_r->out.samr_pipe; + tj->user_handle = *libnet_r->out.user_handle; + tj->dom_sid = dom_sid_string(tj, libnet_r->out.domain_sid); + *machine_password = libnet_r->out.join_password; + + DEBUG(0, ("%s joined domain %s (%s).\n", + libnet_r->in.netbios_name, + libnet_r->out.domain_name, + tj->dom_sid)); + return tj; } @@ -292,24 +343,94 @@ struct policy_handle *torture_join_samr_user_policy(struct test_join *join) return &join->user_handle; } +NTSTATUS torture_leave_ads_domain(TALLOC_CTX *mem_ctx, struct libnet_JoinDomain *libnet_r) +{ + NTSTATUS status; + int rtn; + TALLOC_CTX *tmp_ctx; + + struct ldb_dn *server_dn; + struct ldb_context *ldb_ctx; + + char *remote_ldb_url; + + /* Check if we are a domain controller. If not, exit. */ + if (!libnet_r->out.server_dn_str) { + return NT_STATUS_OK; + } + + tmp_ctx = talloc_named(mem_ctx, 0, "torture_leave temporary context"); + if (!tmp_ctx) { + libnet_r->out.error_string = NULL; + return NT_STATUS_NO_MEMORY; + } + + ldb_ctx = ldb_init(tmp_ctx); + if (!ldb_ctx) { + libnet_r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + /* Remove CN=Servers,... entry from the AD. */ + server_dn = ldb_dn_explode(tmp_ctx, libnet_r->out.server_dn_str); + if (!server_dn) { + libnet_r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + remote_ldb_url = talloc_asprintf(tmp_ctx, "ldap://%s", libnet_r->out.samr_binding->host); + if (!remote_ldb_url) { + libnet_r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + rtn = ldb_connect(ldb_ctx, remote_ldb_url, 0, NULL); + if (rtn != 0) { + libnet_r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + rtn = ldb_delete(ldb_ctx, server_dn); + if (rtn != 0) { + libnet_r->out.error_string = NULL; + talloc_free(tmp_ctx); + return NT_STATUS_UNSUCCESSFUL; + } + + DEBUG(0, ("%s removed successfully.\n", libnet_r->out.server_dn_str)); + + talloc_free(tmp_ctx); + return status; +} + /* leave the domain, deleting the machine acct */ + void torture_leave_domain(struct test_join *join) { struct samr_DeleteUser d; NTSTATUS status; - if (!GUID_all_zero(&join->user_handle.uuid)) { - d.in.user_handle = &join->user_handle; - d.out.user_handle = &join->user_handle; - - status = dcerpc_samr_DeleteUser(join->p, join, &d); - if (!NT_STATUS_IS_OK(status)) { - printf("Delete of machine account failed\n"); - } + d.in.user_handle = &join->user_handle; + d.out.user_handle = &join->user_handle; + + /* Delete machine account */ + status = dcerpc_samr_DeleteUser(join->p, join, &d); + if (!NT_STATUS_IS_OK(status)) { + printf("Delete of machine account failed\n"); + } else { + printf("Delete of machine account was successful.\n"); } + if (join->libnet_r) { + status = torture_leave_ads_domain(join, join->libnet_r); + } + talloc_free(join); } @@ -337,7 +458,7 @@ struct test_join_ads_dc *torture_join_domain_ads_dc(const char *machine_name, return NULL; } - join->join = torture_join_domain(machine_name, domain, + join->join = torture_join_domain(machine_name, ACB_SVRTRUST, machine_password); -- cgit