2 Unix SMB/CIFS implementation.
4 Copyright (C) Rafal Szczesniak 2005
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 a composite function for domain handling
26 #include "libcli/raw/libcliraw.h"
27 #include "libcli/composite/composite.h"
28 #include "libcli/composite/monitor.h"
29 #include "librpc/gen_ndr/ndr_samr.h"
30 #include "libnet/composite.h"
32 static void domain_open_handler(struct rpc_request*);
34 enum domain_open_stage { DOMOPEN_CONNECT, DOMOPEN_LOOKUP, DOMOPEN_OPEN };
36 struct domain_open_state {
37 enum domain_open_stage stage;
38 struct dcerpc_pipe *pipe;
39 struct rpc_request *req;
40 struct samr_Connect connect;
41 struct samr_LookupDomain lookup;
42 struct samr_OpenDomain open;
43 struct lsa_String domain_name;
45 struct policy_handle connect_handle;
46 struct policy_handle domain_handle;
51 * Stage 1: Connect to SAM server.
53 static NTSTATUS domain_open_connect(struct composite_context *c,
54 struct domain_open_state *s)
56 struct samr_LookupDomain *r = &s->lookup;
58 /* receive samr_Connect reply */
59 c->status = dcerpc_ndr_request_recv(s->req);
60 NT_STATUS_NOT_OK_RETURN(c->status);
62 /* prepare for samr_LookupDomain call */
63 r->in.connect_handle = &s->connect_handle;
64 r->in.domain_name = &s->domain_name;
66 s->req = dcerpc_samr_LookupDomain_send(s->pipe, c, r);
67 if (s->req == NULL) goto failure;
69 s->req->async.callback = domain_open_handler;
70 s->req->async.private = c;
71 s->stage = DOMOPEN_LOOKUP;
76 return NT_STATUS_UNSUCCESSFUL;
81 * Stage 2: Lookup domain by name.
83 static NTSTATUS domain_open_lookup(struct composite_context *c,
84 struct domain_open_state *s)
86 struct samr_OpenDomain *r = &s->open;
88 /* receive samr_LookupDomain reply */
89 c->status = dcerpc_ndr_request_recv(s->req);
90 NT_STATUS_NOT_OK_RETURN(c->status);
92 /* prepare for samr_OpenDomain call */
93 r->in.connect_handle = &s->connect_handle;
94 r->in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
95 r->in.sid = s->lookup.out.sid;
96 r->out.domain_handle = &s->domain_handle;
98 s->req = dcerpc_samr_OpenDomain_send(s->pipe, c, r);
99 if (s->req == NULL) goto failure;
101 s->req->async.callback = domain_open_handler;
102 s->req->async.private = c;
103 s->stage = DOMOPEN_OPEN;
108 return NT_STATUS_UNSUCCESSFUL;
113 * Stage 3: Open domain.
115 static NTSTATUS domain_open_open(struct composite_context *c,
116 struct domain_open_state *s)
118 /* receive samr_OpenDomain reply */
119 c->status = dcerpc_ndr_request_recv(s->req);
120 NT_STATUS_NOT_OK_RETURN(c->status);
122 c->state = SMBCLI_REQUEST_DONE;
129 * Event handler for asynchronous request. Handles transition through
130 * intermediate stages of the call.
132 * @param req rpc call context
134 static void domain_open_handler(struct rpc_request *req)
136 struct composite_context *c = req->async.private;
137 struct domain_open_state *s = talloc_get_type(c->private, struct domain_open_state);
138 struct monitor_msg msg;
140 /* Stages of the call */
142 case DOMOPEN_CONNECT:
143 c->status = domain_open_connect(c, s);
146 c->status = domain_open_lookup(c, s);
149 c->status = domain_open_open(c, s);
153 if (!NT_STATUS_IS_OK(c->status)) {
154 c->state = SMBCLI_REQUEST_ERROR;
164 * Sends asynchronous domain_open request
166 * @param p dce/rpc call pipe
167 * @param io arguments and results of the call
169 struct composite_context *libnet_rpc_domain_open_send(struct dcerpc_pipe *p,
170 struct libnet_rpc_domain_open *io,
171 void (*monitor)(struct monitor_msg*))
173 struct composite_context *c;
174 struct domain_open_state *s;
176 c = talloc_zero(p, struct composite_context);
177 if (c == NULL) goto failure;
179 s = talloc_zero(c, struct domain_open_state);
180 if (c == NULL) goto failure;
182 c->state = SMBCLI_REQUEST_SEND;
184 c->event_ctx = dcerpc_event_context(p);
185 c->monitor_fn = monitor;
188 s->access_mask = io->in.access_mask;
189 s->domain_name.string = io->in.domain_name;
191 /* preparing parameters to send rpc request */
192 s->connect.in.system_name = 0;
193 s->connect.in.access_mask = s->access_mask;
194 s->connect.out.connect_handle = &s->connect_handle;
197 s->req = dcerpc_samr_Connect_send(p, c, &s->connect);
199 /* callback handler */
200 s->req->async.callback = domain_open_handler;
201 s->req->async.private = c;
202 s->stage = DOMOPEN_CONNECT;
213 * Waits for and receives result of asynchronous domain_open call
215 * @param c composite context returned by asynchronous domain_open call
216 * @param mem_ctx memory context of the call
217 * @param io pointer to results (and arguments) of the call
218 * @return nt status code of execution
220 NTSTATUS libnet_rpc_domain_open_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
221 struct libnet_rpc_domain_open *io)
224 struct domain_open_state *s;
226 /* wait for results of sending request */
227 status = composite_wait(c);
229 if (NT_STATUS_IS_OK(status) && io) {
230 s = talloc_get_type(c->private, struct domain_open_state);
231 io->out.domain_handle = s->domain_handle;
240 * Synchronous version of domain_open call
242 * @param pipe dce/rpc call pipe
243 * @param mem_ctx memory context for the call
244 * @param io arguments and results of the call
245 * @return nt status code of execution
247 NTSTATUS libnet_rpc_domain_open(struct dcerpc_pipe *p,
249 struct libnet_rpc_domain_open *io)
251 struct composite_context *c = libnet_rpc_domain_open_send(p, io, NULL);
252 return libnet_rpc_domain_open_recv(c, mem_ctx, io);