Copyright (C) Andrew Tridgell 2003
Copyright (C) Stefan (metze) Metzmacher 2004
-
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2006
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "librpc/gen_ndr/ndr_drsuapi.h"
-
-struct DsPrivate {
- struct policy_handle bind_handle;
- struct GUID bind_guid;
- const char *domain_obj_dn;
- const char *domain_guid_str;
- const char *domain_dns_name;
- struct GUID domain_guid;
- struct drsuapi_DsGetDCInfo2 dcinfo;
-};
-
-static BOOL test_DsBind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
- struct DsPrivate *priv)
+#include "torture/torture.h"
+#include "librpc/gen_ndr/ndr_drsuapi_c.h"
+#include "torture/rpc/rpc.h"
+
+#define TEST_MACHINE_NAME "torturetest"
+
+BOOL test_DsBind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct DsPrivate *priv)
{
NTSTATUS status;
struct drsuapi_DsBind r;
return ret;
}
-static BOOL test_DsCrackNames(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+static BOOL test_DsGetDomainControllerInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct DsPrivate *priv)
{
NTSTATUS status;
- struct drsuapi_DsCrackNames r;
- struct drsuapi_DsNameString names[1];
+ struct drsuapi_DsGetDomainControllerInfo r;
BOOL ret = True;
- const char *dns_domain;
- const char *nt4_domain;
- const char *FQDN_1779_name;
-
- ZERO_STRUCT(r);
- r.in.bind_handle = &priv->bind_handle;
- r.in.level = 1;
- r.in.req.req1.unknown1 = 0x000004e4;
- r.in.req.req1.unknown2 = 0x00000407;
- r.in.req.req1.count = 1;
- r.in.req.req1.names = names;
- r.in.req.req1.format_flags = DRSUAPI_DS_NAME_FLAG_NO_FLAGS;
-
- r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_CANONICAL;
- r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
- names[0].str = talloc_asprintf(mem_ctx, "%s/", lp_realm());
-
- printf("testing DsCrackNames with name '%s' desired format:%d\n",
- names[0].str, r.in.req.req1.format_desired);
-
- status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
- }
- printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
- ret = False;
- }
-
- if (!ret) {
- return ret;
- }
-
- dns_domain = r.out.ctr.ctr1->array[0].dns_domain_name;
- nt4_domain = r.out.ctr.ctr1->array[0].result_name;
-
- r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_GUID;
-
- printf("testing DsCrackNames with name '%s' desired format:%d\n",
- names[0].str, r.in.req.req1.format_desired);
-
- status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
- }
- printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
- ret = False;
- }
-
- if (!ret) {
- return ret;
- }
-
- priv->domain_dns_name = r.out.ctr.ctr1->array[0].dns_domain_name;
- priv->domain_guid_str = r.out.ctr.ctr1->array[0].result_name;
- GUID_from_string(priv->domain_guid_str, &priv->domain_guid);
-
-
- r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_GUID;
- r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
- names[0].str = priv->domain_guid_str;
-
- printf("testing DsCrackNames with name '%s' desired format:%d\n",
- names[0].str, r.in.req.req1.format_desired);
-
- status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
- }
- printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
- ret = False;
- }
-
- if (!ret) {
- return ret;
- }
-
- r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
- r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
- names[0].str = nt4_domain;
-
- printf("testing DsCrackNames with name '%s' desired format:%d\n",
- names[0].str, r.in.req.req1.format_desired);
-
- status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
- }
- printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
- ret = False;
- }
-
- if (!ret) {
- return ret;
- }
-
- priv->domain_obj_dn = r.out.ctr.ctr1->array[0].result_name;
-
- r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
- r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
- names[0].str = talloc_asprintf(mem_ctx, "%s%s$", nt4_domain, priv->dcinfo.netbios_name);
-
- printf("testing DsCrackNames with name '%s' desired format:%d\n",
- names[0].str, r.in.req.req1.format_desired);
-
- status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
- }
- printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
- ret = False;
- }
-
- if (!ret) {
- return ret;
- }
-
- FQDN_1779_name = r.out.ctr.ctr1->array[0].result_name;
-
- r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
- r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_CANONICAL;
- names[0].str = FQDN_1779_name;
-
- printf("testing DsCrackNames with name '%s' desired format:%d\n",
- names[0].str, r.in.req.req1.format_desired);
-
- status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
- }
- printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
- ret = False;
- }
-
- if (!ret) {
- return ret;
- }
-
- r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_DISPLAY;
-
- printf("testing DsCrackNames with name '%s' desired format:%d\n",
- names[0].str, r.in.req.req1.format_desired);
-
- status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
- }
- printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
- ret = False;
- }
-
- if (!ret) {
- return ret;
- }
-
- r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_GUID;
-
- printf("testing DsCrackNames with name '%s' desired format:%d\n",
- names[0].str, r.in.req.req1.format_desired);
-
- status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
- }
- printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
- ret = False;
- }
-
- if (!ret) {
- return ret;
- }
-
- r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL;
-
- printf("testing DsCrackNames with name '%s' desired format:%d\n",
- names[0].str, r.in.req.req1.format_desired);
-
- status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
- }
- printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
- ret = False;
- }
-
- if (!ret) {
- return ret;
- }
-
- r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL;
-
- printf("testing DsCrackNames with name '%s' desired format:%d\n",
- names[0].str, r.in.req.req1.format_desired);
-
- status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
- }
- printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
- ret = False;
- }
-
- if (!ret) {
- return ret;
- }
-
- r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_GUID;
- r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
- names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.site_guid);
-
- printf("testing DsCrackNames with Site GUID '%s' desired format:%d\n",
- names[0].str, r.in.req.req1.format_desired);
-
- status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
- }
- printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
- ret = False;
- }
-
- if (!ret) {
- return ret;
- }
-
- r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT;
- names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.computer_guid);
-
- printf("testing DsCrackNames with Computer GUID '%s' desired format:%d\n",
- names[0].str, r.in.req.req1.format_desired);
-
- status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
- }
- printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
- ret = False;
- }
-
- if (!ret) {
- return ret;
- }
-
- r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_GUID;
- r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
- names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.server_guid);
-
- printf("testing DsCrackNames with Server GUID '%s' desired format:%d\n",
- names[0].str, r.in.req.req1.format_desired);
-
- status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
- }
- printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
- ret = False;
- }
-
- if (!ret) {
- return ret;
- }
-
- r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_GUID;
- r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
- names[0].str = GUID_string2(mem_ctx, &priv->dcinfo.ntds_guid);
-
- printf("testing DsCrackNames with NTDS GUID '%s' desired format:%d\n",
- names[0].str, r.in.req.req1.format_desired);
-
- status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
- }
- printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
- ret = False;
- }
-
- if (!ret) {
- return ret;
- }
-
- r.in.req.req1.format_offered = DRSUAPI_DS_NAME_FORMAT_GUID;
- r.in.req.req1.format_desired = DRSUAPI_DS_NAME_FORMAT_FQDN_1779;
- names[0].str = GUID_string2(mem_ctx, &priv->bind_guid);
-
- printf("testing DsCrackNames with BIND GUID '%s' desired format:%d\n",
- names[0].str, r.in.req.req1.format_desired);
+ BOOL found = False;
+ int i, j, k;
+
+ struct {
+ const char *name;
+ WERROR expected;
+ } names[] = {
+ {
+ .name = torture_join_dom_netbios_name(priv->join),
+ .expected = WERR_OK
+ },
+ {
+ .name = torture_join_dom_dns_name(priv->join),
+ .expected = WERR_OK
+ },
+ {
+ .name = "__UNKNOWN_DOMAIN__",
+ .expected = WERR_DS_OBJ_NOT_FOUND
+ },
+ {
+ .name = "unknown.domain.samba.example.com",
+ .expected = WERR_DS_OBJ_NOT_FOUND
+ },
+ };
+ int levels[] = {1, 2};
+ int level;
+
+ for (i=0; i < ARRAY_SIZE(levels); i++) {
+ for (j=0; j < ARRAY_SIZE(names); j++) {
+ level = levels[i];
+ r.in.bind_handle = &priv->bind_handle;
+ r.in.level = 1;
+
+ r.in.req.req1.domain_name = names[j].name;
+ r.in.req.req1.level = level;
+
+ printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
+ r.in.req.req1.level, r.in.req.req1.domain_name);
+
+ status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ const char *errstr = nt_errstr(status);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
+ errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
+ }
+ printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
+ " with dns domain failed - %s\n",
+ r.in.req.req1.level, errstr);
+ ret = False;
+ } else if (!W_ERROR_EQUAL(r.out.result, names[j].expected)) {
+ printf("DsGetDomainControllerInfo level %d\n"
+ " with dns domain failed - %s, expected %s\n",
+ r.in.req.req1.level, win_errstr(r.out.result),
+ win_errstr(names[j].expected));
+ ret = False;
+ }
+
+ if (!W_ERROR_IS_OK(r.out.result)) {
+ /* If this was an error, we can't read the result structure */
+ continue;
+ }
- status = dcerpc_drsuapi_DsCrackNames(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
+ if (r.in.req.req1.level != r.out.level_out) {
+ printf("dcerpc_drsuapi_DsGetDomainControllerInfo level in (%d) != out (%d)\n",
+ r.in.req.req1.level, r.out.level_out);
+ ret = False;
+ /* We can't safely read the result structure */
+ continue;
+ }
+ switch (level) {
+ case 1:
+ for (k=0; k < r.out.ctr.ctr1.count; k++) {
+ if (strcasecmp_m(r.out.ctr.ctr1.array[k].netbios_name,
+ torture_join_netbios_name(priv->join)) == 0) {
+ found = True;
+ break;
+ }
+ }
+ break;
+ case 2:
+ for (k=0; k < r.out.ctr.ctr2.count; k++) {
+ if (strcasecmp_m(r.out.ctr.ctr2.array[k].netbios_name,
+ torture_join_netbios_name(priv->join)) == 0) {
+ found = True;
+ priv->dcinfo = r.out.ctr.ctr2.array[k];
+ break;
+ }
+ }
+ break;
+ }
+ if (!found) {
+ printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d: Failed to find the domain controller (%s) we just created during the join\n",
+ r.in.req.req1.level,
+ torture_join_netbios_name(priv->join));
+ ret = False;
+ }
}
- printf("dcerpc_drsuapi_DsCrackNames failed - %s\n", errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsCrackNames failed - %s\n", win_errstr(r.out.result));
- ret = False;
}
- if (!ret) {
+ if (lp_parm_bool(-1, "torture", "samba4", False)) {
+ printf("skipping DsGetDomainControllerInfo level -1 test against Samba4\n");
return ret;
}
- return ret;
-}
-
-static BOOL test_DsGetDCInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
- struct DsPrivate *priv)
-{
- NTSTATUS status;
- struct drsuapi_DsGetDomainControllerInfo r;
- BOOL ret = True;
-
r.in.bind_handle = &priv->bind_handle;
r.in.level = 1;
-
- r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_realm());
- r.in.req.req1.level = 1;
-
- printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
- r.in.req.req1.level, r.in.req.req1.domain_name);
-
- status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
- }
- printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
- " with dns domain failed - %s\n",
- r.in.req.req1.level, errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsGetDomainControllerInfo level %d\n"
- " with dns domain failed - %s\n",
- r.in.req.req1.level, win_errstr(r.out.result));
- ret = False;
- }
-
- r.in.req.req1.level = 2;
-
- printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
- r.in.req.req1.level, r.in.req.req1.domain_name);
-
- status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
- }
- printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
- " with dns domain failed - %s\n",
- r.in.req.req1.level, errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsGetDomainControllerInfo level %d\n"
- " with dns domain failed - %s\n",
- r.in.req.req1.level, win_errstr(r.out.result));
- ret = False;
- } else {
- if (r.out.ctr.ctr2.count > 0) {
- priv->dcinfo = r.out.ctr.ctr2.array[0];
- }
- }
-
+
+ r.in.req.req1.domain_name = "__UNKNOWN_DOMAIN__"; /* This is clearly ignored for this level */
r.in.req.req1.level = -1;
-
+
printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
- r.in.req.req1.level, r.in.req.req1.domain_name);
-
+ r.in.req.req1.level, r.in.req.req1.domain_name);
+
status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
const char *errstr = nt_errstr(status);
errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
}
printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
- " with dns domain failed - %s\n",
- r.in.req.req1.level, errstr);
+ " with dns domain failed - %s\n",
+ r.in.req.req1.level, errstr);
ret = False;
} else if (!W_ERROR_IS_OK(r.out.result)) {
printf("DsGetDomainControllerInfo level %d\n"
- " with dns domain failed - %s\n",
- r.in.req.req1.level, win_errstr(r.out.result));
+ " with dns domain failed - %s\n",
+ r.in.req.req1.level, win_errstr(r.out.result));
ret = False;
}
-
- r.in.req.req1.domain_name = talloc_strdup(mem_ctx, lp_workgroup());
- r.in.req.req1.level = 2;
-
- printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
- r.in.req.req1.level, r.in.req.req1.domain_name);
-
- status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
+
+ {
+ const char *dc_account = talloc_asprintf(mem_ctx, "%s\\%s$",
+ torture_join_dom_netbios_name(priv->join),
+ priv->dcinfo.netbios_name);
+ for (k=0; k < r.out.ctr.ctr01.count; k++) {
+ if (strcasecmp_m(r.out.ctr.ctr01.array[k].client_account,
+ dc_account)) {
+ found = True;
+ break;
+ }
}
- printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
- " with netbios domain failed - %s\n",
- r.in.req.req1.level, errstr);
- ret = False;
- } else if (!W_ERROR_IS_OK(r.out.result)) {
- printf("DsGetDomainControllerInfo level %d\n"
- " with netbios domain failed - %s\n",
- r.in.req.req1.level, win_errstr(r.out.result));
- ret = False;
- }
-
- r.in.req.req1.domain_name = "__UNKNOWN_DOMAIN__";
- r.in.req.req1.level = 2;
-
- printf("testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
- r.in.req.req1.level, r.in.req.req1.domain_name);
-
- status = dcerpc_drsuapi_DsGetDomainControllerInfo(p, mem_ctx, &r);
- if (!NT_STATUS_IS_OK(status)) {
- const char *errstr = nt_errstr(status);
- if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
- errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
+ if (!found) {
+ printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d: Failed to find the domain controller (%s) in last logon records\n",
+ r.in.req.req1.level,
+ dc_account);
+ ret = False;
}
- printf("dcerpc_drsuapi_DsGetDomainControllerInfo level %d\n"
- " with invalid domain failed - %s\n",
- r.in.req.req1.level, errstr);
- ret = False;
- } else if (!W_ERROR_EQUAL(r.out.result, WERR_DS_OBJ_NOT_FOUND)) {
- printf("DsGetDomainControllerInfo level %d\n"
- " with invalid domain not expected error (WERR_DS_OBJ_NOT_FOUND) - %s\n",
- r.in.req.req1.level, win_errstr(r.out.result));
- ret = False;
}
+
return ret;
}
static BOOL test_DsWriteAccountSpn(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
- struct DsPrivate *priv)
+ struct DsPrivate *priv)
{
NTSTATUS status;
struct drsuapi_DsWriteAccountSpn r;
"__IGNORED__"
},{
DRSUAPI_DS_REPLICA_GET_INFO2,
- DRSUAPI_DS_REPLICA_INFO_CURSURS05,
+ DRSUAPI_DS_REPLICA_INFO_CURSORS05,
NULL
},{
DRSUAPI_DS_REPLICA_GET_INFO2,
}
};
+ if (lp_parm_bool(-1, "torture", "samba4", False)) {
+ printf("skipping DsReplicaGetInfo test against Samba4\n");
+ return True;
+ }
+
r.in.bind_handle = &priv->bind_handle;
for (i=0; i < ARRAY_SIZE(array); i++) {
return True;
}
+ if (lp_parm_bool(-1, "torture", "samba4", False)) {
+ printf("skipping DsReplicaSync test against Samba4\n");
+ return True;
+ }
+
ZERO_STRUCT(null_guid);
ZERO_STRUCT(null_sid);
nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:"";
r.in.req.req1.naming_context = &nc;
- r.in.req.req1.guid1 = priv->dcinfo.ntds_guid;
- r.in.req.req1.string1 = NULL;
+ r.in.req.req1.source_dsa_guid = priv->dcinfo.ntds_guid;
+ r.in.req.req1.other_info = NULL;
r.in.req.req1.options = 16;
break;
}
}
};
+ if (lp_parm_bool(-1, "torture", "samba4", False)) {
+ printf("skipping DsReplicaUpdateRefs test against Samba4\n");
+ return True;
+ }
+
ZERO_STRUCT(null_guid);
ZERO_STRUCT(null_sid);
}
};
+ if (lp_parm_bool(-1, "torture", "samba4", False)) {
+ printf("skipping DsGetNCChanges test against Samba4\n");
+ return True;
+ }
+
ZERO_STRUCT(null_guid);
ZERO_STRUCT(null_sid);
-
+
for (i=0; i < ARRAY_SIZE(array); i++) {
printf("testing DsGetNCChanges level %d\n",
array[i].level);
r.in.bind_handle = &priv->bind_handle;
- r.in.level = array[i].level;
+ r.in.level = &array[i].level;
- switch (r.in.level) {
+ switch (*r.in.level) {
case 5:
- nc.guid = null_guid;
- nc.sid = null_sid;
- nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:"";
-
- r.in.req.req5.guid1 = null_guid;
- r.in.req.req5.guid2 = null_guid;
- r.in.req.req5.naming_context = &nc;
- r.in.req.req5.usn1.usn1 = 0;
- r.in.req.req5.usn1.usn2 = 0;
- r.in.req.req5.usn1.usn3 = 0;
- r.in.req.req5.coursor = NULL;
- r.in.req.req5.unknown1 = 0;/*0x10201C70;*/
- r.in.req.req5.unknown2 = 0;/*402;*/
- r.in.req.req5.unknown3 = 0;/*402116;*/
- r.in.req.req5.unknown4 = 0;
- r.in.req.req5.h1 = 0;
+ nc.guid = null_guid;
+ nc.sid = null_sid;
+ nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:"";
+
+ r.in.req.req5.destination_dsa_guid = GUID_random();
+ r.in.req.req5.source_dsa_invocation_id = null_guid;
+ r.in.req.req5.naming_context = &nc;
+ r.in.req.req5.highwatermark.tmp_highest_usn = 0;
+ r.in.req.req5.highwatermark.reserved_usn = 0;
+ r.in.req.req5.highwatermark.highest_usn = 0;
+ r.in.req.req5.uptodateness_vector = NULL;
+ r.in.req.req5.replica_flags = 0;
+ if (lp_parm_bool(-1, "drsuapi","compression", False)) {
+ r.in.req.req5.replica_flags |= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES;
+ }
+ r.in.req.req5.max_object_count = 0;
+ r.in.req.req5.max_ndr_size = 0;
+ r.in.req.req5.unknown4 = 0;
+ r.in.req.req5.h1 = 0;
break;
case 8:
- nc.guid = null_guid;
- nc.sid = null_sid;
- nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:"";
-
- r.in.req.req8.guid1 = null_guid;
- r.in.req.req8.guid2 = null_guid;
- r.in.req.req8.naming_context = &nc;
- r.in.req.req8.usn1.usn1 = 0;
- r.in.req.req8.usn1.usn2 = 0;
- r.in.req.req8.usn1.usn3 = 0;
- r.in.req.req8.coursor = NULL;
- r.in.req.req8.unknown1 = 0;/*0x10201C70;*/
- r.in.req.req8.unknown2 = 0;/*402;*/
- r.in.req.req8.unknown3 = 0;/*402116;*/
- r.in.req.req8.unknown4 = 0;
- r.in.req.req8.h1 = 0;
- r.in.req.req8.unique_ptr1 = 0;
- r.in.req.req8.unique_ptr2 = 0;
- r.in.req.req8.ctr12.count = 0;
- r.in.req.req8.ctr12.array = NULL;
+ nc.guid = null_guid;
+ nc.sid = null_sid;
+ nc.dn = priv->domain_obj_dn?priv->domain_obj_dn:"";
+
+ r.in.req.req8.destination_dsa_guid = GUID_random();
+ r.in.req.req8.source_dsa_invocation_id = null_guid;
+ r.in.req.req8.naming_context = &nc;
+ r.in.req.req8.highwatermark.tmp_highest_usn = 0;
+ r.in.req.req8.highwatermark.reserved_usn = 0;
+ r.in.req.req8.highwatermark.highest_usn = 0;
+ r.in.req.req8.uptodateness_vector = NULL;
+ r.in.req.req8.replica_flags = 0;
+ if (lp_parm_bool(-1,"drsuapi","compression",False)) {
+ r.in.req.req8.replica_flags |= DRSUAPI_DS_REPLICA_NEIGHBOUR_COMPRESS_CHANGES;
+ }
+ if (lp_parm_bool(-1,"drsuapi","neighbour_writeable",True)) {
+ r.in.req.req8.replica_flags |= DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE;
+ }
+ r.in.req.req8.replica_flags |= DRSUAPI_DS_REPLICA_NEIGHBOUR_SYNC_ON_STARTUP
+ | DRSUAPI_DS_REPLICA_NEIGHBOUR_DO_SCHEDULED_SYNCS
+ | DRSUAPI_DS_REPLICA_NEIGHBOUR_RETURN_OBJECT_PARENTS
+ | DRSUAPI_DS_REPLICA_NEIGHBOUR_NEVER_SYNCED
+ ;
+ r.in.req.req8.max_object_count = 402;
+ r.in.req.req8.max_ndr_size = 402116;
+ r.in.req.req8.unknown4 = 0;
+ r.in.req.req8.h1 = 0;
+ r.in.req.req8.unique_ptr1 = 0;
+ r.in.req.req8.unique_ptr2 = 0;
+ r.in.req.req8.mapping_ctr.num_mappings = 0;
+ r.in.req.req8.mapping_ctr.mappings = NULL;
break;
}
return ret;
}
-static BOOL test_DsUnbind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
- struct DsPrivate *priv)
+BOOL test_QuerySitesByCost(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct DsPrivate *priv)
+{
+ NTSTATUS status;
+ struct drsuapi_QuerySitesByCost r;
+ BOOL ret = True;
+
+ const char *my_site = "Default-First-Site-Name";
+ const char *remote_site1 = "smbtorture-nonexisting-site1";
+ const char *remote_site2 = "smbtorture-nonexisting-site2";
+
+ r.in.bind_handle = &priv->bind_handle;
+ r.in.level = 1;
+ r.in.req.req1.site_from = talloc_strdup(mem_ctx, my_site);
+ r.in.req.req1.num_req = 2;
+ r.in.req.req1.site_to = talloc_zero_array(mem_ctx, const char *, r.in.req.req1.num_req);
+ r.in.req.req1.site_to[0] = talloc_strdup(mem_ctx, remote_site1);
+ r.in.req.req1.site_to[1] = talloc_strdup(mem_ctx, remote_site2);
+ r.in.req.req1.flags = 0;
+
+ status = dcerpc_drsuapi_QuerySitesByCost(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ const char *errstr = nt_errstr(status);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
+ errstr = dcerpc_errstr(mem_ctx, p->last_fault_code);
+ }
+ printf("drsuapi_QuerySitesByCost - %s\n", errstr);
+ ret = False;
+ } else if (!W_ERROR_IS_OK(r.out.result)) {
+ printf("QuerySitesByCost failed - %s\n", win_errstr(r.out.result));
+ ret = False;
+ }
+
+ if (W_ERROR_IS_OK(r.out.result)) {
+
+ if (!W_ERROR_EQUAL(r.out.ctr.ctr1.info[0].error_code, WERR_DS_OBJ_NOT_FOUND) ||
+ !W_ERROR_EQUAL(r.out.ctr.ctr1.info[1].error_code, WERR_DS_OBJ_NOT_FOUND)) {
+ printf("expected error_code WERR_DS_OBJ_NOT_FOUND, got %s\n",
+ win_errstr(r.out.ctr.ctr1.info[0].error_code));
+ ret = False;
+ }
+
+ if ((r.out.ctr.ctr1.info[0].site_cost != (uint32_t) -1) ||
+ (r.out.ctr.ctr1.info[1].site_cost != (uint32_t) -1)) {
+ printf("expected site_cost %d, got %d\n",
+ (uint32_t) -1, r.out.ctr.ctr1.info[0].site_cost);
+ ret = False;
+ }
+ }
+
+ return ret;
+
+
+}
+
+BOOL test_DsUnbind(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct DsPrivate *priv)
{
NTSTATUS status;
struct drsuapi_DsUnbind r;
return ret;
}
-BOOL torture_rpc_drsuapi(void)
+BOOL torture_rpc_drsuapi(struct torture_context *torture)
{
NTSTATUS status;
struct dcerpc_pipe *p;
TALLOC_CTX *mem_ctx;
BOOL ret = True;
struct DsPrivate priv;
+ struct cli_credentials *machine_credentials;
mem_ctx = talloc_init("torture_rpc_drsuapi");
+ ZERO_STRUCT(priv);
+
+ priv.join = torture_join_domain(TEST_MACHINE_NAME, ACB_SVRTRUST,
+ &machine_credentials);
+ if (!priv.join) {
+ talloc_free(mem_ctx);
+ printf("Failed to join as BDC\n");
+ return False;
+ }
+
status = torture_rpc_connection(mem_ctx,
&p,
- DCERPC_DRSUAPI_NAME,
- DCERPC_DRSUAPI_UUID,
- DCERPC_DRSUAPI_VERSION);
+ &dcerpc_table_drsuapi);
if (!NT_STATUS_IS_OK(status)) {
+ torture_leave_domain(priv.join);
talloc_free(mem_ctx);
return False;
}
- printf("Connected to DRAUAPI pipe\n");
-
- ZERO_STRUCT(priv);
-
ret &= test_DsBind(p, mem_ctx, &priv);
-
- ret &= test_DsGetDCInfo(p, mem_ctx, &priv);
+#if 0
+ ret &= test_QuerySitesByCost(p, mem_ctx, &priv);
+#endif
+ ret &= test_DsGetDomainControllerInfo(p, mem_ctx, &priv);
ret &= test_DsCrackNames(p, mem_ctx, &priv);
talloc_free(mem_ctx);
+ torture_leave_domain(priv.join);
+
+ return ret;
+}
+
+
+BOOL torture_rpc_drsuapi_cracknames(struct torture_context *torture)
+{
+ NTSTATUS status;
+ struct dcerpc_pipe *p;
+ TALLOC_CTX *mem_ctx;
+ BOOL ret = True;
+ struct DsPrivate priv;
+ struct cli_credentials *machine_credentials;
+
+ mem_ctx = talloc_init("torture_rpc_drsuapi");
+
+ printf("Connected to DRAUAPI pipe\n");
+
+ ZERO_STRUCT(priv);
+
+ priv.join = torture_join_domain(TEST_MACHINE_NAME, ACB_SVRTRUST,
+ &machine_credentials);
+ if (!priv.join) {
+ talloc_free(mem_ctx);
+ printf("Failed to join as BDC\n");
+ return False;
+ }
+
+ status = torture_rpc_connection(mem_ctx,
+ &p,
+ &dcerpc_table_drsuapi);
+ if (!NT_STATUS_IS_OK(status)) {
+ torture_leave_domain(priv.join);
+ talloc_free(mem_ctx);
+ return False;
+ }
+
+ ret &= test_DsBind(p, mem_ctx, &priv);
+
+ if (ret) {
+ /* We don't care if this fails, we just need some info from it */
+ test_DsGetDomainControllerInfo(p, mem_ctx, &priv);
+
+ ret &= test_DsCrackNames(p, mem_ctx, &priv);
+
+ ret &= test_DsUnbind(p, mem_ctx, &priv);
+ }
+ talloc_free(mem_ctx);
+
+ torture_leave_domain(priv.join);
+
return ret;
}
+