test suite for wkssvc rpc operations
Copyright (C) Andrew Tridgell 2003
+ Copyright (C) Günther Deschner 2007
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
#include "torture/rpc/rpc.h"
#include "lib/cmdline/popt_common.h"
#include "param/param.h"
+#include "../lib/crypto/crypto.h"
+#include "libcli/auth/libcli_auth.h"
#define SMBTORTURE_MACHINE_NAME "smbtrt_name"
#define SMBTORTURE_ALTERNATE_NAME "smbtrt_altname"
NTSTATUS status;
struct wkssvc_NetrWkstaUserGetInfo r;
union wkssvc_NetrWkstaUserInfo info;
- const char *dom = lp_workgroup(global_loadparm);
+ const char *dom = lp_workgroup(tctx->lp_ctx);
struct cli_credentials *creds = cmdline_credentials;
const char *user = cli_credentials_get_username(creds);
int i;
NTSTATUS status;
struct wkssvc_NetrLogonDomainNameAdd r;
- r.in.domain_name = lp_workgroup(global_loadparm);
+ r.in.domain_name = lp_workgroup(tctx->lp_ctx);
torture_comment(tctx, "testing NetrLogonDomainNameAdd\n");
NTSTATUS status;
struct wkssvc_NetrLogonDomainNameDel r;
- r.in.domain_name = lp_workgroup(global_loadparm);
+ r.in.domain_name = lp_workgroup(tctx->lp_ctx);
torture_comment(tctx, "testing NetrLogonDomainNameDel\n");
for (i=0; i<ARRAY_SIZE(levels); i++) {
r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
- r.in.name = lp_workgroup(global_loadparm);
+ r.in.name = lp_workgroup(tctx->lp_ctx);
r.in.Account = NULL;
r.in.Password = NULL;
r.in.name_type = levels[i];
for (i=0; i<ARRAY_SIZE(levels); i++) {
r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
- r.in.name = lp_workgroup(global_loadparm);
+ r.in.name = lp_workgroup(tctx->lp_ctx);
r.in.Account = NULL;
r.in.EncryptedPassword = NULL;
r.in.name_type = levels[i];
size_t size;
uint8_t *msg;
- size = push_ucs2_talloc(tctx, (void **)&msg, message);
+ push_ucs2_talloc(tctx, (void **)&msg, message, &size);
r.in.server_name = dcerpc_server_name(p);
r.in.message_name = dcerpc_server_name(p);
return true;
}
+static bool test_GetJoinInformation(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ enum wkssvc_NetJoinStatus *join_status_p,
+ const char **name)
+{
+ NTSTATUS status;
+ struct wkssvc_NetrGetJoinInformation r;
+ enum wkssvc_NetJoinStatus join_status;
+ const char *name_buffer = "";
+
+ r.in.server_name = dcerpc_server_name(p);
+ r.in.name_buffer = r.out.name_buffer = &name_buffer;
+ r.out.name_type = &join_status;
+
+ status = dcerpc_wkssvc_NetrGetJoinInformation(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "NetrGetJoinInformation failed");
+ torture_assert_werr_ok(tctx, r.out.result,
+ "NetrGetJoinInformation failed");
+
+ if (join_status_p) {
+ *join_status_p = join_status;
+ }
+
+ if (*name) {
+ *name = talloc_strdup(tctx, name_buffer);
+ }
+
+ return true;
+
+}
+
static bool test_NetrGetJoinableOus(struct torture_context *tctx,
struct dcerpc_pipe *p)
{
const char **ous = NULL;
r.in.server_name = dcerpc_server_name(p);
- r.in.domain_name = lp_workgroup(global_loadparm);
+ r.in.domain_name = lp_workgroup(tctx->lp_ctx);
r.in.Account = NULL;
r.in.unknown = NULL;
r.in.num_ous = r.out.num_ous = &num_ous;
const char **ous = NULL;
r.in.server_name = dcerpc_server_name(p);
- r.in.domain_name = lp_workgroup(global_loadparm);
+ r.in.domain_name = lp_workgroup(tctx->lp_ctx);
r.in.Account = NULL;
r.in.EncryptedPassword = NULL;
r.in.num_ous = r.out.num_ous = &num_ous;
return true;
}
+
+static bool test_NetrUnjoinDomain(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ NTSTATUS status;
+ struct wkssvc_NetrUnjoinDomain r;
+ struct cli_credentials *creds = cmdline_credentials;
+ const char *user = cli_credentials_get_username(creds);
+ const char *admin_account = NULL;
+
+ admin_account = talloc_asprintf(tctx, "%s\\%s",
+ lp_workgroup(tctx->lp_ctx),
+ user);
+
+ r.in.server_name = dcerpc_server_name(p);
+ r.in.Account = admin_account;
+ r.in.password = NULL;
+ r.in.unjoin_flags = 0;
+
+ torture_comment(tctx, "testing NetrUnjoinDomain\n");
+
+ status = dcerpc_wkssvc_NetrUnjoinDomain(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "NetrUnjoinDomain failed");
+ torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
+ "NetrUnjoinDomain failed");
+ return true;
+}
+
+static bool test_NetrJoinDomain(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ NTSTATUS status;
+ struct wkssvc_NetrJoinDomain r;
+ struct cli_credentials *creds = cmdline_credentials;
+ const char *user = cli_credentials_get_username(creds);
+ const char *admin_account = NULL;
+
+ admin_account = talloc_asprintf(tctx, "%s\\%s",
+ lp_workgroup(tctx->lp_ctx),
+ user);
+
+ r.in.server_name = dcerpc_server_name(p);
+ r.in.domain_name = lp_realm(tctx->lp_ctx);
+ r.in.account_ou = NULL;
+ r.in.Account = admin_account;
+ r.in.password = NULL;
+ r.in.join_flags = 0;
+
+ torture_comment(tctx, "testing NetrJoinDomain\n");
+
+ status = dcerpc_wkssvc_NetrJoinDomain(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "NetrJoinDomain failed");
+ torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
+ "NetrJoinDomain failed");
+ return true;
+}
+
+/*
+ * prerequisites for remotely joining an unjoined XP SP2 workstation:
+ * - firewall needs to be disabled (or open for ncacn_np access)
+ * - HKLM\System\CurrentControlSet\Control\Lsa\forceguest needs to 0
+ * see also:
+ * http://support.microsoft.com/kb/294355/EN-US/ and
+ * http://support.microsoft.com/kb/290403/EN-US/
+ */
+
+static bool test_NetrJoinDomain2(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ NTSTATUS status;
+ struct wkssvc_NetrJoinDomain2 r;
+ const char *domain_admin_account = NULL;
+ const char *domain_admin_password = NULL;
+ const char *domain_name = NULL;
+ struct wkssvc_PasswordBuffer *pwd_buf;
+ enum wkssvc_NetJoinStatus join_status;
+ const char *join_name = NULL;
+ WERROR expected_err;
+ DATA_BLOB session_key;
+
+ /* FIXME: this test assumes to join workstations / servers and does not
+ * handle DCs (WERR_SETUP_DOMAIN_CONTROLLER) */
+
+ if (!test_GetJoinInformation(tctx, p, &join_status, &join_name))
+ {
+ return false;
+ }
+
+ switch (join_status) {
+ case NET_SETUP_DOMAIN_NAME:
+ expected_err = WERR_SETUP_ALREADY_JOINED;
+ break;
+ case NET_SETUP_UNKNOWN_STATUS:
+ case NET_SETUP_UNJOINED:
+ case NET_SETUP_WORKGROUP_NAME:
+ default:
+ expected_err = WERR_OK;
+ break;
+ }
+
+ domain_admin_account = torture_setting_string(tctx, "domain_admin_account", NULL);
+
+ domain_admin_password = torture_setting_string(tctx, "domain_admin_password", NULL);
+
+ domain_name = torture_setting_string(tctx, "domain_name", NULL);
+
+ if ((domain_admin_account == NULL) ||
+ (domain_admin_password == NULL) ||
+ (domain_name == NULL)) {
+ torture_comment(tctx, "not enough input parameter\n");
+ return false;
+ }
+
+ status = dcerpc_fetch_session_key(p, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ encode_wkssvc_join_password_buffer(tctx, domain_admin_password,
+ &session_key, &pwd_buf);
+
+ r.in.server_name = dcerpc_server_name(p);
+ r.in.domain_name = domain_name;
+ r.in.account_ou = NULL;
+ r.in.admin_account = domain_admin_account;
+ r.in.encrypted_password = pwd_buf;
+ r.in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
+ WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE;
+
+ torture_comment(tctx, "testing NetrJoinDomain2 (assuming non-DC)\n");
+
+ status = dcerpc_wkssvc_NetrJoinDomain2(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "NetrJoinDomain2 failed");
+ torture_assert_werr_equal(tctx, r.out.result, expected_err,
+ "NetrJoinDomain2 failed");
+
+ if (!test_GetJoinInformation(tctx, p, &join_status, &join_name))
+ {
+ return false;
+ }
+
+ if (join_status != NET_SETUP_DOMAIN_NAME) {
+ torture_comment(tctx,
+ "Join verify failed: got %d\n", join_status);
+ return false;
+ }
+
+ return true;
+}
+
+static bool test_NetrUnjoinDomain2(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ NTSTATUS status;
+ struct wkssvc_NetrUnjoinDomain2 r;
+ const char *domain_admin_account = NULL;
+ const char *domain_admin_password = NULL;
+ struct wkssvc_PasswordBuffer *pwd_buf;
+ enum wkssvc_NetJoinStatus join_status;
+ const char *join_name = NULL;
+ WERROR expected_err;
+ DATA_BLOB session_key;
+
+ /* FIXME: this test assumes to join workstations / servers and does not
+ * handle DCs (WERR_SETUP_DOMAIN_CONTROLLER) */
+
+ if (!test_GetJoinInformation(tctx, p, &join_status, &join_name))
+ {
+ return false;
+ }
+
+ switch (join_status) {
+ case NET_SETUP_UNJOINED:
+ expected_err = WERR_SETUP_NOT_JOINED;
+ break;
+ case NET_SETUP_DOMAIN_NAME:
+ case NET_SETUP_UNKNOWN_STATUS:
+ case NET_SETUP_WORKGROUP_NAME:
+ default:
+ expected_err = WERR_OK;
+ break;
+ }
+
+ domain_admin_account = torture_setting_string(tctx, "domain_admin_account", NULL);
+
+ domain_admin_password = torture_setting_string(tctx, "domain_admin_password", NULL);
+
+ if ((domain_admin_account == NULL) ||
+ (domain_admin_password == NULL)) {
+ torture_comment(tctx, "not enough input parameter\n");
+ return false;
+ }
+
+ status = dcerpc_fetch_session_key(p, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ encode_wkssvc_join_password_buffer(tctx, domain_admin_password,
+ &session_key, &pwd_buf);
+
+ r.in.server_name = dcerpc_server_name(p);
+ r.in.account = domain_admin_account;
+ r.in.encrypted_password = pwd_buf;
+ r.in.unjoin_flags = 0;
+
+ torture_comment(tctx, "testing NetrUnjoinDomain2 (assuming non-DC)\n");
+
+ status = dcerpc_wkssvc_NetrUnjoinDomain2(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status,
+ "NetrUnjoinDomain2 failed");
+ torture_assert_werr_equal(tctx, r.out.result, expected_err,
+ "NetrUnjoinDomain2 failed");
+
+ if (!test_GetJoinInformation(tctx, p, &join_status, &join_name))
+ {
+ return false;
+ }
+
+ switch (join_status) {
+ case NET_SETUP_UNJOINED:
+ case NET_SETUP_WORKGROUP_NAME:
+ break;
+ case NET_SETUP_UNKNOWN_STATUS:
+ case NET_SETUP_DOMAIN_NAME:
+ default:
+ torture_comment(tctx,
+ "Unjoin verify failed: got %d\n", join_status);
+ return false;
+ }
+
+ return true;
+}
+
+
struct torture_suite *torture_rpc_wkssvc(TALLOC_CTX *mem_ctx)
{
struct torture_suite *suite;
torture_rpc_tcase_add_test(tcase, "NetrEnumerateComputerNames",
test_NetrEnumerateComputerNames);
+ test = torture_rpc_tcase_add_test(tcase, "NetrJoinDomain2",
+ test_NetrJoinDomain2);
+ test->dangerous = true;
+ test = torture_rpc_tcase_add_test(tcase, "NetrUnjoinDomain2",
+ test_NetrUnjoinDomain2);
+ test->dangerous = true;
+
+ torture_rpc_tcase_add_test(tcase, "NetrJoinDomain",
+ test_NetrJoinDomain);
+ test->dangerous = true;
+ torture_rpc_tcase_add_test(tcase, "NetrUnjoinDomain",
+ test_NetrUnjoinDomain);
+ test->dangerous = true;
torture_rpc_tcase_add_test(tcase, "NetrGetJoinInformation",
test_NetrGetJoinInformation);
torture_rpc_tcase_add_test(tcase, "NetrGetJoinableOus",