s3:rpc_server: add support for AES bases netlogon schannel
[metze/samba/wip.git] / source3 / rpc_server / srv_netlog_nt.c
index 07a0b971a08d4085230c57c357f4fc8a2a020553..c84f3121a402182c84a573e11a22e94b44352231 100644 (file)
@@ -27,6 +27,7 @@
 #include "includes.h"
 #include "../libcli/auth/libcli_auth.h"
 #include "../libcli/auth/schannel_state.h"
+#include "../libcli/auth/schannel.h"
 
 extern userdom_struct current_user_info;
 
@@ -459,6 +460,10 @@ NTSTATUS _netr_ServerAuthenticate3(pipes_struct *p,
                srv_flgs |= NETLOGON_NEG_STRONG_KEYS;
        }
 
+       if (in_neg_flags & NETLOGON_NEG_SUPPORTS_AES) {
+               srv_flgs |= NETLOGON_NEG_SUPPORTS_AES;
+       }
+
        if (lp_server_schannel() != false) {
                srv_flgs |= NETLOGON_NEG_SCHANNEL;
        }
@@ -522,7 +527,7 @@ NTSTATUS _netr_ServerAuthenticate3(pipes_struct *p,
                                           &mach_pwd,
                                           r->in.credentials,
                                           r->out.return_credentials,
-                                          *r->in.negotiate_flags);
+                                          srv_flgs);
        if (!creds) {
                DEBUG(0,("%s: netlogon_creds_server_check failed. Rejecting auth "
                        "request from client %s machine account %s\n",
@@ -595,8 +600,8 @@ static NTSTATUS netr_creds_server_step_check(pipes_struct *p,
        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 == PIPE_AUTH_LEVEL_INTEGRITY ||
-                p->auth.auth_level == PIPE_AUTH_LEVEL_PRIVACY); */
+               (p->auth.auth_level == DCERPC_AUTH_LEVEL_INTEGRITY ||
+                p->auth.auth_level == DCERPC_AUTH_LEVEL_PRIVACY); */
 
        tdb = open_schannel_session_store(mem_ctx);
        if (!tdb) {
@@ -909,6 +914,12 @@ static NTSTATUS _netr_LogonSamLogon_base(pipes_struct *p,
                        return NT_STATUS_NO_MEMORY;
                }
                break;
+       case 6:
+               r->out.validation->sam6 = TALLOC_ZERO_P(p->mem_ctx, struct netr_SamInfo6);
+               if (!r->out.validation->sam6) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+               break;
        default:
                DEBUG(0,("%s: bad validation_level value %d.\n",
                        fn, (int)r->in.validation_level));
@@ -917,6 +928,9 @@ static NTSTATUS _netr_LogonSamLogon_base(pipes_struct *p,
 
        switch (r->in.logon_level) {
        case NetlogonInteractiveInformation:
+       case NetlogonServiceInformation:
+       case NetlogonInteractiveTransitiveInformation:
+       case NetlogonServiceTransitiveInformation:
                nt_username     = logon->password->identity_info.account_name.string;
                nt_domain       = logon->password->identity_info.domain_name.string;
                nt_workstation  = logon->password->identity_info.workstation.string;
@@ -924,6 +938,7 @@ static NTSTATUS _netr_LogonSamLogon_base(pipes_struct *p,
                DEBUG(3,("SAM Logon (Interactive). Domain:[%s].  ", lp_workgroup()));
                break;
        case NetlogonNetworkInformation:
+       case NetlogonNetworkTransitiveInformation:
                nt_username     = logon->network->identity_info.account_name.string;
                nt_domain       = logon->network->identity_info.domain_name.string;
                nt_workstation  = logon->network->identity_info.workstation.string;
@@ -946,6 +961,7 @@ static NTSTATUS _netr_LogonSamLogon_base(pipes_struct *p,
 
        switch (r->in.logon_level) {
        case NetlogonNetworkInformation:
+       case NetlogonNetworkTransitiveInformation:
        {
                const char *wksname = nt_workstation;
 
@@ -975,6 +991,10 @@ static NTSTATUS _netr_LogonSamLogon_base(pipes_struct *p,
                break;
        }
        case NetlogonInteractiveInformation:
+       case NetlogonServiceInformation:
+       case NetlogonInteractiveTransitiveInformation:
+       case NetlogonServiceTransitiveInformation:
+
                /* 'Interactive' authentication, supplies the password in its
                   MD4 form, encrypted with the session key.  We will convert
                   this to challenge/response for the auth subsystem to chew
@@ -1053,7 +1073,7 @@ static NTSTATUS _netr_LogonSamLogon_base(pipes_struct *p,
                    || (p->auth.a_u.schannel_auth == NULL)) {
                        return NT_STATUS_INVALID_HANDLE;
                }
-               memcpy(pipe_session_key, p->auth.a_u.schannel_auth->sess_key, 16);
+               memcpy(pipe_session_key, p->auth.a_u.schannel_auth->creds->session_key, 16);
        }
 
        switch (r->in.validation_level) {
@@ -1065,6 +1085,10 @@ static NTSTATUS _netr_LogonSamLogon_base(pipes_struct *p,
                status = serverinfo_to_SamInfo3(server_info, pipe_session_key, 16,
                                                r->out.validation->sam3);
                break;
+       case 6:
+               status = serverinfo_to_SamInfo6(server_info, pipe_session_key, 16,
+                                               r->out.validation->sam6);
+               break;
        }
 
        TALLOC_FREE(server_info);
@@ -1308,7 +1332,27 @@ WERROR _netr_DsRGetDCName(pipes_struct *p,
 NTSTATUS _netr_LogonGetCapabilities(pipes_struct *p,
                                    struct netr_LogonGetCapabilities *r)
 {
-       return NT_STATUS_NOT_IMPLEMENTED;
+       struct netlogon_creds_CredentialState *creds;
+       NTSTATUS status;
+
+       become_root();
+       status = netr_creds_server_step_check(p, p->mem_ctx,
+                                             r->in.computer_name,
+                                             r->in.credential,
+                                             r->out.return_authenticator,
+                                             &creds);
+       unbecome_root();
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       if (r->in.query_level != 1) {
+               return NT_STATUS_NOT_SUPPORTED;
+       }
+
+       r->out.capabilities->server_capabilities = creds->negotiate_flags;
+
+       return NT_STATUS_OK;
 }
 
 /****************************************************************