[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Thu Aug 9 02:00:03 MDT 2012
The branch, master has been updated
via 0d7b17f s3:smb2_sesssetup: setup global->[en|de]cryption_key
via 0cb11ef s3:smb2_read: don't try sendfile if encryption is used
via a0cf42b s3:smb2_server: add smbd_smb2_request->do_encryption
via 95e4270 s3:smb2_tcon: set global->encryption_required and enforce it
via 64dce26 s3:smb2_sesssetup: set global->encryption_required and enforce it
via 8734887 s3:smbXsrv.idl: add encryption_required to smbXsrv_tcon_global0
via b5a72f4 s3:smb2_server: check the session before we could response with an error.
via f15d9a6 s3:smb2_server: do central file_id check if the operation requires it
from a117fd6 s4-dsdb: Ensure we have indexing enabled during the provision
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 0d7b17f4db9d271ae41ade7c7b003b8d264cf6bf
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Aug 8 09:32:22 2012 +0200
s3:smb2_sesssetup: setup global->[en|de]cryption_key
metze
Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
Autobuild-Date(master): Thu Aug 9 09:59:02 CEST 2012 on sn-devel-104
commit 0cb11efa873d6e70ef54454240df7fbdd54fd3f2
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Aug 8 06:35:34 2012 +0200
s3:smb2_read: don't try sendfile if encryption is used
metze
commit a0cf42b7099097121e14cd337ea659a37ec824c4
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Aug 8 06:35:03 2012 +0200
s3:smb2_server: add smbd_smb2_request->do_encryption
For now it's always false...
metze
commit 95e4270813fa8bfda2dc899b1c8537e49fb9c115
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Aug 8 06:25:10 2012 +0200
s3:smb2_tcon: set global->encryption_required and enforce it
This the account or client doesn't support encryption we should
reject the tree connect.
metze
commit 64dce265338f325e9fdee6b4a95e918d3b704cbf
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Aug 8 06:25:10 2012 +0200
s3:smb2_sesssetup: set global->encryption_required and enforce it
This the account or client doesn't support encryption we should
reject the session setup.
metze
commit 87348873486b01a0367ff9889d8a7b51b7073e26
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Aug 8 06:24:01 2012 +0200
s3:smbXsrv.idl: add encryption_required to smbXsrv_tcon_global0
metze
commit b5a72f4f35a3aecba6294a3f8c07fb2ea252284b
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Aug 8 06:57:45 2012 +0200
s3:smb2_server: check the session before we could response with an error.
metze
commit f15d9a66701eaf580a0b641cf3f0dec185d6dd48
Author: Stefan Metzmacher <metze at samba.org>
Date: Tue Aug 7 09:44:31 2012 +0200
s3:smb2_server: do central file_id check if the operation requires it
Note that it's fine to call file_fsp_smb2() twice, the 2nd call
just returns smb2req->compat_chain_fsp without a 2nd lookup.
metze
-----------------------------------------------------------------------
Summary of changes:
source3/librpc/idl/smbXsrv.idl | 1 +
source3/smbd/globals.h | 1 +
source3/smbd/smb2_read.c | 1 +
source3/smbd/smb2_server.c | 87 +++++++++++++++++++++++++++++++++-------
source3/smbd/smb2_sesssetup.c | 58 ++++++++++++++++++++++++++
source3/smbd/smb2_tcon.c | 34 +++++++++++++--
6 files changed, 162 insertions(+), 20 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index be52723..9111b3d 100644
--- a/source3/librpc/idl/smbXsrv.idl
+++ b/source3/librpc/idl/smbXsrv.idl
@@ -224,6 +224,7 @@ interface smbXsrv
server_id server_id;
NTTIME creation_time;
[charset(UTF8),string] char share_name[];
+ boolean8 encryption_required;
} smbXsrv_tcon_global0;
typedef union {
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 7b2d31d..ac8a1b2 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -456,6 +456,7 @@ struct smbd_smb2_request {
int current_idx;
bool do_signing;
+ bool do_encryption;
struct tevent_timer *async_te;
bool cancelled;
bool compound_related;
diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c
index 150bdb8..e0c615a 100644
--- a/source3/smbd/smb2_read.c
+++ b/source3/smbd/smb2_read.c
@@ -276,6 +276,7 @@ static NTSTATUS schedule_smb2_sendfile_read(struct smbd_smb2_request *smb2req,
if (!lp__use_sendfile(SNUM(fsp->conn)) ||
smb2req->do_signing ||
+ smb2req->do_encryption ||
smb2req->in.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) ||
(fsp->base_fsp != NULL) ||
(fsp->wcp != NULL) ||
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 5242547..a84776a 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -38,6 +38,8 @@ static const struct smbd_smb2_dispatch_table {
bool need_session;
bool need_tcon;
bool as_root;
+ uint16_t fileid_ofs;
+ bool allow_invalid_fileid;
} smbd_smb2_table[] = {
#define _OP(o) .opcode = o, .name = #o
{
@@ -74,26 +76,33 @@ static const struct smbd_smb2_dispatch_table {
_OP(SMB2_OP_CLOSE),
.need_session = true,
.need_tcon = true,
+ .fileid_ofs = 0x08,
},{
_OP(SMB2_OP_FLUSH),
.need_session = true,
.need_tcon = true,
+ .fileid_ofs = 0x08,
},{
_OP(SMB2_OP_READ),
.need_session = true,
.need_tcon = true,
+ .fileid_ofs = 0x10,
},{
_OP(SMB2_OP_WRITE),
.need_session = true,
.need_tcon = true,
+ .fileid_ofs = 0x10,
},{
_OP(SMB2_OP_LOCK),
.need_session = true,
.need_tcon = true,
+ .fileid_ofs = 0x08,
},{
_OP(SMB2_OP_IOCTL),
.need_session = true,
.need_tcon = true,
+ .fileid_ofs = 0x08,
+ .allow_invalid_fileid = true,
},{
_OP(SMB2_OP_CANCEL),
.as_root = true,
@@ -104,22 +113,32 @@ static const struct smbd_smb2_dispatch_table {
_OP(SMB2_OP_FIND),
.need_session = true,
.need_tcon = true,
+ .fileid_ofs = 0x08,
},{
_OP(SMB2_OP_NOTIFY),
.need_session = true,
.need_tcon = true,
+ .fileid_ofs = 0x08,
},{
_OP(SMB2_OP_GETINFO),
.need_session = true,
.need_tcon = true,
+ .fileid_ofs = 0x18,
},{
_OP(SMB2_OP_SETINFO),
.need_session = true,
.need_tcon = true,
+ .fileid_ofs = 0x10,
},{
_OP(SMB2_OP_BREAK),
.need_session = true,
.need_tcon = true,
+ /*
+ * we do not set
+ * .fileid_ofs here
+ * as LEASE breaks does not
+ * have a file id
+ */
}
};
@@ -1023,6 +1042,7 @@ static struct smbd_smb2_request *dup_smb2_req(const struct smbd_smb2_request *re
newreq->sconn = req->sconn;
newreq->session = req->session;
+ newreq->do_encryption = req->do_encryption;
newreq->do_signing = req->do_signing;
newreq->current_idx = req->current_idx;
@@ -1723,21 +1743,6 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
}
}
- call = smbd_smb2_call(opcode);
- if (call == NULL) {
- return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
- }
-
- allowed_flags = SMB2_HDR_FLAG_CHAINED |
- SMB2_HDR_FLAG_SIGNED |
- SMB2_HDR_FLAG_DFS;
- if (opcode == SMB2_OP_CANCEL) {
- allowed_flags |= SMB2_HDR_FLAG_ASYNC;
- }
- if ((flags & ~allowed_flags) != 0) {
- return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
- }
-
/*
* Check if the client provided a valid session id,
* if so smbd_smb2_request_check_session() calls
@@ -1758,6 +1763,21 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
}
}
+ call = smbd_smb2_call(opcode);
+ if (call == NULL) {
+ return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+ }
+
+ allowed_flags = SMB2_HDR_FLAG_CHAINED |
+ SMB2_HDR_FLAG_SIGNED |
+ SMB2_HDR_FLAG_DFS;
+ if (opcode == SMB2_OP_CANCEL) {
+ allowed_flags |= SMB2_HDR_FLAG_ASYNC;
+ }
+ if ((flags & ~allowed_flags) != 0) {
+ return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+ }
+
req->do_signing = false;
if (flags & SMB2_HDR_FLAG_SIGNED) {
DATA_BLOB signing_key;
@@ -1827,7 +1847,44 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
}
}
+ if (call->fileid_ofs != 0) {
+ size_t needed = call->fileid_ofs + 16;
+ const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);
+ size_t body_size = SMBD_SMB2_IN_BODY_LEN(req);
+ uint64_t file_id_persistent;
+ uint64_t file_id_volatile;
+ struct files_struct *fsp;
+
+ SMB_ASSERT(call->need_tcon);
+
+ if (needed > body_size) {
+ return smbd_smb2_request_error(req,
+ NT_STATUS_INVALID_PARAMETER);
+ }
+
+ file_id_persistent = BVAL(body, call->fileid_ofs + 0);
+ file_id_volatile = BVAL(body, call->fileid_ofs + 8);
+
+ fsp = file_fsp_smb2(req, file_id_persistent, file_id_volatile);
+ if (fsp == NULL) {
+ if (!call->allow_invalid_fileid) {
+ return smbd_smb2_request_error(req,
+ NT_STATUS_FILE_CLOSED);
+ }
+
+ if (file_id_persistent != UINT64_MAX) {
+ return smbd_smb2_request_error(req,
+ NT_STATUS_FILE_CLOSED);
+ }
+ if (file_id_volatile != UINT64_MAX) {
+ return smbd_smb2_request_error(req,
+ NT_STATUS_FILE_CLOSED);
+ }
+ }
+ }
+
if (call->as_root) {
+ SMB_ASSERT(call->fileid_ofs == 0);
/* This call needs to be run as root */
change_to_root_user();
} else {
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index 07a168f..12a9d22 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -190,6 +190,10 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
x->global->signing_required = true;
}
+ if (lp_smb_encrypt(-1) == SMB_SIGNING_REQUIRED) {
+ x->global->encryption_required = true;
+ }
+
if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
/* we map anonymous to guest internally */
*out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST;
@@ -199,6 +203,24 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
guest = true;
}
+ if (guest && x->global->encryption_required) {
+ DEBUG(1,("reject guest session as encryption is required\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!(conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION)) {
+ if (x->global->encryption_required) {
+ DEBUG(1,("reject session with dialect[0x%04X] "
+ "as encryption is required\n",
+ conn->smb2.server.dialect));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+
+ if (x->global->encryption_required) {
+ *out_session_flags |= SMB2_SESSION_FLAG_ENCRYPT_DATA;
+ }
+
ZERO_STRUCT(session_key);
memcpy(session_key, session_info->session_key.data,
MIN(session_info->session_key.length, sizeof(session_key)));
@@ -221,6 +243,42 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
x->global->signing_key.data);
}
+ if (conn->protocol >= PROTOCOL_SMB2_24) {
+ const DATA_BLOB label = data_blob_string_const_null("SMB2AESCCM");
+ const DATA_BLOB context = data_blob_string_const_null("ServerIn ");
+
+ x->global->decryption_key = data_blob_talloc(x->global,
+ session_key,
+ sizeof(session_key));
+ if (x->global->decryption_key.data == NULL) {
+ ZERO_STRUCT(session_key);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ smb2_key_derivation(session_key, sizeof(session_key),
+ label.data, label.length,
+ context.data, context.length,
+ x->global->decryption_key.data);
+ }
+
+ if (conn->protocol >= PROTOCOL_SMB2_24) {
+ const DATA_BLOB label = data_blob_string_const_null("SMB2AESCCM");
+ const DATA_BLOB context = data_blob_string_const_null("ServerOut");
+
+ x->global->encryption_key = data_blob_talloc(x->global,
+ session_key,
+ sizeof(session_key));
+ if (x->global->encryption_key.data == NULL) {
+ ZERO_STRUCT(session_key);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ smb2_key_derivation(session_key, sizeof(session_key),
+ label.data, label.length,
+ context.data, context.length,
+ x->global->encryption_key.data);
+ }
+
x->global->application_key = data_blob_dup_talloc(x->global,
x->global->signing_key);
if (x->global->application_key.data == NULL) {
diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c
index a6b47d3..2cf91af 100644
--- a/source3/smbd/smb2_tcon.c
+++ b/source3/smbd/smb2_tcon.c
@@ -175,6 +175,7 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
uint32_t *out_maximal_access,
uint32_t *out_tree_id)
{
+ struct smbXsrv_connection *conn = req->sconn->conn;
const char *share = in_path;
char *service = NULL;
int snum = -1;
@@ -183,6 +184,8 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
connection_struct *compat_conn = NULL;
struct user_struct *compat_vuser = req->session->compat;
NTSTATUS status;
+ bool encryption_required = req->session->global->encryption_required;
+ bool guest_session = false;
if (strncmp(share, "\\\\", 2) == 0) {
const char *p = strchr(share+2, '\\');
@@ -230,11 +233,26 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
}
if (lp_smb_encrypt(snum) == SMB_SIGNING_REQUIRED) {
- status = NT_STATUS_ACCESS_DENIED;
- DEBUG(3,("smbd_smb2_tree_connect: "
- "service %s needs encryption - %s\n",
- service, nt_errstr(status)));
- return status;
+ encryption_required = true;
+ }
+
+ if (security_session_user_level(compat_vuser->session_info, NULL) < SECURITY_USER) {
+ guest_session = true;
+ }
+
+ if (guest_session && encryption_required) {
+ DEBUG(1,("reject guest as encryption is required for service %s\n",
+ service));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!(conn->smb2.server.capabilities & SMB2_CAP_ENCRYPTION)) {
+ if (encryption_required) {
+ DEBUG(1,("reject tcon with dialect[0x%04X] "
+ "as encryption is required for service %s\n",
+ conn->smb2.server.dialect, service));
+ return NT_STATUS_ACCESS_DENIED;
+ }
}
/* create a new tcon as child of the session */
@@ -243,6 +261,8 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
return status;
}
+ tcon->global->encryption_required = encryption_required;
+
compat_conn = make_connection_smb2(req->sconn,
tcon, snum,
req->session->compat,
@@ -309,6 +329,10 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
*out_share_flags |= SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM;
}
+ if (encryption_required) {
+ *out_share_flags |= SMB2_SHAREFLAG_ENCRYPT_DATA;
+ }
+
*out_maximal_access = tcon->compat->share_access;
*out_tree_id = tcon->global->tcon_wire_id;
--
Samba Shared Repository
More information about the samba-cvs
mailing list