summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorRafal Szczesniak <mimir@samba.org>2006-05-15 21:49:27 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:07:24 -0500
commit16b5eac38df91b2377cbffe3009cc956fcb8a78a (patch)
tree66222e7c451efd337e856645c2f37e5275038917 /source4
parent6506e27cb26dd05671a2a001d02536955101dae1 (diff)
downloadsamba-16b5eac38df91b2377cbffe3009cc956fcb8a78a.tar.gz
samba-16b5eac38df91b2377cbffe3009cc956fcb8a78a.tar.bz2
samba-16b5eac38df91b2377cbffe3009cc956fcb8a78a.zip
r15625: Partial commit of my current work. It makes libnet api functions
a bit more smart and more aware of what libnet_context can offer. The context is a help when some of the arguments are not passed (programmer counts on using sensible defaults) and stores some of results so that similar subsequent calls don't need to reopen some of policy handles, pipes, etc. again. It also helps to hide some of details the library user don't really want to know much about. Also, change domain open function to be part of public api, as it is going to be used in ejsnet interface. Note, this is work in progress. Comments are welcome. rafal (This used to be commit 1ed80c594c2f466e364a11194d6fdc30ac4a8f27)
Diffstat (limited to 'source4')
-rw-r--r--source4/libnet/composite.h11
-rw-r--r--source4/libnet/config.mk4
-rw-r--r--source4/libnet/libnet.c3
-rw-r--r--source4/libnet/libnet.h14
-rw-r--r--source4/libnet/libnet_domain.c (renamed from source4/libnet/domain.c)190
-rw-r--r--source4/libnet/libnet_domain.h34
-rw-r--r--source4/libnet/libnet_rpc.c31
-rw-r--r--source4/libnet/libnet_user.c177
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",