s3:schannel more readable check logic
authorSimo Sorce <idra@samba.org>
Thu, 18 Feb 2010 15:19:09 +0000 (10:19 -0500)
committerSimo Sorce <idra@samba.org>
Tue, 23 Feb 2010 17:46:50 +0000 (12:46 -0500)
Make the initial schannel check logic more understandable.
Make it easy to define different policies depending on ther caller's security
requirements (Integrity/Privacy/Both/None)

libcli/auth/schannel_state_proto.h
libcli/auth/schannel_state_tdb.c
source3/rpc_server/srv_netlog_nt.c

index c582c3e8b893875a2a8ad270de614ab664f566ce..d0a071c876d59225902066e9757d6bae2233a4f4 100644 (file)
@@ -36,8 +36,6 @@ NTSTATUS schannel_fetch_session_key_tdb(struct tdb_context *tdb,
 NTSTATUS schannel_creds_server_step_check_tdb(struct tdb_context *tdb,
                                              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);
index 7ec8b3fdea0e5296b67f5a985c2f16f1349a82f4..3da7618e2c1c3d39b5e8c4a6462de1e1bf99a5b4 100644 (file)
@@ -163,8 +163,6 @@ NTSTATUS schannel_fetch_session_key_tdb(struct tdb_context *tdb,
 NTSTATUS schannel_creds_server_step_check_tdb(struct tdb_context *tdb,
                                              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)
@@ -185,19 +183,6 @@ NTSTATUS schannel_creds_server_step_check_tdb(struct tdb_context *tdb,
        status = schannel_fetch_session_key_tdb(tdb, mem_ctx, computer_name,
                                                &creds);
 
-       /* 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 mandatory once schannel is
-        * negotiated, but this is not what windows does */
-       if (schannel_required_for_call && !schannel_in_use) {
-               DEBUG(0,("schannel_creds_server_step_check_tdb: "
-                       "client %s not using schannel for netlogon, despite negotiating it\n",
-                       creds->computer_name ));
-               tdb_transaction_cancel(tdb);
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
        if (NT_STATUS_IS_OK(status)) {
                status = netlogon_creds_server_step_check(creds,
                                                          received_authenticator,
index 71463c28ad82a21bc45994b795beccb1c6ed17ad..769936ca2000312fd43568b5fa64c41f2e57d451 100644 (file)
@@ -765,6 +765,36 @@ NTSTATUS _netr_ServerAuthenticate2(pipes_struct *p,
        return _netr_ServerAuthenticate3(p, &a);
 }
 
+/*************************************************************************
+ * If schannel is required for this call test that it actually is available.
+ *************************************************************************/
+static NTSTATUS schannel_check_required(struct pipe_auth_data *auth_info,
+                                       const char *computer_name,
+                                       bool integrity, bool privacy)
+{
+       if (auth_info && auth_info->auth_type == PIPE_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;
+}
+
 /*************************************************************************
  *************************************************************************/
 
@@ -778,9 +808,15 @@ static NTSTATUS netr_creds_server_step_check(pipes_struct *p,
        NTSTATUS status;
        struct tdb_context *tdb;
        bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
-       bool schannel_in_use = (p->auth.auth_type == PIPE_AUTH_TYPE_SCHANNEL) ? true:false; /* &&
-               (p->auth.auth_level == DCERPC_AUTH_LEVEL_INTEGRITY ||
-                p->auth.auth_level == DCERPC_AUTH_LEVEL_PRIVACY); */
+
+       if (schannel_global_required) {
+               status = schannel_check_required(&p->auth,
+                                                computer_name,
+                                                false, false);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+       }
 
        tdb = open_schannel_session_store(mem_ctx);
        if (!tdb) {
@@ -789,8 +825,6 @@ static NTSTATUS netr_creds_server_step_check(pipes_struct *p,
 
        status = schannel_creds_server_step_check_tdb(tdb, mem_ctx,
                                                      computer_name,
-                                                     schannel_global_required,
-                                                     schannel_in_use,
                                                      received_authenticator,
                                                      return_authenticator,
                                                      creds_out);