This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
static BOOL test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
- struct policy_handle *handle, struct lsa_String *domname)
+ struct policy_handle *handle, struct lsa_String *domname,
+ uint32_t *access_mask)
{
NTSTATUS status;
struct policy_handle h, domain_handle;
struct samr_OpenDomain r3;
printf("connecting\n");
+
+ *access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
r1.in.system_name = 0;
- r1.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ r1.in.access_mask = *access_mask;
r1.out.connect_handle = &h;
status = dcerpc_samr_Connect(p, mem_ctx, &r1);
}
r3.in.connect_handle = &h;
- r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ r3.in.access_mask = *access_mask;
r3.in.sid = r2.out.sid;
r3.out.domain_handle = &domain_handle;
static BOOL test_opendomain_lsa(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
- struct policy_handle **handle, struct lsa_String *domname)
+ 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;
- *handle = talloc_zero(mem_ctx, struct policy_handle);
- if (*handle == NULL) {
- return False;
- }
+ *access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
ZERO_STRUCT(attr);
ZERO_STRUCT(qos);
open.in.system_name = domname->string;
open.in.attr = &attr;
- open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- open.out.handle = *handle;
+ open.in.access_mask = *access_mask;
+ open.out.handle = handle;
status = dcerpc_lsa_OpenPolicy2(p, mem_ctx, &open);
if (!NT_STATUS_IS_OK(status)) {
BOOL torture_domain_open_lsa(struct torture_context *torture)
{
NTSTATUS status;
+ BOOL ret = True;
struct libnet_context *ctx;
struct libnet_DomainOpen r;
- struct dcerpc_binding *binding;
- const char *bindstr;
-
- bindstr = lp_parm_string(-1, "torture", "binding");
- status = dcerpc_parse_binding(torture, bindstr, &binding);
- if (!NT_STATUS_IS_OK(status)) {
- d_printf("failed to parse binding string\n");
- return False;
- }
+ struct lsa_Close lsa_close;
+ struct policy_handle h;
+ const char *domain_name;
+
+ /* we're accessing domain controller so the domain name should be
+ passed (it's going to be resolved to dc name and address) instead
+ of specific server name. */
+ domain_name = lp_workgroup();
ctx = libnet_context_init(NULL);
if (ctx == NULL) {
ctx->cred = cmdline_credentials;
+ ZERO_STRUCT(r);
r.in.type = DOMAIN_LSA;
- r.in.domain_name = binding->host;
+ r.in.domain_name = domain_name;
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));
- return False;
+ ret = False;
+ goto done;
}
- talloc_free(ctx);
+ ZERO_STRUCT(lsa_close);
+ lsa_close.in.handle = &ctx->lsa.handle;
+ lsa_close.out.handle = &h;
+
+ status = dcerpc_lsa_Close(ctx->lsa.pipe, ctx, &lsa_close);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("failed to close domain on lsa service: %s\n", nt_errstr(status));
+ ret = False;
+ }
- return True;
+done:
+ talloc_free(ctx);
+ return ret;
}
BOOL torture_domain_close_lsa(struct torture_context *torture)
{
- BOOL ret;
+ BOOL ret = True;
NTSTATUS status;
- TALLOC_CTX *mem_ctx;
+ TALLOC_CTX *mem_ctx=NULL;
struct libnet_context *ctx;
struct lsa_String domain_name;
struct dcerpc_binding *binding;
const char *bindstr;
- struct policy_handle *h;
+ uint32_t access_mask;
+ struct policy_handle h;
struct dcerpc_pipe *p;
struct libnet_DomainClose r;
- struct lsa_QueryInfoPolicy2 r2;
- bindstr = lp_parm_string(-1, "torture", "binding");
+ 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;
}
- mem_ctx = talloc_init("torture_domain_close_lsa");
ctx = libnet_context_init(NULL);
if (ctx == NULL) {
d_printf("failed to create libnet context\n");
ctx->cred = cmdline_credentials;
- status = torture_rpc_connection(mem_ctx,
- &p,
- &dcerpc_table_lsarpc);
+ 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, mem_ctx, &h, &domain_name)) {
+
+ 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;
}
- /* simulate opening by means of libnet api functions */
- ctx->lsa.pipe = p;
- ctx->lsa.name = domain_name.string;
- ctx->lsa.handle = *h;
-
- r2.in.handle = &ctx->lsa.handle;
- r2.in.level = 1;
-
- status = dcerpc_lsa_QueryInfoPolicy2(ctx->lsa.pipe, mem_ctx, &r2);
-
+ 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 indefinitely */
+ 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)) {
- goto done;
ret = False;
+ goto done;
}
done:
NTSTATUS status;
const char *binding;
struct libnet_context *ctx;
- struct event_context *evt_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;
+ const char *domain_name;
BOOL ret = True;
mem_ctx = talloc_init("test_domainopen_lsa");
- binding = lp_parm_string(-1, "torture", "binding");
+ binding = torture_setting_string(torture, "binding", NULL);
- evt_ctx = event_context_find(torture);
ctx = libnet_context_init(evt_ctx);
+ ctx->cred = cmdline_credentials;
- name.string = lp_workgroup();
+ /* we're accessing domain controller so the domain name should be
+ passed (it's going to be resolved to dc name and address) instead
+ of specific server name. */
+ domain_name = lp_workgroup();
/*
* Testing synchronous version
printf("opening domain\n");
io.in.type = DOMAIN_SAMR;
- io.in.domain_name = name.string;
+ io.in.domain_name = domain_name;
io.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
status = libnet_DomainOpen(ctx, mem_ctx, &io);
goto done;
}
- domain_handle = io.out.domain_handle;
+ domain_handle = ctx->samr.handle;
r.in.handle = &domain_handle;
r.out.handle = &handle;
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,
+ ctx->cred, 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 indefinitely - this wouldn't be the case if pipe was opened
+ by means of libnet call */
+ 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;
+}
+
+
+BOOL torture_domain_list(struct torture_context *torture)
+{
+ BOOL ret = True;
+ NTSTATUS status;
+ TALLOC_CTX *mem_ctx = NULL;
+ const char *bindstr;
+ struct dcerpc_binding *binding;
+ struct libnet_context *ctx;
+ struct libnet_DomainList r;
+ int i;
+
+ 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");
+
+ /*
+ * querying the domain list using default buffer size
+ */
+
+ ZERO_STRUCT(r);
+ r.in.hostname = binding->host;
+
+ status = libnet_DomainList(ctx, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ ret = False;
+ goto done;
+ }
+
+ d_printf("Received list or domains (everything in one piece):\n");
+
+ for (i = 0; i < r.out.count; i++) {
+ d_printf("Name[%d]: %s\n", i, r.out.domains[i].name);
+ }
+
+ /*
+ * querying the domain list using specified (much smaller) buffer size
+ */
+
+ ctx->samr.buf_size = 32;
+
+ ZERO_STRUCT(r);
+ r.in.hostname = binding->host;
+
+ status = libnet_DomainList(ctx, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ ret = False;
+ goto done;
+ }
+
+ d_printf("Received list or domains (collected in more than one round):\n");
+
+ for (i = 0; i < r.out.count; i++) {
+ d_printf("Name[%d]: %s\n", i, r.out.domains[i].name);
+ }
+done:
+ d_printf("\nStatus: %s\n", nt_errstr(status));
+
+ talloc_free(mem_ctx);
+ talloc_free(ctx);
return ret;
}