r8232: remove samr_String and netr_String as they are the same as lsa_String
[jelmer/samba4-debian.git] / source / libnet / domain.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Copyright (C) Rafal Szczesniak 2005
5    
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.
10    
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.
15    
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.
19 */
20
21 /*
22   a composite function for domain handling
23 */
24
25 #include "includes.h"
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"
31
32 static void domain_open_handler(struct rpc_request*);
33
34 enum domain_open_stage { DOMOPEN_CONNECT, DOMOPEN_LOOKUP, DOMOPEN_OPEN };
35
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;
44         uint32_t                  access_mask;
45         struct policy_handle      connect_handle;
46         struct policy_handle      domain_handle;
47 };
48
49
50 /**
51  * Stage 1: Connect to SAM server.
52  */
53 static NTSTATUS domain_open_connect(struct composite_context *c,
54                                     struct domain_open_state *s)
55 {
56         struct samr_LookupDomain *r = &s->lookup;
57
58         /* receive samr_Connect reply */
59         c->status = dcerpc_ndr_request_recv(s->req);
60         NT_STATUS_NOT_OK_RETURN(c->status);
61
62         /* prepare for samr_LookupDomain call */
63         r->in.connect_handle = &s->connect_handle;
64         r->in.domain_name    = &s->domain_name;
65
66         s->req = dcerpc_samr_LookupDomain_send(s->pipe, c, r);
67         if (s->req == NULL) goto failure;
68
69         s->req->async.callback = domain_open_handler;
70         s->req->async.private  = c;
71         s->stage = DOMOPEN_LOOKUP;
72
73         return NT_STATUS_OK;
74
75 failure:
76         return NT_STATUS_UNSUCCESSFUL;
77 }
78
79
80 /**
81  * Stage 2: Lookup domain by name.
82  */
83 static NTSTATUS domain_open_lookup(struct composite_context *c,
84                                    struct domain_open_state *s)
85 {
86         struct samr_OpenDomain *r = &s->open;
87
88         /* receive samr_LookupDomain reply */
89         c->status = dcerpc_ndr_request_recv(s->req);
90         NT_STATUS_NOT_OK_RETURN(c->status);
91
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;
97
98         s->req = dcerpc_samr_OpenDomain_send(s->pipe, c, r);
99         if (s->req == NULL) goto failure;
100
101         s->req->async.callback = domain_open_handler;
102         s->req->async.private  = c;
103         s->stage = DOMOPEN_OPEN;
104
105         return NT_STATUS_OK;
106
107 failure:
108         return NT_STATUS_UNSUCCESSFUL;
109 }
110
111
112 /*
113  * Stage 3: Open domain.
114  */
115 static NTSTATUS domain_open_open(struct composite_context *c,
116                                  struct domain_open_state *s)
117 {
118         /* receive samr_OpenDomain reply */
119         c->status = dcerpc_ndr_request_recv(s->req);
120         NT_STATUS_NOT_OK_RETURN(c->status);
121
122         c->state = SMBCLI_REQUEST_DONE;
123         
124         return NT_STATUS_OK;
125 }
126
127
128 /**
129  * Event handler for asynchronous request. Handles transition through
130  * intermediate stages of the call.
131  *
132  * @param req rpc call context
133  */
134 static void domain_open_handler(struct rpc_request *req)
135 {
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;
139
140         /* Stages of the call */
141         switch (s->stage) {
142         case DOMOPEN_CONNECT:
143                 c->status = domain_open_connect(c, s);
144                 break;
145         case DOMOPEN_LOOKUP:
146                 c->status = domain_open_lookup(c, s);
147                 break;
148         case DOMOPEN_OPEN:
149                 c->status = domain_open_open(c, s);
150                 break;
151         }
152
153         if (!NT_STATUS_IS_OK(c->status)) {
154                 c->state = SMBCLI_REQUEST_ERROR;
155         }
156
157         if (c->monitor_fn) {
158                 c->monitor_fn(&msg);
159         }
160 }
161
162
163 /**
164  * Sends asynchronous domain_open request
165  *
166  * @param p dce/rpc call pipe 
167  * @param io arguments and results of the call
168  */
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*))
172 {
173         struct composite_context *c;
174         struct domain_open_state *s;
175
176         c = talloc_zero(p, struct composite_context);
177         if (c == NULL) goto failure;
178
179         s = talloc_zero(c, struct domain_open_state);
180         if (c == NULL) goto failure;
181
182         c->state       = SMBCLI_REQUEST_SEND;
183         c->private     = s;
184         c->event_ctx   = dcerpc_event_context(p);
185         c->monitor_fn  = monitor;
186
187         s->pipe                = p;
188         s->access_mask         = io->in.access_mask;
189         s->domain_name.string  = io->in.domain_name;
190
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;
195         
196         /* send request */
197         s->req = dcerpc_samr_Connect_send(p, c, &s->connect);
198
199         /* callback handler */
200         s->req->async.callback = domain_open_handler;
201         s->req->async.private  = c;
202         s->stage = DOMOPEN_CONNECT;
203
204         return c;
205
206 failure:
207         talloc_free(c);
208         return NULL;
209 }
210
211
212 /**
213  * Waits for and receives result of asynchronous domain_open call
214  * 
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
219  */
220 NTSTATUS libnet_rpc_domain_open_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
221                                      struct libnet_rpc_domain_open *io)
222 {
223         NTSTATUS status;
224         struct domain_open_state *s;
225
226         /* wait for results of sending request */
227         status = composite_wait(c);
228         
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;
232         }
233
234         talloc_free(c);
235         return status;
236 }
237
238
239 /**
240  * Synchronous version of domain_open call
241  *
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
246  */
247 NTSTATUS libnet_rpc_domain_open(struct dcerpc_pipe *p,
248                                 TALLOC_CTX *mem_ctx,
249                                 struct libnet_rpc_domain_open *io)
250 {
251         struct composite_context *c = libnet_rpc_domain_open_send(p, io, NULL);
252         return libnet_rpc_domain_open_recv(c, mem_ctx, io);
253 }