/*
Unix SMB/CIFS implementation.
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
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,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
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, see .
*/
#include "includes.h"
#include "torture/torture.h"
#include "librpc/gen_ndr/ndr_wkssvc_c.h"
#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"
#define SMBTORTURE_TRANSPORT_NAME "\\Device\\smbtrt_transport_name"
#define SMBTORTURE_USE_NAME "S:"
#define SMBTORTURE_MESSAGE "You are currently tortured by Samba"
static bool test_NetWkstaGetInfo(struct torture_context *tctx,
struct dcerpc_pipe *p)
{
NTSTATUS status;
struct wkssvc_NetWkstaGetInfo r;
union wkssvc_NetWkstaInfo info;
uint16_t levels[] = {100, 101, 102, 502};
int i;
r.in.server_name = dcerpc_server_name(p);
r.out.info = &info;
for (i=0;ilp_ctx);
struct cli_credentials *creds = cmdline_credentials;
const char *user = cli_credentials_get_username(creds);
int i;
const struct {
const char *unknown;
uint32_t level;
WERROR result;
} tests[] = {
{ NULL, 0, WERR_NO_SUCH_LOGON_SESSION },
{ NULL, 1, WERR_NO_SUCH_LOGON_SESSION },
{ NULL, 1101, WERR_OK },
{ dom, 0, WERR_INVALID_PARAM },
{ dom, 1, WERR_INVALID_PARAM },
{ dom, 1101, WERR_INVALID_PARAM },
{ user, 0, WERR_INVALID_PARAM },
{ user, 1, WERR_INVALID_PARAM },
{ user, 1101, WERR_INVALID_PARAM },
};
for (i=0; iinfo0 = &info0;
r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
r.in.level = 0;
r.in.ctr = ctr;
r.in.parm_err = r.out.parm_err = &parm_err;
torture_comment(tctx, "testing NetrUseAdd level %u\n",
r.in.level);
status = dcerpc_wkssvc_NetrUseAdd(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status,
"NetrUseAdd failed");
torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL,
"NetrUseAdd failed");
ZERO_STRUCT(r);
ZERO_STRUCT(info1);
info1.local = SMBTORTURE_USE_NAME;
info1.remote = "\\\\localhost\\sysvol";
info1.password = NULL;
ctr->info1 = &info1;
r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
r.in.level = 1;
r.in.ctr = ctr;
r.in.parm_err = r.out.parm_err = &parm_err;
torture_comment(tctx, "testing NetrUseAdd level %u\n",
r.in.level);
status = dcerpc_wkssvc_NetrUseAdd(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status,
"NetrUseAdd failed");
torture_assert_werr_ok(tctx, r.out.result,
"NetrUseAdd failed");
return true;
}
static bool test_NetrUseDel(struct torture_context *tctx,
struct dcerpc_pipe *p)
{
NTSTATUS status;
struct wkssvc_NetrUseDel r;
r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
r.in.use_name = SMBTORTURE_USE_NAME;
r.in.force_cond = 0;
torture_comment(tctx, "testing NetrUseDel\n");
status = dcerpc_wkssvc_NetrUseDel(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status,
"NetrUseDel failed");
torture_assert_werr_ok(tctx, r.out.result,
"NetrUseDel failed");
return true;
}
static bool test_NetrUseGetInfo_level(struct torture_context *tctx,
struct dcerpc_pipe *p,
const char *use_name,
uint32_t level,
WERROR werr)
{
NTSTATUS status;
struct wkssvc_NetrUseGetInfo r;
union wkssvc_NetrUseGetInfoCtr ctr;
ZERO_STRUCT(ctr);
r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
r.in.use_name = use_name;
r.in.level = level;
r.out.ctr = &ctr;
status = dcerpc_wkssvc_NetrUseGetInfo(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status,
"NetrUseGetInfo failed");
torture_assert_werr_equal(tctx, r.out.result, werr,
"NetrUseGetInfo failed");
return true;
}
static bool test_NetrUseGetInfo(struct torture_context *tctx,
struct dcerpc_pipe *p)
{
NTSTATUS status;
struct wkssvc_NetrUseEnum r;
uint32_t handle = 0;
uint32_t entries_read = 0;
struct wkssvc_NetrUseEnumInfo info;
struct wkssvc_NetrUseEnumCtr0 *use0;
uint32_t levels[] = { 0, 1, 2 };
const char *use_name = NULL;
int i, k;
ZERO_STRUCT(info);
info.level = 0;
use0 = talloc_zero(tctx, struct wkssvc_NetrUseEnumCtr0);
info.ctr.ctr0 = use0;
r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
r.in.prefmaxlen = (uint32_t)-1;
r.in.info = r.out.info = &info;
r.in.resume_handle = r.out.resume_handle = &handle;
r.out.entries_read = &entries_read;
status = dcerpc_wkssvc_NetrUseEnum(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status,
"NetrUseEnum failed");
torture_assert_werr_ok(tctx, r.out.result,
"NetrUseEnum failed");
for (k=0; k < r.out.info->ctr.ctr0->count; k++) {
use_name = r.out.info->ctr.ctr0->array[k].local;
for (i=0; ictr.ctr0->array[k].remote;
for (i=0; ilp_ctx);
torture_comment(tctx, "testing NetrLogonDomainNameAdd\n");
status = dcerpc_wkssvc_NetrLogonDomainNameAdd(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status,
"NetrLogonDomainNameAdd failed");
torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
"NetrLogonDomainNameAdd failed");
return true;
}
static bool test_NetrLogonDomainNameDel(struct torture_context *tctx,
struct dcerpc_pipe *p)
{
NTSTATUS status;
struct wkssvc_NetrLogonDomainNameDel r;
r.in.domain_name = lp_workgroup(tctx->lp_ctx);
torture_comment(tctx, "testing NetrLogonDomainNameDel\n");
status = dcerpc_wkssvc_NetrLogonDomainNameDel(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status,
"NetrLogonDomainNameDel failed");
torture_assert_werr_equal(tctx, r.out.result, WERR_NOT_SUPPORTED,
"NetrLogonDomainNameDel failed");
return true;
}
static bool test_NetrEnumerateComputerNames_level(struct torture_context *tctx,
struct dcerpc_pipe *p,
uint16_t level,
const char ***names,
int *num_names)
{
NTSTATUS status;
struct wkssvc_NetrEnumerateComputerNames r;
struct wkssvc_ComputerNamesCtr *ctr;
int i;
ctr = talloc_zero(tctx, struct wkssvc_ComputerNamesCtr);
r.in.server_name = dcerpc_server_name(p);
r.in.name_type = level;
r.in.Reserved = 0;
r.out.ctr = &ctr;
torture_comment(tctx, "testing NetrEnumerateComputerNames level %u\n",
r.in.name_type);
status = dcerpc_wkssvc_NetrEnumerateComputerNames(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status,
"NetrEnumerateComputerNames failed");
torture_assert_werr_ok(tctx, r.out.result,
"NetrEnumerateComputerNames failed");
if ((level == NetPrimaryComputerName) && ctr->count != 1) {
torture_comment(tctx,
"NetrEnumerateComputerNames did not return one "
"name but %u\n", ctr->count);
return false;
}
if (names && num_names) {
*num_names = 0;
*names = NULL;
for (i=0; icount; i++) {
if (!add_string_to_array(tctx,
ctr->computer_name[i].string,
names,
num_names))
{
return false;
}
}
}
return true;
}
static bool test_NetrEnumerateComputerNames(struct torture_context *tctx,
struct dcerpc_pipe *p)
{
uint16_t levels[] = {0,1,2};
int i;
for (i=0; ilp_ctx);
r.in.Account = NULL;
r.in.Password = NULL;
r.in.name_type = levels[i];
torture_comment(tctx, "testing NetrValidateName level %u\n",
r.in.name_type);
status = dcerpc_wkssvc_NetrValidateName(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status,
"NetrValidateName failed");
torture_assert_werr_equal(tctx, r.out.result,
WERR_NOT_SUPPORTED,
"NetrValidateName failed");
}
return true;
}
static bool test_NetrValidateName2(struct torture_context *tctx,
struct dcerpc_pipe *p)
{
NTSTATUS status;
struct wkssvc_NetrValidateName2 r;
uint16_t levels[] = {0,1,2,3,4,5};
int i;
for (i=0; ilp_ctx);
r.in.Account = NULL;
r.in.EncryptedPassword = NULL;
r.in.name_type = levels[i];
torture_comment(tctx, "testing NetrValidateName2 level %u\n",
r.in.name_type);
status = dcerpc_wkssvc_NetrValidateName2(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status,
"NetrValidateName2 failed");
torture_assert_werr_equal(tctx, r.out.result,
WERR_RPC_E_REMOTE_DISABLED,
"NetrValidateName2 failed");
}
return true;
}
static bool test_NetrAddAlternateComputerName(struct torture_context *tctx,
struct dcerpc_pipe *p)
{
NTSTATUS status;
struct wkssvc_NetrAddAlternateComputerName r;
const char **names = NULL;
int num_names = 0;
int i;
r.in.server_name = dcerpc_server_name(p);
r.in.NewAlternateMachineName = SMBTORTURE_ALTERNATE_NAME;
r.in.Account = NULL;
r.in.EncryptedPassword = NULL;
r.in.Reserved = 0;
torture_comment(tctx, "testing NetrAddAlternateComputerName\n");
status = dcerpc_wkssvc_NetrAddAlternateComputerName(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status,
"NetrAddAlternateComputerName failed");
torture_assert_werr_ok(tctx, r.out.result,
"NetrAddAlternateComputerName failed");
if (!test_NetrEnumerateComputerNames_level(tctx, p,
NetAlternateComputerNames,
&names, &num_names))
{
return false;
}
for (i=0; ilp_ctx);
r.in.Account = NULL;
r.in.unknown = NULL;
r.in.num_ous = r.out.num_ous = &num_ous;
r.out.ous = &ous;
torture_comment(tctx, "testing NetrGetJoinableOus\n");
status = dcerpc_wkssvc_NetrGetJoinableOus(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "NetrGetJoinableOus failed");
torture_assert_werr_equal(tctx, r.out.result,
WERR_NOT_SUPPORTED,
"NetrGetJoinableOus failed");
return true;
}
static bool test_NetrGetJoinableOus2(struct torture_context *tctx,
struct dcerpc_pipe *p)
{
NTSTATUS status;
struct wkssvc_NetrGetJoinableOus2 r;
uint32_t num_ous = 0;
const char **ous = NULL;
r.in.server_name = dcerpc_server_name(p);
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;
r.out.ous = &ous;
torture_comment(tctx, "testing NetrGetJoinableOus2\n");
status = dcerpc_wkssvc_NetrGetJoinableOus2(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "NetrGetJoinableOus2 failed");
torture_assert_werr_equal(tctx, r.out.result,
WERR_RPC_E_REMOTE_DISABLED,
"NetrGetJoinableOus2 failed");
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_dnsdomain(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;
struct torture_rpc_tcase *tcase;
struct torture_test *test;
suite = torture_suite_create(mem_ctx, "WKSSVC");
tcase = torture_suite_add_rpc_iface_tcase(suite, "wkssvc",
&ndr_table_wkssvc);
torture_rpc_tcase_add_test(tcase, "NetWkstaGetInfo",
test_NetWkstaGetInfo);
torture_rpc_tcase_add_test(tcase, "NetWkstaTransportEnum",
test_NetWkstaTransportEnum);
torture_rpc_tcase_add_test(tcase, "NetrWkstaTransportDel",
test_NetrWkstaTransportDel);
torture_rpc_tcase_add_test(tcase, "NetrWkstaTransportAdd",
test_NetrWkstaTransportAdd);
torture_rpc_tcase_add_test(tcase, "NetWkstaEnumUsers",
test_NetWkstaEnumUsers);
torture_rpc_tcase_add_test(tcase, "NetrWkstaUserGetInfo",
test_NetrWkstaUserGetInfo);
torture_rpc_tcase_add_test(tcase, "NetrUseDel",
test_NetrUseDel);
torture_rpc_tcase_add_test(tcase, "NetrUseGetInfo",
test_NetrUseGetInfo);
torture_rpc_tcase_add_test(tcase, "NetrUseEnum",
test_NetrUseEnum);
torture_rpc_tcase_add_test(tcase, "NetrUseAdd",
test_NetrUseAdd);
torture_rpc_tcase_add_test(tcase, "NetrValidateName",
test_NetrValidateName);
torture_rpc_tcase_add_test(tcase, "NetrValidateName2",
test_NetrValidateName2);
torture_rpc_tcase_add_test(tcase, "NetrLogonDomainNameDel",
test_NetrLogonDomainNameDel);
torture_rpc_tcase_add_test(tcase, "NetrLogonDomainNameAdd",
test_NetrLogonDomainNameAdd);
torture_rpc_tcase_add_test(tcase, "NetrRemoveAlternateComputerName",
test_NetrRemoveAlternateComputerName);
torture_rpc_tcase_add_test(tcase, "NetrAddAlternateComputerName",
test_NetrAddAlternateComputerName);
test = torture_rpc_tcase_add_test(tcase, "NetrSetPrimaryComputername",
test_NetrSetPrimaryComputername);
test->dangerous = true;
test = torture_rpc_tcase_add_test(tcase, "NetrRenameMachineInDomain",
test_NetrRenameMachineInDomain);
test->dangerous = true;
test = torture_rpc_tcase_add_test(tcase, "NetrRenameMachineInDomain2",
test_NetrRenameMachineInDomain2);
test->dangerous = true;
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",
test_NetrGetJoinableOus);
torture_rpc_tcase_add_test(tcase, "NetrGetJoinableOus2",
test_NetrGetJoinableOus2);
torture_rpc_tcase_add_test(tcase, "NetrWorkstationStatisticsGet",
test_NetrWorkstationStatisticsGet);
torture_rpc_tcase_add_test(tcase, "NetrMessageBufferSend",
test_NetrMessageBufferSend);
return suite;
}