diff options
-rw-r--r-- | source4/libnet/composite.h | 11 | ||||
-rw-r--r-- | source4/libnet/config.mk | 4 | ||||
-rw-r--r-- | source4/libnet/libnet.c | 3 | ||||
-rw-r--r-- | source4/libnet/libnet.h | 14 | ||||
-rw-r--r-- | source4/libnet/libnet_domain.c (renamed from source4/libnet/domain.c) | 190 | ||||
-rw-r--r-- | source4/libnet/libnet_domain.h | 34 | ||||
-rw-r--r-- | source4/libnet/libnet_rpc.c | 31 | ||||
-rw-r--r-- | source4/libnet/libnet_user.c | 177 |
8 files changed, 403 insertions, 61 deletions
diff --git a/source4/libnet/composite.h b/source4/libnet/composite.h index 916e306124..516fdd4ef9 100644 --- a/source4/libnet/composite.h +++ b/source4/libnet/composite.h @@ -111,14 +111,3 @@ struct libnet_rpc_usermod { } change; } in; }; - - -struct libnet_rpc_domain_open { - struct { - const char *domain_name; - uint32_t access_mask; - } in; - struct { - struct policy_handle domain_handle; - } out; -}; diff --git a/source4/libnet/config.mk b/source4/libnet/config.mk index 05f170cbde..4fa35110e6 100644 --- a/source4/libnet/config.mk +++ b/source4/libnet/config.mk @@ -21,7 +21,7 @@ OBJ_FILES = \ libnet_user.o \ libnet_share.o \ libnet_lookup.o \ + libnet_domain.o \ userinfo.o \ - userman.o \ - domain.o + userman.o PUBLIC_DEPENDENCIES = dcerpc RPC_NDR_SAMR RPC_NDR_LSA RPC_NDR_SRVSVC RPC_NDR_DRSUAPI LIBCLI_COMPOSITE LIBCLI_RESOLVE LIBCLI_FINDDCS LIBSAMBA3 LIBCLI_CLDAP LIBCLI_FINDDCS gensec_schannel diff --git a/source4/libnet/libnet.c b/source4/libnet/libnet.c index c350416895..8398e9ca17 100644 --- a/source4/libnet/libnet.c +++ b/source4/libnet/libnet.c @@ -44,6 +44,9 @@ struct libnet_context *libnet_context_init(struct event_context *ev) /* name resolution methods */ ctx->name_res_methods = str_list_copy(ctx, lp_name_resolve_order()); + + /* connected domain params */ + ZERO_STRUCT(ctx->domain); return ctx; } diff --git a/source4/libnet/libnet.h b/source4/libnet/libnet.h index 04428aa007..39dbb21f32 100644 --- a/source4/libnet/libnet.h +++ b/source4/libnet/libnet.h @@ -25,11 +25,18 @@ struct libnet_context { */ struct cli_credentials *cred; - /* pipe */ + /* pipes */ struct dcerpc_pipe *pipe; + struct dcerpc_pipe *lsa_pipe; + struct dcerpc_pipe *samr_pipe; + + /* opened handles and related properties */ + struct { + const char *name; + uint32_t access_mask; + struct policy_handle handle; + } domain; - /* opened handles */ - struct policy_handle domain_handle; struct policy_handle user_handle; /* name resolution methods */ @@ -49,5 +56,6 @@ struct libnet_context { #include "libnet/libnet_user.h" #include "libnet/libnet_share.h" #include "libnet/libnet_lookup.h" +#include "libnet/libnet_domain.h" #include "libnet/composite.h" #include "libnet/libnet_proto.h" diff --git a/source4/libnet/domain.c b/source4/libnet/libnet_domain.c index e48454f0e1..640cbade09 100644 --- a/source4/libnet/domain.c +++ b/source4/libnet/libnet_domain.c @@ -19,25 +19,30 @@ */ /* - a composite function for domain handling + a composite function for domain handling on samr pipe */ #include "includes.h" #include "libcli/composite/composite.h" -#include "libnet/composite.h" +#include "libnet/libnet.h" #include "librpc/gen_ndr/ndr_samr_c.h" static void domain_open_handler(struct rpc_request*); -enum domain_open_stage { DOMOPEN_CONNECT, DOMOPEN_LOOKUP, DOMOPEN_OPEN }; +enum domain_open_stage { DOMOPEN_CONNECT, DOMOPEN_LOOKUP, DOMOPEN_OPEN, + DOMOPEN_CLOSE_EXISTING, DOMOPEN_RPC_CONNECT }; struct domain_open_state { enum domain_open_stage stage; + struct libnet_context *ctx; struct dcerpc_pipe *pipe; struct rpc_request *req; + struct composite_context *rpcconn_req; struct samr_Connect connect; struct samr_LookupDomain lookup; struct samr_OpenDomain open; + struct samr_Close close; + struct libnet_RpcConnect rpcconn; struct lsa_String domain_name; uint32_t access_mask; struct policy_handle connect_handle; @@ -46,6 +51,72 @@ struct domain_open_state { /** + * Stage 0.5 (optional): Connect to samr rpc pipe + */ +static void domain_open_rpc_connect(struct composite_context *ctx) +{ + struct composite_context *c; + struct domain_open_state *s; + + c = talloc_get_type(ctx->async.private_data, struct composite_context); + s = talloc_get_type(c->private_data, struct domain_open_state); + + c->status = libnet_RpcConnect_recv(ctx, s->ctx, c, &s->rpcconn); + if (!composite_is_ok(c)) return; + + s->pipe = s->rpcconn.out.dcerpc_pipe; + + /* preparing parameters for samr_Connect rpc call */ + s->connect.in.system_name = 0; + s->connect.in.access_mask = s->access_mask; + s->connect.out.connect_handle = &s->connect_handle; + + /* send request */ + s->req = dcerpc_samr_Connect_send(s->pipe, c, &s->connect); + if (composite_nomem(s->req, c)) return; + + /* callback handler */ + s->req->async.callback = domain_open_handler; + s->req->async.private = c; + s->stage = DOMOPEN_CONNECT; +} + + +/** + * Stage 0.5 (optional): Close existing (in libnet context) domain + * handle + */ +static NTSTATUS domain_open_close(struct composite_context *c, + struct domain_open_state *s) +{ + /* receive samr_Close reply */ + c->status = dcerpc_ndr_request_recv(s->req); + NT_STATUS_NOT_OK_RETURN(c->status); + + /* reset domain handle and associated data in libnet_context */ + s->ctx->domain.name = NULL; + s->ctx->domain.access_mask = 0; + ZERO_STRUCT(s->ctx->domain.handle); + + /* preparing parameters for samr_Connect rpc call */ + s->connect.in.system_name = 0; + s->connect.in.access_mask = s->access_mask; + s->connect.out.connect_handle = &s->connect_handle; + + /* send request */ + s->req = dcerpc_samr_Connect_send(s->pipe, c, &s->connect); + if (s->req == NULL) return NT_STATUS_NO_MEMORY; + + /* callback handler */ + s->req->async.callback = domain_open_handler; + s->req->async.private = c; + s->stage = DOMOPEN_CONNECT; + + return NT_STATUS_OK; +} + + +/** * Stage 1: Connect to SAM server. */ static NTSTATUS domain_open_connect(struct composite_context *c, @@ -145,48 +216,106 @@ static void domain_open_handler(struct rpc_request *req) case DOMOPEN_OPEN: c->status = domain_open_open(c, s); break; + case DOMOPEN_CLOSE_EXISTING: + c->status = domain_open_close(c, s); + break; + case DOMOPEN_RPC_CONNECT: + /* this state shouldn't be handled here */ + c->status = NT_STATUS_UNSUCCESSFUL; + break; } if (!NT_STATUS_IS_OK(c->status)) { c->state = COMPOSITE_STATE_ERROR; } + + if (c->state == COMPOSITE_STATE_DONE) { + composite_done(c); + } } /** * Sends asynchronous domain_open request * - * @param p dce/rpc call pipe + * @param ctx initialised libnet context * @param io arguments and results of the call + * @param monitor pointer to monitor function that is passed monitor message */ -struct composite_context *libnet_rpc_domain_open_send(struct dcerpc_pipe *p, - struct libnet_rpc_domain_open *io, - void (*monitor)(struct monitor_msg*)) + +struct composite_context *libnet_DomainOpen_send(struct libnet_context *ctx, + struct libnet_DomainOpen *io, + void (*monitor)(struct monitor_msg*)) { struct composite_context *c; struct domain_open_state *s; - c = talloc_zero(p, struct composite_context); - if (c == NULL) goto failure; + c = talloc_zero(ctx, struct composite_context); + if (c == NULL) return NULL; s = talloc_zero(c, struct domain_open_state); - if (s == NULL) goto failure; + if (composite_nomem(s, c)) return c; - c->state = COMPOSITE_STATE_IN_PROGRESS; - c->private_data= s; - c->event_ctx = dcerpc_event_context(p); + c->state = COMPOSITE_STATE_IN_PROGRESS; + c->private_data = s; + c->event_ctx = ctx->event_ctx; - s->pipe = p; + s->ctx = ctx; + s->pipe = ctx->samr_pipe; s->access_mask = io->in.access_mask; s->domain_name.string = io->in.domain_name; - /* preparing parameters to send rpc request */ + if (ctx->samr_pipe == NULL) { + s->rpcconn.level = LIBNET_RPC_CONNECT_DC; + s->rpcconn.in.name = io->in.domain_name; + s->rpcconn.in.dcerpc_iface = &dcerpc_table_samr; + + s->rpcconn_req = libnet_RpcConnect_send(ctx, c, &s->rpcconn); + if (composite_nomem(s->rpcconn_req, c)) return c; + + s->rpcconn_req->async.fn = domain_open_rpc_connect; + s->rpcconn_req->async.private_data = c; + s->stage = DOMOPEN_RPC_CONNECT; + + return c; + } + + /* libnet context's domain handle is not empty, so check out what + was opened first, before doing anything */ + if (!policy_handle_empty(&ctx->domain.handle)) { + if (strequal(ctx->domain.name, io->in.domain_name) && + ctx->domain.access_mask == io->in.access_mask) { + + /* this domain is already opened */ + composite_done(c); + return c; + + } else { + /* another domain or access rights have been + requested - close the existing handle first */ + s->close.in.handle = &ctx->domain.handle; + + /* send request to close domain handle */ + s->req = dcerpc_samr_Close_send(s->pipe, c, &s->close); + if (composite_nomem(s->req, c)) return c; + + /* callback handler */ + s->req->async.callback = domain_open_handler; + s->req->async.private = c; + s->stage = DOMOPEN_CLOSE_EXISTING; + + return c; + } + } + + /* preparing parameters for samr_Connect rpc call */ s->connect.in.system_name = 0; s->connect.in.access_mask = s->access_mask; s->connect.out.connect_handle = &s->connect_handle; /* send request */ - s->req = dcerpc_samr_Connect_send(p, c, &s->connect); + s->req = dcerpc_samr_Connect_send(s->pipe, c, &s->connect); + if (composite_nomem(s->req, c)) return c; /* callback handler */ s->req->async.callback = domain_open_handler; @@ -194,10 +323,6 @@ struct composite_context *libnet_rpc_domain_open_send(struct dcerpc_pipe *p, s->stage = DOMOPEN_CONNECT; return c; - -failure: - talloc_free(c); - return NULL; } @@ -205,12 +330,14 @@ failure: * Waits for and receives result of asynchronous domain_open call * * @param c composite context returned by asynchronous domain_open call + * @param ctx initialised libnet context * @param mem_ctx memory context of the call * @param io pointer to results (and arguments) of the call * @return nt status code of execution */ -NTSTATUS libnet_rpc_domain_open_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, - struct libnet_rpc_domain_open *io) + +NTSTATUS libnet_DomainOpen_recv(struct composite_context *c, struct libnet_context *ctx, + TALLOC_CTX *mem_ctx, struct libnet_DomainOpen *io) { NTSTATUS status; struct domain_open_state *s; @@ -221,6 +348,12 @@ NTSTATUS libnet_rpc_domain_open_recv(struct composite_context *c, TALLOC_CTX *me if (NT_STATUS_IS_OK(status) && io) { s = talloc_get_type(c->private_data, struct domain_open_state); io->out.domain_handle = s->domain_handle; + + /* store the resulting handle and related data for use by other + libnet functions */ + ctx->domain.handle = s->domain_handle; + ctx->domain.name = talloc_strdup(ctx, s->domain_name.string); + ctx->domain.access_mask = s->access_mask; } talloc_free(c); @@ -231,15 +364,16 @@ NTSTATUS libnet_rpc_domain_open_recv(struct composite_context *c, TALLOC_CTX *me /** * Synchronous version of domain_open call * - * @param pipe dce/rpc call pipe + * @param ctx initialised libnet context * @param mem_ctx memory context for the call * @param io arguments and results of the call * @return nt status code of execution */ -NTSTATUS libnet_rpc_domain_open(struct dcerpc_pipe *p, - TALLOC_CTX *mem_ctx, - struct libnet_rpc_domain_open *io) + +NTSTATUS libnet_DomainOpen(struct libnet_context *ctx, + TALLOC_CTX *mem_ctx, + struct libnet_DomainOpen *io) { - struct composite_context *c = libnet_rpc_domain_open_send(p, io, NULL); - return libnet_rpc_domain_open_recv(c, mem_ctx, io); + struct composite_context *c = libnet_DomainOpen_send(ctx, io, NULL); + return libnet_DomainOpen_recv(c, ctx, mem_ctx, io); } diff --git a/source4/libnet/libnet_domain.h b/source4/libnet/libnet_domain.h new file mode 100644 index 0000000000..6dc4ed3f45 --- /dev/null +++ b/source4/libnet/libnet_domain.h @@ -0,0 +1,34 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Rafal Szczesniak 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +/* + * struct definition for opening a domain + */ + +struct libnet_DomainOpen { + struct { + const char *domain_name; + uint32_t access_mask; + } in; + struct { + struct policy_handle domain_handle; + } out; +}; diff --git a/source4/libnet/libnet_rpc.c b/source4/libnet/libnet_rpc.c index 3e66a5c27c..b185380295 100644 --- a/source4/libnet/libnet_rpc.c +++ b/source4/libnet/libnet_rpc.c @@ -24,6 +24,7 @@ #include "libcli/libcli.h" #include "libcli/composite/composite.h" #include "librpc/gen_ndr/ndr_lsa_c.h" +#include "librpc/gen_ndr/ndr_samr.h" struct rpc_connect_srv_state { @@ -137,7 +138,15 @@ static NTSTATUS libnet_RpcConnectSrv_recv(struct composite_context *c, /* move the returned rpc pipe between memory contexts */ s = talloc_get_type(c->private_data, struct rpc_connect_srv_state); r->out.dcerpc_pipe = talloc_steal(mem_ctx, s->r.out.dcerpc_pipe); - ctx->pipe = r->out.dcerpc_pipe; + + /* reference created pipe structure to long-term libnet_context + so that it can be used by other api functions even after short-term + mem_ctx is freed */ + if (r->in.dcerpc_iface == &dcerpc_table_samr) { + ctx->samr_pipe = talloc_reference(ctx, r->out.dcerpc_pipe); + } else { + ctx->pipe = talloc_reference(ctx, r->out.dcerpc_pipe); + } } talloc_free(c); @@ -301,7 +310,15 @@ static NTSTATUS libnet_RpcConnectDC_recv(struct composite_context *c, /* move connected rpc pipe between memory contexts */ s = talloc_get_type(c->private_data, struct rpc_connect_dc_state); r->out.dcerpc_pipe = talloc_steal(mem_ctx, s->r.out.dcerpc_pipe); - ctx->pipe = r->out.dcerpc_pipe; + + /* reference created pipe structure to long-term libnet_context + so that it can be used by other api functions even after short-term + mem_ctx is freed */ + if (r->in.dcerpc_iface == &dcerpc_table_samr) { + ctx->samr_pipe = talloc_reference(ctx, r->out.dcerpc_pipe); + } else { + ctx->pipe = talloc_reference(ctx, r->out.dcerpc_pipe); + } } talloc_free(c); @@ -639,9 +656,17 @@ static NTSTATUS libnet_RpcConnectDCInfo_recv(struct composite_context *c, struct r->out.guid = talloc_steal(mem_ctx, s->r.out.guid); r->out.domain_name = talloc_steal(mem_ctx, s->r.out.domain_name); r->out.domain_sid = talloc_steal(mem_ctx, s->r.out.domain_sid); + r->out.dcerpc_pipe = talloc_steal(mem_ctx, s->r.out.dcerpc_pipe); - r->out.error_string = NULL; + /* reference created pipe structure to long-term libnet_context + so that it can be used by other api functions even after short-term + mem_ctx is freed */ + if (r->in.dcerpc_iface == &dcerpc_table_samr) { + ctx->samr_pipe = talloc_reference(ctx, r->out.dcerpc_pipe); + } else { + ctx->pipe = talloc_reference(ctx, r->out.dcerpc_pipe); + } } talloc_free(c); diff --git a/source4/libnet/libnet_user.c b/source4/libnet/libnet_user.c index 1fca102d17..53364f7f32 100644 --- a/source4/libnet/libnet_user.c +++ b/source4/libnet/libnet_user.c @@ -21,14 +21,169 @@ #include "includes.h" #include "libnet/libnet.h" +#include "libcli/composite/composite.h" +#include "auth/credentials/credentials.h" +#include "librpc/ndr/libndr.h" #include "librpc/gen_ndr/ndr_samr.h" +struct create_user_state { + struct libnet_CreateUser r; + struct libnet_DomainOpen domain_open; + struct libnet_rpc_useradd user_add; + struct libnet_context *ctx; + + /* information about the progress */ + void (*monitor_fn)(struct monitor_msg *); +}; + + +static void continue_rpc_useradd(struct composite_context *ctx); +static void continue_domain_open(struct composite_context *ctx); + + +struct composite_context* libnet_CreateUser_send(struct libnet_context *ctx, + TALLOC_CTX *mem_ctx, + struct libnet_CreateUser *r, + void (*monitor)(struct monitor_msg*)) +{ + struct composite_context *c; + struct create_user_state *s; + struct composite_context *create_req; + struct composite_context *domopen_req; + + c = talloc_zero(mem_ctx, struct composite_context); + if (c == NULL) return NULL; + + s = talloc_zero(c, struct create_user_state); + if (composite_nomem(s, c)) return c; + + c->state = COMPOSITE_STATE_IN_PROGRESS; + c->private_data = s; + c->event_ctx = ctx->event_ctx; + + s->ctx = ctx; + s->r = *r; + + if (s->r.in.domain_name == NULL) { + + if (policy_handle_empty(&ctx->domain.handle)) { + s->domain_open.in.domain_name = cli_credentials_get_domain(ctx->cred); + s->domain_open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + + domopen_req = libnet_DomainOpen_send(ctx, &s->domain_open, monitor); + if (composite_nomem(domopen_req, c)) return c; + + composite_continue(c, domopen_req, continue_domain_open, c); + return c; + } else { + /* no domain name provided - neither in io structure nor default + stored in libnet context - report an error */ + composite_error(c, NT_STATUS_INVALID_PARAMETER); + return c; + } + + } else { + + if (policy_handle_empty(&ctx->domain.handle) || + !strequal(s->r.in.domain_name, ctx->domain.name)) { + s->domain_open.in.domain_name = s->r.in.domain_name; + s->domain_open.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + + domopen_req = libnet_DomainOpen_send(ctx, &s->domain_open, monitor); + if (composite_nomem(domopen_req, c)) return c; + + composite_continue(c, domopen_req, continue_domain_open, c); + return c; + } + } + + s->user_add.in.username = r->in.user_name; + s->user_add.in.domain_handle = ctx->domain.handle; + + create_req = libnet_rpc_useradd_send(ctx->samr_pipe, &s->user_add, monitor); + if (composite_nomem(create_req, c)) return c; + + composite_continue(c, create_req, continue_rpc_useradd, c); + return c; +} + + +static void continue_domain_open(struct composite_context *ctx) +{ + struct composite_context *c; + struct create_user_state *s; + struct composite_context *create_req; + struct monitor_msg msg; + + c = talloc_get_type(ctx->async.private_data, struct composite_context); + s = talloc_get_type(c->private_data, struct create_user_state); + + c->status = libnet_DomainOpen_recv(ctx, s->ctx, c, &s->domain_open); + if (!composite_is_ok(c)) return; + + if (s->monitor_fn) s->monitor_fn(&msg); + + s->user_add.in.username = s->r.in.user_name; + s->user_add.in.domain_handle = s->ctx->domain.handle; + + create_req = libnet_rpc_useradd_send(s->ctx->samr_pipe, &s->user_add, s->monitor_fn); + if (composite_nomem(create_req, c)) return; + + composite_continue(c, create_req, continue_rpc_useradd, c); +} + + +static void continue_rpc_useradd(struct composite_context *ctx) +{ + struct composite_context *c; + struct create_user_state *s; + struct monitor_msg msg; + + c = talloc_get_type(ctx->async.private_data, struct composite_context); + s = talloc_get_type(c->private_data, struct create_user_state); + + c->status = libnet_rpc_useradd_recv(ctx, c, &s->user_add); + if (!composite_is_ok(c)) return; + + if (s->monitor_fn) s->monitor_fn(&msg); + composite_done(c); +} + + +NTSTATUS libnet_CreateUser_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, + struct libnet_CreateUser *r) +{ + NTSTATUS status; + struct create_user_state *s; + + status = composite_wait(c); + if (!NT_STATUS_IS_OK(status)) { + s = talloc_get_type(c->private_data, struct create_user_state); + r->out.error_string = talloc_steal(mem_ctx, s->r.out.error_string); + } + + r->out.error_string = NULL; + return status; +} + + +NTSTATUS libnet_CreateUser(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, + struct libnet_CreateUser *r) +{ + struct composite_context *c; + + c = libnet_CreateUser_send(ctx, mem_ctx, r, NULL); + return libnet_CreateUser_recv(c, mem_ctx, r); +} + + +#ifdef OBSOLETE NTSTATUS libnet_CreateUser(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_CreateUser *r) { NTSTATUS status; struct libnet_RpcConnect cn; - struct libnet_rpc_domain_open dom_io; + struct libnet_DomainOpen dom_io; struct libnet_rpc_useradd user_io; /* connect rpc service of remote DC */ @@ -44,13 +199,11 @@ NTSTATUS libnet_CreateUser(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } - ctx->pipe = cn.out.dcerpc_pipe; - /* open connected domain */ dom_io.in.domain_name = r->in.domain_name; dom_io.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - status = libnet_rpc_domain_open(ctx->pipe, mem_ctx, &dom_io); + status = libnet_DomainOpen(ctx, mem_ctx, &dom_io); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, "Creating user account failed: %s\n", @@ -58,13 +211,11 @@ NTSTATUS libnet_CreateUser(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } - ctx->domain_handle = dom_io.out.domain_handle; - /* create user */ user_io.in.username = r->in.user_name; user_io.in.domain_handle = dom_io.out.domain_handle; - status = libnet_rpc_useradd(ctx->pipe, mem_ctx, &user_io); + status = libnet_rpc_useradd(ctx, mem_ctx, &user_io); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, "Creating user account failed: %s\n", @@ -76,12 +227,14 @@ NTSTATUS libnet_CreateUser(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } +#endif + NTSTATUS libnet_DeleteUser(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_DeleteUser *r) { NTSTATUS status; struct libnet_RpcConnect cn; - struct libnet_rpc_domain_open dom_io; + struct libnet_DomainOpen dom_io; struct libnet_rpc_userdel user_io; /* connect rpc service of remote DC */ @@ -97,13 +250,11 @@ NTSTATUS libnet_DeleteUser(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } - ctx->pipe = cn.out.dcerpc_pipe; - /* open connected domain */ dom_io.in.domain_name = r->in.domain_name; dom_io.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - status = libnet_rpc_domain_open(ctx->pipe, mem_ctx, &dom_io); + status = libnet_DomainOpen(ctx, mem_ctx, &dom_io); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, "Opening domain to delete user account failed: %s\n", @@ -111,13 +262,11 @@ NTSTATUS libnet_DeleteUser(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } - ctx->domain_handle = dom_io.out.domain_handle; - /* create user */ user_io.in.username = r->in.user_name; user_io.in.domain_handle = dom_io.out.domain_handle; - status = libnet_rpc_userdel(ctx->pipe, mem_ctx, &user_io); + status = libnet_rpc_userdel(ctx, mem_ctx, &user_io); if (!NT_STATUS_IS_OK(status)) { r->out.error_string = talloc_asprintf(mem_ctx, "Deleting user account failed: %s\n", |