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"
31 static void domain_open_handler(struct rpc_request*);
33 enum domain_open_stage { DOMOPEN_CONNECT, DOMOPEN_LOOKUP, DOMOPEN_OPEN,
34 DOMOPEN_CLOSE_EXISTING, DOMOPEN_RPC_CONNECT };
36 struct domain_open_samr_state {
37 enum domain_open_stage stage;
38 struct libnet_context *ctx;
39 struct dcerpc_pipe *pipe;
40 struct rpc_request *req;
41 struct composite_context *rpcconn_req;
42 struct samr_Connect connect;
43 struct samr_LookupDomain lookup;
44 struct samr_OpenDomain open;
45 struct samr_Close close;
46 struct libnet_RpcConnect rpcconn;
47 struct lsa_String domain_name;
49 struct policy_handle connect_handle;
50 struct policy_handle domain_handle;
52 /* information about the progress */
53 void (*monitor_fn)(struct monitor_msg*);
58 * Stage 0.5 (optional): Connect to samr rpc pipe
60 static void domain_open_rpc_connect(struct composite_context *ctx)
62 struct composite_context *c;
63 struct domain_open_samr_state *s;
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 s->req = dcerpc_samr_Connect_send(s->pipe, c, &s->connect);
80 if (composite_nomem(s->req, c)) return;
82 /* callback handler */
83 s->req->async.callback = domain_open_handler;
84 s->req->async.private = c;
85 s->stage = DOMOPEN_CONNECT;
90 * Stage 0.5 (optional): Close existing (in libnet context) domain
93 static NTSTATUS domain_open_close(struct composite_context *c,
94 struct domain_open_samr_state *s)
96 /* receive samr_Close reply */
97 c->status = dcerpc_ndr_request_recv(s->req);
98 NT_STATUS_NOT_OK_RETURN(c->status);
100 /* reset domain handle and associated data in libnet_context */
101 s->ctx->samr.name = NULL;
102 s->ctx->samr.access_mask = 0;
103 ZERO_STRUCT(s->ctx->samr.handle);
105 /* preparing parameters for samr_Connect rpc call */
106 s->connect.in.system_name = 0;
107 s->connect.in.access_mask = s->access_mask;
108 s->connect.out.connect_handle = &s->connect_handle;
111 s->req = dcerpc_samr_Connect_send(s->pipe, c, &s->connect);
112 if (s->req == NULL) return NT_STATUS_NO_MEMORY;
114 /* callback handler */
115 s->req->async.callback = domain_open_handler;
116 s->req->async.private = c;
117 s->stage = DOMOPEN_CONNECT;
124 * Stage 1: Connect to SAM server.
126 static NTSTATUS domain_open_connect(struct composite_context *c,
127 struct domain_open_samr_state *s)
129 struct samr_LookupDomain *r = &s->lookup;
131 /* receive samr_Connect reply */
132 c->status = dcerpc_ndr_request_recv(s->req);
133 NT_STATUS_NOT_OK_RETURN(c->status);
135 /* prepare for samr_LookupDomain call */
136 r->in.connect_handle = &s->connect_handle;
137 r->in.domain_name = &s->domain_name;
139 s->req = dcerpc_samr_LookupDomain_send(s->pipe, c, r);
140 if (s->req == NULL) goto failure;
142 s->req->async.callback = domain_open_handler;
143 s->req->async.private = c;
144 s->stage = DOMOPEN_LOOKUP;
149 return NT_STATUS_UNSUCCESSFUL;
154 * Stage 2: Lookup domain by name.
156 static NTSTATUS domain_open_lookup(struct composite_context *c,
157 struct domain_open_samr_state *s)
159 struct samr_OpenDomain *r = &s->open;
161 /* receive samr_LookupDomain reply */
162 c->status = dcerpc_ndr_request_recv(s->req);
163 NT_STATUS_NOT_OK_RETURN(c->status);
165 /* prepare for samr_OpenDomain call */
166 r->in.connect_handle = &s->connect_handle;
167 r->in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
168 r->in.sid = s->lookup.out.sid;
169 r->out.domain_handle = &s->domain_handle;
171 s->req = dcerpc_samr_OpenDomain_send(s->pipe, c, r);
172 if (s->req == NULL) goto failure;
174 s->req->async.callback = domain_open_handler;
175 s->req->async.private = c;
176 s->stage = DOMOPEN_OPEN;
181 return NT_STATUS_UNSUCCESSFUL;
186 * Stage 3: Open domain.
188 static NTSTATUS domain_open_open(struct composite_context *c,
189 struct domain_open_samr_state *s)
191 /* receive samr_OpenDomain reply */
192 c->status = dcerpc_ndr_request_recv(s->req);
193 NT_STATUS_NOT_OK_RETURN(c->status);
195 c->state = COMPOSITE_STATE_DONE;
202 * Event handler for asynchronous request. Handles transition through
203 * intermediate stages of the call.
205 * @param req rpc call context
207 static void domain_open_handler(struct rpc_request *req)
209 struct composite_context *c = req->async.private;
210 struct domain_open_samr_state *s = talloc_get_type(c->private_data,
211 struct domain_open_samr_state);
213 /* Stages of the call */
215 case DOMOPEN_CONNECT:
216 c->status = domain_open_connect(c, s);
219 c->status = domain_open_lookup(c, s);
222 c->status = domain_open_open(c, s);
224 case DOMOPEN_CLOSE_EXISTING:
225 c->status = domain_open_close(c, s);
227 case DOMOPEN_RPC_CONNECT:
228 /* this state shouldn't be handled here */
229 c->status = NT_STATUS_UNSUCCESSFUL;
233 if (!NT_STATUS_IS_OK(c->status)) {
234 c->state = COMPOSITE_STATE_ERROR;
237 if (c->state == COMPOSITE_STATE_DONE) {
244 * Sends asynchronous DomainOpenSamr request
246 * @param ctx initialised libnet context
247 * @param io arguments and results of the call
248 * @param monitor pointer to monitor function that is passed monitor message
251 struct composite_context *libnet_DomainOpenSamr_send(struct libnet_context *ctx,
252 struct libnet_DomainOpen *io,
253 void (*monitor)(struct monitor_msg*))
255 struct composite_context *c;
256 struct domain_open_samr_state *s;
258 c = composite_create(ctx, ctx->event_ctx);
259 if (c == NULL) return NULL;
261 s = talloc_zero(c, struct domain_open_samr_state);
262 if (composite_nomem(s, c)) return c;
265 s->monitor_fn = monitor;
268 s->pipe = ctx->samr.pipe;
269 s->access_mask = io->in.access_mask;
270 s->domain_name.string = talloc_strdup(c, io->in.domain_name);
272 /* check, if there's samr pipe opened already, before opening a domain */
273 if (ctx->samr.pipe == NULL) {
275 /* attempting to connect a domain controller */
276 s->rpcconn.level = LIBNET_RPC_CONNECT_DC;
277 s->rpcconn.in.name = io->in.domain_name;
278 s->rpcconn.in.dcerpc_iface = &dcerpc_table_samr;
280 /* send rpc pipe connect request */
281 s->rpcconn_req = libnet_RpcConnect_send(ctx, c, &s->rpcconn);
282 if (composite_nomem(s->rpcconn_req, c)) return c;
284 s->rpcconn_req->async.fn = domain_open_rpc_connect;
285 s->rpcconn_req->async.private_data = c;
286 s->stage = DOMOPEN_RPC_CONNECT;
291 /* libnet context's domain handle is not empty, so check out what
292 was opened first, before doing anything */
293 if (!policy_handle_empty(&ctx->samr.handle)) {
294 if (strequal(ctx->samr.name, io->in.domain_name) &&
295 ctx->samr.access_mask == io->in.access_mask) {
297 /* this domain is already opened */
302 /* another domain or access rights have been
303 requested - close the existing handle first */
304 s->close.in.handle = &ctx->samr.handle;
306 /* send request to close domain handle */
307 s->req = dcerpc_samr_Close_send(s->pipe, c, &s->close);
308 if (composite_nomem(s->req, c)) return c;
310 /* callback handler */
311 s->req->async.callback = domain_open_handler;
312 s->req->async.private = c;
313 s->stage = DOMOPEN_CLOSE_EXISTING;
319 /* preparing parameters for samr_Connect rpc call */
320 s->connect.in.system_name = 0;
321 s->connect.in.access_mask = s->access_mask;
322 s->connect.out.connect_handle = &s->connect_handle;
325 s->req = dcerpc_samr_Connect_send(s->pipe, c, &s->connect);
326 if (composite_nomem(s->req, c)) return c;
328 /* callback handler */
329 s->req->async.callback = domain_open_handler;
330 s->req->async.private = c;
331 s->stage = DOMOPEN_CONNECT;
338 * Waits for and receives result of asynchronous DomainOpenSamr call
340 * @param c composite context returned by asynchronous DomainOpen call
341 * @param ctx initialised libnet context
342 * @param mem_ctx memory context of the call
343 * @param io pointer to results (and arguments) of the call
344 * @return nt status code of execution
347 NTSTATUS libnet_DomainOpenSamr_recv(struct composite_context *c, struct libnet_context *ctx,
348 TALLOC_CTX *mem_ctx, struct libnet_DomainOpen *io)
351 struct domain_open_samr_state *s;
353 /* wait for results of sending request */
354 status = composite_wait(c);
356 if (NT_STATUS_IS_OK(status) && io) {
357 s = talloc_get_type(c->private_data, struct domain_open_samr_state);
358 io->out.domain_handle = s->domain_handle;
360 /* store the resulting handle and related data for use by other
362 ctx->samr.handle = s->domain_handle;
363 ctx->samr.name = talloc_steal(ctx, s->domain_name.string);
364 ctx->samr.access_mask = s->access_mask;
372 struct domain_open_lsa_state {
374 uint32_t access_mask;
375 struct libnet_context *ctx;
376 struct libnet_RpcConnect rpcconn;
377 struct lsa_OpenPolicy2 openpol;
378 struct policy_handle handle;
379 struct dcerpc_pipe *pipe;
381 /* information about the progress */
382 void (*monitor_fn)(struct monitor_msg*);
386 static void continue_rpc_connect_lsa(struct composite_context *ctx);
387 static void continue_lsa_policy_open(struct rpc_request *req);
391 * Sends asynchronous DomainOpenLsa request
393 * @param ctx initialised libnet context
394 * @param io arguments and results of the call
395 * @param monitor pointer to monitor function that is passed monitor message
398 struct composite_context* libnet_DomainOpenLsa_send(struct libnet_context *ctx,
399 struct libnet_DomainOpen *io,
400 void (*monitor)(struct monitor_msg*))
402 struct composite_context *c;
403 struct domain_open_lsa_state *s;
404 struct composite_context *rpcconn_req;
405 struct rpc_request *openpol_req;
406 struct lsa_QosInfo *qos;
408 /* create composite context and state */
409 c = composite_create(ctx, ctx->event_ctx);
410 if (c == NULL) return c;
412 s = talloc_zero(c, struct domain_open_lsa_state);
413 if (composite_nomem(s, c)) return c;
417 /* store arguments in the state structure */
418 s->name = talloc_strdup(c, io->in.domain_name);
419 s->access_mask = io->in.access_mask;
422 /* check, if there's lsa pipe opened already, before opening a handle */
423 if (ctx->lsa.pipe == NULL) {
425 /* attempting to connect a domain controller */
426 s->rpcconn.level = LIBNET_RPC_CONNECT_DC;
427 s->rpcconn.in.name = talloc_strdup(c, io->in.domain_name);
428 s->rpcconn.in.dcerpc_iface = &dcerpc_table_lsarpc;
430 /* send rpc pipe connect request */
431 rpcconn_req = libnet_RpcConnect_send(ctx, c, &s->rpcconn);
432 if (composite_nomem(rpcconn_req, c)) return c;
434 composite_continue(c, rpcconn_req, continue_rpc_connect_lsa, c);
438 s->pipe = ctx->lsa.pipe;
440 /* preparing parameters for lsa_OpenPolicy2 rpc call */
441 s->openpol.in.system_name = s->name;
442 s->openpol.in.access_mask = s->access_mask;
443 s->openpol.in.attr = talloc_zero(c, struct lsa_ObjectAttribute);
445 qos = talloc_zero(c, struct lsa_QosInfo);
447 qos->impersonation_level = 2;
448 qos->context_mode = 1;
449 qos->effective_only = 0;
451 s->openpol.in.attr->sec_qos = qos;
452 s->openpol.out.handle = &s->handle;
454 /* send rpc request */
455 openpol_req = dcerpc_lsa_OpenPolicy2_send(s->pipe, c, &s->openpol);
456 if (composite_nomem(openpol_req, c)) return c;
458 composite_continue_rpc(c, openpol_req, continue_lsa_policy_open, c);
464 Stage 0.5 (optional): Rpc pipe connected, send lsa open policy request
466 static void continue_rpc_connect_lsa(struct composite_context *ctx)
468 struct composite_context *c;
469 struct domain_open_lsa_state *s;
470 struct lsa_QosInfo *qos;
471 struct rpc_request *openpol_req;
473 c = talloc_get_type(ctx->async.private_data, struct composite_context);
474 s = talloc_get_type(c->private_data, struct domain_open_lsa_state);
476 /* receive rpc connection */
477 c->status = libnet_RpcConnect_recv(ctx, s->ctx, c, &s->rpcconn);
478 if (!composite_is_ok(c)) return;
480 /* RpcConnect function leaves the pipe in libnet context,
481 so get it from there */
482 s->pipe = s->ctx->lsa.pipe;
484 /* prepare lsa_OpenPolicy2 call */
485 s->openpol.in.system_name = s->name;
486 s->openpol.in.access_mask = s->access_mask;
487 s->openpol.in.attr = talloc_zero(c, struct lsa_ObjectAttribute);
489 qos = talloc_zero(c, struct lsa_QosInfo);
491 qos->impersonation_level = 2;
492 qos->context_mode = 1;
493 qos->effective_only = 0;
495 s->openpol.in.attr->sec_qos = qos;
496 s->openpol.out.handle = &s->handle;
498 /* send rpc request */
499 openpol_req = dcerpc_lsa_OpenPolicy2_send(s->pipe, c, &s->openpol);
500 if (composite_nomem(openpol_req, c)) return;
502 composite_continue_rpc(c, openpol_req, continue_lsa_policy_open, c);
507 Stage 1: Lsa policy opened - we're done, if successfully
509 static void continue_lsa_policy_open(struct rpc_request *req)
511 struct composite_context *c;
512 struct domain_open_lsa_state *s;
514 c = talloc_get_type(req->async.private, struct composite_context);
515 s = talloc_get_type(c->private_data, struct domain_open_lsa_state);
517 c->status = dcerpc_ndr_request_recv(req);
518 if (!composite_is_ok(c)) return;
525 * Receives result of asynchronous DomainOpenLsa call
527 * @param c composite context returned by asynchronous DomainOpenLsa call
528 * @param ctx initialised libnet context
529 * @param mem_ctx memory context of the call
530 * @param io pointer to results (and arguments) of the call
531 * @return nt status code of execution
534 NTSTATUS libnet_DomainOpenLsa_recv(struct composite_context *c, struct libnet_context *ctx,
535 TALLOC_CTX *mem_ctx, struct libnet_DomainOpen *io)
538 struct domain_open_lsa_state *s;
540 status = composite_wait(c);
542 if (NT_STATUS_IS_OK(status) && io) {
543 /* everything went fine - get the results and
544 return the error string */
545 s = talloc_get_type(c->private_data, struct domain_open_lsa_state);
546 io->out.domain_handle = s->handle;
548 ctx->lsa.handle = s->handle;
549 ctx->lsa.name = talloc_steal(ctx, s->name);
550 ctx->lsa.access_mask = s->access_mask;
552 io->out.error_string = talloc_strdup(mem_ctx, "Success");
554 } else if (!NT_STATUS_IS_OK(status)) {
555 /* there was an error, so provide nt status code description */
556 io->out.error_string = talloc_asprintf(mem_ctx,
557 "Failed to open domain: %s",
567 * Sends a request to open a domain in desired service
569 * @param ctx initalised libnet context
570 * @param io arguments and results of the call
571 * @param monitor pointer to monitor function that is passed monitor message
574 struct composite_context* libnet_DomainOpen_send(struct libnet_context *ctx,
575 struct libnet_DomainOpen *io,
576 void (*monitor)(struct monitor_msg*))
578 struct composite_context *c;
580 switch (io->in.type) {
582 /* reques to open a policy handle on \pipe\lsarpc */
583 c = libnet_DomainOpenLsa_send(ctx, io, monitor);
588 /* request to open a domain policy handle on \pipe\samr */
589 c = libnet_DomainOpenSamr_send(ctx, io, monitor);
598 * Receive result of domain open request
600 * @param c composite context returned by DomainOpen_send function
601 * @param ctx initialised libnet context
602 * @param mem_ctx memory context of the call
603 * @param io results and arguments of the call
606 NTSTATUS libnet_DomainOpen_recv(struct composite_context *c, struct libnet_context *ctx,
607 TALLOC_CTX *mem_ctx, struct libnet_DomainOpen *io)
611 switch (io->in.type) {
613 status = libnet_DomainOpenLsa_recv(c, ctx, mem_ctx, io);
618 status = libnet_DomainOpenSamr_recv(c, ctx, mem_ctx, io);
627 * Synchronous version of DomainOpen call
629 * @param ctx initialised libnet context
630 * @param mem_ctx memory context for the call
631 * @param io arguments and results of the call
632 * @return nt status code of execution
635 NTSTATUS libnet_DomainOpen(struct libnet_context *ctx,
637 struct libnet_DomainOpen *io)
639 struct composite_context *c = libnet_DomainOpen_send(ctx, io, NULL);
640 return libnet_DomainOpen_recv(c, ctx, mem_ctx, io);
644 struct domain_close_lsa_state {
645 struct dcerpc_pipe *pipe;
646 struct lsa_Close close;
647 struct policy_handle handle;
649 void (*monitor_fn)(struct monitor_msg*);
653 static void continue_lsa_close(struct rpc_request *req);
656 struct composite_context* libnet_DomainCloseLsa_send(struct libnet_context *ctx,
657 struct libnet_DomainClose *io,
658 void (*monitor)(struct monitor_msg*))
660 struct composite_context *c;
661 struct domain_close_lsa_state *s;
662 struct rpc_request *close_req;
664 /* composite context and state structure allocation */
665 c = composite_create(ctx, ctx->event_ctx);
666 if (c == NULL) return c;
668 s = talloc_zero(c, struct domain_close_lsa_state);
669 if (composite_nomem(s, c)) return c;
672 s->monitor_fn = monitor;
674 /* TODO: check if lsa pipe pointer is non-null */
676 if (!strequal(ctx->lsa.name, io->in.domain_name)) {
677 composite_error(c, NT_STATUS_INVALID_PARAMETER);
681 /* get opened lsarpc pipe pointer */
682 s->pipe = ctx->lsa.pipe;
684 /* prepare close handle call arguments */
685 s->close.in.handle = &ctx->lsa.handle;
686 s->close.out.handle = &s->handle;
688 /* send the request */
689 close_req = dcerpc_lsa_Close_send(s->pipe, c, &s->close);
690 if (composite_nomem(close_req, c)) return c;
692 composite_continue_rpc(c, close_req, continue_lsa_close, c);
698 Stage 1: Receive result of lsa close call
700 static void continue_lsa_close(struct rpc_request *req)
702 struct composite_context *c;
703 struct domain_close_lsa_state *s;
705 c = talloc_get_type(req->async.private, struct composite_context);
706 s = talloc_get_type(c->private_data, struct domain_close_lsa_state);
708 c->status = dcerpc_ndr_request_recv(req);
709 if (!composite_is_ok(c)) return;
715 NTSTATUS libnet_DomainCloseLsa_recv(struct composite_context *c, struct libnet_context *ctx,
716 TALLOC_CTX *mem_ctx, struct libnet_DomainClose *io)
720 status = composite_wait(c);
722 if (NT_STATUS_IS_OK(status) && io) {
723 /* policy handle closed successfully */
725 ctx->lsa.name = NULL;
726 ZERO_STRUCT(ctx->lsa.handle);
728 io->out.error_string = talloc_asprintf(mem_ctx, "Success");
730 } else if (!NT_STATUS_IS_OK(status)) {
731 /* there was an error, so return description of the status code */
732 io->out.error_string = talloc_asprintf(mem_ctx, "Error: %s", nt_errstr(status));
740 struct domain_close_samr_state {
741 struct samr_Close close;
742 struct policy_handle handle;
744 void (*monitor_fn)(struct monitor_msg*);
748 static void continue_samr_close(struct rpc_request *req);
751 struct composite_context* libnet_DomainCloseSamr_send(struct libnet_context *ctx,
752 struct libnet_DomainClose *io,
753 void (*monitor)(struct monitor_msg*))
755 struct composite_context *c;
756 struct domain_close_samr_state *s;
757 struct rpc_request *close_req;
759 /* composite context and state structure allocation */
760 c = composite_create(ctx, ctx->event_ctx);
761 if (c == NULL) return c;
763 s = talloc_zero(c, struct domain_close_samr_state);
764 if (composite_nomem(s, c)) return c;
767 s->monitor_fn = monitor;
769 /* TODO: check if samr pipe pointer is non-null */
771 if (!strequal(ctx->samr.name, io->in.domain_name)) {
772 composite_error(c, NT_STATUS_INVALID_PARAMETER);
776 /* prepare close domain handle call arguments */
777 ZERO_STRUCT(s->close);
778 s->close.in.handle = &ctx->samr.handle;
779 s->close.out.handle = &s->handle;
781 /* send the request */
782 close_req = dcerpc_samr_Close_send(ctx->samr.pipe, ctx, &s->close);
783 if (composite_nomem(close_req, c)) return c;
785 composite_continue_rpc(c, close_req, continue_samr_close, c);
791 Stage 1: Receive result of samr close call
793 static void continue_samr_close(struct rpc_request *req)
795 struct composite_context *c;
796 struct domain_close_samr_state *s;
798 c = talloc_get_type(req->async.private, struct composite_context);
799 s = talloc_get_type(c->private_data, struct domain_close_samr_state);
801 c->status = dcerpc_ndr_request_recv(req);
802 if (!composite_is_ok(c)) return;
808 NTSTATUS libnet_DomainCloseSamr_recv(struct composite_context *c, struct libnet_context *ctx,
809 TALLOC_CTX *mem_ctx, struct libnet_DomainClose *io)
813 status = composite_wait(c);
815 if (NT_STATUS_IS_OK(status) && io) {
816 /* domain policy handle closed successfully */
818 ZERO_STRUCT(ctx->samr.handle);
819 ctx->samr.name = NULL;
821 io->out.error_string = talloc_asprintf(mem_ctx, "Success");
823 } else if (!NT_STATUS_IS_OK(status)) {
824 /* there was an error, so return description of the status code */
825 io->out.error_string = talloc_asprintf(mem_ctx, "Error: %s", nt_errstr(status));
833 struct composite_context* libnet_DomainClose_send(struct libnet_context *ctx,
834 struct libnet_DomainClose *io,
835 void (*monitor)(struct monitor_msg*))
837 struct composite_context *c;
839 switch (io->in.type) {
841 /* request to close policy handle on \pipe\lsarpc */
842 c = libnet_DomainCloseLsa_send(ctx, io, monitor);
847 /* request to close domain policy handle on \pipe\samr */
848 c = libnet_DomainCloseSamr_send(ctx, io, monitor);
856 NTSTATUS libnet_DomainClose_recv(struct composite_context *c, struct libnet_context *ctx,
857 TALLOC_CTX *mem_ctx, struct libnet_DomainClose *io)
861 switch (io->in.type) {
863 /* receive result of closing lsa policy handle */
864 status = libnet_DomainCloseLsa_recv(c, ctx, mem_ctx, io);
869 /* receive result of closing samr domain policy handle */
870 status = libnet_DomainCloseSamr_recv(c, ctx, mem_ctx, io);
878 NTSTATUS libnet_DomainClose(struct libnet_context *ctx, TALLOC_CTX *mem_ctx,
879 struct libnet_DomainClose *io)
881 struct composite_context *c;
883 c = libnet_DomainClose_send(ctx, io, NULL);
884 return libnet_DomainClose_recv(c, ctx, mem_ctx, io);