diff options
author | Stefan Metzmacher <metze@samba.org> | 2005-09-26 11:47:55 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:38:57 -0500 |
commit | ab4d635b92b116b02b88843b4ec4f5b7517bab1a (patch) | |
tree | 63c3ee12153b629071d2ba0209a0a31b134c449e /source4/libcli/composite | |
parent | 0d46be147a1e755bdd6f21a5ddc83b5c39585529 (diff) | |
download | samba-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.c | 311 | ||||
-rw-r--r-- | source4/libcli/composite/composite.c | 4 | ||||
-rw-r--r-- | source4/libcli/composite/composite.h | 147 | ||||
-rw-r--r-- | source4/libcli/composite/connect.c | 395 | ||||
-rw-r--r-- | source4/libcli/composite/fetchfile.c | 186 | ||||
-rw-r--r-- | source4/libcli/composite/fsinfo.c | 200 | ||||
-rw-r--r-- | source4/libcli/composite/loadfile.c | 293 | ||||
-rw-r--r-- | source4/libcli/composite/monitor.h | 42 | ||||
-rw-r--r-- | source4/libcli/composite/savefile.c | 288 | ||||
-rw-r--r-- | source4/libcli/composite/sesssetup.c | 458 |
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); -} |