static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, DATA_BLOB blob1) { DATA_BLOB auth, auth_reply; NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER; if (!spnego_parse_auth(blob1, &auth)) { #if 0 file_save("auth.dat", blob1.data, blob1.length); #endif return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } if (!global_ntlmssp_state) { /* auth before negotiatiate? */ return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } nt_status = auth_ntlmssp_update(global_ntlmssp_state, auth, &auth_reply); data_blob_free(&auth); reply_spnego_ntlmssp(conn, inbuf, outbuf, &global_ntlmssp_state, &auth_reply, nt_status); data_blob_free(&auth_reply); /* and tell smbd that we have already replied to this packet */ return -1; }
static NTSTATUS smbd_smb2_spnego_auth(struct smbd_smb2_session *session, struct smbd_smb2_request *smb2req, uint8_t in_security_mode, DATA_BLOB in_security_buffer, uint16_t *out_session_flags, DATA_BLOB *out_security_buffer, uint64_t *out_session_id) { DATA_BLOB auth = data_blob_null; DATA_BLOB auth_out = data_blob_null; NTSTATUS status; if (!spnego_parse_auth(talloc_tos(), in_security_buffer, &auth)) { TALLOC_FREE(session); return NT_STATUS_LOGON_FAILURE; } if (auth.data[0] == ASN1_APPLICATION(0)) { /* Might be a second negTokenTarg packet */ DATA_BLOB secblob_in = data_blob_null; char *kerb_mech = NULL; status = parse_spnego_mechanisms(talloc_tos(), in_security_buffer, &secblob_in, &kerb_mech); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(session); return status; } #ifdef HAVE_KRB5 if (kerb_mech && ((lp_security()==SEC_ADS) || USE_KERBEROS_KEYTAB) ) { status = smbd_smb2_session_setup_krb5(session, smb2req, in_security_mode, &secblob_in, kerb_mech, out_session_flags, out_security_buffer, out_session_id); data_blob_free(&secblob_in); TALLOC_FREE(kerb_mech); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(session); } return status; } #endif /* Can't blunder into NTLMSSP auth if we have * a krb5 ticket. */ if (kerb_mech) { DEBUG(3,("smb2: network " "misconfiguration, client sent us a " "krb5 ticket and kerberos security " "not enabled\n")); TALLOC_FREE(session); data_blob_free(&secblob_in); TALLOC_FREE(kerb_mech); return NT_STATUS_LOGON_FAILURE; } data_blob_free(&secblob_in); } if (session->auth_ntlmssp_state == NULL) { status = auth_ntlmssp_prepare(session->sconn->remote_address, &session->auth_ntlmssp_state); if (!NT_STATUS_IS_OK(status)) { data_blob_free(&auth); TALLOC_FREE(session); return status; } auth_ntlmssp_want_feature(session->auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY); 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, talloc_tos(), auth, &auth_out); /* If status is NT_STATUS_OK then we need to get the token. * Map to guest is now internal to auth_ntlmssp */ if (NT_STATUS_IS_OK(status)) { status = auth_ntlmssp_session_info(session, session->auth_ntlmssp_state, &session->session_info); } if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { TALLOC_FREE(session->auth_ntlmssp_state); data_blob_free(&auth); TALLOC_FREE(session); return status; } data_blob_free(&auth); *out_security_buffer = spnego_gen_auth_response(smb2req, &auth_out, status, NULL); if (out_security_buffer->data == NULL) { TALLOC_FREE(session->auth_ntlmssp_state); TALLOC_FREE(session); return NT_STATUS_NO_MEMORY; } *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, in_security_buffer, out_session_flags, out_session_id); }
static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, uint16 vuid, int length, int bufsize, DATA_BLOB blob1, AUTH_NTLMSSP_STATE **auth_ntlmssp_state) { DATA_BLOB auth = data_blob(NULL,0); DATA_BLOB auth_reply = data_blob(NULL,0); DATA_BLOB secblob = data_blob(NULL,0); NTSTATUS status = NT_STATUS_INVALID_PARAMETER; if (!spnego_parse_auth(blob1, &auth)) { #if 0 file_save("auth.dat", blob1.data, blob1.length); #endif /* Kill the intermediate vuid */ invalidate_vuid(vuid); return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } if (auth.data[0] == ASN1_APPLICATION(0)) { /* Might be a second negTokenTarg packet */ BOOL got_krb5_mechanism = False; status = parse_spnego_mechanisms(auth, &secblob, &got_krb5_mechanism); if (NT_STATUS_IS_OK(status)) { DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n", (unsigned long)secblob.length)); #ifdef HAVE_KRB5 if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) { BOOL destroy_vuid = True; int ret = reply_spnego_kerberos(conn, inbuf, outbuf, length, bufsize, &secblob, &destroy_vuid); data_blob_free(&secblob); data_blob_free(&auth); if (destroy_vuid) { /* Kill the intermediate vuid */ invalidate_vuid(vuid); } return ret; } #endif } } /* If we get here it wasn't a negTokenTarg auth packet. */ data_blob_free(&secblob); if (!*auth_ntlmssp_state) { /* Kill the intermediate vuid */ invalidate_vuid(vuid); /* auth before negotiatiate? */ return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } status = auth_ntlmssp_update(*auth_ntlmssp_state, auth, &auth_reply); data_blob_free(&auth); reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, auth_ntlmssp_state, &auth_reply, status, True); data_blob_free(&auth_reply); /* and tell smbd that we have already replied to this packet */ return -1; }