[PATCH 2/8] s4:schannel more readable check logic

Simo Sorce idra at samba.org
Thu Feb 18 08:26:24 MST 2010


Make the initial schannel check logic more understandable.
Make it easy to define different policies depending on the caller's
security requirements (Integrity/Privacy/Both/None)

This is the same change applied to s3
---
 libcli/auth/schannel_state_ldb.c              |   10 ----
 libcli/auth/schannel_state_proto.h            |    2 -
 source4/rpc_server/netlogon/dcerpc_netlogon.c |   56 +++++++++++++++++++-----
 3 files changed, 44 insertions(+), 24 deletions(-)

diff --git a/libcli/auth/schannel_state_ldb.c b/libcli/auth/schannel_state_ldb.c
index ba3d96f..2919ed6 100644
--- a/libcli/auth/schannel_state_ldb.c
+++ b/libcli/auth/schannel_state_ldb.c
@@ -264,8 +264,6 @@ NTSTATUS schannel_fetch_session_key_ldb(struct ldb_context *ldb,
 NTSTATUS schannel_creds_server_step_check_ldb(struct ldb_context *ldb,
 					      TALLOC_CTX *mem_ctx,
 					      const char *computer_name,
-					      bool schannel_required_for_call,
-					      bool schannel_in_use,
 					      struct netr_Authenticator *received_authenticator,
 					      struct netr_Authenticator *return_authenticator,
 					      struct netlogon_creds_CredentialState **creds_out)
@@ -277,14 +275,6 @@ NTSTATUS schannel_creds_server_step_check_ldb(struct ldb_context *ldb,
 	/* If we are flaged that schannel is required for a call, and
 	 * it is not in use, then make this an error */
 
-	/* It would be good to make this mandetory once schannel is
-	 * negoiated, but this is not what windows does */
-	if (schannel_required_for_call && !schannel_in_use) {
-		DEBUG(0,("schannel_creds_server_step_check: client %s not using schannel for netlogon, despite negotiating it\n",
-			creds->computer_name ));
-		return NT_STATUS_ACCESS_DENIED;
-	}
-
 	ret = ldb_transaction_start(ldb);
 	if (ret != 0) {
 		return NT_STATUS_INTERNAL_DB_CORRUPTION;
diff --git a/libcli/auth/schannel_state_proto.h b/libcli/auth/schannel_state_proto.h
index d0a071c..da5ebb3 100644
--- a/libcli/auth/schannel_state_proto.h
+++ b/libcli/auth/schannel_state_proto.h
@@ -21,8 +21,6 @@ NTSTATUS schannel_fetch_session_key_ldb(struct ldb_context *ldb,
 NTSTATUS schannel_creds_server_step_check_ldb(struct ldb_context *ldb,
 					      TALLOC_CTX *mem_ctx,
 					      const char *computer_name,
-					      bool schannel_required_for_call,
-					      bool schannel_in_use,
 					      struct netr_Authenticator *received_authenticator,
 					      struct netr_Authenticator *return_authenticator,
 					      struct netlogon_creds_CredentialState **creds_out);
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index de741d5..10b729d 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -307,15 +307,43 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate2(struct dcesrv_call_state *dce_ca
 }
 
 /*
-  Validate an incoming authenticator against the credentials for the remote machine.
+ * NOTE: The following functions are nearly identical to the ones available in
+ * source3/rpc_server/srv_nelog_nt.c
+ * The reason we keep 2 copies is that they use different structures to
+ * represent the auth_info and the decrpc pipes.
+ */
 
-  The credentials are (re)read and from the schannel database, and
-  written back after the caclulations are performed.
+/*
+ * If schannel is required for this call test that it actually is available.
+ */
+static NTSTATUS schannel_check_required(struct dcerpc_auth *auth_info,
+					const char *computer_name,
+					bool integrity, bool privacy)
+{
 
-  The creds_out parameter (if not NULL) returns the credentials, if
-  the caller needs some of that information.
+	if (auth_info && auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
+		if (!privacy && !integrity) {
+			return NT_STATUS_OK;
+		}
+
+		if ((!privacy && integrity) &&
+		    auth_info->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
+			return NT_STATUS_OK;
+		}
+
+		if ((privacy || integrity) &&
+		    auth_info->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
+			return NT_STATUS_OK;
+		}
+	}
+
+	/* test didn't pass */
+	DEBUG(0, ("schannel_check_required: [%s] is not using schannel\n",
+		  computer_name));
+
+	return NT_STATUS_ACCESS_DENIED;
+}
 
-*/
 static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
 						    TALLOC_CTX *mem_ctx,
 						    const char *computer_name,
@@ -325,11 +353,17 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 {
 	NTSTATUS nt_status;
 	struct ldb_context *ldb;
+	struct dcerpc_auth *auth_info = dce_call->conn->auth_state.auth_info;
 	bool schannel_global_required = false; /* Should be lp_schannel_server() == true */
-	bool schannel_in_use = dce_call->conn->auth_state.auth_info
-		&& dce_call->conn->auth_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL
-		&& (dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY
-		    || dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_PRIVACY);
+
+	if (schannel_global_required) {
+		nt_status = schannel_check_required(auth_info,
+						    computer_name,
+						    true, false);
+		if (!NT_STATUS_IS_OK(nt_status)) {
+			return nt_status;
+		}
+	}
 
 	ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
 	if (!ldb) {
@@ -337,8 +371,6 @@ static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dc
 	}
 	nt_status = schannel_creds_server_step_check_ldb(ldb, mem_ctx,
 							 computer_name,
-							 schannel_global_required,
-							 schannel_in_use,
 							 received_authenticator,
 							 return_authenticator, creds_out);
 	talloc_unlink(mem_ctx, ldb);
-- 
1.6.6


--=-s85XraIvagGPiKkswX0v
Content-Disposition: attachment; filename="0003-schannel-merge-header-files.patch"
Content-Type: text/x-patch; name="0003-schannel-merge-header-files.patch"; charset="UTF-8"
Content-Transfer-Encoding: 7bit



More information about the samba-technical mailing list