s3:auth Change auth_ntlmssp_server_info API to return NTSTATUS
[kamenim/samba.git] / source3 / smbd / smb2_sesssetup.c
index b659f2e2ef7bde5506bdf29271b49a99e5083549..6586a454395d431a9c561ca24a2197ba3dc5dfe9 100644 (file)
@@ -23,7 +23,7 @@
 #include "smbd/globals.h"
 #include "../libcli/smb/smb_common.h"
 #include "../libcli/auth/spnego.h"
-#include "ntlmssp.h"
+#include "../libcli/auth/ntlmssp.h"
 
 static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *smb2req,
                                        uint64_t in_session_id,
@@ -170,7 +170,6 @@ static NTSTATUS smbd_smb2_session_setup_krb5(struct smbd_smb2_session *session,
        fstring tmp;
        bool username_was_mapped = false;
        bool map_domainuser_to_guest = false;
-       struct smbd_server_connection *sconn = smbd_server_conn;
 
        if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) {
                status = NT_STATUS_LOGON_FAILURE;
@@ -265,7 +264,7 @@ static NTSTATUS smbd_smb2_session_setup_krb5(struct smbd_smb2_session *session,
 
        /* lookup the passwd struct, create a new user if necessary */
 
-       username_was_mapped = map_username(sconn, user);
+       username_was_mapped = map_username(user);
 
        pw = smb_getpwnam(talloc_tos(), user, real_username, true );
        if (pw) {
@@ -445,7 +444,8 @@ static NTSTATUS smbd_smb2_session_setup_krb5(struct smbd_smb2_session *session,
                        register_homes_share(session->server_info->unix_name);
        }
 
-       if (!session_claim(session->compat_vuser)) {
+       if (!session_claim(sconn_server_id(session->sconn),
+                          session->compat_vuser)) {
                DEBUG(1, ("smb2: Failed to claim session "
                        "for vuid=%d\n",
                        session->compat_vuser->vuid));
@@ -554,15 +554,25 @@ static NTSTATUS smbd_smb2_spnego_negotiate(struct smbd_smb2_session *session,
        }
 #endif
 
-       /* Fall back to NTLMSSP. */
-       status = auth_ntlmssp_start(&session->auth_ntlmssp_state);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
+       if (kerb_mech) {
+               /* The mechtoken is a krb5 ticket, but
+                * we need to fall back to NTLM. */
 
-       status = auth_ntlmssp_update(session->auth_ntlmssp_state,
-                                    secblob_in,
-                                    &chal_out);
+               DEBUG(3,("smb2: Got krb5 ticket in SPNEGO "
+                       "but set to downgrade to NTLMSSP\n"));
+
+               status = NT_STATUS_MORE_PROCESSING_REQUIRED;
+       } else {
+               /* Fall back to NTLMSSP. */
+               status = auth_ntlmssp_start(&session->auth_ntlmssp_state);
+               if (!NT_STATUS_IS_OK(status)) {
+                       goto out;
+               }
+
+               status = auth_ntlmssp_update(session->auth_ntlmssp_state,
+                                            secblob_in,
+                                            &chal_out);
+       }
 
        if (!NT_STATUS_IS_OK(status) &&
                        !NT_STATUS_EQUAL(status,
@@ -605,11 +615,12 @@ static NTSTATUS smbd_smb2_common_ntlmssp_auth_return(struct smbd_smb2_session *s
                                        uint64_t *out_session_id)
 {
        fstring tmp;
-       session->server_info = auth_ntlmssp_server_info(session, session->auth_ntlmssp_state);
-       if (!session->server_info) {
+       NTSTATUS status = auth_ntlmssp_server_info(session, session->auth_ntlmssp_state,
+                                                  &session->server_info);
+       if (!NT_STATUS_IS_OK(status)) {
                auth_ntlmssp_end(&session->auth_ntlmssp_state);
                TALLOC_FREE(session);
-               return NT_STATUS_NO_MEMORY;
+               return status;
        }
 
        if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
@@ -653,7 +664,8 @@ static NTSTATUS smbd_smb2_common_ntlmssp_auth_return(struct smbd_smb2_session *s
                        register_homes_share(session->server_info->unix_name);
        }
 
-       if (!session_claim(session->compat_vuser)) {
+       if (!session_claim(sconn_server_id(session->sconn),
+                          session->compat_vuser)) {
                DEBUG(1, ("smb2: Failed to claim session "
                        "for vuid=%d\n",
                        session->compat_vuser->vuid));
@@ -745,12 +757,24 @@ static NTSTATUS smbd_smb2_spnego_auth(struct smbd_smb2_session *session,
                        SAFE_FREE(kerb_mech);
                        return NT_STATUS_LOGON_FAILURE;
                }
+
+               data_blob_free(&secblob_in);
+       }
+
+       if (session->auth_ntlmssp_state == NULL) {
+               status = auth_ntlmssp_start(&session->auth_ntlmssp_state);
+               if (!NT_STATUS_IS_OK(status)) {
+                       data_blob_free(&auth);
+                       TALLOC_FREE(session);
+                       return status;
+               }
        }
 
        status = auth_ntlmssp_update(session->auth_ntlmssp_state,
                                     auth,
                                     &auth_out);
-       if (!NT_STATUS_IS_OK(status)) {
+       if (!NT_STATUS_IS_OK(status) &&
+                       !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                auth_ntlmssp_end(&session->auth_ntlmssp_state);
                data_blob_free(&auth);
                TALLOC_FREE(session);
@@ -773,6 +797,11 @@ static NTSTATUS smbd_smb2_spnego_auth(struct smbd_smb2_session *session,
 
        *out_session_id = session->vuid;
 
+       if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+               return NT_STATUS_MORE_PROCESSING_REQUIRED;
+       }
+
+       /* We're done - claim the session. */
        return smbd_smb2_common_ntlmssp_auth_return(session,
                                                smb2req,
                                                in_security_mode,