wmi-1.3.16 from opsview.com

This commit is contained in:
Are Casilla
2019-02-16 00:16:52 +01:00
parent 163fdd3d1b
commit 17b3af2911
2146 changed files with 678824 additions and 0 deletions
+117
View File
@@ -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;
}
+63
View File
@@ -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;
}
+381
View File
@@ -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;
}
+192
View File
@@ -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;
}
+222
View File
@@ -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);
}
+248
View File
@@ -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;
}
+740
View File
@@ -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;
}
+378
View File
@@ -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;
}
+642
View File
@@ -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;
}
+39
View File
@@ -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"