summaryrefslogtreecommitdiff
path: root/source4/libnet
diff options
context:
space:
mode:
authorRafal Szczesniak <mimir@samba.org>2005-04-21 07:24:16 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:11:35 -0500
commitdea0c8729f06a192f564ee84600a733869c2b554 (patch)
treed3778091c71e44c0472093da8921f0d67dfefc5c /source4/libnet
parent3df967fe74406b8dd20400c60341a2e402b278bb (diff)
downloadsamba-dea0c8729f06a192f564ee84600a733869c2b554.tar.gz
samba-dea0c8729f06a192f564ee84600a733869c2b554.tar.bz2
samba-dea0c8729f06a192f564ee84600a733869c2b554.zip
r6414: Added composite user del function. Slightly broken still, but I don't
want it to hang around not commited. rafal (This used to be commit 98d98b9bc7437e744e1e730fa8005b43fb1b672b)
Diffstat (limited to 'source4/libnet')
-rw-r--r--source4/libnet/composite.h11
-rw-r--r--source4/libnet/userman.c187
2 files changed, 197 insertions, 1 deletions
diff --git a/source4/libnet/composite.h b/source4/libnet/composite.h
index fe8aad835d..ee7f240c9c 100644
--- a/source4/libnet/composite.h
+++ b/source4/libnet/composite.h
@@ -43,3 +43,14 @@ struct rpc_composite_useradd {
struct policy_handle user_handle;
} out;
};
+
+
+struct rpc_composite_userdel {
+ struct {
+ struct policy_handle domain_handle;
+ const char *username;
+ } in;
+ struct {
+ struct policy_handle user_handle;
+ } out;
+};
diff --git a/source4/libnet/userman.c b/source4/libnet/userman.c
index 72034da75e..6724206b2e 100644
--- a/source4/libnet/userman.c
+++ b/source4/libnet/userman.c
@@ -28,7 +28,11 @@
#include "librpc/gen_ndr/ndr_samr.h"
#include "libnet/composite.h"
-static void useradd_handler(struct rpc_request *req);
+/*
+ * Composite user add function
+ */
+
+static void useradd_handler(struct rpc_request*);
enum useradd_stage { USERADD_CREATE };
@@ -178,3 +182,184 @@ NTSTATUS rpc_composite_useradd(struct dcerpc_pipe *pipe,
struct composite_context *c = rpc_composite_useradd_send(pipe, io);
return rpc_composite_useradd_recv(c, mem_ctx, io);
}
+
+
+/*
+ * Composite user del function
+ */
+
+static void userdel_handler(struct rpc_request*);
+
+enum userdel_stage { USERDEL_LOOKUP, USERDEL_OPEN, USERDEL_DELETE };
+
+struct userdel_state {
+ enum userdel_stage stage;
+ struct dcerpc_pipe *pipe;
+ struct rpc_request *req;
+ struct policy_handle domain_handle;
+ struct policy_handle user_handle;
+ struct samr_LookupNames lookupname;
+ struct samr_OpenUser openuser;
+ struct samr_DeleteUser deleteuser;
+};
+
+
+static NTSTATUS userdel_lookup(struct composite_context *c,
+ struct userdel_state *s)
+{
+ NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+
+ c->status = dcerpc_ndr_request_recv(s->req);
+ NT_STATUS_NOT_OK_RETURN(c->status);
+
+ if (!s->lookupname.out.rids.count) {
+ /* TODO: no such user */
+ status = NT_STATUS_NO_SUCH_USER;
+
+ } else if (!s->lookupname.out.rids.count > 1) {
+ /* TODO: ambiguous username */
+ status = NT_STATUS_INVALID_ACCOUNT_NAME;
+ }
+
+ s->openuser.in.domain_handle = &s->domain_handle;
+ s->openuser.in.rid = s->lookupname.out.rids.ids[0];
+ s->openuser.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ s->openuser.out.user_handle = &s->user_handle;
+
+ s->req = dcerpc_samr_OpenUser_send(s->pipe, c, &s->openuser);
+
+ s->req->async.callback = userdel_handler;
+ s->req->async.private = c;
+ s->stage = USERDEL_OPEN;
+
+ return NT_STATUS_OK;
+failure:
+ talloc_free(c);
+ return status;
+}
+
+
+static NTSTATUS userdel_open(struct composite_context *c,
+ struct userdel_state *s)
+{
+ NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+
+ c->status = dcerpc_ndr_request_recv(s->req);
+ NT_STATUS_NOT_OK_RETURN(c->status);
+
+ s->deleteuser.in.user_handle = &s->user_handle;
+ s->deleteuser.out.user_handle = &s->user_handle;
+
+ s->req = dcerpc_samr_DeleteUser_send(s->pipe, c, &s->deleteuser);
+
+ s->req->async.callback = userdel_handler;
+ s->req->async.private = c;
+ s->stage = USERDEL_DELETE;
+
+ return NT_STATUS_OK;
+}
+
+
+static NTSTATUS userdel_delete(struct composite_context *c,
+ struct userdel_state *s)
+{
+ NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+
+ c->status = dcerpc_ndr_request_recv(s->req);
+ NT_STATUS_NOT_OK_RETURN(c->status);
+
+ c->state = SMBCLI_REQUEST_DONE;
+
+ return NT_STATUS_OK;
+}
+
+
+static void userdel_handler(struct rpc_request *req)
+{
+ struct composite_context *c = req->async.private;
+ struct userdel_state *s = talloc_get_type(c->private, struct userdel_state);
+
+ switch (s->stage) {
+ case USERDEL_LOOKUP:
+ c->status = userdel_lookup(c, s);
+ break;
+ case USERDEL_OPEN:
+ c->status = userdel_open(c, s);
+ break;
+ case USERDEL_DELETE:
+ c->status = userdel_delete(c, s);
+ break;
+ }
+
+ if (!NT_STATUS_IS_OK(c->status)) {
+ c->state = SMBCLI_REQUEST_ERROR;
+ }
+
+ if (c->state >= SMBCLI_REQUEST_DONE &&
+ c->async.fn) {
+ c->async.fn(c);
+ }
+}
+
+
+struct composite_context *rpc_composite_userdel_send(struct dcerpc_pipe *p,
+ struct rpc_composite_userdel *io)
+{
+ struct composite_context *c;
+ struct userdel_state *s;
+
+ c = talloc_zero(p, struct composite_context);
+ if (c == NULL) goto failure;
+
+ s = talloc_zero(c, struct userdel_state);
+ if (s == NULL) goto failure;
+
+ s->pipe = p;
+ c->state = SMBCLI_REQUEST_SEND;
+ c->private = s;
+ c->event_ctx = dcerpc_event_context(p);
+
+ s->lookupname.in.domain_handle = &io->in.domain_handle;
+ s->lookupname.in.num_names = 1;
+ s->lookupname.in.names = talloc_zero(s, struct samr_String);
+ s->lookupname.in.names->string = io->in.username;
+
+ s->req = dcerpc_samr_LookupNames_send(p, c, &s->lookupname);
+
+ s->req->async.callback = userdel_handler;
+ s->req->async.private = c;
+ s->stage = USERDEL_LOOKUP;
+
+ return c;
+
+failure:
+ talloc_free(c);
+ return NULL;
+}
+
+
+NTSTATUS rpc_composite_userdel_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
+ struct rpc_composite_userdel *io)
+{
+ NTSTATUS status;
+ struct userdel_state *s;
+
+ status = composite_wait(c);
+
+ if (NT_STATUS_IS_OK(status) && io) {
+ s = talloc_get_type(c->private, struct userdel_state);
+ io->out.user_handle = s->user_handle;
+ }
+
+ talloc_free(c);
+ return status;
+}
+
+
+NTSTATUS rpc_composite_userdel(struct dcerpc_pipe *pipe,
+ TALLOC_CTX *mem_ctx,
+ struct rpc_composite_userdel *io)
+{
+ struct composite_context *c = rpc_composite_userdel_send(pipe, io);
+ return rpc_composite_userdel_recv(c, mem_ctx, io);
+}