wmi-1.3.16 from opsview.com
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Test suite for libnet calls.
|
||||
|
||||
Copyright (C) Rafal Szczesniak 2005
|
||||
|
||||
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
|
||||
(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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "torture/rpc/rpc.h"
|
||||
#include "lib/events/events.h"
|
||||
#include "libnet/libnet.h"
|
||||
#include "librpc/gen_ndr/ndr_samr_c.h"
|
||||
|
||||
static BOOL test_domainopen(struct libnet_context *net_ctx, TALLOC_CTX *mem_ctx,
|
||||
struct lsa_String *domname,
|
||||
struct policy_handle *domain_handle)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct libnet_DomainOpen io;
|
||||
|
||||
printf("opening domain\n");
|
||||
|
||||
io.in.domain_name = talloc_strdup(mem_ctx, domname->string);
|
||||
io.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
|
||||
status = libnet_DomainOpen(net_ctx, mem_ctx, &io);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Composite domain open failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
*domain_handle = io.out.domain_handle;
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *domain_handle)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct samr_Close r;
|
||||
struct policy_handle handle;
|
||||
|
||||
r.in.handle = domain_handle;
|
||||
r.out.handle = &handle;
|
||||
|
||||
printf("closing domain handle\n");
|
||||
|
||||
status = dcerpc_samr_Close(p, mem_ctx, &r);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Close failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_domainopen(struct torture_context *torture)
|
||||
{
|
||||
NTSTATUS status;
|
||||
const char *binding;
|
||||
struct libnet_context *net_ctx;
|
||||
struct event_context *evt_ctx;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
BOOL ret = True;
|
||||
struct policy_handle h;
|
||||
struct lsa_String name;
|
||||
|
||||
mem_ctx = talloc_init("test_domain_open");
|
||||
binding = torture_setting_string(torture, "binding", NULL);
|
||||
|
||||
evt_ctx = event_context_find(torture);
|
||||
net_ctx = libnet_context_init(evt_ctx);
|
||||
|
||||
status = torture_rpc_connection(mem_ctx,
|
||||
&net_ctx->samr.pipe,
|
||||
&dcerpc_table_samr);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
name.string = lp_workgroup();
|
||||
|
||||
/*
|
||||
* Testing synchronous version
|
||||
*/
|
||||
if (!test_domainopen(net_ctx, mem_ctx, &name, &h)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_cleanup(net_ctx->samr.pipe, mem_ctx, &h)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
talloc_free(mem_ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
SMB torture tester
|
||||
Copyright (C) Jelmer Vernooij 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
|
||||
(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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "torture/torture.h"
|
||||
#include "torture/libnet/proto.h"
|
||||
|
||||
NTSTATUS torture_net_init(void)
|
||||
{
|
||||
struct torture_suite *suite = torture_suite_create(
|
||||
talloc_autofree_context(),
|
||||
"NET");
|
||||
|
||||
torture_suite_add_simple_test(suite, "USERINFO", torture_userinfo);
|
||||
torture_suite_add_simple_test(suite, "USERADD", torture_useradd);
|
||||
torture_suite_add_simple_test(suite, "USERDEL", torture_userdel);
|
||||
torture_suite_add_simple_test(suite, "USERMOD", torture_usermod);
|
||||
torture_suite_add_simple_test(suite, "DOMOPEN", torture_domainopen);
|
||||
torture_suite_add_simple_test(suite, "API-LOOKUP", torture_lookup);
|
||||
torture_suite_add_simple_test(suite, "API-LOOKUPHOST", torture_lookup_host);
|
||||
torture_suite_add_simple_test(suite, "API-LOOKUPPDC", torture_lookup_pdc);
|
||||
torture_suite_add_simple_test(suite, "API-LOOKUPNAME", torture_lookup_sam_name);
|
||||
torture_suite_add_simple_test(suite, "API-CREATEUSER", torture_createuser);
|
||||
torture_suite_add_simple_test(suite, "API-DELETEUSER", torture_deleteuser);
|
||||
torture_suite_add_simple_test(suite, "API-MODIFYUSER", torture_modifyuser);
|
||||
torture_suite_add_simple_test(suite, "API-USERINFO", torture_userinfo_api);
|
||||
torture_suite_add_simple_test(suite, "API-USERLIST", torture_userlist);
|
||||
torture_suite_add_simple_test(suite, "API-RPCCONN-BIND", torture_rpc_connect_binding);
|
||||
torture_suite_add_simple_test(suite, "API-RPCCONN-SRV", torture_rpc_connect_srv);
|
||||
torture_suite_add_simple_test(suite, "API-RPCCONN-PDC", torture_rpc_connect_pdc);
|
||||
torture_suite_add_simple_test(suite, "API-RPCCONN-DC", torture_rpc_connect_dc);
|
||||
torture_suite_add_simple_test(suite, "API-RPCCONN-DCINFO", torture_rpc_connect_dc_info);
|
||||
torture_suite_add_simple_test(suite, "API-LISTSHARES", torture_listshares);
|
||||
torture_suite_add_simple_test(suite, "API-DELSHARE", torture_delshare);
|
||||
torture_suite_add_simple_test(suite, "API-DOMOPENLSA", torture_domain_open_lsa);
|
||||
torture_suite_add_simple_test(suite, "API-DOMCLOSELSA", torture_domain_close_lsa);
|
||||
torture_suite_add_simple_test(suite, "API-DOMOPENSAMR", torture_domain_open_samr);
|
||||
torture_suite_add_simple_test(suite, "API-DOMCLOSESAMR", torture_domain_close_samr);
|
||||
|
||||
suite->description = talloc_strdup(suite,
|
||||
"libnet convenience interface tests");
|
||||
|
||||
torture_register_suite(suite);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Test suite for libnet calls.
|
||||
|
||||
Copyright (C) Rafal Szczesniak 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
|
||||
(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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "includes.h"
|
||||
#include "lib/cmdline/popt_common.h"
|
||||
#include "lib/events/events.h"
|
||||
#include "auth/credentials/credentials.h"
|
||||
#include "libnet/libnet.h"
|
||||
#include "librpc/gen_ndr/ndr_samr_c.h"
|
||||
#include "librpc/gen_ndr/ndr_lsa_c.h"
|
||||
#include "libcli/security/security.h"
|
||||
#include "librpc/rpc/dcerpc.h"
|
||||
#include "torture/torture.h"
|
||||
#include "torture/rpc/rpc.h"
|
||||
|
||||
|
||||
static BOOL test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *handle, struct lsa_String *domname,
|
||||
uint32_t *access_mask)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct policy_handle h, domain_handle;
|
||||
struct samr_Connect r1;
|
||||
struct samr_LookupDomain r2;
|
||||
struct samr_OpenDomain r3;
|
||||
|
||||
printf("connecting\n");
|
||||
|
||||
*access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
|
||||
r1.in.system_name = 0;
|
||||
r1.in.access_mask = *access_mask;
|
||||
r1.out.connect_handle = &h;
|
||||
|
||||
status = dcerpc_samr_Connect(p, mem_ctx, &r1);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Connect failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
r2.in.connect_handle = &h;
|
||||
r2.in.domain_name = domname;
|
||||
|
||||
printf("domain lookup on %s\n", domname->string);
|
||||
|
||||
status = dcerpc_samr_LookupDomain(p, mem_ctx, &r2);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("LookupDomain failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
r3.in.connect_handle = &h;
|
||||
r3.in.access_mask = *access_mask;
|
||||
r3.in.sid = r2.out.sid;
|
||||
r3.out.domain_handle = &domain_handle;
|
||||
|
||||
printf("opening domain\n");
|
||||
|
||||
status = dcerpc_samr_OpenDomain(p, mem_ctx, &r3);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("OpenDomain failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
} else {
|
||||
*handle = domain_handle;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_opendomain_lsa(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *handle, struct lsa_String *domname,
|
||||
uint32_t *access_mask)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct lsa_OpenPolicy2 open;
|
||||
struct lsa_ObjectAttribute attr;
|
||||
struct lsa_QosInfo qos;
|
||||
|
||||
*access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
|
||||
ZERO_STRUCT(attr);
|
||||
ZERO_STRUCT(qos);
|
||||
|
||||
qos.len = 0;
|
||||
qos.impersonation_level = 2;
|
||||
qos.context_mode = 1;
|
||||
qos.effective_only = 0;
|
||||
|
||||
attr.sec_qos = &qos;
|
||||
|
||||
open.in.system_name = domname->string;
|
||||
open.in.attr = &attr;
|
||||
open.in.access_mask = *access_mask;
|
||||
open.out.handle = handle;
|
||||
|
||||
status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &open);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_domain_open_lsa(struct torture_context *torture)
|
||||
{
|
||||
NTSTATUS status;
|
||||
BOOL ret = True;
|
||||
struct libnet_context *ctx;
|
||||
struct libnet_DomainOpen r;
|
||||
struct lsa_Close close;
|
||||
struct dcerpc_binding *binding;
|
||||
struct policy_handle h;
|
||||
const char *bindstr;
|
||||
|
||||
bindstr = torture_setting_string(torture, "binding", NULL);
|
||||
status = dcerpc_parse_binding(torture, bindstr, &binding);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
d_printf("failed to parse binding string\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
ctx = libnet_context_init(NULL);
|
||||
if (ctx == NULL) {
|
||||
d_printf("failed to create libnet context\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
ctx->cred = cmdline_credentials;
|
||||
|
||||
ZERO_STRUCT(r);
|
||||
r.in.type = DOMAIN_LSA;
|
||||
r.in.domain_name = binding->host;
|
||||
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
|
||||
status = libnet_DomainOpen(ctx, torture, &r);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
d_printf("failed to open domain on lsa service: %s\n", nt_errstr(status));
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(close);
|
||||
close.in.handle = &ctx->lsa.handle;
|
||||
close.out.handle = &h;
|
||||
|
||||
status = dcerpc_lsa_Close(ctx->lsa.pipe, ctx, &close);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
d_printf("failed to close domain on lsa service: %s\n", nt_errstr(status));
|
||||
ret = False;
|
||||
}
|
||||
|
||||
done:
|
||||
talloc_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_domain_close_lsa(struct torture_context *torture)
|
||||
{
|
||||
BOOL ret = True;
|
||||
NTSTATUS status;
|
||||
TALLOC_CTX *mem_ctx=NULL;
|
||||
struct libnet_context *ctx;
|
||||
struct lsa_String domain_name;
|
||||
struct dcerpc_binding *binding;
|
||||
const char *bindstr;
|
||||
uint32_t access_mask;
|
||||
struct policy_handle h;
|
||||
struct dcerpc_pipe *p;
|
||||
struct libnet_DomainClose r;
|
||||
|
||||
bindstr = torture_setting_string(torture, "binding", NULL);
|
||||
status = dcerpc_parse_binding(torture, bindstr, &binding);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
d_printf("failed to parse binding string\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
ctx = libnet_context_init(NULL);
|
||||
if (ctx == NULL) {
|
||||
d_printf("failed to create libnet context\n");
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ctx->cred = cmdline_credentials;
|
||||
|
||||
mem_ctx = talloc_init("torture_domain_close_lsa");
|
||||
status = dcerpc_pipe_connect(mem_ctx, &p, bindstr, &dcerpc_table_lsarpc,
|
||||
cmdline_credentials, NULL);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
d_printf("failed to connect to server %s: %s\n", bindstr,
|
||||
nt_errstr(status));
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
domain_name.string = lp_workgroup();
|
||||
|
||||
if (!test_opendomain_lsa(p, torture, &h, &domain_name, &access_mask)) {
|
||||
d_printf("failed to open domain on lsa service\n");
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ctx->lsa.pipe = p;
|
||||
ctx->lsa.name = domain_name.string;
|
||||
ctx->lsa.access_mask = access_mask;
|
||||
ctx->lsa.handle = h;
|
||||
/* we have to use pipe's event context, otherwise the call will
|
||||
hang indefinately */
|
||||
ctx->event_ctx = p->conn->event_ctx;
|
||||
|
||||
ZERO_STRUCT(r);
|
||||
r.in.type = DOMAIN_LSA;
|
||||
r.in.domain_name = domain_name.string;
|
||||
|
||||
status = libnet_DomainClose(ctx, mem_ctx, &r);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
talloc_free(mem_ctx);
|
||||
talloc_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_domain_open_samr(struct torture_context *torture)
|
||||
{
|
||||
NTSTATUS status;
|
||||
const char *binding;
|
||||
struct libnet_context *ctx;
|
||||
struct event_context *evt_ctx=NULL;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
struct policy_handle domain_handle, handle;
|
||||
struct lsa_String name;
|
||||
struct libnet_DomainOpen io;
|
||||
struct samr_Close r;
|
||||
BOOL ret = True;
|
||||
|
||||
mem_ctx = talloc_init("test_domainopen_lsa");
|
||||
binding = torture_setting_string(torture, "binding", NULL);
|
||||
|
||||
ctx = libnet_context_init(evt_ctx);
|
||||
ctx->cred = cmdline_credentials;
|
||||
|
||||
name.string = lp_workgroup();
|
||||
|
||||
/*
|
||||
* Testing synchronous version
|
||||
*/
|
||||
printf("opening domain\n");
|
||||
|
||||
io.in.type = DOMAIN_SAMR;
|
||||
io.in.domain_name = name.string;
|
||||
io.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
|
||||
status = libnet_DomainOpen(ctx, mem_ctx, &io);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Composite domain open failed - %s\n", nt_errstr(status));
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
domain_handle = ctx->samr.handle;
|
||||
|
||||
r.in.handle = &domain_handle;
|
||||
r.out.handle = &handle;
|
||||
|
||||
printf("closing domain handle\n");
|
||||
|
||||
status = dcerpc_samr_Close(ctx->samr.pipe, mem_ctx, &r);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Close failed - %s\n", nt_errstr(status));
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
talloc_free(mem_ctx);
|
||||
talloc_free(ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_domain_close_samr(struct torture_context *torture)
|
||||
{
|
||||
BOOL ret = True;
|
||||
NTSTATUS status;
|
||||
TALLOC_CTX *mem_ctx=NULL;
|
||||
struct libnet_context *ctx;
|
||||
struct lsa_String domain_name;
|
||||
struct dcerpc_binding *binding;
|
||||
const char *bindstr;
|
||||
uint32_t access_mask;
|
||||
struct policy_handle h;
|
||||
struct dcerpc_pipe *p;
|
||||
struct libnet_DomainClose r;
|
||||
|
||||
bindstr = torture_setting_string(torture, "binding", NULL);
|
||||
status = dcerpc_parse_binding(torture, bindstr, &binding);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
d_printf("failed to parse binding string\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
ctx = libnet_context_init(NULL);
|
||||
if (ctx == NULL) {
|
||||
d_printf("failed to create libnet context\n");
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ctx->cred = cmdline_credentials;
|
||||
|
||||
mem_ctx = talloc_init("torture_domain_close_samr");
|
||||
status = dcerpc_pipe_connect(mem_ctx, &p, bindstr, &dcerpc_table_samr,
|
||||
cmdline_credentials, NULL);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
d_printf("failed to connect to server %s: %s\n", bindstr,
|
||||
nt_errstr(status));
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
domain_name.string = lp_workgroup();
|
||||
|
||||
if (!test_opendomain_samr(p, torture, &h, &domain_name, &access_mask)) {
|
||||
d_printf("failed to open domain on samr service\n");
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ctx->samr.pipe = p;
|
||||
ctx->samr.name = domain_name.string;
|
||||
ctx->samr.access_mask = access_mask;
|
||||
ctx->samr.handle = h;
|
||||
/* we have to use pipe's event context, otherwise the call will
|
||||
hang indefinately */
|
||||
ctx->event_ctx = p->conn->event_ctx;
|
||||
|
||||
ZERO_STRUCT(r);
|
||||
r.in.type = DOMAIN_SAMR;
|
||||
r.in.domain_name = domain_name.string;
|
||||
|
||||
status = libnet_DomainClose(ctx, mem_ctx, &r);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
talloc_free(mem_ctx);
|
||||
talloc_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Test suite for libnet calls.
|
||||
|
||||
Copyright (C) Rafal Szczesniak 2005
|
||||
|
||||
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
|
||||
(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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "lib/cmdline/popt_common.h"
|
||||
#include "libnet/libnet.h"
|
||||
#include "librpc/gen_ndr/nbt.h"
|
||||
#include "librpc/rpc/dcerpc.h"
|
||||
#include "libcli/libcli.h"
|
||||
#include "torture/torture.h"
|
||||
|
||||
|
||||
BOOL torture_lookup(struct torture_context *torture)
|
||||
{
|
||||
BOOL ret;
|
||||
NTSTATUS status;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
struct libnet_context *ctx;
|
||||
struct libnet_Lookup lookup;
|
||||
struct dcerpc_binding *bind;
|
||||
const char *bindstr;
|
||||
|
||||
mem_ctx = talloc_init("test_lookup");
|
||||
|
||||
ctx = libnet_context_init(NULL);
|
||||
ctx->cred = cmdline_credentials;
|
||||
|
||||
lookup.in.hostname = torture_setting_string(torture, "host", NULL);
|
||||
if (lookup.in.hostname == NULL) {
|
||||
bindstr = torture_setting_string(torture, "binding", NULL);
|
||||
status = dcerpc_parse_binding(mem_ctx, bindstr, &bind);
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
lookup.in.hostname = bind->host;
|
||||
}
|
||||
}
|
||||
|
||||
lookup.in.type = NBT_NAME_CLIENT;
|
||||
lookup.in.methods = NULL;
|
||||
lookup.out.address = NULL;
|
||||
|
||||
status = libnet_Lookup(ctx, mem_ctx, &lookup);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Couldn't lookup name %s: %s\n", lookup.in.hostname, nt_errstr(status));
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = True;
|
||||
|
||||
printf("Name [%s] found at adrress: %s.\n", lookup.in.hostname, *lookup.out.address);
|
||||
|
||||
done:
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_lookup_host(struct torture_context *torture)
|
||||
{
|
||||
BOOL ret;
|
||||
NTSTATUS status;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
struct libnet_context *ctx;
|
||||
struct libnet_Lookup lookup;
|
||||
struct dcerpc_binding *bind;
|
||||
const char *bindstr;
|
||||
|
||||
mem_ctx = talloc_init("test_lookup_host");
|
||||
|
||||
ctx = libnet_context_init(NULL);
|
||||
ctx->cred = cmdline_credentials;
|
||||
|
||||
lookup.in.hostname = torture_setting_string(torture, "host", NULL);
|
||||
if (lookup.in.hostname == NULL) {
|
||||
bindstr = torture_setting_string(torture, "binding", NULL);
|
||||
status = dcerpc_parse_binding(mem_ctx, bindstr, &bind);
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
lookup.in.hostname = bind->host;
|
||||
}
|
||||
}
|
||||
|
||||
lookup.in.methods = NULL;
|
||||
lookup.out.address = NULL;
|
||||
|
||||
status = libnet_LookupHost(ctx, mem_ctx, &lookup);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Couldn't lookup host %s: %s\n", lookup.in.hostname, nt_errstr(status));
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = True;
|
||||
|
||||
printf("Host [%s] found at adrress: %s.\n", lookup.in.hostname, *lookup.out.address);
|
||||
|
||||
done:
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_lookup_pdc(struct torture_context *torture)
|
||||
{
|
||||
BOOL ret;
|
||||
NTSTATUS status;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
struct libnet_context *ctx;
|
||||
struct libnet_LookupDCs *lookup;
|
||||
int i;
|
||||
|
||||
mem_ctx = talloc_init("test_lookup_pdc");
|
||||
|
||||
ctx = libnet_context_init(NULL);
|
||||
ctx->cred = cmdline_credentials;
|
||||
|
||||
talloc_steal(ctx, mem_ctx);
|
||||
|
||||
lookup = talloc(mem_ctx, struct libnet_LookupDCs);
|
||||
if (!lookup) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
lookup->in.domain_name = lp_workgroup();
|
||||
lookup->in.name_type = NBT_NAME_PDC;
|
||||
|
||||
status = libnet_LookupDCs(ctx, mem_ctx, lookup);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Couldn't lookup pdc %s: %s\n", lookup->in.domain_name,
|
||||
nt_errstr(status));
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = True;
|
||||
|
||||
printf("DCs of domain [%s] found.\n", lookup->in.domain_name);
|
||||
for (i = 0; i < lookup->out.num_dcs; i++) {
|
||||
printf("\tDC[%d]: name=%s, address=%s\n", i, lookup->out.dcs[i].name,
|
||||
lookup->out.dcs[i].address);
|
||||
}
|
||||
|
||||
done:
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_lookup_sam_name(struct torture_context *torture)
|
||||
{
|
||||
NTSTATUS status;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
struct libnet_context *ctx;
|
||||
struct libnet_LookupName r;
|
||||
|
||||
ctx = libnet_context_init(NULL);
|
||||
ctx->cred = cmdline_credentials;
|
||||
|
||||
mem_ctx = talloc_init("torture lookup sam name");
|
||||
if (mem_ctx == NULL) return False;
|
||||
|
||||
r.in.name = "Administrator";
|
||||
r.in.domain_name = lp_workgroup();
|
||||
|
||||
status = libnet_LookupName(ctx, mem_ctx, &r);
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
talloc_free(ctx);
|
||||
|
||||
return True;
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Test suite for libnet calls.
|
||||
|
||||
Copyright (C) Rafal Szczesniak 2005
|
||||
|
||||
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
|
||||
(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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "lib/cmdline/popt_common.h"
|
||||
#include "auth/credentials/credentials.h"
|
||||
#include "libnet/libnet.h"
|
||||
#include "libcli/security/security.h"
|
||||
#include "librpc/ndr/libndr.h"
|
||||
#include "librpc/gen_ndr/ndr_lsa.h"
|
||||
#include "librpc/gen_ndr/ndr_samr.h"
|
||||
#include "librpc/gen_ndr/ndr_srvsvc.h"
|
||||
#include "librpc/rpc/dcerpc.h"
|
||||
#include "torture/torture.h"
|
||||
|
||||
|
||||
static BOOL test_connect_service(struct libnet_context *ctx,
|
||||
const struct dcerpc_interface_table *iface,
|
||||
const char *binding_string,
|
||||
const char *hostname,
|
||||
const enum libnet_RpcConnect_level level,
|
||||
BOOL badcreds, NTSTATUS expected_status)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct libnet_RpcConnect connect;
|
||||
connect.level = level;
|
||||
connect.in.binding = binding_string;
|
||||
connect.in.name = hostname;
|
||||
connect.in.dcerpc_iface = iface;
|
||||
|
||||
/* if bad credentials are needed, set baduser%badpassword instead
|
||||
of default commandline-passed credentials */
|
||||
if (badcreds) {
|
||||
cli_credentials_set_username(ctx->cred, "baduser", CRED_SPECIFIED);
|
||||
cli_credentials_set_password(ctx->cred, "badpassword", CRED_SPECIFIED);
|
||||
}
|
||||
|
||||
status = libnet_RpcConnect(ctx, ctx, &connect);
|
||||
|
||||
if (!NT_STATUS_EQUAL(status, expected_status)) {
|
||||
d_printf("Connecting to rpc service %s on %s.\n\tFAILED. Expected: %s."
|
||||
"Received: %s\n",
|
||||
connect.in.dcerpc_iface->name, connect.in.binding, nt_errstr(expected_status),
|
||||
nt_errstr(status));
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
d_printf("PASSED. Expected: %s, received: %s\n", nt_errstr(expected_status),
|
||||
nt_errstr(status));
|
||||
|
||||
if (connect.level == LIBNET_RPC_CONNECT_DC_INFO && NT_STATUS_IS_OK(status)) {
|
||||
d_printf("Domain Controller Info:\n");
|
||||
d_printf("\tDomain Name:\t %s\n", connect.out.domain_name);
|
||||
d_printf("\tDomain SID:\t %s\n", dom_sid_string(ctx, connect.out.domain_sid));
|
||||
d_printf("\tRealm:\t\t %s\n", connect.out.realm);
|
||||
d_printf("\tGUID:\t\t %s\n", GUID_string(ctx, connect.out.guid));
|
||||
|
||||
} else if (!NT_STATUS_IS_OK(status)) {
|
||||
d_printf("Error string: %s\n", connect.out.error_string);
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static BOOL torture_rpc_connect(struct torture_context *torture,
|
||||
const enum libnet_RpcConnect_level level,
|
||||
const char *bindstr, const char *hostname)
|
||||
{
|
||||
struct libnet_context *ctx;
|
||||
|
||||
ctx = libnet_context_init(NULL);
|
||||
ctx->cred = cmdline_credentials;
|
||||
|
||||
d_printf("Testing connection to LSA interface\n");
|
||||
if (!test_connect_service(ctx, &dcerpc_table_lsarpc, bindstr,
|
||||
hostname, level, False, NT_STATUS_OK)) {
|
||||
d_printf("failed to connect LSA interface\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
d_printf("Testing connection to SAMR interface\n");
|
||||
if (!test_connect_service(ctx, &dcerpc_table_samr, bindstr,
|
||||
hostname, level, False, NT_STATUS_OK)) {
|
||||
d_printf("failed to connect SAMR interface\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
d_printf("Testing connection to SRVSVC interface\n");
|
||||
if (!test_connect_service(ctx, &dcerpc_table_srvsvc, bindstr,
|
||||
hostname, level, False, NT_STATUS_OK)) {
|
||||
d_printf("failed to connect SRVSVC interface\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
d_printf("Testing connection to LSA interface with wrong credentials\n");
|
||||
if (!test_connect_service(ctx, &dcerpc_table_lsarpc, bindstr,
|
||||
hostname, level, True, NT_STATUS_LOGON_FAILURE)) {
|
||||
d_printf("failed to test wrong credentials on LSA interface\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
d_printf("Testing connection to SAMR interface with wrong credentials\n");
|
||||
if (!test_connect_service(ctx, &dcerpc_table_samr, bindstr,
|
||||
hostname, level, True, NT_STATUS_LOGON_FAILURE)) {
|
||||
d_printf("failed to test wrong credentials on SAMR interface\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
talloc_free(ctx);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_rpc_connect_srv(struct torture_context *torture)
|
||||
{
|
||||
const enum libnet_RpcConnect_level level = LIBNET_RPC_CONNECT_SERVER;
|
||||
NTSTATUS status;
|
||||
struct dcerpc_binding *binding;
|
||||
const char *bindstr;;
|
||||
|
||||
bindstr = torture_setting_string(torture, "binding", NULL);
|
||||
status = dcerpc_parse_binding(torture, bindstr, &binding);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
d_printf("failed to parse binding string\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
return torture_rpc_connect(torture, level, NULL, binding->host);
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_rpc_connect_pdc(struct torture_context *torture)
|
||||
{
|
||||
const enum libnet_RpcConnect_level level = LIBNET_RPC_CONNECT_PDC;
|
||||
NTSTATUS status;
|
||||
struct dcerpc_binding *binding;
|
||||
const char *bindstr;
|
||||
|
||||
bindstr = torture_setting_string(torture, "binding", NULL);
|
||||
status = dcerpc_parse_binding(torture, bindstr, &binding);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
d_printf("failed to parse binding string\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
return torture_rpc_connect(torture, level, NULL, binding->host);
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_rpc_connect_dc(struct torture_context *torture)
|
||||
{
|
||||
const enum libnet_RpcConnect_level level = LIBNET_RPC_CONNECT_DC;
|
||||
NTSTATUS status;
|
||||
struct dcerpc_binding *binding;
|
||||
const char *bindstr;
|
||||
|
||||
bindstr = torture_setting_string(torture, "binding", NULL);
|
||||
status = dcerpc_parse_binding(torture, bindstr, &binding);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
d_printf("failed to parse binding string\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
return torture_rpc_connect(torture, level, NULL, binding->host);
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_rpc_connect_dc_info(struct torture_context *torture)
|
||||
{
|
||||
const enum libnet_RpcConnect_level level = LIBNET_RPC_CONNECT_DC_INFO;
|
||||
NTSTATUS status;
|
||||
struct dcerpc_binding *binding;
|
||||
const char *bindstr;
|
||||
|
||||
bindstr = torture_setting_string(torture, "binding", NULL);
|
||||
status = dcerpc_parse_binding(torture, bindstr, &binding);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
d_printf("failed to parse binding string\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
return torture_rpc_connect(torture, level, NULL, binding->host);
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_rpc_connect_binding(struct torture_context *torture)
|
||||
{
|
||||
const enum libnet_RpcConnect_level level = LIBNET_RPC_CONNECT_BINDING;
|
||||
NTSTATUS status;
|
||||
struct dcerpc_binding *binding;
|
||||
const char *bindstr;
|
||||
|
||||
bindstr = torture_setting_string(torture, "binding", NULL);
|
||||
status = dcerpc_parse_binding(torture, bindstr, &binding);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
d_printf("failed to parse binding string\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
return torture_rpc_connect(torture, level, bindstr, NULL);
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Test suite for libnet calls.
|
||||
|
||||
Copyright (C) Gregory LEOCADIE <gleocadie@idealx.com> 2005
|
||||
Copyright (C) Rafal Szczesniak 2005
|
||||
|
||||
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
|
||||
(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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "torture/rpc/rpc.h"
|
||||
#include "libnet/libnet.h"
|
||||
#include "lib/cmdline/popt_common.h"
|
||||
#include "librpc/gen_ndr/ndr_srvsvc_c.h"
|
||||
|
||||
|
||||
#define TEST_SHARENAME "libnetsharetest"
|
||||
|
||||
|
||||
static void test_displayshares(struct libnet_ListShares s)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
struct share_type {
|
||||
enum srvsvc_ShareType type;
|
||||
const char *desc;
|
||||
} share_types[] = {
|
||||
{ STYPE_DISKTREE, "STYPE_DISKTREE" },
|
||||
{ STYPE_DISKTREE_TEMPORARY, "STYPE_DISKTREE_TEMPORARY" },
|
||||
{ STYPE_DISKTREE_HIDDEN, "STYPE_DISKTREE_HIDDEN" },
|
||||
{ STYPE_PRINTQ, "STYPE_PRINTQ" },
|
||||
{ STYPE_PRINTQ_TEMPORARY, "STYPE_PRINTQ_TEMPORARY" },
|
||||
{ STYPE_PRINTQ_HIDDEN, "STYPE_PRINTQ_HIDDEN" },
|
||||
{ STYPE_DEVICE, "STYPE_DEVICE" },
|
||||
{ STYPE_DEVICE_TEMPORARY, "STYPE_DEVICE_TEMPORARY" },
|
||||
{ STYPE_DEVICE_HIDDEN, "STYPE_DEVICE_HIDDEN" },
|
||||
{ STYPE_IPC, "STYPE_IPC" },
|
||||
{ STYPE_IPC_TEMPORARY, "STYPE_IPC_TEMPORARY" },
|
||||
{ STYPE_IPC_HIDDEN, "STYPE_IPC_HIDDEN" }
|
||||
};
|
||||
|
||||
switch (s.in.level) {
|
||||
case 0:
|
||||
for (i = 0; i < s.out.ctr.ctr0->count; i++) {
|
||||
struct srvsvc_NetShareInfo0 *info = &s.out.ctr.ctr0->array[i];
|
||||
d_printf("\t[%d] %s\n", i, info->name);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
for (i = 0; i < s.out.ctr.ctr1->count; i++) {
|
||||
struct srvsvc_NetShareInfo1 *info = &s.out.ctr.ctr1->array[i];
|
||||
for (j = 0; j < ARRAY_SIZE(share_types); j++) {
|
||||
if (share_types[j].type == info->type) break;
|
||||
}
|
||||
d_printf("\t[%d] %s (%s)\t%s\n", i, info->name,
|
||||
info->comment, share_types[j].desc);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
for (i = 0; i < s.out.ctr.ctr2->count; i++) {
|
||||
struct srvsvc_NetShareInfo2 *info = &s.out.ctr.ctr2->array[i];
|
||||
for (j = 0; j < ARRAY_SIZE(share_types); j++) {
|
||||
if (share_types[j].type == info->type) break;
|
||||
}
|
||||
d_printf("\t[%d] %s\t%s\n\t %s\n\t [perms=0x%08x, max_usr=%d, cur_usr=%d, path=%s, pass=%s]\n",
|
||||
i, info->name, share_types[j].desc, info->comment,
|
||||
info->permissions, info->max_users,
|
||||
info->current_users, info->path,
|
||||
info->password);
|
||||
}
|
||||
break;
|
||||
|
||||
case 501:
|
||||
for (i = 0; i < s.out.ctr.ctr501->count; i++) {
|
||||
struct srvsvc_NetShareInfo501 *info = &s.out.ctr.ctr501->array[i];
|
||||
for (j = 0; j < ARRAY_SIZE(share_types); j++) {
|
||||
if (share_types[j].type == info->type) break;
|
||||
}
|
||||
d_printf("\t[%d] %s\t%s [csc_policy=0x%08x]\n\t %s\n", i, info->name,
|
||||
share_types[j].desc, info->csc_policy,
|
||||
info->comment);
|
||||
}
|
||||
break;
|
||||
|
||||
case 502:
|
||||
for (i = 0; i < s.out.ctr.ctr502->count; i++) {
|
||||
struct srvsvc_NetShareInfo502 *info = &s.out.ctr.ctr502->array[i];
|
||||
for (j = 0; j < ARRAY_SIZE(share_types); j++) {
|
||||
if (share_types[j].type == info->type) break;
|
||||
}
|
||||
d_printf("\t[%d] %s\t%s\n\t %s\n\t [perms=0x%08x, max_usr=%d, cur_usr=%d, path=%s, pass=%s, unknown=0x%08x]\n",
|
||||
i, info->name, share_types[j].desc, info->comment,
|
||||
info->permissions, info->max_users,
|
||||
info->current_users, info->path,
|
||||
info->password, info->unknown);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_listshares(struct torture_context *torture)
|
||||
{
|
||||
struct libnet_ListShares share;
|
||||
NTSTATUS status;
|
||||
uint32_t levels[] = { 0, 1, 2, 501, 502 };
|
||||
int i;
|
||||
BOOL ret = True;
|
||||
struct libnet_context* libnetctx;
|
||||
const char *binding;
|
||||
struct dcerpc_binding *bind;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
mem_ctx = talloc_init("test_listshares");
|
||||
binding = torture_setting_string(torture, "binding", NULL);
|
||||
status = dcerpc_parse_binding(mem_ctx, binding, &bind);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Error while parsing the binding string\n");
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
libnetctx = libnet_context_init(NULL);
|
||||
if (!libnetctx) {
|
||||
printf("Couldn't allocate libnet context\n");
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
libnetctx->cred = cmdline_credentials;
|
||||
|
||||
printf("Testing libnet_ListShare\n");
|
||||
|
||||
share.in.server_name = talloc_asprintf(mem_ctx, "%s", bind->host);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(levels); i++) {
|
||||
share.in.level = levels[i];
|
||||
printf("testing libnet_ListShare level %u\n", share.in.level);
|
||||
|
||||
status = libnet_ListShares(libnetctx, mem_ctx, &share);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("libnet_ListShare level %u failed - %s\n", share.in.level, share.out.error_string);
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
printf("listing shares:\n");
|
||||
test_displayshares(share);
|
||||
}
|
||||
|
||||
done:
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_addshare(struct dcerpc_pipe *pipe, TALLOC_CTX *mem_ctx, const char *host,
|
||||
const char* share)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct srvsvc_NetShareAdd add;
|
||||
struct srvsvc_NetShareInfo2 i;
|
||||
|
||||
i.name = share;
|
||||
i.type = STYPE_DISKTREE;
|
||||
i.path = "C:\\WINDOWS\\TEMP";
|
||||
i.max_users = 5;
|
||||
i.comment = "Comment to the test share";
|
||||
i.password = NULL;
|
||||
i.permissions = 0x0;
|
||||
|
||||
add.in.server_unc = host;
|
||||
add.in.level = 2;
|
||||
add.in.info.info2 = &i;
|
||||
|
||||
status = dcerpc_srvsvc_NetShareAdd(pipe, mem_ctx, &add);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Failed to add a new share\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
printf("share added\n");
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_delshare(struct torture_context *torture)
|
||||
{
|
||||
struct dcerpc_pipe *p;
|
||||
struct dcerpc_binding *bind;
|
||||
struct libnet_context* libnetctx;
|
||||
const char *host, *binding;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
NTSTATUS status;
|
||||
BOOL ret = True;
|
||||
struct libnet_DelShare share;
|
||||
|
||||
mem_ctx = talloc_init("test_listshares");
|
||||
host = torture_setting_string(torture, "host", NULL);
|
||||
binding = torture_setting_string(torture, "binding", NULL);
|
||||
status = dcerpc_parse_binding(mem_ctx, binding, &bind);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Error while parsing the binding string\n");
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
libnetctx = libnet_context_init(NULL);
|
||||
libnetctx->cred = cmdline_credentials;
|
||||
|
||||
status = torture_rpc_connection(mem_ctx,
|
||||
&p,
|
||||
&dcerpc_table_srvsvc);
|
||||
|
||||
if (!test_addshare(p, mem_ctx, host, TEST_SHARENAME)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
share.in.server_name = bind->host;
|
||||
share.in.share_name = TEST_SHARENAME;
|
||||
|
||||
status = libnet_DelShare(libnetctx, mem_ctx, &share);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
done:
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,740 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Test suite for libnet calls.
|
||||
|
||||
Copyright (C) Rafal Szczesniak 2005
|
||||
|
||||
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
|
||||
(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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "system/time.h"
|
||||
#include "lib/cmdline/popt_common.h"
|
||||
#include "libnet/libnet.h"
|
||||
#include "librpc/gen_ndr/ndr_samr_c.h"
|
||||
#include "librpc/gen_ndr/ndr_lsa_c.h"
|
||||
#include "torture/torture.h"
|
||||
#include "torture/rpc/rpc.h"
|
||||
#include "torture/libnet/usertest.h"
|
||||
|
||||
|
||||
static BOOL test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *domain_handle, const char *username)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct samr_LookupNames r1;
|
||||
struct samr_OpenUser r2;
|
||||
struct samr_DeleteUser r3;
|
||||
struct lsa_String names[2];
|
||||
uint32_t rid;
|
||||
struct policy_handle user_handle;
|
||||
|
||||
names[0].string = username;
|
||||
|
||||
r1.in.domain_handle = domain_handle;
|
||||
r1.in.num_names = 1;
|
||||
r1.in.names = names;
|
||||
|
||||
printf("user account lookup '%s'\n", username);
|
||||
|
||||
status = dcerpc_samr_LookupNames(p, mem_ctx, &r1);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("LookupNames failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
rid = r1.out.rids.ids[0];
|
||||
|
||||
r2.in.domain_handle = domain_handle;
|
||||
r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
r2.in.rid = rid;
|
||||
r2.out.user_handle = &user_handle;
|
||||
|
||||
printf("opening user account\n");
|
||||
|
||||
status = dcerpc_samr_OpenUser(p, mem_ctx, &r2);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("OpenUser failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
r3.in.user_handle = &user_handle;
|
||||
r3.out.user_handle = &user_handle;
|
||||
|
||||
printf("deleting user account\n");
|
||||
|
||||
status = dcerpc_samr_DeleteUser(p, mem_ctx, &r3);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("DeleteUser failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *handle, struct lsa_String *domname)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct policy_handle h, domain_handle;
|
||||
struct samr_Connect r1;
|
||||
struct samr_LookupDomain r2;
|
||||
struct samr_OpenDomain r3;
|
||||
|
||||
printf("connecting\n");
|
||||
|
||||
r1.in.system_name = 0;
|
||||
r1.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
r1.out.connect_handle = &h;
|
||||
|
||||
status = dcerpc_samr_Connect(p, mem_ctx, &r1);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Connect failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
r2.in.connect_handle = &h;
|
||||
r2.in.domain_name = domname;
|
||||
|
||||
printf("domain lookup on %s\n", domname->string);
|
||||
|
||||
status = dcerpc_samr_LookupDomain(p, mem_ctx, &r2);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("LookupDomain failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
r3.in.connect_handle = &h;
|
||||
r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
r3.in.sid = r2.out.sid;
|
||||
r3.out.domain_handle = &domain_handle;
|
||||
|
||||
printf("opening domain\n");
|
||||
|
||||
status = dcerpc_samr_OpenDomain(p, mem_ctx, &r3);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("OpenDomain failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
} else {
|
||||
*handle = domain_handle;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_samr_close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *domain_handle)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct samr_Close r;
|
||||
|
||||
r.in.handle = domain_handle;
|
||||
r.out.handle = domain_handle;
|
||||
|
||||
status = dcerpc_samr_Close(p, mem_ctx, &r);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Close samr domain failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_lsa_close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *domain_handle)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct lsa_Close r;
|
||||
|
||||
r.in.handle = domain_handle;
|
||||
r.out.handle = domain_handle;
|
||||
|
||||
status = dcerpc_lsa_Close(p, mem_ctx, &r);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Close lsa domain failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_createuser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *handle, const char* user)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct policy_handle user_handle;
|
||||
struct lsa_String username;
|
||||
struct samr_CreateUser r1;
|
||||
struct samr_Close r2;
|
||||
uint32_t user_rid;
|
||||
|
||||
username.string = user;
|
||||
|
||||
r1.in.domain_handle = handle;
|
||||
r1.in.account_name = &username;
|
||||
r1.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
r1.out.user_handle = &user_handle;
|
||||
r1.out.rid = &user_rid;
|
||||
|
||||
printf("creating user '%s'\n", username.string);
|
||||
|
||||
status = dcerpc_samr_CreateUser(p, mem_ctx, &r1);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("CreateUser failed - %s\n", nt_errstr(status));
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
|
||||
printf("User (%s) already exists - attempting to delete and recreate account again\n", user);
|
||||
if (!test_cleanup(p, mem_ctx, handle, TEST_USERNAME)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
printf("creating user account\n");
|
||||
|
||||
status = dcerpc_samr_CreateUser(p, mem_ctx, &r1);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("CreateUser failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
r2.in.handle = &user_handle;
|
||||
r2.out.handle = &user_handle;
|
||||
|
||||
printf("closing user '%s'\n", username.string);
|
||||
|
||||
status = dcerpc_samr_Close(p, mem_ctx, &r2);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Close failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_createuser(struct torture_context *torture)
|
||||
{
|
||||
NTSTATUS status;
|
||||
const char *binding;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
struct libnet_context *ctx;
|
||||
struct libnet_CreateUser req;
|
||||
BOOL ret = True;
|
||||
|
||||
mem_ctx = talloc_init("test_createuser");
|
||||
binding = torture_setting_string(torture, "binding", NULL);
|
||||
|
||||
ctx = libnet_context_init(NULL);
|
||||
ctx->cred = cmdline_credentials;
|
||||
|
||||
req.in.user_name = TEST_USERNAME;
|
||||
req.in.domain_name = lp_workgroup();
|
||||
req.out.error_string = NULL;
|
||||
|
||||
status = libnet_CreateUser(ctx, mem_ctx, &req);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("libnet_CreateUser call failed: %s\n", nt_errstr(status));
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_cleanup(ctx->samr.pipe, mem_ctx, &ctx->samr.handle, TEST_USERNAME)) {
|
||||
printf("cleanup failed\n");
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_samr_close(ctx->samr.pipe, mem_ctx, &ctx->samr.handle)) {
|
||||
printf("domain close failed\n");
|
||||
ret = False;
|
||||
}
|
||||
|
||||
done:
|
||||
talloc_free(ctx);
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_deleteuser(struct torture_context *torture)
|
||||
{
|
||||
NTSTATUS status;
|
||||
const char *binding;
|
||||
struct dcerpc_pipe *p;
|
||||
TALLOC_CTX *prep_mem_ctx, *mem_ctx;
|
||||
struct policy_handle h;
|
||||
struct lsa_String domain_name;
|
||||
const char *name = TEST_USERNAME;
|
||||
struct libnet_context *ctx;
|
||||
struct libnet_DeleteUser req;
|
||||
BOOL ret = True;
|
||||
|
||||
prep_mem_ctx = talloc_init("prepare test_deleteuser");
|
||||
binding = torture_setting_string(torture, "binding", NULL);
|
||||
|
||||
ctx = libnet_context_init(NULL);
|
||||
ctx->cred = cmdline_credentials;
|
||||
|
||||
req.in.user_name = TEST_USERNAME;
|
||||
req.in.domain_name = lp_workgroup();
|
||||
|
||||
status = torture_rpc_connection(prep_mem_ctx,
|
||||
&p,
|
||||
&dcerpc_table_samr);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
domain_name.string = lp_workgroup();
|
||||
if (!test_opendomain(p, prep_mem_ctx, &h, &domain_name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_createuser(p, prep_mem_ctx, &h, name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
mem_ctx = talloc_init("test_deleteuser");
|
||||
|
||||
status = libnet_DeleteUser(ctx, mem_ctx, &req);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("libnet_DeleteUser call failed: %s\n", nt_errstr(status));
|
||||
ret = False;
|
||||
}
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
|
||||
done:
|
||||
talloc_free(ctx);
|
||||
talloc_free(prep_mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Generate testing set of random changes
|
||||
*/
|
||||
|
||||
static void set_test_changes(TALLOC_CTX *mem_ctx, struct libnet_ModifyUser *r,
|
||||
int num_changes, char **user_name, enum test_fields req_change)
|
||||
{
|
||||
const char* logon_scripts[] = { "start_login.cmd", "login.bat", "start.cmd" };
|
||||
const char* home_dirs[] = { "\\\\srv\\home", "\\\\homesrv\\home\\user", "\\\\pdcsrv\\domain" };
|
||||
const char* home_drives[] = { "H:", "z:", "I:", "J:", "n:" };
|
||||
const char *homedir, *homedrive, *logonscript;
|
||||
struct timeval now;
|
||||
int i, testfld;
|
||||
|
||||
srandom((unsigned)time(NULL));
|
||||
|
||||
printf("Fields to change: [");
|
||||
|
||||
for (i = 0; i < num_changes && i < FIELDS_NUM; i++) {
|
||||
const char *fldname;
|
||||
|
||||
testfld = (req_change == none) ? (random() % FIELDS_NUM) : req_change;
|
||||
|
||||
/* get one in case we hit time field this time */
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
switch (testfld) {
|
||||
case account_name:
|
||||
continue_if_field_set(r->in.account_name);
|
||||
r->in.account_name = talloc_asprintf(mem_ctx, TEST_CHG_ACCOUNTNAME,
|
||||
(int)(random() % 100));
|
||||
fldname = "account_name";
|
||||
|
||||
/* update the test's user name in case it's about to change */
|
||||
*user_name = talloc_strdup(mem_ctx, r->in.account_name);
|
||||
break;
|
||||
|
||||
case full_name:
|
||||
continue_if_field_set(r->in.full_name);
|
||||
r->in.full_name = talloc_asprintf(mem_ctx, TEST_CHG_FULLNAME,
|
||||
(unsigned int)random(), (unsigned int)random());
|
||||
fldname = "full_name";
|
||||
break;
|
||||
|
||||
case description:
|
||||
continue_if_field_set(r->in.description);
|
||||
r->in.description = talloc_asprintf(mem_ctx, TEST_CHG_DESCRIPTION,
|
||||
(long)random());
|
||||
fldname = "description";
|
||||
break;
|
||||
|
||||
case home_directory:
|
||||
continue_if_field_set(r->in.home_directory);
|
||||
homedir = home_dirs[random() % (sizeof(home_dirs)/sizeof(char*))];
|
||||
r->in.home_directory = talloc_strdup(mem_ctx, homedir);
|
||||
fldname = "home_dir";
|
||||
break;
|
||||
|
||||
case home_drive:
|
||||
continue_if_field_set(r->in.home_drive);
|
||||
homedrive = home_drives[random() % (sizeof(home_drives)/sizeof(char*))];
|
||||
r->in.home_drive = talloc_strdup(mem_ctx, homedrive);
|
||||
fldname = "home_drive";
|
||||
break;
|
||||
|
||||
case comment:
|
||||
continue_if_field_set(r->in.comment);
|
||||
r->in.comment = talloc_asprintf(mem_ctx, TEST_CHG_COMMENT,
|
||||
(unsigned long)random(), (unsigned long)random());
|
||||
fldname = "comment";
|
||||
break;
|
||||
|
||||
case logon_script:
|
||||
continue_if_field_set(r->in.logon_script);
|
||||
logonscript = logon_scripts[random() % (sizeof(logon_scripts)/sizeof(char*))];
|
||||
r->in.logon_script = talloc_strdup(mem_ctx, logonscript);
|
||||
fldname = "logon_script";
|
||||
break;
|
||||
|
||||
case profile_path:
|
||||
continue_if_field_set(r->in.profile_path);
|
||||
r->in.profile_path = talloc_asprintf(mem_ctx, TEST_CHG_PROFILEPATH,
|
||||
(unsigned long)random(), (unsigned int)random());
|
||||
fldname = "profile_path";
|
||||
break;
|
||||
|
||||
case acct_expiry:
|
||||
continue_if_field_set(r->in.acct_expiry);
|
||||
now = timeval_add(&now, (random() % (31*24*60*60)), 0);
|
||||
r->in.acct_expiry = talloc_memdup(mem_ctx, &now, sizeof(now));
|
||||
fldname = "acct_expiry";
|
||||
break;
|
||||
|
||||
default:
|
||||
fldname = "unknown_field";
|
||||
}
|
||||
|
||||
printf(((i < num_changes - 1) ? "%s," : "%s"), fldname);
|
||||
|
||||
/* disable requested field (it's supposed to be the only one used) */
|
||||
if (req_change != none) req_change = none;
|
||||
}
|
||||
|
||||
printf("]\n");
|
||||
}
|
||||
|
||||
|
||||
#define TEST_STR_FLD(fld) \
|
||||
if (!strequal(req.in.fld, user_req.out.fld)) { \
|
||||
printf("failed to change '%s'\n", #fld); \
|
||||
ret = False; \
|
||||
goto cleanup; \
|
||||
}
|
||||
|
||||
#define TEST_TIME_FLD(fld) \
|
||||
if (timeval_compare(req.in.fld, user_req.out.fld)) { \
|
||||
printf("failed to change '%s'\n", #fld); \
|
||||
ret = False; \
|
||||
goto cleanup; \
|
||||
}
|
||||
|
||||
#define TEST_NUM_FLD(fld) \
|
||||
if (req.in.fld != user_req.out.fld) { \
|
||||
printf("failed to change '%s'\n", #fld); \
|
||||
ret = False; \
|
||||
goto cleanup; \
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_modifyuser(struct torture_context *torture)
|
||||
{
|
||||
NTSTATUS status;
|
||||
const char *binding;
|
||||
struct dcerpc_binding *bind;
|
||||
struct dcerpc_pipe *p;
|
||||
TALLOC_CTX *prep_mem_ctx, *mem_ctx;
|
||||
struct policy_handle h;
|
||||
struct lsa_String domain_name;
|
||||
char *name;
|
||||
struct libnet_context *ctx;
|
||||
struct libnet_ModifyUser req;
|
||||
struct libnet_UserInfo user_req;
|
||||
int fld;
|
||||
BOOL ret = True;
|
||||
|
||||
prep_mem_ctx = talloc_init("prepare test_deleteuser");
|
||||
binding = torture_setting_string(torture, "binding", NULL);
|
||||
|
||||
ctx = libnet_context_init(NULL);
|
||||
ctx->cred = cmdline_credentials;
|
||||
|
||||
status = torture_rpc_connection(prep_mem_ctx,
|
||||
&p,
|
||||
&dcerpc_table_samr);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
name = talloc_strdup(prep_mem_ctx, TEST_USERNAME);
|
||||
|
||||
domain_name.string = lp_workgroup();
|
||||
if (!test_opendomain(p, prep_mem_ctx, &h, &domain_name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_createuser(p, prep_mem_ctx, &h, name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
mem_ctx = talloc_init("test_modifyuser");
|
||||
|
||||
status = dcerpc_parse_binding(mem_ctx, binding, &bind);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
printf("Testing change of all fields - each single one in turn\n");
|
||||
|
||||
for (fld = 1; fld < FIELDS_NUM - 1; fld++) {
|
||||
ZERO_STRUCT(req);
|
||||
req.in.domain_name = lp_workgroup();
|
||||
req.in.user_name = name;
|
||||
|
||||
set_test_changes(mem_ctx, &req, 1, &name, fld);
|
||||
|
||||
status = libnet_ModifyUser(ctx, mem_ctx, &req);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("libnet_ModifyUser call failed: %s\n", nt_errstr(status));
|
||||
ret = False;
|
||||
continue;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(user_req);
|
||||
user_req.in.domain_name = lp_workgroup();
|
||||
user_req.in.user_name = name;
|
||||
|
||||
status = libnet_UserInfo(ctx, mem_ctx, &user_req);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("libnet_UserInfo call failed: %s\n", nt_errstr(status));
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (fld) {
|
||||
case account_name: TEST_STR_FLD(account_name);
|
||||
break;
|
||||
case full_name: TEST_STR_FLD(full_name);
|
||||
break;
|
||||
case comment: TEST_STR_FLD(comment);
|
||||
break;
|
||||
case description: TEST_STR_FLD(description);
|
||||
break;
|
||||
case home_directory: TEST_STR_FLD(home_directory);
|
||||
break;
|
||||
case home_drive: TEST_STR_FLD(home_drive);
|
||||
break;
|
||||
case logon_script: TEST_STR_FLD(logon_script);
|
||||
break;
|
||||
case profile_path: TEST_STR_FLD(profile_path);
|
||||
break;
|
||||
case acct_expiry: TEST_TIME_FLD(acct_expiry);
|
||||
break;
|
||||
case acct_flags: TEST_NUM_FLD(acct_flags);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (fld == account_name) {
|
||||
/* restore original testing username - it's useful when test fails
|
||||
because it prevents from problems with recreating account */
|
||||
ZERO_STRUCT(req);
|
||||
req.in.domain_name = lp_workgroup();
|
||||
req.in.user_name = name;
|
||||
req.in.account_name = TEST_USERNAME;
|
||||
|
||||
status = libnet_ModifyUser(ctx, mem_ctx, &req);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("libnet_ModifyUser call failed: %s\n", nt_errstr(status));
|
||||
talloc_free(mem_ctx);
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
name = talloc_strdup(mem_ctx, TEST_USERNAME);
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (!test_cleanup(ctx->samr.pipe, mem_ctx, &ctx->samr.handle, name)) {
|
||||
printf("cleanup failed\n");
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_samr_close(ctx->samr.pipe, mem_ctx, &ctx->samr.handle)) {
|
||||
printf("domain close failed\n");
|
||||
ret = False;
|
||||
}
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
|
||||
done:
|
||||
talloc_free(ctx);
|
||||
talloc_free(prep_mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_userinfo_api(struct torture_context *torture)
|
||||
{
|
||||
const char *name = TEST_USERNAME;
|
||||
const char *binding;
|
||||
BOOL ret = True;
|
||||
NTSTATUS status;
|
||||
TALLOC_CTX *mem_ctx = NULL, *prep_mem_ctx;
|
||||
struct libnet_context *ctx;
|
||||
struct dcerpc_pipe *p;
|
||||
struct policy_handle h;
|
||||
struct lsa_String domain_name;
|
||||
struct libnet_UserInfo req;
|
||||
|
||||
prep_mem_ctx = talloc_init("prepare torture user info");
|
||||
binding = torture_setting_string(torture, "binding", NULL);
|
||||
|
||||
ctx = libnet_context_init(NULL);
|
||||
ctx->cred = cmdline_credentials;
|
||||
|
||||
status = torture_rpc_connection(prep_mem_ctx,
|
||||
&p,
|
||||
&dcerpc_table_samr);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
domain_name.string = lp_workgroup();
|
||||
if (!test_opendomain(p, prep_mem_ctx, &h, &domain_name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_createuser(p, prep_mem_ctx, &h, name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
mem_ctx = talloc_init("torture user info");
|
||||
|
||||
ZERO_STRUCT(req);
|
||||
|
||||
req.in.domain_name = domain_name.string;
|
||||
req.in.user_name = name;
|
||||
|
||||
status = libnet_UserInfo(ctx, mem_ctx, &req);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("libnet_UserInfo call failed: %s\n", nt_errstr(status));
|
||||
ret = False;
|
||||
talloc_free(mem_ctx);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_cleanup(ctx->samr.pipe, mem_ctx, &ctx->samr.handle, TEST_USERNAME)) {
|
||||
printf("cleanup failed\n");
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_samr_close(ctx->samr.pipe, mem_ctx, &ctx->samr.handle)) {
|
||||
printf("domain close failed\n");
|
||||
ret = False;
|
||||
}
|
||||
|
||||
talloc_free(ctx);
|
||||
|
||||
done:
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_userlist(struct torture_context *torture)
|
||||
{
|
||||
const char *binding;
|
||||
BOOL ret = True;
|
||||
NTSTATUS status;
|
||||
TALLOC_CTX *mem_ctx = NULL;
|
||||
struct libnet_context *ctx;
|
||||
struct lsa_String domain_name;
|
||||
struct libnet_UserList req;
|
||||
int i;
|
||||
|
||||
binding = torture_setting_string(torture, "binding", NULL);
|
||||
|
||||
ctx = libnet_context_init(NULL);
|
||||
ctx->cred = cmdline_credentials;
|
||||
|
||||
domain_name.string = lp_workgroup();
|
||||
mem_ctx = talloc_init("torture user list");
|
||||
|
||||
ZERO_STRUCT(req);
|
||||
|
||||
printf("listing user accounts:\n");
|
||||
|
||||
do {
|
||||
|
||||
req.in.domain_name = domain_name.string;
|
||||
req.in.page_size = 128;
|
||||
req.in.resume_index = req.out.resume_index;
|
||||
|
||||
status = libnet_UserList(ctx, mem_ctx, &req);
|
||||
|
||||
for (i = 0; i < req.out.count; i++) {
|
||||
printf("\tuser: %s, sid=%s\n",
|
||||
req.out.users[i].username, req.out.users[i].sid);
|
||||
}
|
||||
|
||||
} while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
|
||||
|
||||
if (!(NT_STATUS_IS_OK(status) ||
|
||||
NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))) {
|
||||
printf("libnet_UserList call failed: %s\n", nt_errstr(status));
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_samr_close(ctx->samr.pipe, mem_ctx, &ctx->samr.handle)) {
|
||||
printf("samr domain close failed\n");
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_lsa_close(ctx->lsa.pipe, mem_ctx, &ctx->lsa.handle)) {
|
||||
printf("lsa domain close failed\n");
|
||||
ret = False;
|
||||
}
|
||||
|
||||
talloc_free(ctx);
|
||||
|
||||
done:
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,378 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Test suite for libnet calls.
|
||||
|
||||
Copyright (C) Rafal Szczesniak 2005
|
||||
|
||||
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
|
||||
(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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "torture/rpc/rpc.h"
|
||||
#include "libnet/libnet.h"
|
||||
#include "libcli/security/security.h"
|
||||
#include "librpc/gen_ndr/ndr_samr_c.h"
|
||||
|
||||
#define TEST_USERNAME "libnetuserinfotest"
|
||||
|
||||
static BOOL test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *handle, struct lsa_String *domname,
|
||||
struct dom_sid2 *sid)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct policy_handle h, domain_handle;
|
||||
struct samr_Connect r1;
|
||||
struct samr_LookupDomain r2;
|
||||
struct samr_OpenDomain r3;
|
||||
|
||||
printf("connecting\n");
|
||||
|
||||
r1.in.system_name = 0;
|
||||
r1.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
r1.out.connect_handle = &h;
|
||||
|
||||
status = dcerpc_samr_Connect(p, mem_ctx, &r1);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Connect failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
r2.in.connect_handle = &h;
|
||||
r2.in.domain_name = domname;
|
||||
|
||||
printf("domain lookup on %s\n", domname->string);
|
||||
|
||||
status = dcerpc_samr_LookupDomain(p, mem_ctx, &r2);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("LookupDomain failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
r3.in.connect_handle = &h;
|
||||
r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
r3.in.sid = r2.out.sid;
|
||||
r3.out.domain_handle = &domain_handle;
|
||||
|
||||
printf("opening domain\n");
|
||||
|
||||
status = dcerpc_samr_OpenDomain(p, mem_ctx, &r3);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("OpenDomain failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
} else {
|
||||
*handle = domain_handle;
|
||||
}
|
||||
|
||||
*sid = *r2.out.sid;
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *domain_handle, const char *username)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct samr_LookupNames r1;
|
||||
struct samr_OpenUser r2;
|
||||
struct samr_DeleteUser r3;
|
||||
struct lsa_String names[2];
|
||||
uint32_t rid;
|
||||
struct policy_handle user_handle;
|
||||
|
||||
names[0].string = username;
|
||||
|
||||
r1.in.domain_handle = domain_handle;
|
||||
r1.in.num_names = 1;
|
||||
r1.in.names = names;
|
||||
|
||||
printf("user account lookup '%s'\n", username);
|
||||
|
||||
status = dcerpc_samr_LookupNames(p, mem_ctx, &r1);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("LookupNames failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
rid = r1.out.rids.ids[0];
|
||||
|
||||
r2.in.domain_handle = domain_handle;
|
||||
r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
r2.in.rid = rid;
|
||||
r2.out.user_handle = &user_handle;
|
||||
|
||||
printf("opening user account\n");
|
||||
|
||||
status = dcerpc_samr_OpenUser(p, mem_ctx, &r2);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("OpenUser failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
r3.in.user_handle = &user_handle;
|
||||
r3.out.user_handle = &user_handle;
|
||||
|
||||
printf("deleting user account\n");
|
||||
|
||||
status = dcerpc_samr_DeleteUser(p, mem_ctx, &r3);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("DeleteUser failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_create(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *handle, const char *name, uint32_t *rid)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct lsa_String username;
|
||||
struct samr_CreateUser r;
|
||||
struct policy_handle user_handle;
|
||||
|
||||
username.string = name;
|
||||
|
||||
r.in.domain_handle = handle;
|
||||
r.in.account_name = &username;
|
||||
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
r.out.user_handle = &user_handle;
|
||||
r.out.rid = rid;
|
||||
|
||||
printf("creating user account %s\n", name);
|
||||
|
||||
status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("CreateUser failed - %s\n", nt_errstr(status));
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
|
||||
printf("User (%s) already exists - attempting to delete and recreate account again\n", name);
|
||||
if (!test_cleanup(p, mem_ctx, handle, TEST_USERNAME)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
printf("creating user account\n");
|
||||
|
||||
status = dcerpc_samr_CreateUser(p, mem_ctx, &r);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("CreateUser failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_userinfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *domain_handle,
|
||||
struct dom_sid2 *domain_sid, const char* user_name,
|
||||
uint32_t *rid)
|
||||
{
|
||||
const uint16_t level = 5;
|
||||
NTSTATUS status;
|
||||
struct libnet_rpc_userinfo user;
|
||||
struct dom_sid *user_sid;
|
||||
|
||||
user_sid = dom_sid_add_rid(mem_ctx, domain_sid, *rid);
|
||||
|
||||
user.in.domain_handle = *domain_handle;
|
||||
user.in.sid = dom_sid_string(mem_ctx, user_sid);
|
||||
user.in.level = level; /* this should be extended */
|
||||
|
||||
printf("Testing sync libnet_rpc_userinfo (SID argument)\n");
|
||||
status = libnet_rpc_userinfo(p, mem_ctx, &user);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Failed to call sync libnet_rpc_userinfo - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(user);
|
||||
|
||||
user.in.domain_handle = *domain_handle;
|
||||
user.in.sid = NULL;
|
||||
user.in.username = TEST_USERNAME;
|
||||
user.in.level = level;
|
||||
|
||||
printf("Testing sync libnet_rpc_userinfo (username argument)\n");
|
||||
status = libnet_rpc_userinfo(p, mem_ctx, &user);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Failed to call sync libnet_rpc_userinfo - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static void msg_handler(struct monitor_msg *m)
|
||||
{
|
||||
struct msg_rpc_open_user *msg_open;
|
||||
struct msg_rpc_query_user *msg_query;
|
||||
struct msg_rpc_close_user *msg_close;
|
||||
|
||||
switch (m->type) {
|
||||
case rpc_open_user:
|
||||
msg_open = (struct msg_rpc_open_user*)m->data;
|
||||
printf("monitor_msg: user opened (rid=%d, access_mask=0x%08x)\n",
|
||||
msg_open->rid, msg_open->access_mask);
|
||||
break;
|
||||
case rpc_query_user:
|
||||
msg_query = (struct msg_rpc_query_user*)m->data;
|
||||
printf("monitor_msg: user queried (level=%d)\n", msg_query->level);
|
||||
break;
|
||||
case rpc_close_user:
|
||||
msg_close = (struct msg_rpc_close_user*)m->data;
|
||||
printf("monitor_msg: user closed (rid=%d)\n", msg_close->rid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_userinfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *domain_handle,
|
||||
struct dom_sid2 *domain_sid, const char* user_name,
|
||||
uint32_t *rid)
|
||||
{
|
||||
const uint16_t level = 10;
|
||||
NTSTATUS status;
|
||||
struct composite_context *c;
|
||||
struct libnet_rpc_userinfo user;
|
||||
struct dom_sid *user_sid;
|
||||
|
||||
user_sid = dom_sid_add_rid(mem_ctx, domain_sid, *rid);
|
||||
|
||||
user.in.domain_handle = *domain_handle;
|
||||
user.in.sid = dom_sid_string(mem_ctx, user_sid);
|
||||
user.in.level = level; /* this should be extended */
|
||||
|
||||
printf("Testing async libnet_rpc_userinfo (SID argument)\n");
|
||||
|
||||
c = libnet_rpc_userinfo_send(p, &user, msg_handler);
|
||||
if (!c) {
|
||||
printf("Failed to call sync libnet_rpc_userinfo_send\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
status = libnet_rpc_userinfo_recv(c, mem_ctx, &user);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Calling async libnet_rpc_userinfo failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(user);
|
||||
|
||||
user.in.domain_handle = *domain_handle;
|
||||
user.in.sid = NULL;
|
||||
user.in.username = TEST_USERNAME;
|
||||
user.in.level = level;
|
||||
|
||||
printf("Testing async libnet_rpc_userinfo (username argument)\n");
|
||||
|
||||
c = libnet_rpc_userinfo_send(p, &user, msg_handler);
|
||||
if (!c) {
|
||||
printf("Failed to call sync libnet_rpc_userinfo_send\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
status = libnet_rpc_userinfo_recv(c, mem_ctx, &user);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Calling async libnet_rpc_userinfo failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_userinfo(struct torture_context *torture)
|
||||
{
|
||||
NTSTATUS status;
|
||||
const char *binding;
|
||||
struct dcerpc_pipe *p;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
BOOL ret = True;
|
||||
struct policy_handle h;
|
||||
struct lsa_String name;
|
||||
struct dom_sid2 sid;
|
||||
uint32_t rid;
|
||||
|
||||
mem_ctx = talloc_init("test_userinfo");
|
||||
binding = torture_setting_string(torture, "binding", NULL);
|
||||
|
||||
status = torture_rpc_connection(mem_ctx,
|
||||
&p,
|
||||
&dcerpc_table_samr);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
name.string = lp_workgroup();
|
||||
|
||||
/*
|
||||
* Testing synchronous version
|
||||
*/
|
||||
if (!test_opendomain(p, mem_ctx, &h, &name, &sid)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_create(p, mem_ctx, &h, TEST_USERNAME, &rid)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_userinfo(p, mem_ctx, &h, &sid, TEST_USERNAME, &rid)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_cleanup(p, mem_ctx, &h, TEST_USERNAME)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Testing asynchronous version and monitor messages
|
||||
*/
|
||||
if (!test_opendomain(p, mem_ctx, &h, &name, &sid)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_create(p, mem_ctx, &h, TEST_USERNAME, &rid)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_userinfo_async(p, mem_ctx, &h, &sid, TEST_USERNAME, &rid)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_cleanup(p, mem_ctx, &h, TEST_USERNAME)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
talloc_free(mem_ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,642 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Test suite for libnet calls.
|
||||
|
||||
Copyright (C) Rafal Szczesniak 2005
|
||||
|
||||
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
|
||||
(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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include "torture/rpc/rpc.h"
|
||||
#include "torture/libnet/usertest.h"
|
||||
#include "libnet/libnet.h"
|
||||
#include "librpc/gen_ndr/ndr_samr_c.h"
|
||||
|
||||
|
||||
static BOOL test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *handle, struct lsa_String *domname)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct policy_handle h, domain_handle;
|
||||
struct samr_Connect r1;
|
||||
struct samr_LookupDomain r2;
|
||||
struct samr_OpenDomain r3;
|
||||
|
||||
printf("connecting\n");
|
||||
|
||||
r1.in.system_name = 0;
|
||||
r1.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
r1.out.connect_handle = &h;
|
||||
|
||||
status = dcerpc_samr_Connect(p, mem_ctx, &r1);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Connect failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
r2.in.connect_handle = &h;
|
||||
r2.in.domain_name = domname;
|
||||
|
||||
printf("domain lookup on %s\n", domname->string);
|
||||
|
||||
status = dcerpc_samr_LookupDomain(p, mem_ctx, &r2);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("LookupDomain failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
r3.in.connect_handle = &h;
|
||||
r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
r3.in.sid = r2.out.sid;
|
||||
r3.out.domain_handle = &domain_handle;
|
||||
|
||||
printf("opening domain\n");
|
||||
|
||||
status = dcerpc_samr_OpenDomain(p, mem_ctx, &r3);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("OpenDomain failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
} else {
|
||||
*handle = domain_handle;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_useradd(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *domain_handle,
|
||||
const char *name)
|
||||
{
|
||||
NTSTATUS status;
|
||||
BOOL ret = True;
|
||||
struct libnet_rpc_useradd user;
|
||||
|
||||
user.in.domain_handle = *domain_handle;
|
||||
user.in.username = name;
|
||||
|
||||
printf("Testing libnet_rpc_useradd\n");
|
||||
|
||||
status = libnet_rpc_useradd(p, mem_ctx, &user);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Failed to call sync rpc_composite_userinfo - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void msg_handler(struct monitor_msg *m)
|
||||
{
|
||||
struct msg_rpc_create_user *msg_create;
|
||||
|
||||
switch (m->type) {
|
||||
case rpc_create_user:
|
||||
msg_create = (struct msg_rpc_create_user*)m->data;
|
||||
printf("monitor_msg: user created (rid=%d)\n", msg_create->rid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_useradd_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *handle, const char* username)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct composite_context *c;
|
||||
struct libnet_rpc_useradd user;
|
||||
|
||||
user.in.domain_handle = *handle;
|
||||
user.in.username = username;
|
||||
|
||||
printf("Testing async libnet_rpc_useradd\n");
|
||||
|
||||
c = libnet_rpc_useradd_send(p, &user, msg_handler);
|
||||
if (!c) {
|
||||
printf("Failed to call async libnet_rpc_useradd\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
status = libnet_rpc_useradd_recv(c, mem_ctx, &user);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Calling async libnet_rpc_useradd failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *domain_handle, const char *username)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct samr_LookupNames r1;
|
||||
struct samr_OpenUser r2;
|
||||
struct samr_DeleteUser r3;
|
||||
struct lsa_String names[2];
|
||||
uint32_t rid;
|
||||
struct policy_handle user_handle;
|
||||
|
||||
names[0].string = username;
|
||||
|
||||
r1.in.domain_handle = domain_handle;
|
||||
r1.in.num_names = 1;
|
||||
r1.in.names = names;
|
||||
|
||||
printf("user account lookup '%s'\n", username);
|
||||
|
||||
status = dcerpc_samr_LookupNames(p, mem_ctx, &r1);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("LookupNames failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
rid = r1.out.rids.ids[0];
|
||||
|
||||
r2.in.domain_handle = domain_handle;
|
||||
r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
r2.in.rid = rid;
|
||||
r2.out.user_handle = &user_handle;
|
||||
|
||||
printf("opening user account\n");
|
||||
|
||||
status = dcerpc_samr_OpenUser(p, mem_ctx, &r2);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("OpenUser failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
r3.in.user_handle = &user_handle;
|
||||
r3.out.user_handle = &user_handle;
|
||||
|
||||
printf("deleting user account\n");
|
||||
|
||||
status = dcerpc_samr_DeleteUser(p, mem_ctx, &r3);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("DeleteUser failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_createuser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *handle, const char* user)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct policy_handle user_handle;
|
||||
struct lsa_String username;
|
||||
struct samr_CreateUser r1;
|
||||
struct samr_Close r2;
|
||||
uint32_t user_rid;
|
||||
|
||||
username.string = user;
|
||||
|
||||
r1.in.domain_handle = handle;
|
||||
r1.in.account_name = &username;
|
||||
r1.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
|
||||
r1.out.user_handle = &user_handle;
|
||||
r1.out.rid = &user_rid;
|
||||
|
||||
printf("creating user '%s'\n", username.string);
|
||||
|
||||
status = dcerpc_samr_CreateUser(p, mem_ctx, &r1);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("CreateUser failed - %s\n", nt_errstr(status));
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
|
||||
printf("User (%s) already exists - attempting to delete and recreate account again\n", user);
|
||||
if (!test_cleanup(p, mem_ctx, handle, TEST_USERNAME)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
printf("creating user account\n");
|
||||
|
||||
status = dcerpc_samr_CreateUser(p, mem_ctx, &r1);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("CreateUser failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
r2.in.handle = &user_handle;
|
||||
r2.out.handle = &user_handle;
|
||||
|
||||
printf("closing user '%s'\n", username.string);
|
||||
|
||||
status = dcerpc_samr_Close(p, mem_ctx, &r2);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Close failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_usermod(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *handle, int num_changes,
|
||||
struct libnet_rpc_usermod *mod, char **username)
|
||||
{
|
||||
const char* logon_scripts[] = { "start_login.cmd", "login.bat", "start.cmd" };
|
||||
const char* home_dirs[] = { "\\\\srv\\home", "\\\\homesrv\\home\\user", "\\\\pdcsrv\\domain" };
|
||||
const char* home_drives[] = { "H:", "z:", "I:", "J:", "n:" };
|
||||
const char *homedir, *homedrive, *logonscript;
|
||||
const uint32_t flags[] = { (ACB_DISABLED | ACB_NORMAL),
|
||||
(ACB_NORMAL | ACB_PWNOEXP),
|
||||
(ACB_NORMAL) };
|
||||
|
||||
NTSTATUS status;
|
||||
struct timeval now;
|
||||
enum test_fields testfld;
|
||||
int i;
|
||||
|
||||
ZERO_STRUCT(*mod);
|
||||
srandom((unsigned)time(NULL));
|
||||
|
||||
mod->in.username = talloc_strdup(mem_ctx, *username);
|
||||
mod->in.domain_handle = *handle;
|
||||
|
||||
printf("modifying user (%d simultaneous change(s))\n", num_changes);
|
||||
|
||||
printf("fields to change: [");
|
||||
|
||||
for (i = 0; i < num_changes && i < FIELDS_NUM - 1; i++) {
|
||||
const char *fldname;
|
||||
|
||||
testfld = (random() % (FIELDS_NUM - 1)) + 1;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
switch (testfld) {
|
||||
case account_name:
|
||||
continue_if_field_set(mod->in.change.account_name);
|
||||
mod->in.change.account_name = talloc_asprintf(mem_ctx, TEST_CHG_ACCOUNTNAME,
|
||||
(int)(random() % 100));
|
||||
mod->in.change.fields |= USERMOD_FIELD_ACCOUNT_NAME;
|
||||
fldname = "account_name";
|
||||
*username = talloc_strdup(mem_ctx, mod->in.change.account_name);
|
||||
break;
|
||||
|
||||
case full_name:
|
||||
continue_if_field_set(mod->in.change.full_name);
|
||||
mod->in.change.full_name = talloc_asprintf(mem_ctx, TEST_CHG_FULLNAME,
|
||||
(int)random(), (int)random());
|
||||
mod->in.change.fields |= USERMOD_FIELD_FULL_NAME;
|
||||
fldname = "full_name";
|
||||
break;
|
||||
|
||||
case description:
|
||||
continue_if_field_set(mod->in.change.description);
|
||||
mod->in.change.description = talloc_asprintf(mem_ctx, TEST_CHG_DESCRIPTION,
|
||||
random());
|
||||
mod->in.change.fields |= USERMOD_FIELD_DESCRIPTION;
|
||||
fldname = "description";
|
||||
break;
|
||||
|
||||
case home_directory:
|
||||
continue_if_field_set(mod->in.change.home_directory);
|
||||
homedir = home_dirs[random() % (sizeof(home_dirs)/sizeof(char*))];
|
||||
mod->in.change.home_directory = talloc_strdup(mem_ctx, homedir);
|
||||
mod->in.change.fields |= USERMOD_FIELD_HOME_DIRECTORY;
|
||||
fldname = "home_directory";
|
||||
break;
|
||||
|
||||
case home_drive:
|
||||
continue_if_field_set(mod->in.change.home_drive);
|
||||
homedrive = home_drives[random() % (sizeof(home_drives)/sizeof(char*))];
|
||||
mod->in.change.home_drive = talloc_strdup(mem_ctx, homedrive);
|
||||
mod->in.change.fields |= USERMOD_FIELD_HOME_DRIVE;
|
||||
fldname = "home_drive";
|
||||
break;
|
||||
|
||||
case comment:
|
||||
continue_if_field_set(mod->in.change.comment);
|
||||
mod->in.change.comment = talloc_asprintf(mem_ctx, TEST_CHG_COMMENT,
|
||||
random(), random());
|
||||
mod->in.change.fields |= USERMOD_FIELD_COMMENT;
|
||||
fldname = "comment";
|
||||
break;
|
||||
|
||||
case logon_script:
|
||||
continue_if_field_set(mod->in.change.logon_script);
|
||||
logonscript = logon_scripts[random() % (sizeof(logon_scripts)/sizeof(char*))];
|
||||
mod->in.change.logon_script = talloc_strdup(mem_ctx, logonscript);
|
||||
mod->in.change.fields |= USERMOD_FIELD_LOGON_SCRIPT;
|
||||
fldname = "logon_script";
|
||||
break;
|
||||
|
||||
case profile_path:
|
||||
continue_if_field_set(mod->in.change.profile_path);
|
||||
mod->in.change.profile_path = talloc_asprintf(mem_ctx, TEST_CHG_PROFILEPATH,
|
||||
(long int)random(), (unsigned int)random());
|
||||
mod->in.change.fields |= USERMOD_FIELD_PROFILE_PATH;
|
||||
fldname = "profile_path";
|
||||
break;
|
||||
|
||||
case acct_expiry:
|
||||
continue_if_field_set(mod->in.change.acct_expiry);
|
||||
now = timeval_add(&now, (random() % (31*24*60*60)), 0);
|
||||
mod->in.change.acct_expiry = talloc_memdup(mem_ctx, &now, sizeof(now));
|
||||
mod->in.change.fields |= USERMOD_FIELD_ACCT_EXPIRY;
|
||||
fldname = "acct_expiry";
|
||||
break;
|
||||
|
||||
case acct_flags:
|
||||
continue_if_field_set(mod->in.change.acct_flags);
|
||||
mod->in.change.acct_flags = flags[random() % (sizeof(flags)/sizeof(uint32_t))];
|
||||
mod->in.change.fields |= USERMOD_FIELD_ACCT_FLAGS;
|
||||
fldname = "acct_flags";
|
||||
break;
|
||||
|
||||
default:
|
||||
fldname = talloc_asprintf(mem_ctx, "unknown_field (%d)", testfld);
|
||||
break;
|
||||
}
|
||||
|
||||
printf(((i < num_changes - 1) ? "%s," : "%s"), fldname);
|
||||
}
|
||||
printf("]\n");
|
||||
|
||||
status = libnet_rpc_usermod(p, mem_ctx, mod);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Failed to call sync libnet_rpc_usermod - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_userdel(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *handle, const char *username)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct libnet_rpc_userdel user;
|
||||
|
||||
user.in.domain_handle = *handle;
|
||||
user.in.username = username;
|
||||
|
||||
status = libnet_rpc_userdel(p, mem_ctx, &user);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Failed to call sync libnet_rpc_userdel - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
#define CMP_LSA_STRING_FLD(fld, flags) \
|
||||
if ((mod->in.change.fields & flags) && \
|
||||
!strequal(i->fld.string, mod->in.change.fld)) { \
|
||||
printf("'%s' field does not match\n", #fld); \
|
||||
printf("received: '%s'\n", i->fld.string); \
|
||||
printf("expected: '%s'\n", mod->in.change.fld); \
|
||||
return False; \
|
||||
}
|
||||
|
||||
|
||||
#define CMP_TIME_FLD(fld, flags) \
|
||||
if (mod->in.change.fields & flags) { \
|
||||
nttime_to_timeval(&t, i->fld); \
|
||||
if (timeval_compare(&t, mod->in.change.fld)) { \
|
||||
printf("'%s' field does not match\n", #fld); \
|
||||
printf("received: '%s (+%ld us)'\n", timestring(mem_ctx, t.tv_sec), t.tv_usec); \
|
||||
printf("expected: '%s (+%ld us)'\n", timestring(mem_ctx, mod->in.change.fld->tv_sec), mod->in.change.fld->tv_usec); \
|
||||
return False; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CMP_NUM_FLD(fld, flags) \
|
||||
if ((mod->in.change.fields & flags) && \
|
||||
(i->fld != mod->in.change.fld)) { \
|
||||
printf("'%s' field does not match\n", #fld); \
|
||||
printf("received: '%04x'\n", i->fld); \
|
||||
printf("expected: '%04x'\n", mod->in.change.fld); \
|
||||
return False; \
|
||||
}
|
||||
|
||||
|
||||
static BOOL test_compare(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
|
||||
struct policy_handle *handle, struct libnet_rpc_usermod *mod,
|
||||
const char *username)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct libnet_rpc_userinfo info;
|
||||
struct samr_UserInfo21 *i;
|
||||
struct timeval t;
|
||||
|
||||
ZERO_STRUCT(info);
|
||||
|
||||
info.in.username = username;
|
||||
info.in.domain_handle = *handle;
|
||||
info.in.level = 21; /* the most rich infolevel available */
|
||||
|
||||
status = libnet_rpc_userinfo(p, mem_ctx, &info);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("Failed to call sync libnet_rpc_userinfo - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
i = &info.out.info.info21;
|
||||
|
||||
CMP_LSA_STRING_FLD(account_name, USERMOD_FIELD_ACCOUNT_NAME);
|
||||
CMP_LSA_STRING_FLD(full_name, USERMOD_FIELD_FULL_NAME);
|
||||
CMP_LSA_STRING_FLD(description, USERMOD_FIELD_DESCRIPTION);
|
||||
CMP_LSA_STRING_FLD(comment, USERMOD_FIELD_COMMENT);
|
||||
CMP_LSA_STRING_FLD(logon_script, USERMOD_FIELD_LOGON_SCRIPT);
|
||||
CMP_LSA_STRING_FLD(profile_path, USERMOD_FIELD_PROFILE_PATH);
|
||||
CMP_LSA_STRING_FLD(home_directory, USERMOD_FIELD_HOME_DIRECTORY);
|
||||
CMP_LSA_STRING_FLD(home_drive, USERMOD_FIELD_HOME_DRIVE);
|
||||
CMP_TIME_FLD(acct_expiry, USERMOD_FIELD_ACCT_EXPIRY);
|
||||
CMP_NUM_FLD(acct_flags, USERMOD_FIELD_ACCT_FLAGS)
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_useradd(struct torture_context *torture)
|
||||
{
|
||||
NTSTATUS status;
|
||||
const char *binding;
|
||||
struct dcerpc_pipe *p;
|
||||
struct policy_handle h;
|
||||
struct lsa_String domain_name;
|
||||
const char *name = TEST_USERNAME;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
BOOL ret = True;
|
||||
|
||||
mem_ctx = talloc_init("test_useradd");
|
||||
binding = torture_setting_string(torture, "binding", NULL);
|
||||
|
||||
status = torture_rpc_connection(mem_ctx,
|
||||
&p,
|
||||
&dcerpc_table_samr);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
domain_name.string = lp_workgroup();
|
||||
if (!test_opendomain(p, mem_ctx, &h, &domain_name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_useradd(p, mem_ctx, &h, name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_cleanup(p, mem_ctx, &h, name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_opendomain(p, mem_ctx, &h, &domain_name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_useradd_async(p, mem_ctx, &h, name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_cleanup(p, mem_ctx, &h, name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_userdel(struct torture_context *torture)
|
||||
{
|
||||
NTSTATUS status;
|
||||
const char *binding;
|
||||
struct dcerpc_pipe *p;
|
||||
struct policy_handle h;
|
||||
struct lsa_String domain_name;
|
||||
const char *name = TEST_USERNAME;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
BOOL ret = True;
|
||||
|
||||
mem_ctx = talloc_init("test_userdel");
|
||||
binding = torture_setting_string(torture, "binding", NULL);
|
||||
|
||||
status = torture_rpc_connection(mem_ctx,
|
||||
&p,
|
||||
&dcerpc_table_samr);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
domain_name.string = lp_workgroup();
|
||||
if (!test_opendomain(p, mem_ctx, &h, &domain_name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_createuser(p, mem_ctx, &h, name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_userdel(p, mem_ctx, &h, name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
BOOL torture_usermod(struct torture_context *torture)
|
||||
{
|
||||
NTSTATUS status;
|
||||
const char *binding;
|
||||
struct dcerpc_pipe *p;
|
||||
struct policy_handle h;
|
||||
struct lsa_String domain_name;
|
||||
int i;
|
||||
char *name;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
BOOL ret = True;
|
||||
|
||||
mem_ctx = talloc_init("test_userdel");
|
||||
binding = torture_setting_string(torture, "binding", NULL);
|
||||
|
||||
status = torture_rpc_connection(mem_ctx,
|
||||
&p,
|
||||
&dcerpc_table_samr);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
domain_name.string = lp_workgroup();
|
||||
name = talloc_strdup(mem_ctx, TEST_USERNAME);
|
||||
|
||||
if (!test_opendomain(p, mem_ctx, &h, &domain_name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!test_createuser(p, mem_ctx, &h, name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (i = 1; i < FIELDS_NUM; i++) {
|
||||
struct libnet_rpc_usermod m;
|
||||
|
||||
if (!test_usermod(p, mem_ctx, &h, i, &m, &name)) {
|
||||
ret = False;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!test_compare(p, mem_ctx, &h, &m, name)) {
|
||||
ret = False;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (!test_cleanup(p, mem_ctx, &h, name)) {
|
||||
ret = False;
|
||||
goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
talloc_free(mem_ctx);
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
|
||||
Copyright (C) Rafal Szczesniak 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
|
||||
(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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#define TEST_USERNAME "libnetusertest"
|
||||
|
||||
#define continue_if_field_set(field) \
|
||||
if (field != 0) { \
|
||||
i--; \
|
||||
continue; \
|
||||
}
|
||||
|
||||
|
||||
#define FIELDS_NUM 11
|
||||
enum test_fields { none = 0, account_name, full_name, description, home_directory, home_drive,
|
||||
comment, logon_script, profile_path, acct_expiry, acct_flags };
|
||||
|
||||
|
||||
#define TEST_CHG_ACCOUNTNAME "newlibnetusertest%02d"
|
||||
#define TEST_CHG_DESCRIPTION "Sample description %ld"
|
||||
#define TEST_CHG_FULLNAME "First%04x Last%04x"
|
||||
#define TEST_CHG_COMMENT "Comment[%04lu%04lu]"
|
||||
#define TEST_CHG_PROFILEPATH "\\\\srv%04ld\\profile%02u\\prof"
|
||||
Reference in New Issue
Block a user