From 0e9008be35a5b334bd65e6417193d4b8f27bdc36 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 21 Sep 2008 21:26:40 +0200 Subject: Rename smbd -> samba. --- source4/smb_server/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/config.mk b/source4/smb_server/config.mk index e11968a100..52c000839d 100644 --- a/source4/smb_server/config.mk +++ b/source4/smb_server/config.mk @@ -2,7 +2,7 @@ # [MODULE::SERVICE_SMB] INIT_FUNCTION = server_service_smb_init -SUBSYSTEM = smbd +SUBSYSTEM = samba PRIVATE_DEPENDENCIES = SMB_SERVER SERVICE_SMB_OBJ_FILES = $(smb_serversrcdir)/smb_server.o -- cgit From 05ea5e23cf4e70de0bd658b1c5c0ead133967091 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 21 Sep 2008 21:32:40 +0200 Subject: Revert "Rename smbd -> samba." This reverts commit 0e9008be35a5b334bd65e6417193d4b8f27bdc36. --- source4/smb_server/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/config.mk b/source4/smb_server/config.mk index 52c000839d..e11968a100 100644 --- a/source4/smb_server/config.mk +++ b/source4/smb_server/config.mk @@ -2,7 +2,7 @@ # [MODULE::SERVICE_SMB] INIT_FUNCTION = server_service_smb_init -SUBSYSTEM = samba +SUBSYSTEM = smbd PRIVATE_DEPENDENCIES = SMB_SERVER SERVICE_SMB_OBJ_FILES = $(smb_serversrcdir)/smb_server.o -- cgit From bee2b6c3a3890949bd87e1e4b8c6de010c808f4d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 Sep 2008 03:57:31 +0200 Subject: process incoming connections and fork a samba3 in inetd mode --- source4/smb_server/config.mk | 8 ++ source4/smb_server/smb_samba3.c | 174 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 source4/smb_server/smb_samba3.c (limited to 'source4/smb_server') diff --git a/source4/smb_server/config.mk b/source4/smb_server/config.mk index e11968a100..d1ec6d49e8 100644 --- a/source4/smb_server/config.mk +++ b/source4/smb_server/config.mk @@ -9,6 +9,14 @@ SERVICE_SMB_OBJ_FILES = $(smb_serversrcdir)/smb_server.o $(eval $(call proto_header_template,$(smb_serversrcdir)/service_smb_proto.h,$(SERVICE_SMB_OBJ_FILES:.o=.c))) +# samba3 SMB server subsystem +# +[MODULE::SERVICE_SAMBA3_SMB] +INIT_FUNCTION = server_service_samba3_smb_init +SUBSYSTEM = smbd + +SERVICE_SAMBA3_SMB_OBJ_FILES = $(smb_serversrcdir)/smb_samba3.o + ####################### # Start SUBSYSTEM SMB [SUBSYSTEM::SMB_SERVER] diff --git a/source4/smb_server/smb_samba3.c b/source4/smb_server/smb_samba3.c new file mode 100644 index 0000000000..7b3229892f --- /dev/null +++ b/source4/smb_server/smb_samba3.c @@ -0,0 +1,174 @@ +/* + Unix SMB/CIFS implementation. + + process incoming connections and fork a samba3 in inetd mode + + Copyright (C) Stefan Metzmacher 2008 + + 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 3 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, see . +*/ + +#include "includes.h" +#include "smbd/service_task.h" +#include "smbd/service_stream.h" +#include "smbd/service.h" +#include "lib/messaging/irpc.h" +#include "lib/stream/packet.h" +#include "lib/socket/socket.h" +#include "libcli/smb2/smb2.h" +#include "smb_server/smb2/smb2_server.h" +#include "system/network.h" +#include "lib/socket/netif.h" +#include "param/share.h" +#include "dsdb/samdb/samdb.h" +#include "param/param.h" +#include "dynconfig/dynconfig.h" +#include "smbd/process_model.h" + +/* + initialise a server_context from a open socket and register a event handler + for reading from that socket +*/ +static void samba3_smb_accept(struct stream_connection *conn) +{ + int i; + int fd = socket_get_fd(conn->socket); + const char *prog; + char *argv[2]; + char *reason; + + close(0); + close(1); + dup2(fd, 0); + dup2(fd, 1); + for (i=2;i<256;i++) { + close(i); + } + + prog = lp_parm_string(conn->lp_ctx, NULL, "samba3", "smbd"); + + if (prog == NULL) { + argv[0] = talloc_asprintf(conn, "%s/%s", dyn_BINDIR, "smbd3"); + } + else { + argv[0] = talloc_strdup(conn, prog); + } + + if (argv[0] == NULL) { + stream_terminate_connection(conn, "out of memory"); + return; + } + argv[1] = NULL; + + execve(argv[0], argv, environ); + + /* + * Should never get here + */ + reason = talloc_asprintf(conn, "Could not execute %s", argv[0]); + if (reason == NULL) { + stream_terminate_connection(conn, "out of memory"); + return; + } + stream_terminate_connection(conn, reason); + talloc_free(reason); +} + +static const struct stream_server_ops samba3_smb_stream_ops = { + .name = "samba3", + .accept_connection = samba3_smb_accept, +}; + +/* + setup a listening socket on all the SMB ports for a particular address +*/ +static NTSTATUS samba3_add_socket(struct event_context *event_context, + struct loadparm_context *lp_ctx, + const struct model_ops *model_ops, + const char *address) +{ + const char **ports = lp_smb_ports(lp_ctx); + int i; + NTSTATUS status; + + for (i=0;ports[i];i++) { + uint16_t port = atoi(ports[i]); + if (port == 0) continue; + status = stream_setup_socket(event_context, lp_ctx, + model_ops, &samba3_smb_stream_ops, + "ip", address, &port, + lp_socket_options(lp_ctx), + NULL); + NT_STATUS_NOT_OK_RETURN(status); + } + + return NT_STATUS_OK; +} + + +/* + open the smb server sockets +*/ +static void samba3_smb_task_init(struct task_server *task) +{ + NTSTATUS status; + const struct model_ops *model_ops; + + model_ops = process_model_startup(task->event_ctx, "standard"); + + if (model_ops == NULL) { + goto failed; + } + + task_server_set_title(task, "task[samba3_smb]"); + + if (lp_interfaces(task->lp_ctx) + && lp_bind_interfaces_only(task->lp_ctx)) { + int num_interfaces; + int i; + struct interface *ifaces; + + load_interfaces(task, lp_interfaces(task->lp_ctx), &ifaces); + + num_interfaces = iface_count(ifaces); + + /* We have been given an interfaces line, and been + told to only bind to those interfaces. Create a + socket per interface and bind to only these. + */ + for(i = 0; i < num_interfaces; i++) { + const char *address = iface_n_ip(ifaces, i); + status = samba3_add_socket(task->event_ctx, + task->lp_ctx, + model_ops, address); + if (!NT_STATUS_IS_OK(status)) goto failed; + } + } else { + /* Just bind to lp_socket_address() (usually 0.0.0.0) */ + status = samba3_add_socket(task->event_ctx, task->lp_ctx, + model_ops, + lp_socket_address(task->lp_ctx)); + if (!NT_STATUS_IS_OK(status)) goto failed; + } + + return; +failed: + task_server_terminate(task, "Failed to startup samba3 smb task"); +} + +/* called at smbd startup - register ourselves as a server service */ +NTSTATUS server_service_samba3_smb_init(void) +{ + return register_server_service("samba3_smb", samba3_smb_task_init); +} -- cgit From 3b5060fdbaee5ffdfcb304179772d5e89dc8cff0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 22 Sep 2008 16:32:04 -0700 Subject: Explain why we use signing for DCs, but not file servers --- source4/smb_server/smb/signing.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb/signing.c b/source4/smb_server/smb/signing.c index ee4531c8f6..21dc99b165 100644 --- a/source4/smb_server/smb/signing.c +++ b/source4/smb_server/smb/signing.c @@ -118,10 +118,19 @@ bool smbsrv_init_signing(struct smbsrv_connection *smb_conn) smb_conn->signing.mandatory_signing = true; break; case SMB_SIGNING_AUTO: + /* If we are a domain controller, SMB signing is + * really important, as it can prevent a number of + * attacks on communications between us and the + * clients */ + if (lp_server_role(smb_conn->lp_ctx) == ROLE_DOMAIN_CONTROLLER) { smb_conn->signing.allow_smb_signing = true; smb_conn->signing.mandatory_signing = true; } else { + /* However, it really sucks (no sendfile, CPU + * overhead) performance-wise when used on a + * file server, so disable it by default (auto + * is the default) on non-DCs */ smb_conn->signing.allow_smb_signing = false; } break; -- cgit From 171349bc21cc727685abb5ed836d62f4ae80b496 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Sep 2008 02:30:15 +0200 Subject: s4:smb_server: remove the bogus smbsrv_signing_restart() Real signing always starts with seqnumber 2, and once signing is on the session key never change anymore for the complete smb connection. metze --- source4/smb_server/smb/sesssetup.c | 19 ++----------------- source4/smb_server/smb/signing.c | 24 ------------------------ 2 files changed, 2 insertions(+), 41 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb/sesssetup.c b/source4/smb_server/smb/sesssetup.c index f45cbf1756..a12bbd5cec 100644 --- a/source4/smb_server/smb/sesssetup.c +++ b/source4/smb_server/smb/sesssetup.c @@ -193,16 +193,6 @@ static void sesssetup_nt1_send(struct auth_check_password_request *areq, goto done; } - /* Force check of the request packet, now we know the session key */ - smbsrv_signing_check_incoming(req); -/* TODO: why don't we check the result here? */ - - /* Unfortunetly win2k3 as a client doesn't sign the request - * packet here, so we have to force signing to start again */ - - smbsrv_signing_restart(req->smb_conn, &session_info->session_key, &sess->nt1.in.password2, - session_info->server_info->authenticated); - done: status = NT_STATUS_OK; failed: @@ -321,13 +311,8 @@ static void sesssetup_spnego_send(struct gensec_update_request *greq, void *priv if (!NT_STATUS_IS_OK(status)) goto failed; skey_status = gensec_session_key(smb_sess->gensec_ctx, &session_key); - if (NT_STATUS_IS_OK(skey_status) && - smbsrv_setup_signing(req->smb_conn, &session_key, NULL)) { - /* Force check of the request packet, now we know the session key */ - smbsrv_signing_check_incoming(req); - - smbsrv_signing_restart(req->smb_conn, &session_key, NULL, - session_info->server_info->authenticated); + if (NT_STATUS_IS_OK(skey_status)) { + smbsrv_setup_signing(req->smb_conn, &session_key, NULL); } /* Ensure this is marked as a 'real' vuid, not one diff --git a/source4/smb_server/smb/signing.c b/source4/smb_server/smb/signing.c index 21dc99b165..0b5cf56fdb 100644 --- a/source4/smb_server/smb/signing.c +++ b/source4/smb_server/smb/signing.c @@ -75,30 +75,6 @@ bool smbsrv_setup_signing(struct smbsrv_connection *smb_conn, &smb_conn->signing, session_key, response); } -void smbsrv_signing_restart(struct smbsrv_connection *smb_conn, - DATA_BLOB *session_key, - DATA_BLOB *response, - bool authenticated_session) -{ - if (!smb_conn->signing.seen_valid) { - DEBUG(5, ("Client did not send a valid signature on " - "SPNEGO session setup - ignored, expect good next time\n")); - /* force things back on (most clients do not sign this packet)... */ - smbsrv_setup_signing(smb_conn, session_key, response); - smb_conn->signing.next_seq_num = 2; - - /* If mandetory_signing is set, and this was an authenticated logon, then force on */ - if (smb_conn->signing.mandatory_signing && authenticated_session) { - DEBUG(5, ("Configured for mandatory signing, 'good packet seen' forced on\n")); - /* if this is mandatory, then - * pretend we have seen a - * valid packet, so we don't - * turn it off */ - smb_conn->signing.seen_valid = true; - } - } -} - bool smbsrv_init_signing(struct smbsrv_connection *smb_conn) { smb_conn->signing.mac_key = data_blob(NULL, 0); -- cgit From 6a689c23e83fef71a562a9009b92983d750f63cc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 24 Sep 2008 03:16:15 +0200 Subject: Rename smbd -> samba. This reverts commit 05ea5e23cf4e70de0bd658b1c5c0ead133967091. Conflicts: source4/smbd/server.c --- source4/smb_server/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/config.mk b/source4/smb_server/config.mk index d1ec6d49e8..8ed03b17fe 100644 --- a/source4/smb_server/config.mk +++ b/source4/smb_server/config.mk @@ -2,7 +2,7 @@ # [MODULE::SERVICE_SMB] INIT_FUNCTION = server_service_smb_init -SUBSYSTEM = smbd +SUBSYSTEM = samba PRIVATE_DEPENDENCIES = SMB_SERVER SERVICE_SMB_OBJ_FILES = $(smb_serversrcdir)/smb_server.o -- cgit From ff542275c3e2bf432bcc303e95124374ada03675 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 23 Sep 2008 20:01:06 -0700 Subject: stricter checking of SMB2 echo body (per the spec) thanks to the bluearc test suite --- source4/smb_server/smb2/keepalive.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb2/keepalive.c b/source4/smb_server/smb2/keepalive.c index f40bcc485c..d1a0ef3d72 100644 --- a/source4/smb_server/smb2/keepalive.c +++ b/source4/smb_server/smb2/keepalive.c @@ -54,11 +54,16 @@ void smb2srv_keepalive_recv(struct smb2srv_request *req) { uint16_t _pad; - if (req->in.body_size < 0x04) { + if (req->in.body_size != 0x04) { smb2srv_send_error(req, NT_STATUS_FOOBAR); return; } + if (SVAL(req->in.body, 0x00) != 0x04) { + smb2srv_send_error(req, NT_STATUS_INVALID_PARAMETER); + return; + } + _pad = SVAL(req->in.body, 0x02); req->status = smb2srv_keepalive_backend(req); -- cgit From 71ae732669d641cf8b3fd7f6fa73ead4634178f1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 Sep 2008 08:58:16 -0700 Subject: fixed error code for bad keepalive --- source4/smb_server/smb2/keepalive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb2/keepalive.c b/source4/smb_server/smb2/keepalive.c index d1a0ef3d72..ff47d594f0 100644 --- a/source4/smb_server/smb2/keepalive.c +++ b/source4/smb_server/smb2/keepalive.c @@ -55,7 +55,7 @@ void smb2srv_keepalive_recv(struct smb2srv_request *req) uint16_t _pad; if (req->in.body_size != 0x04) { - smb2srv_send_error(req, NT_STATUS_FOOBAR); + smb2srv_send_error(req, NT_STATUS_INVALID_PARAMETER); return; } -- cgit From 7e57626d1d5a4497ecf5b4c741b8486e7ab97733 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 Sep 2008 17:32:47 -0700 Subject: the offset is 16 bits in SMB2 fileinfo --- source4/smb_server/smb2/fileinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb2/fileinfo.c b/source4/smb_server/smb2/fileinfo.c index 6c4b8f33d5..82b006c4a1 100644 --- a/source4/smb_server/smb2/fileinfo.c +++ b/source4/smb_server/smb2/fileinfo.c @@ -369,7 +369,7 @@ void smb2srv_setinfo_recv(struct smb2srv_request *req) SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_setinfo_send, NTVFS_ASYNC_STATE_MAY_ASYNC); info->in.level = SVAL(req->in.body, 0x02); - SMB2SRV_CHECK(smb2_pull_s32o32_blob(&req->in, info, req->in.body+0x04, &info->in.blob)); + SMB2SRV_CHECK(smb2_pull_s32o16_blob(&req->in, info, req->in.body+0x04, &info->in.blob)); info->in.flags = IVAL(req->in.body, 0x0C); info->in.file.ntvfs = smb2srv_pull_handle(req, req->in.body, 0x10); -- cgit From a3536c4c06d9725b2e96b9a3ddc1ab14e47f472c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 Sep 2008 17:33:15 -0700 Subject: check for a 0 byte in the buffer in SMB2 read --- source4/smb_server/smb2/fileio.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb2/fileio.c b/source4/smb_server/smb2/fileio.c index 2c322ea587..4f4402ba33 100644 --- a/source4/smb_server/smb2/fileio.c +++ b/source4/smb_server/smb2/fileio.c @@ -254,6 +254,12 @@ void smb2srv_read_recv(struct smb2srv_request *req) union smb_read *io; SMB2SRV_CHECK_BODY_SIZE(req, 0x30, true); + + /* MS-SMB2 2.2.19 read must have a single byte of zero */ + if (req->in.body_size - req->in.body_fixed < 1) { + smb2srv_send_error(req, NT_STATUS_INVALID_PARAMETER); + return; + } SMB2SRV_TALLOC_IO_PTR(io, union smb_read); SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_read_send, NTVFS_ASYNC_STATE_MAY_ASYNC); -- cgit From 49c80cea0bc00a88336fc9bd4bb332a7a399afd5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 Sep 2008 17:34:04 -0700 Subject: cope with body_size zero in SMB2 receive --- source4/smb_server/smb2/smb2_server.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb2/smb2_server.h b/source4/smb_server/smb2/smb2_server.h index d45e0861af..431add4ed9 100644 --- a/source4/smb_server/smb2/smb2_server.h +++ b/source4/smb_server/smb2/smb2_server.h @@ -75,7 +75,7 @@ struct smbsrv_request; /* useful way of catching field size errors with file and line number */ #define SMB2SRV_CHECK_BODY_SIZE(req, size, dynamic) do { \ size_t is_size = req->in.body_size; \ - uint16_t field_size = SVAL(req->in.body, 0); \ + uint16_t field_size; \ uint16_t want_size = ((dynamic)?(size)+1:(size)); \ if (is_size < (size)) { \ DEBUG(0,("%s: buffer too small 0x%x. Expected 0x%x\n", \ @@ -83,6 +83,7 @@ struct smbsrv_request; smb2srv_send_error(req, NT_STATUS_INVALID_PARAMETER); \ return; \ }\ + field_size = SVAL(req->in.body, 0); \ if (field_size != want_size) { \ DEBUG(0,("%s: unexpected fixed body size 0x%x. Expected 0x%x\n", \ __location__, (unsigned)field_size, (unsigned)want_size)); \ -- cgit From 63685c7d02f2364344fd8d4a3307ee36716e4a66 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 Sep 2008 17:34:58 -0700 Subject: record highest seq number in SMB2 to check for seqnum going backwards --- source4/smb_server/smb_server.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb_server.h b/source4/smb_server/smb_server.h index 4676fc3e9c..b3c3122765 100644 --- a/source4/smb_server/smb_server.h +++ b/source4/smb_server/smb_server.h @@ -386,6 +386,8 @@ struct smbsrv_connection { struct loadparm_context *lp_ctx; bool smb2_signing_required; + + uint64_t highest_smb2_seqnum; }; struct model_ops; -- cgit From 742a99e046313760a281da67eb3ba6e7fcfa8fa6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 Sep 2008 17:36:24 -0700 Subject: - add reserved field in basic_information level - use INVALID_PARAMETER for info length mismatch to match windows behaviour - added parsing of LINK_INFORMATION level --- source4/smb_server/blob.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/blob.c b/source4/smb_server/blob.c index 368b81d18e..4f018a5143 100644 --- a/source4/smb_server/blob.c +++ b/source4/smb_server/blob.c @@ -35,7 +35,7 @@ #define BLOB_CHECK_MIN_SIZE(blob, size) do { \ if ((blob)->length < (size)) { \ - return NT_STATUS_INFO_LENGTH_MISMATCH; \ + return NT_STATUS_INVALID_PARAMETER; \ } \ } while (0) @@ -530,13 +530,14 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx, switch (level) { case SMB_SFILEINFO_BASIC_INFORMATION: - BLOB_CHECK_MIN_SIZE(blob, 36); + BLOB_CHECK_MIN_SIZE(blob, 40); st->basic_info.in.create_time = pull_nttime(blob->data, 0); st->basic_info.in.access_time = pull_nttime(blob->data, 8); st->basic_info.in.write_time = pull_nttime(blob->data, 16); st->basic_info.in.change_time = pull_nttime(blob->data, 24); - st->basic_info.in.attrib = IVAL(blob->data, 32); + st->basic_info.in.attrib = IVAL(blob->data, 32); + st->basic_info.in.reserved = IVAL(blob->data, 36); return NT_STATUS_OK; @@ -581,6 +582,27 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; + + case RAW_SFILEINFO_LINK_INFORMATION: + if (!bufinfo) { + return NT_STATUS_INTERNAL_ERROR; + } + BLOB_CHECK_MIN_SIZE(blob, 20); + st->link_information.in.overwrite = CVAL(blob->data, 0); + st->link_information.in.root_fid = IVAL(blob->data, 8); + len = IVAL(blob->data, 16); + ofs = 20; + str_blob = *blob; + str_blob.length = MIN(str_blob.length, ofs+len); + smbsrv_blob_pull_string(bufinfo, &str_blob, ofs, + &st->link_information.in.new_name, + STR_UNICODE); + if (st->link_information.in.new_name == NULL) { + return NT_STATUS_FOOBAR; + } + + return NT_STATUS_OK; + case RAW_SFILEINFO_RENAME_INFORMATION_SMB2: /* SMB2 uses a different format for rename information */ if (!bufinfo) { -- cgit From eb5b3f50d17dfca198304d636033ad93410d570f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 Sep 2008 17:45:48 -0700 Subject: we should terminate the connection on a bad negprot packet size --- source4/smb_server/smb2/negprot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index d64b36d659..49a2d12ef4 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -192,7 +192,7 @@ void smb2srv_negprot_recv(struct smb2srv_request *req) enum ndr_err_code ndr_err; if (req->in.body_size < 0x26) { - smb2srv_send_error(req, NT_STATUS_FOOBAR); + smbsrv_terminate_connection(req->smb_conn, "Bad body size in SMB2 negprot"); return; } @@ -209,7 +209,7 @@ void smb2srv_negprot_recv(struct smb2srv_request *req) 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)) { - smbsrv_terminate_connection(req->smb_conn, nt_errstr(NT_STATUS_FOOBAR)); + smbsrv_terminate_connection(req->smb_conn, "Bad GUID in SMB2 negprot"); talloc_free(req); return; } -- cgit From 0cf717512659469a9b293685ba2a6db4742dcff7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 Sep 2008 18:58:38 -0700 Subject: we need different error handling for truncated packets in NETPROT and other SMB2 operations. --- source4/smb_server/smb2/receive.c | 41 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb2/receive.c b/source4/smb_server/smb2/receive.c index 1fe6f0b877..c3607f0a33 100644 --- a/source4/smb_server/smb2/receive.c +++ b/source4/smb_server/smb2/receive.c @@ -153,7 +153,7 @@ static void smb2srv_chain_reply(struct smb2srv_request *p_req) chain_offset = p_req->chain_offset; p_req->chain_offset = 0; - if (p_req->in.size < (NBT_HDR_SIZE + chain_offset + SMB2_MIN_SIZE)) { + if (p_req->in.size < (NBT_HDR_SIZE + chain_offset + SMB2_MIN_SIZE_NO_BODY)) { DEBUG(2,("Invalid SMB2 chained packet at offset 0x%X\n", chain_offset)); smbsrv_terminate_connection(p_req->smb_conn, "Invalid SMB2 chained packet"); @@ -184,6 +184,19 @@ static void smb2srv_chain_reply(struct smb2srv_request *p_req) req->in.body_size = req->in.size - (NBT_HDR_SIZE+ chain_offset + SMB2_HDR_BODY); req->in.dynamic = NULL; + req->seqnum = BVAL(req->in.hdr, SMB2_HDR_MESSAGE_ID); + + if (req->in.body_size < 2) { + /* error handling for this is different for negprot to + other packet types */ + uint16_t opcode = SVAL(req->in.hdr, SMB2_HDR_OPCODE); + if (opcode == SMB2_OP_NEGPROT) { + smbsrv_terminate_connection(req->smb_conn, "Bad body size in SMB2 negprot"); + } else { + smb2srv_send_error(req, NT_STATUS_INVALID_PARAMETER); + } + } + buffer_code = SVAL(req->in.body, 0); req->in.body_fixed = (buffer_code & ~1); dynamic_size = req->in.body_size - req->in.body_fixed; @@ -290,6 +303,10 @@ static NTSTATUS smb2srv_reply(struct smb2srv_request *req) uint64_t uid; uint32_t flags; + if (SVAL(req->in.hdr, SMB2_HDR_LENGTH) != SMB2_HDR_BODY) { + smbsrv_terminate_connection(req->smb_conn, "Invalid SMB2 header length"); + return NT_STATUS_INVALID_PARAMETER; + } opcode = SVAL(req->in.hdr, SMB2_HDR_OPCODE); req->chain_offset = IVAL(req->in.hdr, SMB2_HDR_NEXT_COMMAND); req->seqnum = BVAL(req->in.hdr, SMB2_HDR_MESSAGE_ID); @@ -297,6 +314,13 @@ 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 && + 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; + req->session = smbsrv_session_find(req->smb_conn, uid, req->request_time); req->tcon = smbsrv_smb2_tcon_find(req->session, tid, req->request_time); @@ -443,7 +467,7 @@ NTSTATUS smbsrv_recv_smb2_request(void *private, DATA_BLOB blob) return NT_STATUS_OK; } - if (blob.length < (NBT_HDR_SIZE + SMB2_MIN_SIZE)) { + if (blob.length < (NBT_HDR_SIZE + SMB2_MIN_SIZE_NO_BODY)) { DEBUG(2,("Invalid SMB2 packet length count %ld\n", (long)blob.length)); smbsrv_terminate_connection(smb_conn, "Invalid SMB2 packet"); return NT_STATUS_OK; @@ -470,6 +494,19 @@ NTSTATUS smbsrv_recv_smb2_request(void *private, DATA_BLOB blob) req->in.body_size = req->in.size - (SMB2_HDR_BODY+NBT_HDR_SIZE); req->in.dynamic = NULL; + req->seqnum = BVAL(req->in.hdr, SMB2_HDR_MESSAGE_ID); + + if (req->in.body_size < 2) { + /* error handling for this is different for negprot to + other packet types */ + uint16_t opcode = SVAL(req->in.hdr, SMB2_HDR_OPCODE); + if (opcode == SMB2_OP_NEGPROT) { + smbsrv_terminate_connection(req->smb_conn, "Bad body size in SMB2 negprot"); + } else { + smb2srv_send_error(req, NT_STATUS_INVALID_PARAMETER); + } + } + buffer_code = SVAL(req->in.body, 0); req->in.body_fixed = (buffer_code & ~1); dynamic_size = req->in.body_size - req->in.body_fixed; -- cgit From 8dd35fabbb4732cf601a93abbe0373fd53e661a1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 24 Sep 2008 11:20:45 -0700 Subject: NetApp found that we never set the smb signing flags2. This was found during testing at the CIFS plugfest. No other client seems to honour or use this bit, but it is quite ligitimately required by the spec. Andrew Bartlett --- source4/smb_server/smb/request.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb/request.c b/source4/smb_server/smb/request.c index c7fa2d7d8a..eb3e100b96 100644 --- a/source4/smb_server/smb/request.c +++ b/source4/smb_server/smb/request.c @@ -140,6 +140,10 @@ void smbsrv_setup_reply(struct smbsrv_request *req, uint_t wct, size_t buflen) flags2 |= FLAGS2_32_BIT_ERROR_CODES; } + if (req->smb_conn->signing.allow_smb_signing || req->smb_conn->signing.mandatory_signing) { + flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; + } + req->out.hdr = req->out.buffer + NBT_HDR_SIZE; req->out.vwv = req->out.hdr + HDR_VWV; req->out.wct = wct; -- cgit From e622325155a13fd9f6f85a767d345344f18eca41 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 30 Sep 2008 08:41:16 +0200 Subject: s4:smb_server/smb: FLAGS2_SMB_SECURITY_SIGNATURES should only be echoed, not set always metze --- source4/smb_server/smb/request.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb/request.c b/source4/smb_server/smb/request.c index eb3e100b96..241c262857 100644 --- a/source4/smb_server/smb/request.c +++ b/source4/smb_server/smb/request.c @@ -135,15 +135,16 @@ void smbsrv_setup_reply(struct smbsrv_request *req, uint_t wct, size_t buflen) flags2 = FLAGS2_LONG_PATH_COMPONENTS | FLAGS2_EXTENDED_ATTRIBUTES | FLAGS2_IS_LONG_NAME; - flags2 |= (req->flags2 & (FLAGS2_UNICODE_STRINGS|FLAGS2_EXTENDED_SECURITY)); +#define _SMB_FLAGS2_ECHOED_FLAGS ( \ + FLAGS2_UNICODE_STRINGS | \ + FLAGS2_EXTENDED_SECURITY | \ + FLAGS2_SMB_SECURITY_SIGNATURES \ +) + flags2 |= (req->flags2 & _SMB_FLAGS2_ECHOED_FLAGS); if (req->smb_conn->negotiate.client_caps & CAP_STATUS32) { flags2 |= FLAGS2_32_BIT_ERROR_CODES; } - if (req->smb_conn->signing.allow_smb_signing || req->smb_conn->signing.mandatory_signing) { - flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; - } - req->out.hdr = req->out.buffer + NBT_HDR_SIZE; req->out.vwv = req->out.hdr + HDR_VWV; req->out.wct = wct; -- cgit From 9542b2fe60482382459d387294fb92c182f35d64 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 5 Oct 2008 16:09:18 +0200 Subject: Re-enable build of smb_samba3.c after the rename smbd->samba --- source4/smb_server/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/config.mk b/source4/smb_server/config.mk index 8ed03b17fe..6a1a50ffbf 100644 --- a/source4/smb_server/config.mk +++ b/source4/smb_server/config.mk @@ -13,7 +13,7 @@ $(eval $(call proto_header_template,$(smb_serversrcdir)/service_smb_proto.h,$(SE # [MODULE::SERVICE_SAMBA3_SMB] INIT_FUNCTION = server_service_samba3_smb_init -SUBSYSTEM = smbd +SUBSYSTEM = samba SERVICE_SAMBA3_SMB_OBJ_FILES = $(smb_serversrcdir)/smb_samba3.o -- cgit From 1a228b442e9382167872fb863529001ac71d7567 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 5 Oct 2008 20:47:00 +0200 Subject: smbd3 is unhappy if stderr is not open --- source4/smb_server/smb_samba3.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/smb_samba3.c b/source4/smb_server/smb_samba3.c index 7b3229892f..259d29039d 100644 --- a/source4/smb_server/smb_samba3.c +++ b/source4/smb_server/smb_samba3.c @@ -52,7 +52,8 @@ static void samba3_smb_accept(struct stream_connection *conn) close(1); dup2(fd, 0); dup2(fd, 1); - for (i=2;i<256;i++) { + dup2(fd, 2); + for (i=3;i<256;i++) { close(i); } -- cgit