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 on samr and lsa pipes
26 #include "libcli/composite/composite.h"
27 #include "libnet/libnet.h"
28 #include "librpc/gen_ndr/ndr_samr_c.h"
29 #include "librpc/gen_ndr/ndr_lsa_c.h"
32 struct domain_open_samr_state
{
33 struct libnet_context
*ctx
;
34 struct dcerpc_pipe
*pipe
;
35 struct libnet_RpcConnect rpcconn
;
36 struct samr_Connect connect
;
37 struct samr_LookupDomain lookup
;
38 struct samr_OpenDomain open
;
39 struct samr_Close close
;
40 struct lsa_String domain_name
;
42 struct policy_handle connect_handle
;
43 struct policy_handle domain_handle
;
45 /* information about the progress */
46 void (*monitor_fn
)(struct monitor_msg
*);
50 static void continue_domain_open_close(struct rpc_request
*req
);
51 static void continue_domain_open_connect(struct rpc_request
*req
);
52 static void continue_domain_open_lookup(struct rpc_request
*req
);
53 static void continue_domain_open_open(struct rpc_request
*req
);
57 * Stage 0.5 (optional): Connect to samr rpc pipe
59 static void continue_domain_open_rpc_connect(struct composite_context
*ctx
)
61 struct composite_context
*c
;
62 struct domain_open_samr_state
*s
;
63 struct rpc_request
*conn_req
;
65 c
= talloc_get_type(ctx
->async
.private_data
, struct composite_context
);
66 s
= talloc_get_type(c
->private_data
, struct domain_open_samr_state
);
68 c
->status
= libnet_RpcConnect_recv(ctx
, s
->ctx
, c
, &s
->rpcconn
);
69 if (!composite_is_ok(c
)) return;
71 s
->pipe
= s
->rpcconn
.out
.dcerpc_pipe
;
73 /* preparing parameters for samr_Connect rpc call */
74 s
->connect
.in
.system_name
= 0;
75 s
->connect
.in
.access_mask
= s
->access_mask
;
76 s
->connect
.out
.connect_handle
= &s
->connect_handle
;
79 conn_req
= dcerpc_samr_Connect_send(s
->pipe
, c
, &s
->connect
);
80 if (composite_nomem(conn_req
, c
)) return;
82 /* callback handler */
83 composite_continue_rpc(c
, conn_req
, continue_domain_open_connect
, c
);
88 * Stage 0.5 (optional): Close existing (in libnet context) domain
91 static void continue_domain_open_close(struct rpc_request
*req
)
93 struct composite_context
*c
;
94 struct domain_open_samr_state
*s
;
95 struct rpc_request
*conn_req
;
97 c
= talloc_get_type(req
->async
.private, struct composite_context
);
98 s
= talloc_get_type(c
->private_data
, struct domain_open_samr_state
);
100 /* receive samr_Close reply */
101 c
->status
= dcerpc_ndr_request_recv(req
);
102 if (!composite_is_ok(c
)) return;
104 /* reset domain handle and associated data in libnet_context */
105 s
->ctx
->samr
.name
= NULL
;
106 s
->ctx
->samr
.access_mask
= 0;
107 ZERO_STRUCT(s
->ctx
->samr
.handle
);
109 /* preparing parameters for samr_Connect rpc call */
110 s
->connect
.in
.system_name
= 0;
111 s
->connect
.in
.access_mask
= s
->access_mask
;
112 s
->connect
.out
.connect_handle
= &s
->connect_handle
;
115 conn_req
= dcerpc_samr_Connect_send(s
->pipe
, c
, &s
->connect
);
116 if (composite_nomem(conn_req
, c
)) return;
118 /* callback handler */
119 composite_continue_rpc(c
, conn_req
, continue_domain_open_connect
, c
);
124 * Stage 1: Connect to SAM server.
126 static void continue_domain_open_connect(struct rpc_request
*req
)
128 struct composite_context
*c
;
129 struct domain_open_samr_state
*s
;
130 struct rpc_request
*lookup_req
;
131 struct samr_LookupDomain
*r
;
133 c
= talloc_get_type(req
->async
.private, struct composite_context
);
134 s
= talloc_get_type(c
->private_data
, struct domain_open_samr_state
);
136 /* receive samr_Connect reply */
137 c
->status
= dcerpc_ndr_request_recv(req
);
138 if (!composite_is_ok(c
)) return;
142 /* prepare for samr_LookupDomain call */
143 r
->in
.connect_handle
= &s
->connect_handle
;
144 r
->in
.domain_name
= &s
->domain_name
;
146 lookup_req
= dcerpc_samr_LookupDomain_send(s
->pipe
, c
, r
);
147 if (composite_nomem(lookup_req
, c
)) return;
149 composite_continue_rpc(c
, lookup_req
, continue_domain_open_lookup
, c
);
154 * Stage 2: Lookup domain by name.
156 static void continue_domain_open_lookup(struct rpc_request
*req
)
158 struct composite_context
*c
;
159 struct domain_open_samr_state
*s
;
160 struct rpc_request
*opendom_req
;
161 struct samr_OpenDomain
*r
;
163 c
= talloc_get_type(req
->async
.private, struct composite_context
);
164 s
= talloc_get_type(c
->private_data
, struct domain_open_samr_state
);
166 /* receive samr_LookupDomain reply */
167 c
->status
= dcerpc_ndr_request_recv(req
);
171 /* check the rpc layer status */
172 if (!composite_is_ok(c
));
174 /* check the rpc call itself status */
175 if (!NT_STATUS_IS_OK(s
->lookup
.out
.result
)) {
176 composite_error(c
, s
->lookup
.out
.result
);
180 /* prepare for samr_OpenDomain call */
181 r
->in
.connect_handle
= &s
->connect_handle
;
182 r
->in
.access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
183 r
->in
.sid
= s
->lookup
.out
.sid
;
184 r
->out
.domain_handle
= &s
->domain_handle
;
186 opendom_req
= dcerpc_samr_OpenDomain_send(s
->pipe
, c
, r
);
187 if (composite_nomem(opendom_req
, c
)) return;
189 composite_continue_rpc(c
, opendom_req
, continue_domain_open_open
, c
);
194 * Stage 3: Open domain.
196 static void continue_domain_open_open(struct rpc_request
*req
)
198 struct composite_context
*c
;
199 struct domain_open_samr_state
*s
;
201 c
= talloc_get_type(req
->async
.private, struct composite_context
);
202 s
= talloc_get_type(c
->private_data
, struct domain_open_samr_state
);
204 /* receive samr_OpenDomain reply */
205 c
->status
= dcerpc_ndr_request_recv(req
);
206 if (!composite_is_ok(c
)) return;
213 * Sends asynchronous DomainOpenSamr request
215 * @param ctx initialised libnet context
216 * @param io arguments and results of the call
217 * @param monitor pointer to monitor function that is passed monitor message
220 struct composite_context
*libnet_DomainOpenSamr_send(struct libnet_context
*ctx
,
221 struct libnet_DomainOpen
*io
,
222 void (*monitor
)(struct monitor_msg
*))
224 struct composite_context
*c
;
225 struct domain_open_samr_state
*s
;
226 struct composite_context
*rpcconn_req
;
227 struct rpc_request
*close_req
, *conn_req
;
229 c
= composite_create(ctx
, ctx
->event_ctx
);
230 if (c
== NULL
) return NULL
;
232 s
= talloc_zero(c
, struct domain_open_samr_state
);
233 if (composite_nomem(s
, c
)) return c
;
236 s
->monitor_fn
= monitor
;
239 s
->pipe
= ctx
->samr
.pipe
;
240 s
->access_mask
= io
->in
.access_mask
;
241 s
->domain_name
.string
= talloc_strdup(c
, io
->in
.domain_name
);
243 /* check, if there's samr pipe opened already, before opening a domain */
244 if (ctx
->samr
.pipe
== NULL
) {
246 /* attempting to connect a domain controller */
247 s
->rpcconn
.level
= LIBNET_RPC_CONNECT_DC
;
248 s
->rpcconn
.in
.name
= io
->in
.domain_name
;
249 s
->rpcconn
.in
.dcerpc_iface
= &dcerpc_table_samr
;
251 /* send rpc pipe connect request */
252 rpcconn_req
= libnet_RpcConnect_send(ctx
, c
, &s
->rpcconn
);
253 if (composite_nomem(rpcconn_req
, c
)) return c
;
255 composite_continue(c
, rpcconn_req
, continue_domain_open_rpc_connect
, c
);
259 /* libnet context's domain handle is not empty, so check out what
260 was opened first, before doing anything */
261 if (!policy_handle_empty(&ctx
->samr
.handle
)) {
262 if (strequal(ctx
->samr
.name
, io
->in
.domain_name
) &&
263 ctx
->samr
.access_mask
== io
->in
.access_mask
) {
265 /* this domain is already opened */
270 /* another domain or access rights have been
271 requested - close the existing handle first */
272 s
->close
.in
.handle
= &ctx
->samr
.handle
;
274 /* send request to close domain handle */
275 close_req
= dcerpc_samr_Close_send(s
->pipe
, c
, &s
->close
);
276 if (composite_nomem(close_req
, c
)) return c
;
278 /* callback handler */
279 composite_continue_rpc(c
, close_req
, continue_domain_open_close
, c
);
284 /* preparing parameters for samr_Connect rpc call */
285 s
->connect
.in
.system_name
= 0;
286 s
->connect
.in
.access_mask
= s
->access_mask
;
287 s
->connect
.out
.connect_handle
= &s
->connect_handle
;
290 conn_req
= dcerpc_samr_Connect_send(s
->pipe
, c
, &s
->connect
);
291 if (composite_nomem(conn_req
, c
)) return c
;
293 /* callback handler */
294 composite_continue_rpc(c
, conn_req
, continue_domain_open_connect
, c
);
300 * Waits for and receives result of asynchronous DomainOpenSamr call
302 * @param c composite context returned by asynchronous DomainOpen call
303 * @param ctx initialised libnet context
304 * @param mem_ctx memory context of the call
305 * @param io pointer to results (and arguments) of the call
306 * @return nt status code of execution
309 NTSTATUS
libnet_DomainOpenSamr_recv(struct composite_context
*c
, struct libnet_context
*ctx
,
310 TALLOC_CTX
*mem_ctx
, struct libnet_DomainOpen
*io
)
313 struct domain_open_samr_state
*s
;
315 /* wait for results of sending request */
316 status
= composite_wait(c
);
318 if (NT_STATUS_IS_OK(status
) && io
) {
319 s
= talloc_get_type(c
->private_data
, struct domain_open_samr_state
);
320 io
->out
.domain_handle
= s
->domain_handle
;
322 /* store the resulting handle and related data for use by other
324 ctx
->samr
.handle
= s
->domain_handle
;
325 ctx
->samr
.name
= talloc_steal(ctx
, s
->domain_name
.string
);
326 ctx
->samr
.access_mask
= s
->access_mask
;
334 struct domain_open_lsa_state
{
336 uint32_t access_mask
;
337 struct libnet_context
*ctx
;
338 struct libnet_RpcConnect rpcconn
;
339 struct lsa_OpenPolicy2 openpol
;
340 struct policy_handle handle
;
341 struct dcerpc_pipe
*pipe
;
343 /* information about the progress */
344 void (*monitor_fn
)(struct monitor_msg
*);
348 static void continue_rpc_connect_lsa(struct composite_context
*ctx
);
349 static void continue_lsa_policy_open(struct rpc_request
*req
);
353 * Sends asynchronous DomainOpenLsa request
355 * @param ctx initialised libnet context
356 * @param io arguments and results of the call
357 * @param monitor pointer to monitor function that is passed monitor message
360 struct composite_context
* libnet_DomainOpenLsa_send(struct libnet_context
*ctx
,
361 struct libnet_DomainOpen
*io
,
362 void (*monitor
)(struct monitor_msg
*))
364 struct composite_context
*c
;
365 struct domain_open_lsa_state
*s
;
366 struct composite_context
*rpcconn_req
;
367 struct rpc_request
*openpol_req
;
368 struct lsa_QosInfo
*qos
;
370 /* create composite context and state */
371 c
= composite_create(ctx
, ctx
->event_ctx
);
372 if (c
== NULL
) return c
;
374 s
= talloc_zero(c
, struct domain_open_lsa_state
);
375 if (composite_nomem(s
, c
)) return c
;
379 /* store arguments in the state structure */
380 s
->name
= talloc_strdup(c
, io
->in
.domain_name
);
381 s
->access_mask
= io
->in
.access_mask
;
384 /* check, if there's lsa pipe opened already, before opening a handle */
385 if (ctx
->lsa
.pipe
== NULL
) {
387 /* attempting to connect a domain controller */
388 s
->rpcconn
.level
= LIBNET_RPC_CONNECT_DC
;
389 s
->rpcconn
.in
.name
= talloc_strdup(c
, io
->in
.domain_name
);
390 s
->rpcconn
.in
.dcerpc_iface
= &dcerpc_table_lsarpc
;
392 /* send rpc pipe connect request */
393 rpcconn_req
= libnet_RpcConnect_send(ctx
, c
, &s
->rpcconn
);
394 if (composite_nomem(rpcconn_req
, c
)) return c
;
396 composite_continue(c
, rpcconn_req
, continue_rpc_connect_lsa
, c
);
400 s
->pipe
= ctx
->lsa
.pipe
;
402 /* preparing parameters for lsa_OpenPolicy2 rpc call */
403 s
->openpol
.in
.system_name
= s
->name
;
404 s
->openpol
.in
.access_mask
= s
->access_mask
;
405 s
->openpol
.in
.attr
= talloc_zero(c
, struct lsa_ObjectAttribute
);
407 qos
= talloc_zero(c
, struct lsa_QosInfo
);
409 qos
->impersonation_level
= 2;
410 qos
->context_mode
= 1;
411 qos
->effective_only
= 0;
413 s
->openpol
.in
.attr
->sec_qos
= qos
;
414 s
->openpol
.out
.handle
= &s
->handle
;
416 /* send rpc request */
417 openpol_req
= dcerpc_lsa_OpenPolicy2_send(s
->pipe
, c
, &s
->openpol
);
418 if (composite_nomem(openpol_req
, c
)) return c
;
420 composite_continue_rpc(c
, openpol_req
, continue_lsa_policy_open
, c
);
426 Stage 0.5 (optional): Rpc pipe connected, send lsa open policy request
428 static void continue_rpc_connect_lsa(struct composite_context
*ctx
)
430 struct composite_context
*c
;
431 struct domain_open_lsa_state
*s
;
432 struct lsa_QosInfo
*qos
;
433 struct rpc_request
*openpol_req
;
435 c
= talloc_get_type(ctx
->async
.private_data
, struct composite_context
);
436 s
= talloc_get_type(c
->private_data
, struct domain_open_lsa_state
);
438 /* receive rpc connection */
439 c
->status
= libnet_RpcConnect_recv(ctx
, s
->ctx
, c
, &s
->rpcconn
);
440 if (!composite_is_ok(c
)) return;
442 /* RpcConnect function leaves the pipe in libnet context,
443 so get it from there */
444 s
->pipe
= s
->ctx
->lsa
.pipe
;
446 /* prepare lsa_OpenPolicy2 call */
447 s
->openpol
.in
.system_name
= s
->name
;
448 s
->openpol
.in
.access_mask
= s
->access_mask
;
449 s
->openpol
.in
.attr
= talloc_zero(c
, struct lsa_ObjectAttribute
);
451 qos
= talloc_zero(c
, struct lsa_QosInfo
);
453 qos
->impersonation_level
= 2;
454 qos
->context_mode
= 1;
455 qos
->effective_only
= 0;
457 s
->openpol
.in
.attr
->sec_qos
= qos
;
458 s
->openpol
.out
.handle
= &s
->handle
;
460 /* send rpc request */
461 openpol_req
= dcerpc_lsa_OpenPolicy2_send(s
->pipe
, c
, &s
->openpol
);
462 if (composite_nomem(openpol_req
, c
)) return;
464 composite_continue_rpc(c
, openpol_req
, continue_lsa_policy_open
, c
);
469 Stage 1: Lsa policy opened - we're done, if successfully
471 static void continue_lsa_policy_open(struct rpc_request
*req
)
473 struct composite_context
*c
;
474 struct domain_open_lsa_state
*s
;
476 c
= talloc_get_type(req
->async
.private, struct composite_context
);
477 s
= talloc_get_type(c
->private_data
, struct domain_open_lsa_state
);
479 c
->status
= dcerpc_ndr_request_recv(req
);
480 if (!composite_is_ok(c
)) return;
487 * Receives result of asynchronous DomainOpenLsa call
489 * @param c composite context returned by asynchronous DomainOpenLsa call
490 * @param ctx initialised libnet context
491 * @param mem_ctx memory context of the call
492 * @param io pointer to results (and arguments) of the call
493 * @return nt status code of execution
496 NTSTATUS
libnet_DomainOpenLsa_recv(struct composite_context
*c
, struct libnet_context
*ctx
,
497 TALLOC_CTX
*mem_ctx
, struct libnet_DomainOpen
*io
)
500 struct domain_open_lsa_state
*s
;
502 status
= composite_wait(c
);
504 if (NT_STATUS_IS_OK(status
) && io
) {
505 /* everything went fine - get the results and
506 return the error string */
507 s
= talloc_get_type(c
->private_data
, struct domain_open_lsa_state
);
508 io
->out
.domain_handle
= s
->handle
;
510 ctx
->lsa
.handle
= s
->handle
;
511 ctx
->lsa
.name
= talloc_steal(ctx
, s
->name
);
512 ctx
->lsa
.access_mask
= s
->access_mask
;
514 io
->out
.error_string
= talloc_strdup(mem_ctx
, "Success");
516 } else if (!NT_STATUS_IS_OK(status
)) {
517 /* there was an error, so provide nt status code description */
518 io
->out
.error_string
= talloc_asprintf(mem_ctx
,
519 "Failed to open domain: %s",
529 * Sends a request to open a domain in desired service
531 * @param ctx initalised libnet context
532 * @param io arguments and results of the call
533 * @param monitor pointer to monitor function that is passed monitor message
536 struct composite_context
* libnet_DomainOpen_send(struct libnet_context
*ctx
,
537 struct libnet_DomainOpen
*io
,
538 void (*monitor
)(struct monitor_msg
*))
540 struct composite_context
*c
;
542 switch (io
->in
.type
) {
544 /* reques to open a policy handle on \pipe\lsarpc */
545 c
= libnet_DomainOpenLsa_send(ctx
, io
, monitor
);
550 /* request to open a domain policy handle on \pipe\samr */
551 c
= libnet_DomainOpenSamr_send(ctx
, io
, monitor
);
560 * Receive result of domain open request
562 * @param c composite context returned by DomainOpen_send function
563 * @param ctx initialised libnet context
564 * @param mem_ctx memory context of the call
565 * @param io results and arguments of the call
568 NTSTATUS
libnet_DomainOpen_recv(struct composite_context
*c
, struct libnet_context
*ctx
,
569 TALLOC_CTX
*mem_ctx
, struct libnet_DomainOpen
*io
)
573 switch (io
->in
.type
) {
575 status
= libnet_DomainOpenLsa_recv(c
, ctx
, mem_ctx
, io
);
580 status
= libnet_DomainOpenSamr_recv(c
, ctx
, mem_ctx
, io
);
589 * Synchronous version of DomainOpen call
591 * @param ctx initialised libnet context
592 * @param mem_ctx memory context for the call
593 * @param io arguments and results of the call
594 * @return nt status code of execution
597 NTSTATUS
libnet_DomainOpen(struct libnet_context
*ctx
,
599 struct libnet_DomainOpen
*io
)
601 struct composite_context
*c
= libnet_DomainOpen_send(ctx
, io
, NULL
);
602 return libnet_DomainOpen_recv(c
, ctx
, mem_ctx
, io
);
606 struct domain_close_lsa_state
{
607 struct dcerpc_pipe
*pipe
;
608 struct lsa_Close close
;
609 struct policy_handle handle
;
611 void (*monitor_fn
)(struct monitor_msg
*);
615 static void continue_lsa_close(struct rpc_request
*req
);
618 struct composite_context
* libnet_DomainCloseLsa_send(struct libnet_context
*ctx
,
619 struct libnet_DomainClose
*io
,
620 void (*monitor
)(struct monitor_msg
*))
622 struct composite_context
*c
;
623 struct domain_close_lsa_state
*s
;
624 struct rpc_request
*close_req
;
626 /* composite context and state structure allocation */
627 c
= composite_create(ctx
, ctx
->event_ctx
);
628 if (c
== NULL
) return c
;
630 s
= talloc_zero(c
, struct domain_close_lsa_state
);
631 if (composite_nomem(s
, c
)) return c
;
634 s
->monitor_fn
= monitor
;
636 /* TODO: check if lsa pipe pointer is non-null */
638 if (!strequal(ctx
->lsa
.name
, io
->in
.domain_name
)) {
639 composite_error(c
, NT_STATUS_INVALID_PARAMETER
);
643 /* get opened lsarpc pipe pointer */
644 s
->pipe
= ctx
->lsa
.pipe
;
646 /* prepare close handle call arguments */
647 s
->close
.in
.handle
= &ctx
->lsa
.handle
;
648 s
->close
.out
.handle
= &s
->handle
;
650 /* send the request */
651 close_req
= dcerpc_lsa_Close_send(s
->pipe
, c
, &s
->close
);
652 if (composite_nomem(close_req
, c
)) return c
;
654 composite_continue_rpc(c
, close_req
, continue_lsa_close
, c
);
660 Stage 1: Receive result of lsa close call
662 static void continue_lsa_close(struct rpc_request
*req
)
664 struct composite_context
*c
;
665 struct domain_close_lsa_state
*s
;
667 c
= talloc_get_type(req
->async
.private, struct composite_context
);
668 s
= talloc_get_type(c
->private_data
, struct domain_close_lsa_state
);
670 c
->status
= dcerpc_ndr_request_recv(req
);
671 if (!composite_is_ok(c
)) return;
677 NTSTATUS
libnet_DomainCloseLsa_recv(struct composite_context
*c
, struct libnet_context
*ctx
,
678 TALLOC_CTX
*mem_ctx
, struct libnet_DomainClose
*io
)
682 status
= composite_wait(c
);
684 if (NT_STATUS_IS_OK(status
) && io
) {
685 /* policy handle closed successfully */
687 ctx
->lsa
.name
= NULL
;
688 ZERO_STRUCT(ctx
->lsa
.handle
);
690 io
->out
.error_string
= talloc_asprintf(mem_ctx
, "Success");
692 } else if (!NT_STATUS_IS_OK(status
)) {
693 /* there was an error, so return description of the status code */
694 io
->out
.error_string
= talloc_asprintf(mem_ctx
, "Error: %s", nt_errstr(status
));
702 struct domain_close_samr_state
{
703 struct samr_Close close
;
704 struct policy_handle handle
;
706 void (*monitor_fn
)(struct monitor_msg
*);
710 static void continue_samr_close(struct rpc_request
*req
);
713 struct composite_context
* libnet_DomainCloseSamr_send(struct libnet_context
*ctx
,
714 struct libnet_DomainClose
*io
,
715 void (*monitor
)(struct monitor_msg
*))
717 struct composite_context
*c
;
718 struct domain_close_samr_state
*s
;
719 struct rpc_request
*close_req
;
721 /* composite context and state structure allocation */
722 c
= composite_create(ctx
, ctx
->event_ctx
);
723 if (c
== NULL
) return c
;
725 s
= talloc_zero(c
, struct domain_close_samr_state
);
726 if (composite_nomem(s
, c
)) return c
;
729 s
->monitor_fn
= monitor
;
731 /* TODO: check if samr pipe pointer is non-null */
733 if (!strequal(ctx
->samr
.name
, io
->in
.domain_name
)) {
734 composite_error(c
, NT_STATUS_INVALID_PARAMETER
);
738 /* prepare close domain handle call arguments */
739 ZERO_STRUCT(s
->close
);
740 s
->close
.in
.handle
= &ctx
->samr
.handle
;
741 s
->close
.out
.handle
= &s
->handle
;
743 /* send the request */
744 close_req
= dcerpc_samr_Close_send(ctx
->samr
.pipe
, ctx
, &s
->close
);
745 if (composite_nomem(close_req
, c
)) return c
;
747 composite_continue_rpc(c
, close_req
, continue_samr_close
, c
);
753 Stage 1: Receive result of samr close call
755 static void continue_samr_close(struct rpc_request
*req
)
757 struct composite_context
*c
;
758 struct domain_close_samr_state
*s
;
760 c
= talloc_get_type(req
->async
.private, struct composite_context
);
761 s
= talloc_get_type(c
->private_data
, struct domain_close_samr_state
);
763 c
->status
= dcerpc_ndr_request_recv(req
);
764 if (!composite_is_ok(c
)) return;
770 NTSTATUS
libnet_DomainCloseSamr_recv(struct composite_context
*c
, struct libnet_context
*ctx
,
771 TALLOC_CTX
*mem_ctx
, struct libnet_DomainClose
*io
)
775 status
= composite_wait(c
);
777 if (NT_STATUS_IS_OK(status
) && io
) {
778 /* domain policy handle closed successfully */
780 ZERO_STRUCT(ctx
->samr
.handle
);
781 ctx
->samr
.name
= NULL
;
783 io
->out
.error_string
= talloc_asprintf(mem_ctx
, "Success");
785 } else if (!NT_STATUS_IS_OK(status
)) {
786 /* there was an error, so return description of the status code */
787 io
->out
.error_string
= talloc_asprintf(mem_ctx
, "Error: %s", nt_errstr(status
));
795 struct composite_context
* libnet_DomainClose_send(struct libnet_context
*ctx
,
796 struct libnet_DomainClose
*io
,
797 void (*monitor
)(struct monitor_msg
*))
799 struct composite_context
*c
;
801 switch (io
->in
.type
) {
803 /* request to close policy handle on \pipe\lsarpc */
804 c
= libnet_DomainCloseLsa_send(ctx
, io
, monitor
);
809 /* request to close domain policy handle on \pipe\samr */
810 c
= libnet_DomainCloseSamr_send(ctx
, io
, monitor
);
818 NTSTATUS
libnet_DomainClose_recv(struct composite_context
*c
, struct libnet_context
*ctx
,
819 TALLOC_CTX
*mem_ctx
, struct libnet_DomainClose
*io
)
823 switch (io
->in
.type
) {
825 /* receive result of closing lsa policy handle */
826 status
= libnet_DomainCloseLsa_recv(c
, ctx
, mem_ctx
, io
);
831 /* receive result of closing samr domain policy handle */
832 status
= libnet_DomainCloseSamr_recv(c
, ctx
, mem_ctx
, io
);
840 NTSTATUS
libnet_DomainClose(struct libnet_context
*ctx
, TALLOC_CTX
*mem_ctx
,
841 struct libnet_DomainClose
*io
)
843 struct composite_context
*c
;
845 c
= libnet_DomainClose_send(ctx
, io
, NULL
);
846 return libnet_DomainClose_recv(c
, ctx
, mem_ctx
, io
);