#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,
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;
/* 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) {
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));
}
#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,
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) ||
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));
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);
*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,