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/composite/composite.h"
27 #include "libnet/composite.h"
29 static void domain_open_handler(struct rpc_request*);
31 enum domain_open_stage { DOMOPEN_CONNECT, DOMOPEN_LOOKUP, DOMOPEN_OPEN };
33 struct domain_open_state {
34 enum domain_open_stage stage;
35 struct dcerpc_pipe *pipe;
36 struct rpc_request *req;
37 struct samr_Connect connect;
38 struct samr_LookupDomain lookup;
39 struct samr_OpenDomain open;
40 struct lsa_String domain_name;
42 struct policy_handle connect_handle;
43 struct policy_handle domain_handle;
48 * Stage 1: Connect to SAM server.
50 static NTSTATUS domain_open_connect(struct composite_context *c,
51 struct domain_open_state *s)
53 struct samr_LookupDomain *r = &s->lookup;
55 /* receive samr_Connect reply */
56 c->status = dcerpc_ndr_request_recv(s->req);
57 NT_STATUS_NOT_OK_RETURN(c->status);
59 /* prepare for samr_LookupDomain call */
60 r->in.connect_handle = &s->connect_handle;
61 r->in.domain_name = &s->domain_name;
63 s->req = dcerpc_samr_LookupDomain_send(s->pipe, c, r);
64 if (s->req == NULL) goto failure;
66 s->req->async.callback = domain_open_handler;
67 s->req->async.private = c;
68 s->stage = DOMOPEN_LOOKUP;
73 return NT_STATUS_UNSUCCESSFUL;
78 * Stage 2: Lookup domain by name.
80 static NTSTATUS domain_open_lookup(struct composite_context *c,
81 struct domain_open_state *s)
83 struct samr_OpenDomain *r = &s->open;
85 /* receive samr_LookupDomain reply */
86 c->status = dcerpc_ndr_request_recv(s->req);
87 NT_STATUS_NOT_OK_RETURN(c->status);
89 /* prepare for samr_OpenDomain call */
90 r->in.connect_handle = &s->connect_handle;
91 r->in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
92 r->in.sid = s->lookup.out.sid;
93 r->out.domain_handle = &s->domain_handle;
95 s->req = dcerpc_samr_OpenDomain_send(s->pipe, c, r);
96 if (s->req == NULL) goto failure;
98 s->req->async.callback = domain_open_handler;
99 s->req->async.private = c;
100 s->stage = DOMOPEN_OPEN;
105 return NT_STATUS_UNSUCCESSFUL;
110 * Stage 3: Open domain.
112 static NTSTATUS domain_open_open(struct composite_context *c,
113 struct domain_open_state *s)
115 /* receive samr_OpenDomain reply */
116 c->status = dcerpc_ndr_request_recv(s->req);
117 NT_STATUS_NOT_OK_RETURN(c->status);
119 c->state = COMPOSITE_STATE_DONE;
126 * Event handler for asynchronous request. Handles transition through
127 * intermediate stages of the call.
129 * @param req rpc call context
131 static void domain_open_handler(struct rpc_request *req)
133 struct composite_context *c = req->async.private;
134 struct domain_open_state *s = talloc_get_type(c->private_data, struct domain_open_state);
136 /* Stages of the call */
138 case DOMOPEN_CONNECT:
139 c->status = domain_open_connect(c, s);
142 c->status = domain_open_lookup(c, s);
145 c->status = domain_open_open(c, s);
149 if (!NT_STATUS_IS_OK(c->status)) {
150 c->state = COMPOSITE_STATE_ERROR;
156 * Sends asynchronous domain_open request
158 * @param p dce/rpc call pipe
159 * @param io arguments and results of the call
161 struct composite_context *libnet_rpc_domain_open_send(struct dcerpc_pipe *p,
162 struct libnet_rpc_domain_open *io,
163 void (*monitor)(struct monitor_msg*))
165 struct composite_context *c;
166 struct domain_open_state *s;
168 c = talloc_zero(p, struct composite_context);
169 if (c == NULL) goto failure;
171 s = talloc_zero(c, struct domain_open_state);
172 if (s == NULL) goto failure;
174 c->state = COMPOSITE_STATE_IN_PROGRESS;
176 c->event_ctx = dcerpc_event_context(p);
179 s->access_mask = io->in.access_mask;
180 s->domain_name.string = io->in.domain_name;
182 /* preparing parameters to send rpc request */
183 s->connect.in.system_name = 0;
184 s->connect.in.access_mask = s->access_mask;
185 s->connect.out.connect_handle = &s->connect_handle;
188 s->req = dcerpc_samr_Connect_send(p, c, &s->connect);
190 /* callback handler */
191 s->req->async.callback = domain_open_handler;
192 s->req->async.private = c;
193 s->stage = DOMOPEN_CONNECT;
204 * Waits for and receives result of asynchronous domain_open call
206 * @param c composite context returned by asynchronous domain_open call
207 * @param mem_ctx memory context of the call
208 * @param io pointer to results (and arguments) of the call
209 * @return nt status code of execution
211 NTSTATUS libnet_rpc_domain_open_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
212 struct libnet_rpc_domain_open *io)
215 struct domain_open_state *s;
217 /* wait for results of sending request */
218 status = composite_wait(c);
220 if (NT_STATUS_IS_OK(status) && io) {
221 s = talloc_get_type(c->private_data, struct domain_open_state);
222 io->out.domain_handle = s->domain_handle;
231 * Synchronous version of domain_open call
233 * @param pipe dce/rpc call pipe
234 * @param mem_ctx memory context for the call
235 * @param io arguments and results of the call
236 * @return nt status code of execution
238 NTSTATUS libnet_rpc_domain_open(struct dcerpc_pipe *p,
240 struct libnet_rpc_domain_open *io)
242 struct composite_context *c = libnet_rpc_domain_open_send(p, io, NULL);
243 return libnet_rpc_domain_open_recv(c, mem_ctx, io);