r22522: Print why we can't find these entries.
[Samba.git] / source / libnet / libnet_domain.c
blob7d8bbc8958b93f1f8a2eb5db5d2c7dafc32e8b20
1 /*
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
25 #include "includes.h"
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;
41 uint32_t access_mask;
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);
56 /**
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;
78 /* send request */
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);
87 /**
88 * Stage 0.5 (optional): Close existing (in libnet context) domain
89 * handle
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;
114 /* send request */
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;
140 r = &s->lookup;
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);
169 r = &s->open;
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);
177 return;
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;
208 composite_done(c);
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;
235 c->private_data = s;
236 s->monitor_fn = monitor;
238 s->ctx = ctx;
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);
256 return 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 */
266 composite_done(c);
267 return c;
269 } else {
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);
280 return 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;
289 /* send request */
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);
295 return 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)
312 NTSTATUS status;
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
323 libnet functions */
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;
329 talloc_free(c);
330 return status;
334 struct domain_open_lsa_state {
335 const char *name;
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;
377 c->private_data = s;
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;
382 s->ctx = ctx;
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);
397 return 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);
408 qos->len = 0;
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);
421 return 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);
452 qos->len = 0;
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;
482 composite_done(c);
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)
499 NTSTATUS status;
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",
520 nt_errstr(status));
523 talloc_free(c);
524 return status;
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) {
543 case DOMAIN_LSA:
544 /* reques to open a policy handle on \pipe\lsarpc */
545 c = libnet_DomainOpenLsa_send(ctx, io, monitor);
546 break;
548 case DOMAIN_SAMR:
549 default:
550 /* request to open a domain policy handle on \pipe\samr */
551 c = libnet_DomainOpenSamr_send(ctx, io, monitor);
552 break;
555 return c;
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)
571 NTSTATUS status;
573 switch (io->in.type) {
574 case DOMAIN_LSA:
575 status = libnet_DomainOpenLsa_recv(c, ctx, mem_ctx, io);
576 break;
578 case DOMAIN_SAMR:
579 default:
580 status = libnet_DomainOpenSamr_recv(c, ctx, mem_ctx, io);
581 break;
584 return status;
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,
598 TALLOC_CTX *mem_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;
633 c->private_data = s;
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);
640 return c;
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);
655 return 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;
673 composite_done(c);
677 NTSTATUS libnet_DomainCloseLsa_recv(struct composite_context *c, struct libnet_context *ctx,
678 TALLOC_CTX *mem_ctx, struct libnet_DomainClose *io)
680 NTSTATUS status;
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));
697 talloc_free(c);
698 return 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;
728 c->private_data = s;
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);
735 return c;
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);
748 return 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;
766 composite_done(c);
770 NTSTATUS libnet_DomainCloseSamr_recv(struct composite_context *c, struct libnet_context *ctx,
771 TALLOC_CTX *mem_ctx, struct libnet_DomainClose *io)
773 NTSTATUS status;
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));
790 talloc_free(c);
791 return 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) {
802 case DOMAIN_LSA:
803 /* request to close policy handle on \pipe\lsarpc */
804 c = libnet_DomainCloseLsa_send(ctx, io, monitor);
805 break;
807 case DOMAIN_SAMR:
808 default:
809 /* request to close domain policy handle on \pipe\samr */
810 c = libnet_DomainCloseSamr_send(ctx, io, monitor);
811 break;
814 return c;
818 NTSTATUS libnet_DomainClose_recv(struct composite_context *c, struct libnet_context *ctx,
819 TALLOC_CTX *mem_ctx, struct libnet_DomainClose *io)
821 NTSTATUS status;
823 switch (io->in.type) {
824 case DOMAIN_LSA:
825 /* receive result of closing lsa policy handle */
826 status = libnet_DomainCloseLsa_recv(c, ctx, mem_ctx, io);
827 break;
829 case DOMAIN_SAMR:
830 default:
831 /* receive result of closing samr domain policy handle */
832 status = libnet_DomainCloseSamr_recv(c, ctx, mem_ctx, io);
833 break;
836 return status;
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);