diff options
-rw-r--r-- | source4/libnet/composite.h | 1 | ||||
-rw-r--r-- | source4/libnet/domain.c | 109 |
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); +} |