diff options
Diffstat (limited to 'source4/smb_server/smb2')
-rw-r--r-- | source4/smb_server/smb2/config.mk | 19 | ||||
-rw-r--r-- | source4/smb_server/smb2/fileinfo.c | 4 | ||||
-rw-r--r-- | source4/smb_server/smb2/fileio.c | 4 | ||||
-rw-r--r-- | source4/smb_server/smb2/find.c | 3 | ||||
-rw-r--r-- | source4/smb_server/smb2/negprot.c | 18 | ||||
-rw-r--r-- | source4/smb_server/smb2/receive.c | 11 | ||||
-rw-r--r-- | source4/smb_server/smb2/sesssetup.c | 30 | ||||
-rw-r--r-- | source4/smb_server/smb2/tcon.c | 12 | ||||
-rw-r--r-- | source4/smb_server/smb2/wscript_build | 8 |
9 files changed, 57 insertions, 52 deletions
diff --git a/source4/smb_server/smb2/config.mk b/source4/smb_server/smb2/config.mk deleted file mode 100644 index f0c3739926..0000000000 --- a/source4/smb_server/smb2/config.mk +++ /dev/null @@ -1,19 +0,0 @@ -####################### -# Start SUBSYSTEM SMB2_PROTOCOL -[SUBSYSTEM::SMB2_PROTOCOL] -PUBLIC_DEPENDENCIES = \ - ntvfs LIBPACKET LIBCLI_SMB2 samba_server_gensec -# End SUBSYSTEM SMB2_PROTOCOL -####################### - -SMB2_PROTOCOL_OBJ_FILES = $(addprefix $(smb_serversrcdir)/smb2/, \ - receive.o \ - negprot.o \ - sesssetup.o \ - tcon.o \ - fileio.o \ - fileinfo.o \ - find.o \ - keepalive.o) - -$(eval $(call proto_header_template,$(smb_serversrcdir)/smb2/smb2_proto.h,$(SMB2_PROTOCOL_OBJ_FILES:.o=.c))) diff --git a/source4/smb_server/smb2/fileinfo.c b/source4/smb_server/smb2/fileinfo.c index 3084236355..5e4f35e02b 100644 --- a/source4/smb_server/smb2/fileinfo.c +++ b/source4/smb_server/smb2/fileinfo.c @@ -150,7 +150,7 @@ static NTSTATUS smb2srv_getinfo_security_send(struct smb2srv_getinfo_op *op) union smb_fileinfo *io = talloc_get_type(op->io_ptr, union smb_fileinfo); enum ndr_err_code ndr_err; - ndr_err = ndr_push_struct_blob(&op->info->out.blob, op->req, NULL, + ndr_err = ndr_push_struct_blob(&op->info->out.blob, op->req, io->query_secdesc.out.sd, (ndr_push_flags_fn_t)ndr_push_security_descriptor); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { @@ -316,7 +316,7 @@ static NTSTATUS smb2srv_setinfo_security(struct smb2srv_setinfo_op *op, uint8_t io->set_secdesc.in.sd = talloc(io, struct security_descriptor); NT_STATUS_HAVE_NO_MEMORY(io->set_secdesc.in.sd); - ndr_err = ndr_pull_struct_blob(&op->info->in.blob, io, NULL, + ndr_err = ndr_pull_struct_blob(&op->info->in.blob, io, io->set_secdesc.in.sd, (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { diff --git a/source4/smb_server/smb2/fileio.c b/source4/smb_server/smb2/fileio.c index 497a6c531b..f6460e0ee7 100644 --- a/source4/smb_server/smb2/fileio.c +++ b/source4/smb_server/smb2/fileio.c @@ -109,7 +109,7 @@ void smb2srv_create_recv(struct smb2srv_request *req) smb2srv_send_error(req, NT_STATUS_NO_MEMORY); return; } - ndr_err = ndr_pull_struct_blob(&io->smb2.in.blobs.blobs[i].data, io, NULL, + ndr_err = ndr_pull_struct_blob(&io->smb2.in.blobs.blobs[i].data, io, io->smb2.in.sec_desc, (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { @@ -345,7 +345,7 @@ void smb2srv_lock_recv(struct smb2srv_request *req) io->smb2.level = RAW_LOCK_SMB2; io->smb2.in.lock_count = SVAL(req->in.body, 0x02); - io->smb2.in.reserved = IVAL(req->in.body, 0x04); + io->smb2.in.lock_sequence = IVAL(req->in.body, 0x04); io->smb2.in.file.ntvfs = smb2srv_pull_handle(req, req->in.body, 0x08); if (req->in.body_size < 24 + 24*(uint64_t)io->smb2.in.lock_count) { DEBUG(0,("%s: lock buffer too small\n", __location__)); diff --git a/source4/smb_server/smb2/find.c b/source4/smb_server/smb2/find.c index cd52872a1c..17f09e15ae 100644 --- a/source4/smb_server/smb2/find.c +++ b/source4/smb_server/smb2/find.c @@ -130,9 +130,6 @@ static NTSTATUS smb2srv_find_backend(struct smb2srv_find_state *state) return ntvfs_search_next(state->req->ntvfs, state->fn, state, smb2srv_find_callback); } - - /* should not be reached */ - return NT_STATUS_INTERNAL_ERROR; } void smb2srv_find_recv(struct smb2srv_request *req) diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index 5283a0db6e..da60676322 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -119,7 +119,7 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2 boot_time = timeval_current(); /* TODO: fix me */ ZERO_STRUCT(io->out); - switch (lp_server_signing(req->smb_conn->lp_ctx)) { + switch (lpcfg_server_signing(req->smb_conn->lp_ctx)) { case SMB_SIGNING_OFF: io->out.security_mode = 0; break; @@ -135,11 +135,11 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2 } io->out.dialect_revision = dialect; io->out.capabilities = 0; - io->out.max_transact_size = lp_parm_ulong(req->smb_conn->lp_ctx, NULL, + io->out.max_transact_size = lpcfg_parm_ulong(req->smb_conn->lp_ctx, NULL, "smb2", "max transaction size", 0x10000); - io->out.max_read_size = lp_parm_ulong(req->smb_conn->lp_ctx, NULL, + io->out.max_read_size = lpcfg_parm_ulong(req->smb_conn->lp_ctx, NULL, "smb2", "max read size", 0x10000); - io->out.max_write_size = lp_parm_ulong(req->smb_conn->lp_ctx, NULL, + io->out.max_write_size = lpcfg_parm_ulong(req->smb_conn->lp_ctx, NULL, "smb2", "max write size", 0x10000); io->out.system_time = timeval_to_nttime(¤t_time); io->out.server_start_time = timeval_to_nttime(&boot_time); @@ -153,7 +153,6 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2 static void smb2srv_negprot_send(struct smb2srv_request *req, struct smb2_negprot *io) { NTSTATUS status; - enum ndr_err_code ndr_err; if (NT_STATUS_IS_ERR(req->status)) { smb2srv_send_error(req, req->status); /* TODO: is this correct? */ @@ -170,8 +169,8 @@ static void smb2srv_negprot_send(struct smb2srv_request *req, struct smb2_negpro SSVAL(req->out.body, 0x02, io->out.security_mode); SIVAL(req->out.body, 0x04, io->out.dialect_revision); SIVAL(req->out.body, 0x06, io->out.reserved); - ndr_err = smbcli_push_guid(req->out.body, 0x08, &io->out.server_guid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = smbcli_push_guid(req->out.body, 0x08, &io->out.server_guid); + if (!NT_STATUS_IS_OK(status)) { smbsrv_terminate_connection(req->smb_conn, nt_errstr(status)); talloc_free(req); return; @@ -197,7 +196,6 @@ void smb2srv_negprot_recv(struct smb2srv_request *req) { struct smb2_negprot *io; int i; - enum ndr_err_code ndr_err; if (req->in.body_size < 0x26) { smbsrv_terminate_connection(req->smb_conn, "Bad body size in SMB2 negprot"); @@ -215,8 +213,8 @@ void smb2srv_negprot_recv(struct smb2srv_request *req) io->in.security_mode = SVAL(req->in.body, 0x04); io->in.reserved = SVAL(req->in.body, 0x06); io->in.capabilities = IVAL(req->in.body, 0x08); - ndr_err = smbcli_pull_guid(req->in.body, 0xC, &io->in.client_guid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + req->status = smbcli_pull_guid(req->in.body, 0xC, &io->in.client_guid); + if (!NT_STATUS_IS_OK(req->status)) { smbsrv_terminate_connection(req->smb_conn, "Bad GUID in SMB2 negprot"); talloc_free(req); return; diff --git a/source4/smb_server/smb2/receive.c b/source4/smb_server/smb2/receive.c index abcf172738..40a57b88f1 100644 --- a/source4/smb_server/smb2/receive.c +++ b/source4/smb_server/smb2/receive.c @@ -322,13 +322,16 @@ static NTSTATUS smb2srv_reply(struct smb2srv_request *req) uid = BVAL(req->in.hdr, SMB2_HDR_SESSION_ID); flags = IVAL(req->in.hdr, SMB2_HDR_FLAGS); - if (req->smb_conn->highest_smb2_seqnum != 0 && + if (opcode != SMB2_OP_CANCEL && + req->smb_conn->highest_smb2_seqnum != 0 && req->seqnum <= req->smb_conn->highest_smb2_seqnum) { smbsrv_terminate_connection(req->smb_conn, "Invalid SMB2 sequence number"); return NT_STATUS_INVALID_PARAMETER; } - req->smb_conn->highest_smb2_seqnum = req->seqnum; - + if (opcode != SMB2_OP_CANCEL) { + req->smb_conn->highest_smb2_seqnum = req->seqnum; + } + req->session = smbsrv_session_find(req->smb_conn, uid, req->request_time); req->tcon = smbsrv_smb2_tcon_find(req->session, tid, req->request_time); @@ -656,7 +659,7 @@ NTSTATUS smbsrv_init_smb2_connection(struct smbsrv_connection *smb_conn) /* this is the size that w2k uses, and it appears to be important for good performance */ - smb_conn->negotiate.max_recv = lp_max_xmit(smb_conn->lp_ctx); + smb_conn->negotiate.max_recv = lpcfg_max_xmit(smb_conn->lp_ctx); smb_conn->negotiate.zone_offset = get_time_zone(time(NULL)); diff --git a/source4/smb_server/smb2/sesssetup.c b/source4/smb_server/smb2/sesssetup.c index 58090305a0..94fe0da9fa 100644 --- a/source4/smb_server/smb2/sesssetup.c +++ b/source4/smb_server/smb2/sesssetup.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include <tevent.h> #include "auth/gensec/gensec.h" #include "auth/auth.h" #include "libcli/smb2/smb2.h" @@ -26,6 +27,7 @@ #include "smb_server/smb_server.h" #include "smb_server/smb2/smb2_server.h" #include "smbd/service_stream.h" +#include "lib/stream/packet.h" static void smb2srv_sesssetup_send(struct smb2srv_request *req, union smb_sesssetup *io) { @@ -57,9 +59,9 @@ struct smb2srv_sesssetup_callback_ctx { struct smbsrv_session *smb_sess; }; -static void smb2srv_sesssetup_callback(struct gensec_update_request *greq, void *private_data) +static void smb2srv_sesssetup_callback(struct tevent_req *subreq) { - struct smb2srv_sesssetup_callback_ctx *ctx = talloc_get_type(private_data, + struct smb2srv_sesssetup_callback_ctx *ctx = tevent_req_callback_data(subreq, struct smb2srv_sesssetup_callback_ctx); struct smb2srv_request *req = ctx->req; union smb_sesssetup *io = ctx->io; @@ -67,7 +69,10 @@ static void smb2srv_sesssetup_callback(struct gensec_update_request *greq, void struct auth_session_info *session_info = NULL; NTSTATUS status; - status = gensec_update_recv(greq, req, &io->smb2.out.secblob); + packet_recv_enable(req->smb_conn->packet); + + status = gensec_update_recv(subreq, req, &io->smb2.out.secblob); + TALLOC_FREE(subreq); if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { goto done; } else if (!NT_STATUS_IS_OK(status)) { @@ -94,7 +99,7 @@ static void smb2srv_sesssetup_callback(struct gensec_update_request *greq, void done: io->smb2.out.uid = smb_sess->vuid; failed: - req->status = auth_nt_status_squash(status); + req->status = nt_status_squash(status); smb2srv_sesssetup_send(req, io); if (!NT_STATUS_IS_OK(status) && ! NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { @@ -108,6 +113,7 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses struct smb2srv_sesssetup_callback_ctx *callback_ctx; struct smbsrv_session *smb_sess = NULL; uint64_t vuid; + struct tevent_req *subreq; io->smb2.out.session_flags = 0; io->smb2.out.uid = 0; @@ -174,8 +180,12 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses callback_ctx->io = io; callback_ctx->smb_sess = smb_sess; - gensec_update_send(smb_sess->gensec_ctx, io->smb2.in.secblob, - smb2srv_sesssetup_callback, callback_ctx); + subreq = gensec_update_send(callback_ctx, + req->smb_conn->connection->event.ctx, + smb_sess->gensec_ctx, + io->smb2.in.secblob); + if (!subreq) goto nomem; + tevent_req_set_callback(subreq, smb2srv_sesssetup_callback, callback_ctx); /* note that we ignore SMB2_NEGOTIATE_SIGNING_ENABLED from the client. This is deliberate as windows does not set it even when it does @@ -192,12 +202,18 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses goto failed; } + /* disable receipt of more packets on this socket until we've + finished with the session setup. This avoids a problem with + crashes if we get EOF on the socket while processing a session + setup */ + packet_recv_disable(req->smb_conn->packet); + return; nomem: status = NT_STATUS_NO_MEMORY; failed: talloc_free(smb_sess); - req->status = auth_nt_status_squash(status); + req->status = nt_status_squash(status); smb2srv_sesssetup_send(req, io); } diff --git a/source4/smb_server/smb2/tcon.c b/source4/smb_server/smb2/tcon.c index d802146128..0dac29cf57 100644 --- a/source4/smb_server/smb2/tcon.c +++ b/source4/smb_server/smb2/tcon.c @@ -84,7 +84,7 @@ static NTSTATUS smb2srv_send_oplock_break(void *p, struct ntvfs_handle *h, uint8 return NT_STATUS_OK; } -struct ntvfs_handle *smb2srv_pull_handle(struct smb2srv_request *req, const uint8_t *base, uint_t offset) +struct ntvfs_handle *smb2srv_pull_handle(struct smb2srv_request *req, const uint8_t *base, unsigned int offset) { struct smbsrv_tcon *tcon; struct smbsrv_handle *handle; @@ -160,7 +160,7 @@ struct ntvfs_handle *smb2srv_pull_handle(struct smb2srv_request *req, const uint return handle->ntvfs; } -void smb2srv_push_handle(uint8_t *base, uint_t offset, struct ntvfs_handle *ntvfs) +void smb2srv_push_handle(uint8_t *base, unsigned int offset, struct ntvfs_handle *ntvfs) { struct smbsrv_handle *handle = talloc_get_type(ntvfs->frontend_data.private_data, struct smbsrv_handle); @@ -304,9 +304,11 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon goto failed; } - status = ntvfs_set_addr_callbacks(tcon->ntvfs, smbsrv_get_my_addr, smbsrv_get_peer_addr, req->smb_conn); + status = ntvfs_set_addresses(tcon->ntvfs, + req->smb_conn->connection->local_address, + req->smb_conn->connection->remote_address); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("smb2srv_tcon_backend: NTVFS failed to set the addr callbacks!\n")); + DEBUG(0,("smb2srv_tcon_backend: NTVFS failed to set the address!\n")); goto failed; } @@ -343,7 +345,7 @@ static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon /* Invoke NTVFS connection hook */ status = ntvfs_connect(req->ntvfs, io); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("smb2srv_tcon_backend: NTVFS ntvfs_connect() failed!\n")); + DEBUG(0,("smb2srv_tcon_backend: NTVFS ntvfs_connect() failed: %s!\n", nt_errstr(status))); goto failed; } diff --git a/source4/smb_server/smb2/wscript_build b/source4/smb_server/smb2/wscript_build new file mode 100644 index 0000000000..fd140eb8e2 --- /dev/null +++ b/source4/smb_server/smb2/wscript_build @@ -0,0 +1,8 @@ +#!/usr/bin/env python + +bld.SAMBA_SUBSYSTEM('SMB2_PROTOCOL', + source='receive.c negprot.c sesssetup.c tcon.c fileio.c fileinfo.c find.c keepalive.c', + autoproto='smb2_proto.h', + public_deps='ntvfs LIBPACKET LIBCLI_SMB2 samba_server_gensec NDR_DFSBLOBS' + ) + |