[SCM] Samba Shared Repository - branch master updated

Ralph Böhme slow at samba.org
Fri Jan 22 10:07:03 UTC 2016


The branch, master has been updated
       via  b74bef8 smbstatus: add support for SMB1 signing and CIFS UNIX extensions encryption
       via  f955499 libcli/smb: add define SMB_ENCRYPTION_GSSAPI for CIFS encryption type
       via  1e60a3f smbstatus: show signing state of sessions and tcons
       via  8d8af47 s3:lib/conn_tdb: store the connection dialect
       via  9d28443 s3:smb2_server: add signing state tracking flags
       via  fe5353c s3:smb2_server: convert signing_required bool to flags bitmap
       via  780743d smbstatus: show encrpytion state of tree connects
       via  83a557d smbstatus: align tree connect header and output
       via  e0fc931 smbstatus: show encrpytion state of sessions
       via  5d75078 smbstatus: align session list header and ouput
       via  603f1de smbstatus: pass talloc context to traverse_connections
       via  c2443d6 smbstatus: pass talloc context to traverse_sessionid
       via  f59ef03 smbstatus: rework connection dialect printing
       via  e501c73 s3:smb2_server: add encryption state tracking flags
       via  736cd36 s3:smb2_server: store encryption cipher in the channel
       via  bfdffea s3:smb2_server: convert encryption desired and required bools to flags
       via  63a13f4 smbstatus: remove obsolete verbose message
      from  ef269c9 substitute: Fix talloc_sub_basic for %G in the case of a local user.

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit b74bef8f7d3452f9a5aee4c934c9ff62afc2b2bd
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Nov 30 17:03:26 2015 +0100

    smbstatus: add support for SMB1 signing and CIFS UNIX extensions encryption
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Ralph Böhme <slow at samba.org>
    Autobuild-Date(master): Fri Jan 22 11:06:05 CET 2016 on sn-devel-144

commit f95549957ec73a67bee0093a17e84808adfe97de
Author: Ralph Boehme <slow at samba.org>
Date:   Thu Dec 3 12:17:50 2015 +0100

    libcli/smb: add define SMB_ENCRYPTION_GSSAPI for CIFS encryption type
    
    Add a define for the CIFS UNIX extensions encryption type. We store this
    in smbXsrv_channel and use it in smbstatus for showing the
    CIFS/SMB2/SMB3 encryption cipher used.
    
    The SMB3 encryption cipher constants start at 1, carefully choosing the
    highest available bit for the CIFS UNIX extensions encryption cipher
    should avoid collisions and leaves room for many SMB3 ciphers in the
    future.
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 1e60a3f009649df4b22ce09828a9f3c82848cee0
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Nov 30 11:20:43 2015 +0100

    smbstatus: show signing state of sessions and tcons
    
    Show the signing state of sesssions tcons in smbstatus. This is SMB2/3
    only. SMB1 support will be added in a later commit.
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 8d8af479e22f3a8b394c72d36a49715cd5de6ca0
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Nov 30 11:14:34 2015 +0100

    s3:lib/conn_tdb: store the connection dialect
    
    This will be used in a subsequent commit that will print the signing
    cipher in smbstatus. We need the connection dialect for that.
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 9d284431fc478bc6e19ac2d98b3c330800521ad3
Author: Ralph Boehme <slow at samba.org>
Date:   Sun Nov 15 11:12:34 2015 +0100

    s3:smb2_server: add signing state tracking flags
    
    Add flags that track the signing state of all incoming and outgoing SMB2
    packets and a helper function that can be used to determine whether a
    session of tcon can be considered "signed".
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit fe5353c82ee41ef620aa8340acd4748dd3bc795f
Author: Ralph Boehme <slow at samba.org>
Date:   Sun Nov 15 10:49:38 2015 +0100

    s3:smb2_server: convert signing_required bool to flags bitmap
    
    Use a flags bitmap for storing the signing state. This is in preparation
    of a subsequent patch that adds more flags to the bitmap.
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 780743d1b28d92352fa91322f9a14dc86055ea08
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Nov 9 17:26:51 2015 +0100

    smbstatus: show encrpytion state of tree connects
    
    Show the encrpytion state of tcons in smbstatus. This is SMB3 only. CIFS
    UNIX extensions encryption will be added in a later commit.
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 83a557dfad713c0ab30c071ae4cdab0713337928
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Nov 9 18:01:47 2015 +0100

    smbstatus: align tree connect header and output
    
    Align output and use timestring() instead of time_to_asc(). The latter calls
    asctime() which forces a \n into the time string.
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit e0fc93112f4eaaba7eae8c7bf1a2276e46ce3673
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Nov 9 17:17:17 2015 +0100

    smbstatus: show encrpytion state of sessions
    
    Show the encrpytion state of sessions in smbstatus. This is SMB3
    only. CIFS UNIX extensions encryption will be added in a later commit.
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 5d750787eb3da0e25d54554a8542a116bf244334
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Nov 9 17:02:38 2015 +0100

    smbstatus: align session list header and ouput
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 603f1de9cf9bc18998c735529abfe9ad79153af3
Author: Ralph Boehme <slow at samba.org>
Date:   Thu Nov 19 15:54:17 2015 +0100

    smbstatus: pass talloc context to traverse_connections
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit c2443d608ad3c698951af80819a7428634cf5365
Author: Ralph Boehme <slow at samba.org>
Date:   Thu Nov 19 10:40:29 2015 +0100

    smbstatus: pass talloc context to traverse_sessionid
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit f59ef038eda8f52ade832e8c5790629e47059984
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Nov 30 10:48:12 2015 +0100

    smbstatus: rework connection dialect printing
    
    In a later change I want to print the signing cipher which depends upon
    the connection dialect. So let's store the connection dialect in the
    sessionid struct and move the code that maps dialect integers to strings
    to smbstatus.
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit e501c733ecdba2bae2da3f5b9a27b69be89ac228
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Nov 13 10:30:50 2015 +0100

    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 at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 736cd36d36ea4985c7bcff19c683bc140566da4c
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Nov 13 10:35:58 2015 +0100

    s3:smb2_server: store encryption cipher in the channel
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit bfdffea0fa8e6af57c2b3e51472bab46d46fbaca
Author: Ralph Boehme <slow at samba.org>
Date:   Mon Nov 9 17:23:29 2015 +0100

    s3:smb2_server: convert encryption desired and required bools to flags
    
    This adds a bitmap smbXsrv_encrpytion_flags with flags to the
    smbXsrv_session_global.tdb and smbXsrv_tcon_global.tdb that we use
    instead of bools for desired and required.
    
    We need this info in the smbXsrv tdbs for smbstatus. Subsequent commits
    for smbstatus will use it.
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 63a13f40cfe31c58c57373ae384b3c067a4d5498
Author: Ralph Boehme <slow at samba.org>
Date:   Fri Nov 13 17:00:29 2015 +0100

    smbstatus: remove obsolete verbose message
    
    Signed-off-by: Ralph Boehme <slow at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 libcli/smb/smb_unix_ext.h      |   2 +-
 source3/include/session.h      |   5 +-
 source3/lib/conn_tdb.c         |  10 +++
 source3/lib/conn_tdb.h         |   4 +
 source3/lib/sessionid_tdb.c    |  39 ++-------
 source3/librpc/idl/smbXsrv.idl |  23 ++++--
 source3/smbd/globals.h         |   5 ++
 source3/smbd/process.c         |  77 ++++++++++++++++++
 source3/smbd/smb2_server.c     | 126 +++++++++++++++++++++++++++--
 source3/smbd/smb2_sesssetup.c  |  18 +++--
 source3/smbd/smb2_tcon.c       |  12 ++-
 source3/utils/status.c         | 176 +++++++++++++++++++++++++++++++++++------
 12 files changed, 413 insertions(+), 84 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libcli/smb/smb_unix_ext.h b/libcli/smb/smb_unix_ext.h
index ff705aa..e74976b 100644
--- a/libcli/smb/smb_unix_ext.h
+++ b/libcli/smb/smb_unix_ext.h
@@ -358,7 +358,7 @@ enum smb_whoami_flags {
  */
 
 #define SMB_REQUEST_TRANSPORT_ENCRYPTION     0x203 /* QFSINFO */
-
+#define SMB_ENCRYPTION_GSSAPI                0x8000
 
 /* The query/set info levels for POSIX ACLs. */
 #define SMB_QUERY_POSIX_ACL  0x204
diff --git a/source3/include/session.h b/source3/include/session.h
index fe41954..c32c8b0 100644
--- a/source3/include/session.h
+++ b/source3/include/session.h
@@ -38,6 +38,9 @@ struct sessionid {
 	struct server_id pid;
 	fstring ip_addr_str;
 	time_t connect_start;
-	fstring protocol_ver;
+	uint16_t connection_dialect;
+	uint8_t encryption_flags;
+	uint16_t cipher;
+	uint8_t signing_flags;
 };
 
diff --git a/source3/lib/conn_tdb.c b/source3/lib/conn_tdb.c
index bf66d7d..36d5fae 100644
--- a/source3/lib/conn_tdb.c
+++ b/source3/lib/conn_tdb.c
@@ -41,6 +41,9 @@ struct connections_forall_session {
 	gid_t gid;
 	fstring machine;
 	fstring addr;
+	uint16_t cipher;
+	uint16_t dialect;
+	uint8_t signing_flags;
 };
 
 static int collect_sessions_fn(struct smbXsrv_session_global0 *global,
@@ -62,6 +65,9 @@ static int collect_sessions_fn(struct smbXsrv_session_global0 *global,
 	}
 	fstrcpy(sess.machine, global->channels[0].remote_name);
 	fstrcpy(sess.addr, global->channels[0].remote_address);
+	sess.cipher = global->channels[0].encryption_cipher;
+	sess.dialect = global->connection_dialect;
+	sess.signing_flags = global->signing_flags;
 
 	status = dbwrap_store(state->session_by_pid,
 			      make_tdb_data((void*)&id, sizeof(id)),
@@ -123,6 +129,10 @@ static int traverse_tcon_fn(struct smbXsrv_tcon_global0 *global,
 	fstrcpy(data.addr, sess.addr);
 	fstrcpy(data.machine, sess.machine);
 	data.start = nt_time_to_unix(global->creation_time);
+	data.encryption_flags = global->encryption_flags;
+	data.cipher = sess.cipher;
+	data.dialect = sess.dialect;
+	data.signing_flags = global->signing_flags;
 
 	state->count++;
 
diff --git a/source3/lib/conn_tdb.h b/source3/lib/conn_tdb.h
index 217814f..34f0019 100644
--- a/source3/lib/conn_tdb.h
+++ b/source3/lib/conn_tdb.h
@@ -33,6 +33,10 @@ struct connections_data {
 	fstring addr;
 	fstring machine;
 	time_t start;
+	uint8_t encryption_flags;
+	uint16_t cipher;
+	uint16_t dialect;
+	uint8_t signing_flags;
 };
 
 /* The following definitions come from lib/conn_tdb.c  */
diff --git a/source3/lib/sessionid_tdb.c b/source3/lib/sessionid_tdb.c
index 68f9c43..cac0730 100644
--- a/source3/lib/sessionid_tdb.c
+++ b/source3/lib/sessionid_tdb.c
@@ -43,42 +43,9 @@ static int sessionid_traverse_read_fn(struct smbXsrv_session_global0 *global,
 		.id_num = global->session_global_id,
 		.connect_start = nt_time_to_unix(global->creation_time),
 		.pid = global->channels[0].server_id,
+		.connection_dialect = global->connection_dialect,
 	};
 
-	switch(global->connection_dialect){
-	case SMB2_DIALECT_REVISION_000:
-		fstrcpy(session.protocol_ver, "NT1");
-		break;
-	case SMB2_DIALECT_REVISION_202:
-		fstrcpy(session.protocol_ver, "SMB2_02");
-		break;
-	case SMB2_DIALECT_REVISION_210:
-		fstrcpy(session.protocol_ver, "SMB2_10");
-		break;
-	case SMB2_DIALECT_REVISION_222:
-		fstrcpy(session.protocol_ver, "SMB2_22");
-		break;
-	case SMB2_DIALECT_REVISION_224:
-		fstrcpy(session.protocol_ver, "SMB2_24");
-		break;
-	case SMB3_DIALECT_REVISION_300:
-		fstrcpy(session.protocol_ver, "SMB3_00");
-		break;
-	case SMB3_DIALECT_REVISION_302:
-		fstrcpy(session.protocol_ver, "SMB3_02");
-		break;
-	case SMB3_DIALECT_REVISION_310:
-		fstrcpy(session.protocol_ver, "SMB3_10");
-		break;
-	case SMB3_DIALECT_REVISION_311:
-		fstrcpy(session.protocol_ver, "SMB3_11");
-		break;
-	default:
-		fstr_sprintf(session.protocol_ver, "Unknown (0x%04x)",
-			     global->connection_dialect);
-		break;
-	}
-
 	if (session_info != NULL) {
 		session.uid = session_info->unix_token->uid;
 		session.gid = session_info->unix_token->gid;
@@ -102,6 +69,10 @@ static int sessionid_traverse_read_fn(struct smbXsrv_session_global0 *global,
 		global->channels[0].remote_address,
 		sizeof(fstring)-1);
 
+	session.encryption_flags = global->encryption_flags;
+	session.cipher = global->channels[0].encryption_cipher;
+	session.signing_flags = global->signing_flags;
+
 	return state->fn(NULL, &session, state->private_data);
 }
 
diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index 4062610..8528770 100644
--- a/source3/librpc/idl/smbXsrv.idl
+++ b/source3/librpc/idl/smbXsrv.idl
@@ -116,6 +116,19 @@ interface smbXsrv
 
 	/* sessions */
 
+	typedef [public,bitmap8bit] bitmap {
+		SMBXSRV_ENCRYPTION_REQUIRED		= 0x01,
+		SMBXSRV_ENCRYPTION_DESIRED		= 0x02,
+		SMBXSRV_PROCESSED_ENCRYPTED_PACKET	= 0x04,
+		SMBXSRV_PROCESSED_UNENCRYPTED_PACKET	= 0x08
+	} smbXsrv_encrpytion_flags;
+
+	typedef [public,bitmap8bit] bitmap {
+		SMBXSRV_SIGNING_REQUIRED		= 0x01,
+		SMBXSRV_PROCESSED_SIGNED_PACKET		= 0x02,
+		SMBXSRV_PROCESSED_UNSIGNED_PACKET	= 0x04
+	} smbXsrv_signing_flags;
+
 	typedef struct {
 		server_id				server_id;
 		[charset(UTF8),string] char		local_address[];
@@ -124,6 +137,7 @@ interface smbXsrv
 		[noprint] DATA_BLOB			signing_key;
 		uint32					auth_session_info_seqnum;
 		[ignore] smbXsrv_connection		*connection;
+		uint16					encryption_cipher;
 	} smbXsrv_channel_global0;
 
 	typedef struct {
@@ -140,8 +154,8 @@ interface smbXsrv
 		uint32					auth_session_info_seqnum;
 		auth_session_info			*auth_session_info;
 		uint16					connection_dialect;
-		boolean8				signing_required;
-		boolean8				encryption_required;
+		smbXsrv_signing_flags			signing_flags;
+		smbXsrv_encrpytion_flags		encryption_flags;
 		[noprint] DATA_BLOB			signing_key;
 		[noprint] DATA_BLOB			encryption_key;
 		[noprint] DATA_BLOB			decryption_key;
@@ -206,7 +220,6 @@ interface smbXsrv
 		[ignore] user_struct			*compat;
 		[ignore] smbXsrv_tcon_table		*tcon_table;
 		smbXsrv_session_auth0			*pending_auth;
-		boolean8				encryption_desired;
 	} smbXsrv_session;
 
 	typedef union {
@@ -259,11 +272,12 @@ interface smbXsrv
 		server_id				server_id;
 		NTTIME					creation_time;
 		[charset(UTF8),string] char		share_name[];
-		boolean8				encryption_required;
+		smbXsrv_encrpytion_flags		encryption_flags;
 		/*
 		 * for SMB1 this is the session that the tcon was opened on
 		 */
 		uint32					session_global_id;
+		smbXsrv_signing_flags                   signing_flags;
 	} smbXsrv_tcon_global0;
 
 	typedef union {
@@ -301,7 +315,6 @@ interface smbXsrv
 		NTSTATUS				status;
 		NTTIME					idle_time;
 		[ignore] connection_struct		*compat;
-		boolean8				encryption_desired;
 	} smbXsrv_tcon;
 
 	typedef union {
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 0422cbe..90d8dcc 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -636,6 +636,11 @@ NTSTATUS smbXsrv_open_global_traverse(
 	void *private_data);
 
 NTSTATUS smbXsrv_open_cleanup(uint64_t persistent_id);
+bool smbXsrv_is_encrypted(uint8_t encryption_flags);
+bool smbXsrv_is_partially_encrypted(uint8_t encryption_flags);
+bool smbXsrv_set_crypto_flag(uint8_t *flags, uint8_t flag);
+bool smbXsrv_is_signed(uint8_t signing_flags);
+bool smbXsrv_is_partially_signed(uint8_t signing_flags);
 
 struct smbd_smb2_send_queue {
 	struct smbd_smb2_send_queue *prev, *next;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 79ca91f..e5c52be 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1431,6 +1431,54 @@ static void smb_dump(const char *name, int type, const char *data)
 	TALLOC_FREE(fname);
 }
 
+static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
+					struct smb_request *req,
+					uint8_t type,
+					bool *update_session_globalp,
+					bool *update_tcon_globalp)
+{
+	connection_struct *conn = req->conn;
+	struct smbXsrv_tcon *tcon = conn ? conn->tcon : NULL;
+	uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
+	uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
+	bool update_session = false;
+	bool update_tcon = false;
+
+	if (req->encrypted) {
+		encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
+	}
+
+	if (srv_is_signing_active(req->xconn)) {
+		sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
+	} else if ((type == SMBecho) || (type == SMBsesssetupX)) {
+		/*
+		 * echo can be unsigned. Sesssion setup except final
+		 * session setup response too
+		 */
+		sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
+	}
+
+	update_session |= smbXsrv_set_crypto_flag(
+		&session->global->encryption_flags, encrypt_flag);
+	update_session |= smbXsrv_set_crypto_flag(
+		&session->global->signing_flags, sign_flag);
+
+	if (tcon) {
+		update_tcon |= smbXsrv_set_crypto_flag(
+			&tcon->global->encryption_flags, encrypt_flag);
+		update_tcon |= smbXsrv_set_crypto_flag(
+			&tcon->global->signing_flags, sign_flag);
+	}
+
+	if (update_session) {
+		session->global->channels[0].encryption_cipher = SMB_ENCRYPTION_GSSAPI;
+	}
+
+	*update_session_globalp = update_session;
+	*update_tcon_globalp = update_tcon;
+	return;
+}
+
 /****************************************************************************
  Prepare everything for calling the actual request function, and potentially
  call the request function via the "new" interface.
@@ -1647,6 +1695,35 @@ static connection_struct *switch_message(uint8_t type, struct smb_request *req)
 		}
 	}
 
+	/*
+	 * Update encryption and signing state tracking flags that are
+	 * used by smbstatus to display signing and encryption status.
+	 */
+	if (session != NULL) {
+		bool update_session_global = false;
+		bool update_tcon_global = false;
+
+		smb1srv_update_crypto_flags(session, req, type,
+					    &update_session_global,
+					    &update_tcon_global);
+
+		if (update_session_global) {
+			status = smbXsrv_session_update(session);
+			if (!NT_STATUS_IS_OK(status)) {
+				reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
+				return conn;
+			}
+		}
+
+		if (update_tcon_global) {
+			status = smbXsrv_tcon_update(req->conn->tcon);
+			if (!NT_STATUS_IS_OK(status)) {
+				reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
+				return conn;
+			}
+		}
+	}
+
 	smb_messages[type].fn(req);
 	return req->conn;
 }
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index cdcead0..9adbb99 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -2004,6 +2004,96 @@ 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 and unsigned */
+	struct smbXsrv_session *session = req->session;
+	struct smbXsrv_tcon *tcon = req->tcon;
+	uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
+	uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
+	bool update_session = false;
+	bool update_tcon = false;
+
+	if (req->was_encrypted && req->do_encryption) {
+		encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
+		sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
+	} else {
+		/* Unencrypted packet, can be signed */
+		if (req->do_signing) {
+			sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
+		} else if (opcode == SMB2_OP_CANCEL) {
+			/* Cancel requests are allowed to skip signing */
+			sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
+		}
+	}
+
+	update_session |= smbXsrv_set_crypto_flag(
+		&session->global->encryption_flags, encrypt_flag);
+	update_session |= smbXsrv_set_crypto_flag(
+		&session->global->signing_flags, sign_flag);
+
+	if (tcon) {
+		update_tcon |= smbXsrv_set_crypto_flag(
+			&tcon->global->encryption_flags, encrypt_flag);
+		update_tcon |= smbXsrv_set_crypto_flag(
+			&tcon->global->signing_flags, sign_flag);
+	}
+
+	*update_session_globalp = update_session;
+	*update_tcon_globalp = update_tcon;
+	return;
+}
+
+bool smbXsrv_is_signed(uint8_t signing_flags)
+{
+	/*
+	 * Signing is always enabled, so unless we got an unsigned
+	 * packet and at least one signed packet that was not
+	 * encrypted, the session or tcon is "signed".
+	 */
+	return (!(signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
+		(signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
+}
+
+bool smbXsrv_is_partially_signed(uint8_t signing_flags)
+{
+	return ((signing_flags & SMBXSRV_PROCESSED_UNSIGNED_PACKET) &&
+		(signing_flags & SMBXSRV_PROCESSED_SIGNED_PACKET));
+}
+
 NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 {
 	struct smbXsrv_connection *xconn = req->xconn;
@@ -2066,9 +2156,9 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 	session_status = smbd_smb2_request_check_session(req);
 	x = req->session;
 	if (x != NULL) {
-		signing_required = x->global->signing_required;
-		encryption_desired = x->encryption_desired;
-		encryption_required = x->global->encryption_required;
+		signing_required = x->global->signing_flags & SMBXSRV_SIGNING_REQUIRED;
+		encryption_desired = x->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED;
+		encryption_required = x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED;
 	}
 
 	req->do_signing = false;
@@ -2224,10 +2314,10 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 		if (!NT_STATUS_IS_OK(status)) {
 			return smbd_smb2_request_error(req, status);
 		}
-		if (req->tcon->encryption_desired) {
+		if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
 			encryption_desired = true;
 		}
-		if (req->tcon->global->encryption_required) {
+		if (req->tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED) {
 			encryption_required = true;
 		}
 		if (encryption_required && !req->was_encrypted) {
@@ -2240,6 +2330,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);
@@ -2882,8 +2994,8 @@ static NTSTATUS smbd_smb2_send_break(struct smbXsrv_connection *xconn,
 
 	if (session != NULL) {
 		session_wire_id = session->global->session_wire_id;
-		do_encryption = session->encryption_desired;
-		if (tcon->encryption_desired) {
+		do_encryption = session->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED;
+		if (tcon->global->encryption_flags & SMBXSRV_ENCRYPTION_DESIRED) {
 			do_encryption = true;
 		}
 	}
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index 30e2d7f..a6c66e2 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -263,17 +263,17 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
 
 	if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
 	    lp_server_signing() == SMB_SIGNING_REQUIRED) {
-		x->global->signing_required = true;
+		x->global->signing_flags = SMBXSRV_SIGNING_REQUIRED;
 	}
 


-- 
Samba Shared Repository



More information about the samba-cvs mailing list