summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h4
-rw-r--r--source3/smbd/sesssetup.c9
-rw-r--r--source3/smbd/smb2_sesssetup.c35
3 files changed, 38 insertions, 10 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index ad16e7e52f..6f8eebb459 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6166,6 +6166,10 @@ int sessionid_traverse_read(int (*fn)(const char *key,
/* The following definitions come from smbd/sesssetup.c */
+NTSTATUS do_map_to_guest(NTSTATUS status,
+ struct auth_serversupplied_info **server_info,
+ const char *user, const char *domain);
+
NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in,
DATA_BLOB *pblob_out,
char **kerb_mechOID);
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index 80a5239de3..52fcd282a6 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -41,10 +41,13 @@ struct pending_auth_data {
on a logon error possibly map the error to success if "map to guest"
is set approriately
*/
-static NTSTATUS do_map_to_guest(NTSTATUS status,
- struct auth_serversupplied_info **server_info,
- const char *user, const char *domain)
+NTSTATUS do_map_to_guest(NTSTATUS status,
+ struct auth_serversupplied_info **server_info,
+ const char *user, const char *domain)
{
+ user = user ? user : "";
+ domain = domain ? domain : "";
+
if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
(lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index 6586a45439..493e74802d 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -143,6 +143,26 @@ static int smbd_smb2_session_destructor(struct smbd_smb2_session *session)
return 0;
}
+static NTSTATUS setup_ntlmssp_server_info(struct smbd_smb2_session *session,
+ NTSTATUS status)
+{
+ if (NT_STATUS_IS_OK(status)) {
+ status = auth_ntlmssp_server_info(session,
+ session->auth_ntlmssp_state,
+ &session->server_info);
+ } else {
+ /* Note that this server_info won't have a session
+ * key. But for map to guest, that's exactly the right
+ * thing - we can't reasonably guess the key the
+ * client wants, as the password was wrong */
+ status = do_map_to_guest(status,
+ &session->server_info,
+ auth_ntlmssp_get_username(session->auth_ntlmssp_state),
+ auth_ntlmssp_get_domain(session->auth_ntlmssp_state));
+ }
+ return status;
+}
+
#ifdef HAVE_KRB5
static NTSTATUS smbd_smb2_session_setup_krb5(struct smbd_smb2_session *session,
struct smbd_smb2_request *smb2req,
@@ -615,13 +635,6 @@ static NTSTATUS smbd_smb2_common_ntlmssp_auth_return(struct smbd_smb2_session *s
uint64_t *out_session_id)
{
fstring tmp;
- 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 status;
- }
if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
lp_server_signing() == Required) {
@@ -775,6 +788,11 @@ static NTSTATUS smbd_smb2_spnego_auth(struct smbd_smb2_session *session,
&auth_out);
if (!NT_STATUS_IS_OK(status) &&
!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ status = setup_ntlmssp_server_info(session, 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);
@@ -850,6 +868,9 @@ static NTSTATUS smbd_smb2_raw_ntlmssp_auth(struct smbd_smb2_session *session,
*out_session_id = session->vuid;
return status;
}
+
+ status = setup_ntlmssp_server_info(session, status);
+
if (!NT_STATUS_IS_OK(status)) {
auth_ntlmssp_end(&session->auth_ntlmssp_state);
TALLOC_FREE(session);