summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libnet/composite.h1
-rw-r--r--source4/libnet/domain.c109
2 files changed, 106 insertions, 4 deletions
diff --git a/source4/libnet/composite.h b/source4/libnet/composite.h
index e1a3b5051f..b983117adc 100644
--- a/source4/libnet/composite.h
+++ b/source4/libnet/composite.h
@@ -58,6 +58,7 @@ struct rpc_composite_userdel {
struct rpc_composite_domain_open {
struct {
+ const char *domain_name;
uint32_t access_mask;
} in;
struct {
diff --git a/source4/libnet/domain.c b/source4/libnet/domain.c
index 5bf33acacd..802a3f12c0 100644
--- a/source4/libnet/domain.c
+++ b/source4/libnet/domain.c
@@ -40,11 +40,79 @@ struct domain_open_state {
struct samr_Connect connect;
struct samr_LookupDomain lookup;
struct samr_OpenDomain open;
+ struct samr_String domain_name;
uint32_t access_mask;
+ struct policy_handle connect_handle;
struct policy_handle domain_handle;
};
+static NTSTATUS domain_open_connect(struct composite_context *c,
+ struct domain_open_state *s)
+{
+ struct samr_LookupDomain *r = &s->lookup;
+
+ /* receive samr_Connect reply */
+ c->status = dcerpc_ndr_request_recv(s->req);
+ NT_STATUS_NOT_OK_RETURN(c->status);
+
+ /* prepare for samr_LookupDomain call */
+ r->in.connect_handle = &s->connect_handle;
+ r->in.domain_name = &s->domain_name;
+
+ s->req = dcerpc_samr_LookupDomain_send(s->pipe, c, r);
+ if (s->req == NULL) goto failure;
+
+ s->req->async.callback = domain_open_handler;
+ s->req->async.private = c;
+ s->stage = DOMOPEN_LOOKUP;
+
+ return NT_STATUS_OK;
+
+failure:
+ return NT_STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS domain_open_lookup(struct composite_context *c,
+ struct domain_open_state *s)
+{
+ struct samr_OpenDomain *r = &s->open;
+
+ c->status = dcerpc_ndr_request_recv(s->req);
+ NT_STATUS_NOT_OK_RETURN(c->status);
+
+ r->in.connect_handle = &s->connect_handle;
+ r->in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ r->in.sid = s->lookup.out.sid;
+ r->out.domain_handle = &s->domain_handle;
+
+ s->req = dcerpc_samr_OpenDomain_send(s->pipe, c, r);
+ if (s->req == NULL) goto failure;
+
+ s->req->async.callback = domain_open_handler;
+ s->req->async.private = c;
+ s->stage = DOMOPEN_OPEN;
+
+ return NT_STATUS_OK;
+
+failure:
+ return NT_STATUS_UNSUCCESSFUL;
+}
+
+
+static NTSTATUS domain_open_open(struct composite_context *c,
+ struct domain_open_state *s)
+{
+ c->status = dcerpc_ndr_request_recv(s->req);
+ NT_STATUS_NOT_OK_RETURN(c->status);
+
+ c->state = SMBCLI_REQUEST_DONE;
+
+ return NT_STATUS_OK;
+}
+
+
static void domain_open_handler(struct rpc_request *req)
{
struct composite_context *c = req->async.private;
@@ -54,10 +122,13 @@ static void domain_open_handler(struct rpc_request *req)
/* Stages of the call */
switch (s->stage) {
case DOMOPEN_CONNECT:
+ c->status = domain_open_connect(c, s);
break;
case DOMOPEN_LOOKUP:
+ c->status = domain_open_lookup(c, s);
break;
case DOMOPEN_OPEN:
+ c->status = domain_open_open(c, s);
break;
}
@@ -84,16 +155,19 @@ struct composite_context *rpc_composite_domain_open_send(struct dcerpc_pipe *p,
s = talloc_zero(c, struct domain_open_state);
if (c == NULL) goto failure;
- s->access_mask = io->in.access_mask;
-
c->state = SMBCLI_REQUEST_SEND;
c->private = s;
c->event_ctx = dcerpc_event_context(p);
c->monitor_fn = monitor;
+ s->pipe = p;
+ s->access_mask = io->in.access_mask;
+ s->domain_name.string = io->in.domain_name;
+
/* preparing parameters to send rpc request */
- s->connect.in.system_name = 0;
- s->connect.in.access_mask = s->access_mask;
+ s->connect.in.system_name = 0;
+ s->connect.in.access_mask = s->access_mask;
+ s->connect.out.connect_handle = &s->connect_handle;
/* send request */
s->req = dcerpc_samr_Connect_send(p, c, &s->connect);
@@ -109,3 +183,30 @@ failure:
talloc_free(c);
return NULL;
}
+
+
+NTSTATUS rpc_composite_domain_open_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
+ struct rpc_composite_domain_open *io)
+{
+ NTSTATUS status;
+ struct domain_open_state *s;
+
+ status = composite_wait(c);
+
+ if (NT_STATUS_IS_OK(status) && io) {
+ s = talloc_get_type(c->private, struct domain_open_state);
+ io->out.domain_handle = s->domain_handle;
+ }
+
+ talloc_free(c);
+ return status;
+}
+
+
+NTSTATUS rpc_composite_domain_open(struct dcerpc_pipe *p,
+ TALLOC_CTX *mem_ctx,
+ struct rpc_composite_domain_open *io)
+{
+ struct composite_context *c = rpc_composite_domain_open_send(p, io, NULL);
+ return rpc_composite_domain_open_recv(c, mem_ctx, io);
+}