summaryrefslogtreecommitdiff
path: root/source4/libcli/composite
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2005-09-26 11:47:55 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:38:57 -0500
commitab4d635b92b116b02b88843b4ec4f5b7517bab1a (patch)
tree63c3ee12153b629071d2ba0209a0a31b134c449e /source4/libcli/composite
parent0d46be147a1e755bdd6f21a5ddc83b5c39585529 (diff)
downloadsamba-ab4d635b92b116b02b88843b4ec4f5b7517bab1a.tar.gz
samba-ab4d635b92b116b02b88843b4ec4f5b7517bab1a.tar.bz2
samba-ab4d635b92b116b02b88843b4ec4f5b7517bab1a.zip
r10504: - seperate implementation specific stuff, from the generic composite
stuff. - don't use SMBCLI_REQUEST_* state's in the genreic composite stuff - move monitor_fn to libnet. NOTE: I have maybe found some bugs, in code that is dirrectly in DONE or ERROR state in the _send() function. I haven't fixed this bugs in this commit! We may need some composite_trigger_*() functions or so. And maybe some other generic helper functions... metze (This used to be commit 4527815a0a9b96e460f301cb1f0c0b3964c166fc)
Diffstat (limited to 'source4/libcli/composite')
-rw-r--r--source4/libcli/composite/appendacl.c311
-rw-r--r--source4/libcli/composite/composite.c4
-rw-r--r--source4/libcli/composite/composite.h147
-rw-r--r--source4/libcli/composite/connect.c395
-rw-r--r--source4/libcli/composite/fetchfile.c186
-rw-r--r--source4/libcli/composite/fsinfo.c200
-rw-r--r--source4/libcli/composite/loadfile.c293
-rw-r--r--source4/libcli/composite/monitor.h42
-rw-r--r--source4/libcli/composite/savefile.c288
-rw-r--r--source4/libcli/composite/sesssetup.c458
10 files changed, 17 insertions, 2307 deletions
diff --git a/source4/libcli/composite/appendacl.c b/source4/libcli/composite/appendacl.c
deleted file mode 100644
index 76702e6bca..0000000000
--- a/source4/libcli/composite/appendacl.c
+++ /dev/null
@@ -1,311 +0,0 @@
-#include "includes.h"
-#include "libcli/raw/libcliraw.h"
-#include "libcli/composite/composite.h"
-#include "librpc/gen_ndr/ndr_security.h"
-
-/* the stages of this call */
-enum appendacl_stage {APPENDACL_OPENPATH, APPENDACL_GET,
- APPENDACL_SET, APPENDACL_GETAGAIN, APPENDACL_CLOSEPATH};
-
-static void appendacl_handler(struct smbcli_request *req);
-
-struct appendacl_state {
- enum appendacl_stage stage;
- struct smb_composite_appendacl *io;
-
- union smb_open *io_open;
- union smb_setfileinfo *io_setfileinfo;
- union smb_fileinfo *io_fileinfo;
-
- struct smbcli_request *req;
-};
-
-
-static NTSTATUS appendacl_open(struct composite_context *c,
- struct smb_composite_appendacl *io)
-{
- struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state);
- struct smbcli_tree *tree = state->req->tree;
- NTSTATUS status;
-
- status = smb_raw_open_recv(state->req, c, state->io_open);
- NT_STATUS_NOT_OK_RETURN(status);
-
- /* setup structures for getting fileinfo */
- state->io_fileinfo = talloc(c, union smb_fileinfo);
- NT_STATUS_HAVE_NO_MEMORY(state->io_fileinfo);
-
- state->io_fileinfo->query_secdesc.level = RAW_FILEINFO_SEC_DESC;
- state->io_fileinfo->query_secdesc.in.fnum = state->io_open->ntcreatex.out.fnum;
- state->io_fileinfo->query_secdesc.secinfo_flags = SECINFO_DACL;
-
- state->req = smb_raw_fileinfo_send(tree, state->io_fileinfo);
- NT_STATUS_HAVE_NO_MEMORY(state->req);
-
- /* set the handler */
- state->req->async.fn = appendacl_handler;
- state->req->async.private = c;
- state->stage = APPENDACL_GET;
-
- talloc_free (state->io_open);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS appendacl_get(struct composite_context *c,
- struct smb_composite_appendacl *io)
-{
- struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state);
- struct smbcli_tree *tree = state->req->tree;
- int i;
- NTSTATUS status;
-
- status = smb_raw_fileinfo_recv(state->req, state->io_fileinfo, state->io_fileinfo);
- NT_STATUS_NOT_OK_RETURN(status);
-
- /* setup structures for setting fileinfo */
- state->io_setfileinfo = talloc(c, union smb_setfileinfo);
- NT_STATUS_HAVE_NO_MEMORY(state->io_setfileinfo);
-
- state->io_setfileinfo->set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
- state->io_setfileinfo->set_secdesc.file.fnum = state->io_fileinfo->query_secdesc.in.fnum;
-
- state->io_setfileinfo->set_secdesc.in.secinfo_flags = SECINFO_DACL;
- state->io_setfileinfo->set_secdesc.in.sd = state->io_fileinfo->query_secdesc.out.sd;
- talloc_steal(state->io_setfileinfo, state->io_setfileinfo->set_secdesc.in.sd);
-
- /* append all aces from io->in.sd->dacl to new security descriptor */
- if (io->in.sd->dacl != NULL) {
- for (i = 0; i < io->in.sd->dacl->num_aces; i++) {
- security_descriptor_dacl_add(state->io_setfileinfo->set_secdesc.in.sd,
- &(io->in.sd->dacl->aces[i]));
- }
- }
-
- status = smb_raw_setfileinfo(tree, state->io_setfileinfo);
- NT_STATUS_NOT_OK_RETURN(status);
-
- state->req = smb_raw_setfileinfo_send(tree, state->io_setfileinfo);
- NT_STATUS_HAVE_NO_MEMORY(state->req);
-
- /* call handler when done setting new security descriptor on file */
- state->req->async.fn = appendacl_handler;
- state->req->async.private = c;
- state->stage = APPENDACL_SET;
-
- talloc_free (state->io_fileinfo);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS appendacl_set(struct composite_context *c,
- struct smb_composite_appendacl *io)
-{
- struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state);
- struct smbcli_tree *tree = state->req->tree;
- NTSTATUS status;
-
- status = smbcli_request_simple_recv(state->req);
- NT_STATUS_NOT_OK_RETURN(status);
-
- /* setup structures for getting fileinfo */
- state->io_fileinfo = talloc(c, union smb_fileinfo);
- NT_STATUS_HAVE_NO_MEMORY(state->io_fileinfo);
-
-
- state->io_fileinfo->query_secdesc.level = RAW_FILEINFO_SEC_DESC;
- state->io_fileinfo->query_secdesc.in.fnum = state->io_setfileinfo->set_secdesc.file.fnum;
- state->io_fileinfo->query_secdesc.secinfo_flags = SECINFO_DACL;
-
- state->req = smb_raw_fileinfo_send(tree, state->io_fileinfo);
- NT_STATUS_HAVE_NO_MEMORY(state->req);
-
- /* set the handler */
- state->req->async.fn = appendacl_handler;
- state->req->async.private = c;
- state->stage = APPENDACL_GETAGAIN;
-
- talloc_free (state->io_setfileinfo);
-
- return NT_STATUS_OK;
-}
-
-
-static NTSTATUS appendacl_getagain(struct composite_context *c,
- struct smb_composite_appendacl *io)
-{
- struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state);
- struct smbcli_tree *tree = state->req->tree;
- union smb_close *io_close;
- NTSTATUS status;
-
- status = smb_raw_fileinfo_recv(state->req, c, state->io_fileinfo);
- NT_STATUS_NOT_OK_RETURN(status);
-
- io->out.sd = state->io_fileinfo->query_secdesc.out.sd;
-
- /* setup structures for close */
- io_close = talloc(c, union smb_close);
- NT_STATUS_HAVE_NO_MEMORY(io_close);
-
- io_close->close.level = RAW_CLOSE_CLOSE;
- io_close->close.in.fnum = state->io_fileinfo->query_secdesc.in.fnum;
- io_close->close.in.write_time = 0;
-
- state->req = smb_raw_close_send(tree, io_close);
- NT_STATUS_HAVE_NO_MEMORY(state->req);
-
- /* call the handler */
- state->req->async.fn = appendacl_handler;
- state->req->async.private = c;
- state->stage = APPENDACL_CLOSEPATH;
-
- talloc_free (state->io_fileinfo);
-
- return NT_STATUS_OK;
-}
-
-
-
-static NTSTATUS appendacl_close(struct composite_context *c,
- struct smb_composite_appendacl *io)
-{
- struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state);
- NTSTATUS status;
-
- status = smbcli_request_simple_recv(state->req);
- NT_STATUS_NOT_OK_RETURN(status);
-
- c->state = SMBCLI_REQUEST_DONE;
-
- return NT_STATUS_OK;
-}
-
-/*
- handler for completion of a sub-request in appendacl
-*/
-static void appendacl_handler(struct smbcli_request *req)
-{
- struct composite_context *c = req->async.private;
- struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state);
-
- /* when this handler is called, the stage indicates what
- call has just finished */
- switch (state->stage) {
- case APPENDACL_OPENPATH:
- c->status = appendacl_open(c, state->io);
- break;
-
- case APPENDACL_GET:
- c->status = appendacl_get(c, state->io);
- break;
-
- case APPENDACL_SET:
- c->status = appendacl_set(c, state->io);
- break;
-
- case APPENDACL_GETAGAIN:
- c->status = appendacl_getagain(c, state->io);
- break;
-
- case APPENDACL_CLOSEPATH:
- c->status = appendacl_close(c, state->io);
- break;
- }
-
- /* We should get here if c->state >= SMBCLI_REQUEST_DONE */
- 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);
- }
-}
-
-
-/*
- composite appendacl call - does an open followed by a number setfileinfo,
- after that new acls are read with fileinfo, followed by a close
-*/
-struct composite_context *smb_composite_appendacl_send(struct smbcli_tree *tree,
- struct smb_composite_appendacl *io)
-{
- struct composite_context *c;
- struct appendacl_state *state;
-
- c = talloc_zero(tree, struct composite_context);
- if (c == NULL) goto failed;
-
- state = talloc(c, struct appendacl_state);
- if (state == NULL) goto failed;
-
- state->io = io;
-
- c->private = state;
- c->state = SMBCLI_REQUEST_SEND;
- c->event_ctx = tree->session->transport->socket->event.ctx;
-
- /* setup structures for opening file */
- state->io_open = talloc_zero(c, union smb_open);
- if (state->io_open == NULL) goto failed;
-
- state->io_open->ntcreatex.level = RAW_OPEN_NTCREATEX;
- state->io_open->ntcreatex.in.root_fid = 0;
- state->io_open->ntcreatex.in.flags = 0;
- state->io_open->ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- state->io_open->ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
- state->io_open->ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
- state->io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
- state->io_open->ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
- state->io_open->ntcreatex.in.security_flags = 0;
- state->io_open->ntcreatex.in.fname = io->in.fname;
-
- /* send the open on its way */
- state->req = smb_raw_open_send(tree, state->io_open);
- if (state->req == NULL) goto failed;
-
- /* setup the callback handler */
- state->req->async.fn = appendacl_handler;
- state->req->async.private = c;
- state->stage = APPENDACL_OPENPATH;
-
- return c;
-
-failed:
- talloc_free(c);
- return NULL;
-}
-
-
-/*
- composite appendacl call - recv side
-*/
-NTSTATUS smb_composite_appendacl_recv(struct composite_context *c, TALLOC_CTX *mem_ctx)
-{
- NTSTATUS status;
-
- status = composite_wait(c);
-
- if (NT_STATUS_IS_OK(status)) {
- struct appendacl_state *state = talloc_get_type(c->private, struct appendacl_state);
- state->io->out.sd = security_descriptor_copy (mem_ctx, state->io->out.sd);
- }
-
- talloc_free(c);
- return status;
-}
-
-
-/*
- composite appendacl call - sync interface
-*/
-NTSTATUS smb_composite_appendacl(struct smbcli_tree *tree,
- TALLOC_CTX *mem_ctx,
- struct smb_composite_appendacl *io)
-{
- struct composite_context *c = smb_composite_appendacl_send(tree, io);
- return smb_composite_appendacl_recv(c, mem_ctx);
-}
-
diff --git a/source4/libcli/composite/composite.c b/source4/libcli/composite/composite.c
index f04309bbfb..4a5247c9ea 100644
--- a/source4/libcli/composite/composite.c
+++ b/source4/libcli/composite/composite.c
@@ -34,7 +34,7 @@ NTSTATUS composite_wait(struct composite_context *c)
{
if (c == NULL) return NT_STATUS_NO_MEMORY;
- while (c->state < SMBCLI_REQUEST_DONE) {
+ while (c->state < COMPOSITE_STATE_DONE) {
if (event_loop_once(c->event_ctx) != 0) {
return NT_STATUS_UNSUCCESSFUL;
}
@@ -51,7 +51,6 @@ static void composite_trigger(struct event_context *ev, struct timed_event *te,
struct timeval t, void *ptr)
{
struct composite_context *c = talloc_get_type(ptr, struct composite_context);
- c->state = SMBCLI_REQUEST_DONE;
if (c->async.fn) {
c->async.fn(c);
}
@@ -65,6 +64,7 @@ static void composite_trigger(struct event_context *ev, struct timed_event *te,
*/
void composite_trigger_done(struct composite_context *c)
{
+ c->state = COMPOSITE_STATE_DONE;
/* a zero timeout means immediate */
event_add_timed(c->event_ctx, c, timeval_zero(), composite_trigger, c);
}
diff --git a/source4/libcli/composite/composite.h b/source4/libcli/composite/composite.h
index be7fbd9972..83857edd14 100644
--- a/source4/libcli/composite/composite.h
+++ b/source4/libcli/composite/composite.h
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
- SMB composite request interfaces
+ composite request interfaces
Copyright (C) Andrew Tridgell 2005
@@ -23,19 +23,28 @@
/*
this defines the structures associated with "composite"
requests. Composite requests are libcli requests that are internally
- implemented as multiple libcli/raw/ calls, but can be treated as a
+ implemented as multiple async calls, but can be treated as a
single call via these composite calls. The composite calls are
- particularly designed to be used in async applications
+ particularly designed to be used in async applications.
+ you can also stack multiple level of composite call
*/
+/*
+ a composite call moves between the following 3 states.
+*/
+enum composite_state {COMPOSITE_STATE_INIT, /* we are creating the request */
+ COMPOSITE_STATE_IN_PROGRESS, /* the request is in the outgoing socket Q */
+ COMPOSITE_STATE_DONE, /* the request is received by the caller finished */
+ COMPOSITE_STATE_ERROR}; /* a packet or transport level error has occurred */
+/* the context of one "composite" call */
struct composite_context {
/* the external state - will be queried by the caller */
- enum smbcli_request_state state;
+ enum composite_state state;
/* a private pointer for use by the composite function
implementation */
- void *private;
+ void *private_data;
/* status code when finished */
NTSTATUS status;
@@ -46,132 +55,6 @@ struct composite_context {
/* information on what to do on completion */
struct {
void (*fn)(struct composite_context *);
- void *private;
+ void *private_data;
} async;
-
- /* information about the progress */
- void (*monitor_fn)(struct monitor_msg *);
-};
-
-
-/*
- a composite open/read(s)/close request that loads a whole file
- into memory. Used as a demo of the composite system.
-*/
-struct smb_composite_loadfile {
- struct {
- const char *fname;
- } in;
- struct {
- uint8_t *data;
- uint32_t size;
- } out;
-};
-
-struct smb_composite_fetchfile {
- struct {
- const char *dest_host;
- int port;
- const char *called_name;
- const char *service;
- const char *service_type;
- struct cli_credentials *credentials;
- const char *workgroup;
- const char *filename;
- } in;
- struct {
- uint8_t *data;
- uint32_t size;
- } out;
-};
-
-/*
- a composite open/write(s)/close request that saves a whole file from
- memory. Used as a demo of the composite system.
-*/
-struct smb_composite_savefile {
- struct {
- const char *fname;
- uint8_t *data;
- uint32_t size;
- } in;
-};
-
-
-/*
- a composite request for a full connection to a remote server. Includes
-
- - socket establishment
- - session request
- - negprot
- - session setup
- - tree connect
-*/
-struct smb_composite_connect {
- struct {
- const char *dest_host;
- int port;
- const char *called_name;
- const char *service;
- const char *service_type;
- struct cli_credentials *credentials;
- const char *workgroup;
- } in;
- struct {
- struct smbcli_tree *tree;
- } out;
-};
-
-
-/*
- generic session setup interface that takes care of which
- session setup varient to use
-*/
-struct smb_composite_sesssetup {
- struct {
- uint32_t sesskey;
- uint32_t capabilities;
- struct cli_credentials *credentials;
- const char *workgroup;
- } in;
- struct {
- uint16_t vuid;
- } out;
-};
-
-/*
- query file system info
-*/
-struct smb_composite_fsinfo {
- struct {
- const char *dest_host;
- int port;
- const char *called_name;
- const char *service;
- const char *service_type;
- struct cli_credentials *credentials;
- const char *workgroup;
- enum smb_fsinfo_level level;
- } in;
-
- struct {
- union smb_fsinfo *fsinfo;
- } out;
-};
-
-/*
- composite call for appending new acl to the file's security descriptor and get
- new full acl
-*/
-
-struct smb_composite_appendacl {
- struct {
- const char *fname;
-
- const struct security_descriptor *sd;
- } in;
-
- struct {
- struct security_descriptor *sd;
- } out;
};
diff --git a/source4/libcli/composite/connect.c b/source4/libcli/composite/connect.c
deleted file mode 100644
index a5ce5308e5..0000000000
--- a/source4/libcli/composite/connect.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Copyright (C) Andrew Tridgell 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.
-*/
-/*
- a composite API for making a full SMB connection
-*/
-
-#include "includes.h"
-#include "libcli/raw/libcliraw.h"
-#include "libcli/composite/composite.h"
-
-/* the stages of this call */
-enum connect_stage {CONNECT_RESOLVE,
- CONNECT_SOCKET,
- CONNECT_SESSION_REQUEST,
- CONNECT_NEGPROT,
- CONNECT_SESSION_SETUP,
- CONNECT_TCON};
-
-struct connect_state {
- enum connect_stage stage;
- struct smbcli_socket *sock;
- struct smbcli_transport *transport;
- struct smbcli_session *session;
- struct smb_composite_connect *io;
- union smb_tcon *io_tcon;
- struct smb_composite_sesssetup *io_setup;
- struct smbcli_request *req;
- struct composite_context *creq;
-};
-
-
-static void request_handler(struct smbcli_request *);
-static void composite_handler(struct composite_context *);
-
-/*
- setup a negprot send
-*/
-static NTSTATUS connect_send_negprot(struct composite_context *c,
- struct smb_composite_connect *io)
-{
- struct connect_state *state = talloc_get_type(c->private, struct connect_state);
-
- state->req = smb_raw_negotiate_send(state->transport, lp_maxprotocol());
- NT_STATUS_HAVE_NO_MEMORY(state->req);
-
- state->req->async.fn = request_handler;
- state->req->async.private = c;
- state->stage = CONNECT_NEGPROT;
-
- return NT_STATUS_OK;
-}
-
-
-/*
- a tree connect request has competed
-*/
-static NTSTATUS connect_tcon(struct composite_context *c,
- struct smb_composite_connect *io)
-{
- struct connect_state *state = talloc_get_type(c->private, struct connect_state);
- NTSTATUS status;
-
- status = smb_raw_tcon_recv(state->req, c, state->io_tcon);
- NT_STATUS_NOT_OK_RETURN(status);
-
- io->out.tree->tid = state->io_tcon->tconx.out.tid;
- if (state->io_tcon->tconx.out.dev_type) {
- io->out.tree->device = talloc_strdup(io->out.tree,
- state->io_tcon->tconx.out.dev_type);
- }
- if (state->io_tcon->tconx.out.fs_type) {
- io->out.tree->fs_type = talloc_strdup(io->out.tree,
- state->io_tcon->tconx.out.fs_type);
- }
-
- /* all done! */
- c->state = SMBCLI_REQUEST_DONE;
-
- return NT_STATUS_OK;
-}
-
-
-/*
- a session setup request has competed
-*/
-static NTSTATUS connect_session_setup(struct composite_context *c,
- struct smb_composite_connect *io)
-{
- struct connect_state *state = talloc_get_type(c->private, struct connect_state);
- NTSTATUS status;
-
- status = smb_composite_sesssetup_recv(state->creq);
- NT_STATUS_NOT_OK_RETURN(status);
-
- state->session->vuid = state->io_setup->out.vuid;
-
- /* setup for a tconx */
- io->out.tree = smbcli_tree_init(state->session, state, True);
- NT_STATUS_HAVE_NO_MEMORY(io->out.tree);
-
- state->io_tcon = talloc(c, union smb_tcon);
- NT_STATUS_HAVE_NO_MEMORY(state->io_tcon);
-
- /* connect to a share using a tree connect */
- state->io_tcon->generic.level = RAW_TCON_TCONX;
- state->io_tcon->tconx.in.flags = 0;
- state->io_tcon->tconx.in.password = data_blob(NULL, 0);
-
- state->io_tcon->tconx.in.path = talloc_asprintf(state->io_tcon,
- "\\\\%s\\%s",
- io->in.called_name,
- io->in.service);
- NT_STATUS_HAVE_NO_MEMORY(state->io_tcon->tconx.in.path);
- if (!io->in.service_type) {
- state->io_tcon->tconx.in.device = "?????";
- } else {
- state->io_tcon->tconx.in.device = io->in.service_type;
- }
-
- state->req = smb_raw_tcon_send(io->out.tree, state->io_tcon);
- NT_STATUS_HAVE_NO_MEMORY(state->req);
- if (state->req->state == SMBCLI_REQUEST_ERROR) {
- return state->req->status;
- }
-
- state->req->async.fn = request_handler;
- state->req->async.private = c;
- state->stage = CONNECT_TCON;
-
- return NT_STATUS_OK;
-}
-
-/*
- a negprot request has competed
-*/
-static NTSTATUS connect_negprot(struct composite_context *c,
- struct smb_composite_connect *io)
-{
- struct connect_state *state = talloc_get_type(c->private, struct connect_state);
- NTSTATUS status;
-
- status = smb_raw_negotiate_recv(state->req);
- NT_STATUS_NOT_OK_RETURN(status);
-
- /* next step is a session setup */
- state->session = smbcli_session_init(state->transport, state, True);
- NT_STATUS_HAVE_NO_MEMORY(state->session);
-
- state->io_setup = talloc(c, struct smb_composite_sesssetup);
- NT_STATUS_HAVE_NO_MEMORY(state->io_setup);
-
- /* prepare a session setup to establish a security context */
- state->io_setup->in.sesskey = state->transport->negotiate.sesskey;
- state->io_setup->in.capabilities = state->transport->negotiate.capabilities;
- state->io_setup->in.credentials = io->in.credentials;
- state->io_setup->in.workgroup = io->in.workgroup;
-
- state->creq = smb_composite_sesssetup_send(state->session, state->io_setup);
- NT_STATUS_HAVE_NO_MEMORY(state->creq);
- if (state->creq->state == SMBCLI_REQUEST_ERROR) {
- return state->creq->status;
- }
-
- state->creq->async.fn = composite_handler;
- state->creq->async.private = c;
- state->stage = CONNECT_SESSION_SETUP;
-
- return NT_STATUS_OK;
-}
-
-
-/*
- a session request operation has competed
-*/
-static NTSTATUS connect_session_request(struct composite_context *c,
- struct smb_composite_connect *io)
-{
- struct connect_state *state = talloc_get_type(c->private, struct connect_state);
- NTSTATUS status;
-
- status = smbcli_transport_connect_recv(state->req);
- NT_STATUS_NOT_OK_RETURN(status);
-
- /* next step is a negprot */
- return connect_send_negprot(c, io);
-}
-
-/*
- a socket connection operation has competed
-*/
-static NTSTATUS connect_socket(struct composite_context *c,
- struct smb_composite_connect *io)
-{
- struct connect_state *state = talloc_get_type(c->private, struct connect_state);
- NTSTATUS status;
- struct nbt_name calling, called;
-
- status = smbcli_sock_connect_recv(state->creq);
- NT_STATUS_NOT_OK_RETURN(status);
-
- /* the socket is up - we can initialise the smbcli transport layer */
- state->transport = smbcli_transport_init(state->sock, state, True);
- NT_STATUS_HAVE_NO_MEMORY(state->transport);
-
- make_nbt_name_client(&calling, cli_credentials_get_workstation(io->in.credentials));
-
- nbt_choose_called_name(state, &called, io->in.called_name, NBT_NAME_SERVER);
-
- /* we have a connected socket - next step is a session
- request, if needed. Port 445 doesn't need it, so it goes
- straight to the negprot */
- if (state->sock->port == 445) {
- status = nbt_name_dup(state->transport, &called,
- &state->transport->called);
- NT_STATUS_NOT_OK_RETURN(status);
- return connect_send_negprot(c, io);
- }
-
- state->req = smbcli_transport_connect_send(state->transport, &calling, &called);
- NT_STATUS_HAVE_NO_MEMORY(state->req);
-
- state->req->async.fn = request_handler;
- state->req->async.private = c;
- state->stage = CONNECT_SESSION_REQUEST;
-
- return NT_STATUS_OK;
-}
-
-
-/*
- called when name resolution is finished
-*/
-static NTSTATUS connect_resolve(struct composite_context *c,
- struct smb_composite_connect *io)
-{
- struct connect_state *state = talloc_get_type(c->private, struct connect_state);
- NTSTATUS status;
- const char *address;
-
- status = resolve_name_recv(state->creq, state, &address);
- NT_STATUS_NOT_OK_RETURN(status);
-
- state->creq = smbcli_sock_connect_send(state->sock, address, state->io->in.port, io->in.dest_host);
- NT_STATUS_HAVE_NO_MEMORY(state->creq);
-
- state->stage = CONNECT_SOCKET;
- state->creq->async.private = c;
- state->creq->async.fn = composite_handler;
-
- return NT_STATUS_OK;
-}
-
-
-/*
- handle and dispatch state transitions
-*/
-static void state_handler(struct composite_context *c)
-{
- struct connect_state *state = talloc_get_type(c->private, struct connect_state);
-
- switch (state->stage) {
- case CONNECT_RESOLVE:
- c->status = connect_resolve(c, state->io);
- break;
- case CONNECT_SOCKET:
- c->status = connect_socket(c, state->io);
- break;
- case CONNECT_SESSION_REQUEST:
- c->status = connect_session_request(c, state->io);
- break;
- case CONNECT_NEGPROT:
- c->status = connect_negprot(c, state->io);
- break;
- case CONNECT_SESSION_SETUP:
- c->status = connect_session_setup(c, state->io);
- break;
- case CONNECT_TCON:
- c->status = connect_tcon(c, state->io);
- 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);
- }
-}
-
-
-/*
- handler for completion of a smbcli_request sub-request
-*/
-static void request_handler(struct smbcli_request *req)
-{
- struct composite_context *c = talloc_get_type(req->async.private,
- struct composite_context);
- state_handler(c);
-}
-
-/*
- handler for completion of a smbcli_composite sub-request
-*/
-static void composite_handler(struct composite_context *req)
-{
- struct composite_context *c = talloc_get_type(req->async.private,
- struct composite_context);
- state_handler(c);
-}
-
-/*
- a function to establish a smbcli_tree from scratch
-*/
-struct composite_context *smb_composite_connect_send(struct smb_composite_connect *io,
- struct event_context *event_ctx)
-{
- struct composite_context *c;
- struct connect_state *state;
- struct nbt_name name;
-
- c = talloc_zero(NULL, struct composite_context);
- if (c == NULL) goto failed;
-
- state = talloc(c, struct connect_state);
- if (state == NULL) goto failed;
-
- state->sock = smbcli_sock_init(state, event_ctx);
- if (state->sock == NULL) goto failed;
-
- state->io = io;
-
- c->state = SMBCLI_REQUEST_SEND;
- c->event_ctx = talloc_reference(c, state->sock->event.ctx);
- c->private = state;
-
- state->stage = CONNECT_RESOLVE;
- make_nbt_name_server(&name, io->in.dest_host);
- state->creq = resolve_name_send(&name, c->event_ctx, lp_name_resolve_order());
-
- if (state->creq == NULL) goto failed;
- state->creq->async.private = c;
- state->creq->async.fn = composite_handler;
-
- return c;
-failed:
- talloc_free(c);
- return NULL;
-}
-
-/*
- recv half of async composite connect code
-*/
-NTSTATUS smb_composite_connect_recv(struct composite_context *c, TALLOC_CTX *mem_ctx)
-{
- NTSTATUS status;
-
- status = composite_wait(c);
-
- if (NT_STATUS_IS_OK(status)) {
- struct connect_state *state = talloc_get_type(c->private, struct connect_state);
- talloc_steal(mem_ctx, state->io->out.tree);
- }
-
- talloc_free(c);
- return status;
-}
-
-/*
- sync version of smb_composite_connect
-*/
-NTSTATUS smb_composite_connect(struct smb_composite_connect *io, TALLOC_CTX *mem_ctx,
- struct event_context *ev)
-{
- struct composite_context *c = smb_composite_connect_send(io, ev);
- return smb_composite_connect_recv(c, mem_ctx);
-}
diff --git a/source4/libcli/composite/fetchfile.c b/source4/libcli/composite/fetchfile.c
deleted file mode 100644
index c9e8321db2..0000000000
--- a/source4/libcli/composite/fetchfile.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Copyright (C) Volker Lendecke 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.
-*/
-/*
- a composite API for loading a whole file into memory
-*/
-
-#include "includes.h"
-#include "libcli/raw/libcliraw.h"
-#include "libcli/composite/composite.h"
-
-enum fetchfile_stage {FETCHFILE_CONNECT,
- FETCHFILE_READ};
-
-struct fetchfile_state {
- enum fetchfile_stage stage;
- struct smb_composite_fetchfile *io;
- struct composite_context *req;
- struct smb_composite_connect *connect;
- struct smb_composite_loadfile *loadfile;
-};
-
-static void fetchfile_composite_handler(struct composite_context *req);
-
-static NTSTATUS fetchfile_connect(struct composite_context *c,
- struct smb_composite_fetchfile *io)
-{
- NTSTATUS status;
- struct fetchfile_state *state;
- state = talloc_get_type(c->private, struct fetchfile_state);
-
- status = smb_composite_connect_recv(state->req, c);
- NT_STATUS_NOT_OK_RETURN(status);
-
- state->loadfile = talloc(state, struct smb_composite_loadfile);
- NT_STATUS_HAVE_NO_MEMORY(state->loadfile);
-
- state->loadfile->in.fname = io->in.filename;
-
- state->req = smb_composite_loadfile_send(state->connect->out.tree,
- state->loadfile);
- NT_STATUS_HAVE_NO_MEMORY(state->req);
-
- state->req->async.private = c;
- state->req->async.fn = fetchfile_composite_handler;
-
- state->stage = FETCHFILE_READ;
- c->event_ctx = talloc_reference(c, state->req->event_ctx);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS fetchfile_read(struct composite_context *c,
- struct smb_composite_fetchfile *io)
-{
- NTSTATUS status;
- struct fetchfile_state *state;
- state = talloc_get_type(c->private, struct fetchfile_state);
-
- status = smb_composite_loadfile_recv(state->req, NULL);
- NT_STATUS_NOT_OK_RETURN(status);
-
- io->out.data = state->loadfile->out.data;
- io->out.size = state->loadfile->out.size;
-
- c->state = SMBCLI_REQUEST_DONE;
- if (c->async.fn)
- c->async.fn(c);
-
- return NT_STATUS_OK;
-}
-
-static void fetchfile_state_handler(struct composite_context *c)
-{
- struct fetchfile_state *state;
- NTSTATUS status;
-
- state = talloc_get_type(c->private, struct fetchfile_state);
-
- /* when this handler is called, the stage indicates what
- call has just finished */
- switch (state->stage) {
- case FETCHFILE_CONNECT:
- status = fetchfile_connect(c, state->io);
- break;
- case FETCHFILE_READ:
- status = fetchfile_read(c, state->io);
- break;
- }
-
- if (!NT_STATUS_IS_OK(status)) {
- c->status = status;
- c->state = SMBCLI_REQUEST_ERROR;
- if (c->async.fn) {
- c->async.fn(c);
- }
- }
-}
-
-static void fetchfile_composite_handler(struct composite_context *req)
-{
- struct composite_context *c = talloc_get_type(req->async.private,
- struct composite_context);
- fetchfile_state_handler(c);
-}
-
-struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetchfile *io,
- struct event_context *event_ctx)
-{
- struct composite_context *c;
- struct fetchfile_state *state;
-
- c = talloc_zero(NULL, struct composite_context);
- if (c == NULL) goto failed;
-
- state = talloc(c, struct fetchfile_state);
- if (state == NULL) goto failed;
-
- state->connect = talloc(state, struct smb_composite_connect);
- if (state->connect == NULL) goto failed;
-
- state->io = io;
-
- state->connect->in.dest_host = io->in.dest_host;
- state->connect->in.port = io->in.port;
- state->connect->in.called_name = io->in.called_name;
- state->connect->in.service = io->in.service;
- state->connect->in.service_type = io->in.service_type;
- state->connect->in.credentials = io->in.credentials;
- state->connect->in.workgroup = io->in.workgroup;
-
- state->req = smb_composite_connect_send(state->connect, event_ctx);
- if (state->req == NULL) goto failed;
-
- state->req->async.private = c;
- state->req->async.fn = fetchfile_composite_handler;
-
- c->state = SMBCLI_REQUEST_SEND;
- state->stage = FETCHFILE_CONNECT;
- c->event_ctx = talloc_reference(c, state->req->event_ctx);
- c->private = state;
-
- return c;
- failed:
- talloc_free(c);
- return NULL;
-}
-
-NTSTATUS smb_composite_fetchfile_recv(struct composite_context *c,
- TALLOC_CTX *mem_ctx)
-{
- NTSTATUS status;
-
- status = composite_wait(c);
-
- if (NT_STATUS_IS_OK(status)) {
- struct fetchfile_state *state = talloc_get_type(c->private, struct fetchfile_state);
- talloc_steal(mem_ctx, state->io->out.data);
- }
-
- talloc_free(c);
- return status;
-}
-
-NTSTATUS smb_composite_fetchfile(struct smb_composite_fetchfile *io,
- TALLOC_CTX *mem_ctx)
-{
- struct composite_context *c = smb_composite_fetchfile_send(io, NULL);
- return smb_composite_fetchfile_recv(c, mem_ctx);
-}
diff --git a/source4/libcli/composite/fsinfo.c b/source4/libcli/composite/fsinfo.c
deleted file mode 100644
index e0accbb6a6..0000000000
--- a/source4/libcli/composite/fsinfo.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- a composite API for quering file system information
-*/
-
-#include "includes.h"
-#include "libcli/raw/libcliraw.h"
-#include "libcli/composite/composite.h"
-#include "librpc/gen_ndr/ndr_security.h"
-
-/* the stages of this call */
-enum fsinfo_stage {FSINFO_CONNECT, FSINFO_QUERY};
-
-
-static void fsinfo_raw_handler(struct smbcli_request *req);
-static void fsinfo_composite_handler(struct composite_context *c);
-static void fsinfo_state_handler(struct composite_context *c);
-
-struct fsinfo_state {
- enum fsinfo_stage stage;
- struct composite_context *creq;
- struct smb_composite_fsinfo *io;
- struct smb_composite_connect *connect;
- union smb_fsinfo *fsinfo;
- struct smbcli_tree *tree;
- struct smbcli_request *req;
-};
-
-static NTSTATUS fsinfo_connect(struct composite_context *c,
- struct smb_composite_fsinfo *io)
-{
- NTSTATUS status;
- struct fsinfo_state *state;
- state = talloc_get_type(c->private, struct fsinfo_state);
-
- status = smb_composite_connect_recv(state->creq, c);
- NT_STATUS_NOT_OK_RETURN(status);
-
- state->fsinfo = talloc(state, union smb_fsinfo);
- NT_STATUS_HAVE_NO_MEMORY(state->fsinfo);
-
- state->fsinfo->generic.level = io->in.level;
-
- state->req = smb_raw_fsinfo_send(state->connect->out.tree,
- state,
- state->fsinfo);
- NT_STATUS_HAVE_NO_MEMORY(state->req);
-
- state->req->async.private = c;
- state->req->async.fn = fsinfo_raw_handler;
-
- state->stage = FSINFO_QUERY;
- c->event_ctx = talloc_reference(c, state->req->session->transport->socket->event.ctx);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS fsinfo_query(struct composite_context *c,
- struct smb_composite_fsinfo *io)
-{
- NTSTATUS status;
- struct fsinfo_state *state;
- state = talloc_get_type(c->private, struct fsinfo_state);
-
- status = smb_raw_fsinfo_recv(state->req, state, state->fsinfo);
- NT_STATUS_NOT_OK_RETURN(status);
-
- state->io->out.fsinfo = state->fsinfo;
-
- c->state = SMBCLI_REQUEST_DONE;
-
- if (c->async.fn)
- c->async.fn(c);
-
- return NT_STATUS_OK;
-
-}
-
-/*
- handler for completion of a sub-request in fsinfo
-*/
-static void fsinfo_state_handler(struct composite_context *req)
-{
- struct fsinfo_state *state = talloc_get_type(req->private, struct fsinfo_state);
-
- /* when this handler is called, the stage indicates what
- call has just finished */
- switch (state->stage) {
- case FSINFO_CONNECT:
- req->status = fsinfo_connect(req, state->io);
- break;
-
- case FSINFO_QUERY:
- req->status = fsinfo_query(req, state->io);
- break;
- }
-
- if (!NT_STATUS_IS_OK(req->status)) {
- req->state = SMBCLI_REQUEST_ERROR;
- }
-
- if (req->state >= SMBCLI_REQUEST_DONE && req->async.fn) {
- req->async.fn(req);
- }
-}
-
-/*
- As raw and composite handlers take different requests, we need to handlers
- to adapt both for the same state machine in fsinfo_state_handler()
-*/
-static void fsinfo_raw_handler(struct smbcli_request *req)
-{
- struct composite_context *c = talloc_get_type(req->async.private,
- struct composite_context);
- fsinfo_state_handler(c);
-}
-
-static void fsinfo_composite_handler(struct composite_context *req)
-{
- struct composite_context *c = talloc_get_type(req->async.private,
- struct composite_context);
- fsinfo_state_handler(c);
-}
-
-/*
- composite fsinfo call - connects to a tree and queries a file system information
-*/
-struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree,
- struct smb_composite_fsinfo *io)
-{
- struct composite_context *c;
- struct fsinfo_state *state;
-
- c = talloc_zero(tree, struct composite_context);
- if (c == NULL) goto failed;
-
- state = talloc(c, struct fsinfo_state);
- if (state == NULL) goto failed;
-
- state->io = io;
-
- state->connect = talloc(state, struct smb_composite_connect);
-
- if (state->connect == NULL) goto failed;
-
- state->connect->in.dest_host = io->in.dest_host;
- state->connect->in.port = io->in.port;
- state->connect->in.called_name = io->in.called_name;
- state->connect->in.service = io->in.service;
- state->connect->in.service_type = io->in.service_type;
- state->connect->in.credentials = io->in.credentials;
- state->connect->in.workgroup = io->in.workgroup;
-
- c->state = SMBCLI_REQUEST_SEND;
- state->stage = FSINFO_CONNECT;
- c->event_ctx = talloc_reference(c, tree->session->transport->socket->event.ctx);
- c->private = state;
-
- state->creq = smb_composite_connect_send(state->connect, c->event_ctx);
-
- if (state->creq == NULL) goto failed;
-
- state->creq->async.private = c;
- state->creq->async.fn = fsinfo_composite_handler;
-
- return c;
-failed:
- talloc_free(c);
- return NULL;
-}
-
-/*
- composite fsinfo call - recv side
-*/
-NTSTATUS smb_composite_fsinfo_recv(struct composite_context *c, TALLOC_CTX *mem_ctx)
-{
- NTSTATUS status;
-
- status = composite_wait(c);
-
- if (NT_STATUS_IS_OK(status)) {
- struct fsinfo_state *state = talloc_get_type(c->private, struct fsinfo_state);
- talloc_steal(mem_ctx, state->io->out.fsinfo);
- }
-
- talloc_free(c);
- return status;
-}
-
-
-/*
- composite fsinfo call - sync interface
-*/
-NTSTATUS smb_composite_fsinfo(struct smbcli_tree *tree,
- TALLOC_CTX *mem_ctx,
- struct smb_composite_fsinfo *io)
-{
- struct composite_context *c = smb_composite_fsinfo_send(tree, io);
- return smb_composite_fsinfo_recv(c, mem_ctx);
-}
-
diff --git a/source4/libcli/composite/loadfile.c b/source4/libcli/composite/loadfile.c
deleted file mode 100644
index 69a8219dba..0000000000
--- a/source4/libcli/composite/loadfile.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Copyright (C) Andrew Tridgell 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.
-*/
-/*
- a composite API for loading a whole file into memory
-*/
-
-#include "includes.h"
-#include "libcli/raw/libcliraw.h"
-#include "libcli/composite/composite.h"
-#include "librpc/gen_ndr/ndr_security.h"
-
-/* the stages of this call */
-enum loadfile_stage {LOADFILE_OPEN, LOADFILE_READ, LOADFILE_CLOSE};
-
-
-static void loadfile_handler(struct smbcli_request *req);
-
-struct loadfile_state {
- enum loadfile_stage stage;
- struct smb_composite_loadfile *io;
- struct smbcli_request *req;
- union smb_open *io_open;
- union smb_read *io_read;
-};
-
-/*
- setup for the close
-*/
-static NTSTATUS setup_close(struct composite_context *c,
- struct smbcli_tree *tree, uint16_t fnum)
-{
- struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state);
- union smb_close *io_close;
-
- /* nothing to read, setup the close */
- io_close = talloc(c, union smb_close);
- NT_STATUS_HAVE_NO_MEMORY(io_close);
-
- io_close->close.level = RAW_CLOSE_CLOSE;
- io_close->close.in.fnum = fnum;
- io_close->close.in.write_time = 0;
-
- state->req = smb_raw_close_send(tree, io_close);
- NT_STATUS_HAVE_NO_MEMORY(state->req);
-
- /* call the handler again when the close is done */
- state->req->async.fn = loadfile_handler;
- state->req->async.private = c;
- state->stage = LOADFILE_CLOSE;
-
- return NT_STATUS_OK;
-}
-
-/*
- called when the open is done - pull the results and setup for the
- first readx, or close if the file is zero size
-*/
-static NTSTATUS loadfile_open(struct composite_context *c,
- struct smb_composite_loadfile *io)
-{
- struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state);
- struct smbcli_tree *tree = state->req->tree;
- NTSTATUS status;
-
- status = smb_raw_open_recv(state->req, c, state->io_open);
- NT_STATUS_NOT_OK_RETURN(status);
-
- /* don't allow stupidly large loads */
- if (state->io_open->ntcreatex.out.size > 100*1000*1000) {
- return NT_STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* allocate space for the file data */
- io->out.size = state->io_open->ntcreatex.out.size;
- io->out.data = talloc_array(c, uint8_t, io->out.size);
- NT_STATUS_HAVE_NO_MEMORY(io->out.data);
-
- if (io->out.size == 0) {
- return setup_close(c, tree, state->io_open->ntcreatex.out.fnum);
- }
-
- /* setup for the read */
- state->io_read = talloc(c, union smb_read);
- NT_STATUS_HAVE_NO_MEMORY(state->io_read);
-
- state->io_read->readx.level = RAW_READ_READX;
- state->io_read->readx.in.fnum = state->io_open->ntcreatex.out.fnum;
- state->io_read->readx.in.offset = 0;
- state->io_read->readx.in.mincnt = MIN(32768, io->out.size);
- state->io_read->readx.in.maxcnt = state->io_read->readx.in.mincnt;
- state->io_read->readx.in.remaining = 0;
- state->io_read->readx.out.data = io->out.data;
-
- state->req = smb_raw_read_send(tree, state->io_read);
- NT_STATUS_HAVE_NO_MEMORY(state->req);
-
- /* call the handler again when the first read is done */
- state->req->async.fn = loadfile_handler;
- state->req->async.private = c;
- state->stage = LOADFILE_READ;
-
- talloc_free(state->io_open);
-
- return NT_STATUS_OK;
-}
-
-
-/*
- called when a read is done - pull the results and setup for the
- next read, or close if the file is all done
-*/
-static NTSTATUS loadfile_read(struct composite_context *c,
- struct smb_composite_loadfile *io)
-{
- struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state);
- struct smbcli_tree *tree = state->req->tree;
- NTSTATUS status;
-
- status = smb_raw_read_recv(state->req, state->io_read);
- NT_STATUS_NOT_OK_RETURN(status);
-
- /* we might be done */
- if (state->io_read->readx.in.offset +
- state->io_read->readx.out.nread == io->out.size) {
- return setup_close(c, tree, state->io_read->readx.in.fnum);
- }
-
- /* setup for the next read */
- state->io_read->readx.in.offset += state->io_read->readx.out.nread;
- state->io_read->readx.in.mincnt = MIN(32768, io->out.size - state->io_read->readx.in.offset);
- state->io_read->readx.out.data = io->out.data + state->io_read->readx.in.offset;
-
- state->req = smb_raw_read_send(tree, state->io_read);
- NT_STATUS_HAVE_NO_MEMORY(state->req);
-
- /* call the handler again when the read is done */
- state->req->async.fn = loadfile_handler;
- state->req->async.private = c;
-
- return NT_STATUS_OK;
-}
-
-/*
- called when the close is done, check the status and cleanup
-*/
-static NTSTATUS loadfile_close(struct composite_context *c,
- struct smb_composite_loadfile *io)
-{
- struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state);
- NTSTATUS status;
-
- status = smbcli_request_simple_recv(state->req);
- NT_STATUS_NOT_OK_RETURN(status);
-
- c->state = SMBCLI_REQUEST_DONE;
-
- return NT_STATUS_OK;
-}
-
-
-/*
- handler for completion of a sub-request in loadfile
-*/
-static void loadfile_handler(struct smbcli_request *req)
-{
- struct composite_context *c = req->async.private;
- struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state);
-
- /* when this handler is called, the stage indicates what
- call has just finished */
- switch (state->stage) {
- case LOADFILE_OPEN:
- c->status = loadfile_open(c, state->io);
- break;
-
- case LOADFILE_READ:
- c->status = loadfile_read(c, state->io);
- break;
-
- case LOADFILE_CLOSE:
- c->status = loadfile_close(c, state->io);
- 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);
- }
-}
-
-/*
- composite loadfile call - does an openx followed by a number of readx calls,
- followed by a close
-*/
-struct composite_context *smb_composite_loadfile_send(struct smbcli_tree *tree,
- struct smb_composite_loadfile *io)
-{
- struct composite_context *c;
- struct loadfile_state *state;
-
- c = talloc_zero(tree, struct composite_context);
- if (c == NULL) goto failed;
-
- state = talloc(c, struct loadfile_state);
- if (state == NULL) goto failed;
-
- state->io = io;
-
- c->private = state;
- c->state = SMBCLI_REQUEST_SEND;
- c->event_ctx = tree->session->transport->socket->event.ctx;
-
- /* setup for the open */
- state->io_open = talloc_zero(c, union smb_open);
- if (state->io_open == NULL) goto failed;
-
- state->io_open->ntcreatex.level = RAW_OPEN_NTCREATEX;
- state->io_open->ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
- state->io_open->ntcreatex.in.access_mask = SEC_FILE_READ_DATA;
- state->io_open->ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
- state->io_open->ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
- state->io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
- state->io_open->ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
- state->io_open->ntcreatex.in.fname = io->in.fname;
-
- /* send the open on its way */
- state->req = smb_raw_open_send(tree, state->io_open);
- if (state->req == NULL) goto failed;
-
- /* setup the callback handler */
- state->req->async.fn = loadfile_handler;
- state->req->async.private = c;
- state->stage = LOADFILE_OPEN;
-
- return c;
-
-failed:
- talloc_free(c);
- return NULL;
-}
-
-
-/*
- composite loadfile call - recv side
-*/
-NTSTATUS smb_composite_loadfile_recv(struct composite_context *c, TALLOC_CTX *mem_ctx)
-{
- NTSTATUS status;
-
- status = composite_wait(c);
-
- if (NT_STATUS_IS_OK(status)) {
- struct loadfile_state *state = talloc_get_type(c->private, struct loadfile_state);
- talloc_steal(mem_ctx, state->io->out.data);
- }
-
- talloc_free(c);
- return status;
-}
-
-
-/*
- composite loadfile call - sync interface
-*/
-NTSTATUS smb_composite_loadfile(struct smbcli_tree *tree,
- TALLOC_CTX *mem_ctx,
- struct smb_composite_loadfile *io)
-{
- struct composite_context *c = smb_composite_loadfile_send(tree, io);
- return smb_composite_loadfile_recv(c, mem_ctx);
-}
-
diff --git a/source4/libcli/composite/monitor.h b/source4/libcli/composite/monitor.h
deleted file mode 100644
index dce9dedc92..0000000000
--- a/source4/libcli/composite/monitor.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Definitions of composite function monitoring messages.
-
- 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.
-*/
-
-/*
- * Monitor structure and message types definitions. Composite function monitoring
- * allows client application to be notified on function progress. This enables
- * eg. gui client to display progress bars, status messages, etc.
- */
-
-
-#define rpc_create_user (0x00000001) /* userman.h */
-#define rpc_open_user (0x00000002) /* userinfo.h */
-#define rpc_query_user (0x00000003) /* userinfo.h */
-#define rpc_close_user (0x00000004) /* userinfo.h */
-#define rpc_lookup_name (0x00000005) /* userman.h */
-#define rpc_delete_user (0x00000006) /* userman.h */
-
-
-struct monitor_msg {
- uint32_t type;
- void *data;
- size_t data_size;
-};
diff --git a/source4/libcli/composite/savefile.c b/source4/libcli/composite/savefile.c
deleted file mode 100644
index 0b08963966..0000000000
--- a/source4/libcli/composite/savefile.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Copyright (C) Andrew Tridgell 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.
-*/
-/*
- a composite API for saving a whole file from memory
-*/
-
-#include "includes.h"
-#include "libcli/raw/libcliraw.h"
-#include "libcli/composite/composite.h"
-#include "librpc/gen_ndr/ndr_security.h"
-
-/* the stages of this call */
-enum savefile_stage {SAVEFILE_OPEN, SAVEFILE_WRITE, SAVEFILE_CLOSE};
-
-static void savefile_handler(struct smbcli_request *req);
-
-struct savefile_state {
- enum savefile_stage stage;
- off_t total_written;
- struct smb_composite_savefile *io;
- union smb_open *io_open;
- union smb_write *io_write;
- struct smbcli_request *req;
-};
-
-
-/*
- setup for the close
-*/
-static NTSTATUS setup_close(struct composite_context *c,
- struct smbcli_tree *tree, uint16_t fnum)
-{
- struct savefile_state *state = talloc_get_type(c->private, struct savefile_state);
- union smb_close *io_close;
-
- /* nothing to write, setup the close */
- io_close = talloc(c, union smb_close);
- NT_STATUS_HAVE_NO_MEMORY(io_close);
-
- io_close->close.level = RAW_CLOSE_CLOSE;
- io_close->close.in.fnum = fnum;
- io_close->close.in.write_time = 0;
-
- state->req = smb_raw_close_send(tree, io_close);
- NT_STATUS_HAVE_NO_MEMORY(state->req);
-
- /* call the handler again when the close is done */
- state->stage = SAVEFILE_CLOSE;
- state->req->async.fn = savefile_handler;
- state->req->async.private = c;
-
- return NT_STATUS_OK;
-}
-
-/*
- called when the open is done - pull the results and setup for the
- first writex, or close if the file is zero size
-*/
-static NTSTATUS savefile_open(struct composite_context *c,
- struct smb_composite_savefile *io)
-{
- struct savefile_state *state = talloc_get_type(c->private, struct savefile_state);
- union smb_write *io_write;
- struct smbcli_tree *tree = state->req->tree;
- NTSTATUS status;
- uint32_t max_xmit = tree->session->transport->negotiate.max_xmit;
-
- status = smb_raw_open_recv(state->req, c, state->io_open);
- NT_STATUS_NOT_OK_RETURN(status);
-
- if (io->in.size == 0) {
- return setup_close(c, tree, state->io_open->ntcreatex.out.fnum);
- }
-
- /* setup for the first write */
- io_write = talloc(c, union smb_write);
- NT_STATUS_HAVE_NO_MEMORY(io_write);
-
- io_write->writex.level = RAW_WRITE_WRITEX;
- io_write->writex.in.fnum = state->io_open->ntcreatex.out.fnum;
- io_write->writex.in.offset = 0;
- io_write->writex.in.wmode = 0;
- io_write->writex.in.remaining = 0;
- io_write->writex.in.count = MIN(max_xmit - 100, io->in.size);
- io_write->writex.in.data = io->in.data;
- state->io_write = io_write;
-
- state->req = smb_raw_write_send(tree, io_write);
- NT_STATUS_HAVE_NO_MEMORY(state->req);
-
- /* call the handler again when the first write is done */
- state->stage = SAVEFILE_WRITE;
- state->req->async.fn = savefile_handler;
- state->req->async.private = c;
- talloc_free(state->io_open);
-
- return NT_STATUS_OK;
-}
-
-
-/*
- called when a write is done - pull the results and setup for the
- next write, or close if the file is all done
-*/
-static NTSTATUS savefile_write(struct composite_context *c,
- struct smb_composite_savefile *io)
-{
- struct savefile_state *state = talloc_get_type(c->private, struct savefile_state);
- struct smbcli_tree *tree = state->req->tree;
- NTSTATUS status;
- uint32_t max_xmit = tree->session->transport->negotiate.max_xmit;
-
- status = smb_raw_write_recv(state->req, state->io_write);
- NT_STATUS_NOT_OK_RETURN(status);
-
- state->total_written += state->io_write->writex.out.nwritten;
-
- /* we might be done */
- if (state->io_write->writex.out.nwritten != state->io_write->writex.in.count ||
- state->total_written == io->in.size) {
- return setup_close(c, tree, state->io_write->writex.in.fnum);
- }
-
- /* setup for the next write */
- state->io_write->writex.in.offset = state->total_written;
- state->io_write->writex.in.count = MIN(max_xmit - 100,
- io->in.size - state->total_written);
- state->io_write->writex.in.data = io->in.data + state->total_written;
-
- state->req = smb_raw_write_send(tree, state->io_write);
- NT_STATUS_HAVE_NO_MEMORY(state->req);
-
- /* call the handler again when the write is done */
- state->req->async.fn = savefile_handler;
- state->req->async.private = c;
-
- return NT_STATUS_OK;
-}
-
-/*
- called when the close is done, check the status and cleanup
-*/
-static NTSTATUS savefile_close(struct composite_context *c,
- struct smb_composite_savefile *io)
-{
- struct savefile_state *state = talloc_get_type(c->private, struct savefile_state);
- NTSTATUS status;
-
- status = smbcli_request_simple_recv(state->req);
- NT_STATUS_NOT_OK_RETURN(status);
-
- if (state->total_written != io->in.size) {
- return NT_STATUS_DISK_FULL;
- }
-
- c->state = SMBCLI_REQUEST_DONE;
-
- return NT_STATUS_OK;
-}
-
-
-/*
- handler for completion of a sub-request in savefile
-*/
-static void savefile_handler(struct smbcli_request *req)
-{
- struct composite_context *c = req->async.private;
- struct savefile_state *state = talloc_get_type(c->private, struct savefile_state);
-
- /* when this handler is called, the stage indicates what
- call has just finished */
- switch (state->stage) {
- case SAVEFILE_OPEN:
- c->status = savefile_open(c, state->io);
- break;
-
- case SAVEFILE_WRITE:
- c->status = savefile_write(c, state->io);
- break;
-
- case SAVEFILE_CLOSE:
- c->status = savefile_close(c, state->io);
- 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);
- }
-}
-
-/*
- composite savefile call - does an openx followed by a number of writex calls,
- followed by a close
-*/
-struct composite_context *smb_composite_savefile_send(struct smbcli_tree *tree,
- struct smb_composite_savefile *io)
-{
- struct composite_context *c;
- struct savefile_state *state;
- union smb_open *io_open;
-
- c = talloc_zero(tree, struct composite_context);
- if (c == NULL) goto failed;
-
- c->state = SMBCLI_REQUEST_SEND;
- c->event_ctx = tree->session->transport->socket->event.ctx;
-
- state = talloc(c, struct savefile_state);
- if (state == NULL) goto failed;
-
- state->stage = SAVEFILE_OPEN;
- state->total_written = 0;
- state->io = io;
-
- /* setup for the open */
- io_open = talloc_zero(c, union smb_open);
- if (io_open == NULL) goto failed;
-
- io_open->ntcreatex.level = RAW_OPEN_NTCREATEX;
- io_open->ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
- io_open->ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
- io_open->ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
- io_open->ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
- io_open->ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
- io_open->ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
- io_open->ntcreatex.in.fname = io->in.fname;
- state->io_open = io_open;
-
- /* send the open on its way */
- state->req = smb_raw_open_send(tree, io_open);
- if (state->req == NULL) goto failed;
-
- /* setup the callback handler */
- state->req->async.fn = savefile_handler;
- state->req->async.private = c;
- c->private = state;
-
- return c;
-
-failed:
- talloc_free(c);
- return NULL;
-}
-
-
-/*
- composite savefile call - recv side
-*/
-NTSTATUS smb_composite_savefile_recv(struct composite_context *c)
-{
- NTSTATUS status;
- status = composite_wait(c);
- talloc_free(c);
- return status;
-}
-
-
-/*
- composite savefile call - sync interface
-*/
-NTSTATUS smb_composite_savefile(struct smbcli_tree *tree,
- struct smb_composite_savefile *io)
-{
- struct composite_context *c = smb_composite_savefile_send(tree, io);
- return smb_composite_savefile_recv(c);
-}
diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c
deleted file mode 100644
index 3bd9ed285d..0000000000
--- a/source4/libcli/composite/sesssetup.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Copyright (C) Andrew Tridgell 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.
-*/
-/*
- a composite API for making handling a generic async session setup
-*/
-
-#include "includes.h"
-#include "libcli/raw/libcliraw.h"
-#include "libcli/composite/composite.h"
-#include "auth/auth.h"
-#include "version.h"
-
-struct sesssetup_state {
- union smb_sesssetup setup;
- NTSTATUS gensec_status;
- struct smb_composite_sesssetup *io;
- struct smbcli_request *req;
-};
-
-
-/*
- form an encrypted lanman password from a plaintext password
- and the server supplied challenge
-*/
-static DATA_BLOB lanman_blob(TALLOC_CTX *mem_ctx, const char *pass, DATA_BLOB challenge)
-{
- DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24);
- SMBencrypt(pass, challenge.data, blob.data);
- return blob;
-}
-
-/*
- form an encrypted NT password from a plaintext password
- and the server supplied challenge
-*/
-static DATA_BLOB nt_blob(TALLOC_CTX *mem_ctx, const struct samr_Password *nt_hash, DATA_BLOB challenge)
-{
- DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24);
- SMBOWFencrypt(nt_hash->hash, challenge.data, blob.data);
- return blob;
-}
-
-/*
- store the user session key for a transport
-*/
-static void set_user_session_key(struct smbcli_session *session,
- const DATA_BLOB *session_key)
-{
- session->user_session_key = data_blob_talloc(session,
- session_key->data,
- session_key->length);
-}
-
-/*
- handler for completion of a smbcli_request sub-request
-*/
-static void request_handler(struct smbcli_request *req)
-{
- struct composite_context *c = req->async.private;
- struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state);
- struct smbcli_session *session = req->session;
- DATA_BLOB session_key = data_blob(NULL, 0);
- DATA_BLOB null_data_blob = data_blob(NULL, 0);
- NTSTATUS session_key_err;
-
- c->status = smb_raw_sesssetup_recv(req, state, &state->setup);
-
- switch (state->setup.old.level) {
- case RAW_SESSSETUP_OLD:
- state->io->out.vuid = state->setup.old.out.vuid;
- break;
-
- case RAW_SESSSETUP_NT1:
- state->io->out.vuid = state->setup.nt1.out.vuid;
- break;
-
- case RAW_SESSSETUP_SPNEGO:
- session->vuid = state->io->out.vuid = state->setup.spnego.out.vuid;
- if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
- !NT_STATUS_IS_OK(c->status)) {
- break;
- }
- if (NT_STATUS_EQUAL(state->gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
-
- /* The status value here, from the earlier pass at GENSEC is
- * vital to the security of the system. Even if the other end
- * accepts, if GENSEC claims 'MORE_PROCESSING_REQUIRED' then
- * you must keep feeding it blobs, or else the remote
- * host/attacker might avoid mutal authentication
- * requirements */
-
- state->gensec_status = gensec_update(session->gensec, state,
- state->setup.spnego.out.secblob,
- &state->setup.spnego.in.secblob);
- c->status = state->gensec_status;
- if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
- !NT_STATUS_IS_OK(c->status)) {
- break;
- }
- } else {
- state->setup.spnego.in.secblob = data_blob(NULL, 0);
- }
-
- /* we need to do another round of session setup. We keep going until both sides
- are happy */
- session_key_err = gensec_session_key(session->gensec, &session_key);
- if (NT_STATUS_IS_OK(session_key_err)) {
- set_user_session_key(session, &session_key);
- smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob);
- }
-
- if (state->setup.spnego.in.secblob.length) {
- state->req = smb_raw_sesssetup_send(session, &state->setup);
- state->req->async.fn = request_handler;
- state->req->async.private = c;
- return;
- }
- }
-
- /* enforce the local signing required flag */
- if (NT_STATUS_IS_OK(c->status) && !cli_credentials_is_anonymous(state->io->in.credentials)) {
- if (!session->transport->negotiate.sign_info.doing_signing
- && session->transport->negotiate.sign_info.mandatory_signing) {
- DEBUG(0, ("SMB signing required, but server does not support it\n"));
- c->status = NT_STATUS_ACCESS_DENIED;
- }
- }
-
- if (NT_STATUS_IS_OK(c->status)) {
- c->state = SMBCLI_REQUEST_DONE;
- } else {
- c->state = SMBCLI_REQUEST_ERROR;
- }
- if (c->async.fn) {
- c->async.fn(c);
- }
-}
-
-
-/*
- send a nt1 style session setup
-*/
-static NTSTATUS session_setup_nt1(struct composite_context *c,
- struct smbcli_session *session,
- struct smb_composite_sesssetup *io,
- struct smbcli_request **req)
-{
- struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state);
- const struct samr_Password *nt_hash = cli_credentials_get_nt_hash(io->in.credentials, state);
- const char *password = cli_credentials_get_password(io->in.credentials);
-
- state->setup.nt1.level = RAW_SESSSETUP_NT1;
- state->setup.nt1.in.bufsize = session->transport->options.max_xmit;
- state->setup.nt1.in.mpx_max = session->transport->options.max_mux;
- state->setup.nt1.in.vc_num = 1;
- state->setup.nt1.in.sesskey = io->in.sesskey;
- state->setup.nt1.in.capabilities = io->in.capabilities;
- state->setup.nt1.in.os = "Unix";
- state->setup.nt1.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING);
- cli_credentials_get_ntlm_username_domain(io->in.credentials, state,
- &state->setup.nt1.in.user,
- &state->setup.nt1.in.domain);
-
- if (!password) {
- state->setup.nt1.in.password1 = data_blob(NULL, 0);
- state->setup.nt1.in.password2 = data_blob(NULL, 0);
- } else if (session->transport->negotiate.sec_mode &
- NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) {
- DATA_BLOB session_key;
- if (lp_client_ntlmv2_auth()) {
- DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, lp_netbios_name(), lp_workgroup());
- DATA_BLOB lmv2_response, ntlmv2_response, lmv2_session_key;
-
- if (!SMBNTLMv2encrypt_hash(state,
- state->setup.nt1.in.user, state->setup.nt1.in.domain,
- nt_hash->hash, &session->transport->negotiate.secblob,
- &names_blob,
- &lmv2_response, &ntlmv2_response,
- &lmv2_session_key, &session_key)) {
- data_blob_free(&names_blob);
- return NT_STATUS_NO_MEMORY;
- }
- data_blob_free(&names_blob);
- state->setup.nt1.in.password1 = lmv2_response;
- state->setup.nt1.in.password2 = ntlmv2_response;
-
- smbcli_transport_simple_set_signing(session->transport, session_key,
- state->setup.nt1.in.password2);
- set_user_session_key(session, &session_key);
-
- data_blob_free(&lmv2_session_key);
- data_blob_free(&session_key);
- } else {
-
- state->setup.nt1.in.password2 = nt_blob(state, nt_hash,
- session->transport->negotiate.secblob);
- if (lp_client_lanman_auth()) {
- state->setup.nt1.in.password1 = lanman_blob(state, password,
- session->transport->negotiate.secblob);
- } else {
- /* if not sending the LM password, send the NT password twice */
- state->setup.nt1.in.password1 = state->setup.nt1.in.password2;
- }
-
- session_key = data_blob_talloc(session, NULL, 16);
- SMBsesskeygen_ntv1(nt_hash->hash, session_key.data);
- smbcli_transport_simple_set_signing(session->transport, session_key,
- state->setup.nt1.in.password2);
- set_user_session_key(session, &session_key);
-
- data_blob_free(&session_key);
- }
-
- } else if (lp_client_plaintext_auth()) {
- state->setup.nt1.in.password1 = data_blob_talloc(state, password, strlen(password));
- state->setup.nt1.in.password2 = data_blob(NULL, 0);
- } else {
- /* could match windows client and return 'cannot logon from this workstation', but it just confuses everybody */
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- *req = smb_raw_sesssetup_send(session, &state->setup);
- if (!*req) {
- return NT_STATUS_NO_MEMORY;
- }
- return (*req)->status;
-}
-
-
-/*
- old style session setup (pre NT1 protocol level)
-*/
-static NTSTATUS session_setup_old(struct composite_context *c,
- struct smbcli_session *session,
- struct smb_composite_sesssetup *io,
- struct smbcli_request **req)
-{
- struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state);
- const char *password = cli_credentials_get_password(io->in.credentials);
-
- state->setup.old.level = RAW_SESSSETUP_OLD;
- state->setup.old.in.bufsize = session->transport->options.max_xmit;
- state->setup.old.in.mpx_max = session->transport->options.max_mux;
- state->setup.old.in.vc_num = 1;
- state->setup.old.in.sesskey = io->in.sesskey;
- state->setup.old.in.os = "Unix";
- state->setup.old.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING);
- cli_credentials_get_ntlm_username_domain(io->in.credentials, state,
- &state->setup.old.in.user,
- &state->setup.old.in.domain);
-
- if (!password) {
- state->setup.old.in.password = data_blob(NULL, 0);
- } else if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) {
- state->setup.old.in.password = lanman_blob(state, password,
- session->transport->negotiate.secblob);
- } else {
- state->setup.old.in.password = data_blob_talloc(state,
- password,
- strlen(password));
- }
-
- *req = smb_raw_sesssetup_send(session, &state->setup);
- if (!*req) {
- return NT_STATUS_NO_MEMORY;
- }
- return (*req)->status;
-}
-
-
-/*
- Modern, all singing, all dancing extended security (and possibly SPNEGO) request
-*/
-static NTSTATUS session_setup_spnego(struct composite_context *c,
- struct smbcli_session *session,
- struct smb_composite_sesssetup *io,
- struct smbcli_request **req)
-{
- struct sesssetup_state *state = talloc_get_type(c->private, struct sesssetup_state);
- NTSTATUS status, session_key_err;
- DATA_BLOB session_key = data_blob(NULL, 0);
- DATA_BLOB null_data_blob = data_blob(NULL, 0);
- const char *chosen_oid = NULL;
-
- state->setup.spnego.level = RAW_SESSSETUP_SPNEGO;
- state->setup.spnego.in.bufsize = session->transport->options.max_xmit;
- state->setup.spnego.in.mpx_max = session->transport->options.max_mux;
- state->setup.spnego.in.vc_num = 1;
- state->setup.spnego.in.sesskey = io->in.sesskey;
- state->setup.spnego.in.capabilities = io->in.capabilities;
- state->setup.spnego.in.os = "Unix";
- state->setup.spnego.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING);
- state->setup.spnego.in.workgroup = io->in.workgroup;
-
- state->setup.spnego.out.vuid = session->vuid;
-
- smbcli_temp_set_signing(session->transport);
-
- status = gensec_client_start(session, &session->gensec, c->event_ctx);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status)));
- return status;
- }
-
- gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY);
-
- status = gensec_set_credentials(session->gensec, io->in.credentials);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Failed to start set GENSEC client credentails: %s\n",
- nt_errstr(status)));
- return status;
- }
-
- status = gensec_set_target_hostname(session->gensec, session->transport->socket->hostname);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n",
- nt_errstr(status)));
- return status;
- }
-
- status = gensec_set_target_service(session->gensec, "cifs");
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Failed to start set GENSEC target service: %s\n",
- nt_errstr(status)));
- return status;
- }
-
- if (session->transport->negotiate.secblob.length) {
- chosen_oid = GENSEC_OID_SPNEGO;
- } else {
- /* without a sec blob, means raw NTLMSSP */
- chosen_oid = GENSEC_OID_NTLMSSP;
- }
-
- status = gensec_start_mech_by_oid(session->gensec, chosen_oid);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism %s: %s\n",
- gensec_get_name_by_oid(chosen_oid), nt_errstr(status)));
- return status;
- }
-
- status = gensec_update(session->gensec, state,
- session->transport->negotiate.secblob,
- &state->setup.spnego.in.secblob);
- if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
- !NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Failed initial gensec_update with mechanism %s: %s\n",
- gensec_get_name_by_oid(chosen_oid), nt_errstr(status)));
- return status;
- }
- state->gensec_status = status;
-
- session_key_err = gensec_session_key(session->gensec, &session_key);
- if (NT_STATUS_IS_OK(session_key_err)) {
- smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob);
- }
-
- *req = smb_raw_sesssetup_send(session, &state->setup);
- if (!*req) {
- return NT_STATUS_NO_MEMORY;
- }
- return (*req)->status;
-}
-
-
-/*
- composite session setup function that hides the details of all the
- different session setup varients, including the multi-pass nature of
- the spnego varient
-*/
-struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *session,
- struct smb_composite_sesssetup *io)
-{
- struct composite_context *c;
- struct sesssetup_state *state;
- NTSTATUS status;
-
- c = talloc_zero(session, struct composite_context);
- if (c == NULL) return NULL;
-
- state = talloc(c, struct sesssetup_state);
- if (state == NULL) {
- c->state = SMBCLI_REQUEST_ERROR;
- c->status = NT_STATUS_NO_MEMORY;
- }
-
- state->io = io;
-
- c->state = SMBCLI_REQUEST_SEND;
- c->private = state;
- c->event_ctx = session->transport->socket->event.ctx;
-
- /* no session setup at all in earliest protocol varients */
- if (session->transport->negotiate.protocol < PROTOCOL_LANMAN1) {
- ZERO_STRUCT(io->out);
- c->state = SMBCLI_REQUEST_DONE;
- return c;
- }
-
- /* see what session setup interface we will use */
- if (session->transport->negotiate.protocol < PROTOCOL_NT1) {
- status = session_setup_old(c, session, io, &state->req);
- } else if (!session->transport->options.use_spnego ||
- !(io->in.capabilities & CAP_EXTENDED_SECURITY)) {
- status = session_setup_nt1(c, session, io, &state->req);
- } else {
- status = session_setup_spnego(c, session, io, &state->req);
- }
-
- if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) ||
- NT_STATUS_IS_OK(status)) {
- state->req->async.fn = request_handler;
- state->req->async.private = c;
- return c;
- }
-
- c->state = SMBCLI_REQUEST_ERROR;
- c->status = status;
- return c;
-}
-
-
-/*
- receive a composite session setup reply
-*/
-NTSTATUS smb_composite_sesssetup_recv(struct composite_context *c)
-{
- NTSTATUS status;
- status = composite_wait(c);
- talloc_free(c);
- return status;
-}
-
-/*
- sync version of smb_composite_sesssetup
-*/
-NTSTATUS smb_composite_sesssetup(struct smbcli_session *session, struct smb_composite_sesssetup *io)
-{
- struct composite_context *c = smb_composite_sesssetup_send(session, io);
- return smb_composite_sesssetup_recv(c);
-}