summaryrefslogtreecommitdiff
path: root/source3/smbd/smb2_server.c
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2015-11-13 10:30:50 +0100
committerRalph Boehme <slow@samba.org>2016-01-22 07:52:20 +0100
commite501c733ecdba2bae2da3f5b9a27b69be89ac228 (patch)
treeb889347d2dd1f449fa76815c6d399c5bfded182f /source3/smbd/smb2_server.c
parent736cd36d36ea4985c7bcff19c683bc140566da4c (diff)
downloadsamba-e501c733ecdba2bae2da3f5b9a27b69be89ac228.tar.gz
s3:smb2_server: add encryption state tracking flags
Add two encryption state tracking flags that can be used to tell whether a session or tcon is "encrypted" and add a helper function to calculate the encryption state from those flags. Signed-off-by: Ralph Boehme <slow@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3/smbd/smb2_server.c')
-rw-r--r--source3/smbd/smb2_server.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index bd8261a153f..70fbdc7a0b3 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -2004,6 +2004,65 @@ NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
return NT_STATUS_OK;
}
+bool smbXsrv_is_encrypted(uint8_t encryption_flags)
+{
+ return (!(encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET)
+ &&
+ (encryption_flags & (SMBXSRV_PROCESSED_ENCRYPTED_PACKET |
+ SMBXSRV_ENCRYPTION_DESIRED |
+ SMBXSRV_ENCRYPTION_REQUIRED)));
+}
+
+bool smbXsrv_is_partially_encrypted(uint8_t encryption_flags)
+{
+ return ((encryption_flags & SMBXSRV_PROCESSED_ENCRYPTED_PACKET) &&
+ (encryption_flags & SMBXSRV_PROCESSED_UNENCRYPTED_PACKET));
+}
+
+/* Set a flag if not already set, return true if set */
+bool smbXsrv_set_crypto_flag(uint8_t *flags, uint8_t flag)
+{
+ if ((flag == 0) || (*flags & flag)) {
+ return false;
+ }
+
+ *flags |= flag;
+ return true;
+}
+
+/*
+ * Update encryption state tracking flags, this can be used to
+ * determine whether whether the session or tcon is "encrypted".
+ */
+static void smb2srv_update_crypto_flags(struct smbd_smb2_request *req,
+ uint16_t opcode,
+ bool *update_session_globalp,
+ bool *update_tcon_globalp)
+{
+ /* Default: assume unecrypted */
+ struct smbXsrv_session *session = req->session;
+ struct smbXsrv_tcon *tcon = req->tcon;
+ uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
+ bool update_session = false;
+ bool update_tcon = false;
+
+ if (req->was_encrypted && req->do_encryption) {
+ encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
+ }
+
+ update_session |= smbXsrv_set_crypto_flag(
+ &session->global->encryption_flags, encrypt_flag);
+
+ if (tcon) {
+ update_tcon |= smbXsrv_set_crypto_flag(
+ &tcon->global->encryption_flags, encrypt_flag);
+ }
+
+ *update_session_globalp = update_session;
+ *update_tcon_globalp = update_tcon;
+ return;
+}
+
NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
{
struct smbXsrv_connection *xconn = req->xconn;
@@ -2240,6 +2299,28 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
req->do_encryption = true;
}
+ if (req->session) {
+ bool update_session_global = false;
+ bool update_tcon_global = false;
+
+ smb2srv_update_crypto_flags(req, opcode,
+ &update_session_global,
+ &update_tcon_global);
+
+ if (update_session_global) {
+ status = smbXsrv_session_update(x);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+ }
+ if (update_tcon_global) {
+ status = smbXsrv_tcon_update(req->tcon);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+ }
+ }
+
if (call->fileid_ofs != 0) {
size_t needed = call->fileid_ofs + 16;
const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req);