Make the "map to guest" parameter work correctly with NTLMSSP (spnego
authorJeremy Allison <jra@samba.org>
Fri, 16 Jul 2010 18:05:34 +0000 (11:05 -0700)
committerJeremy Allison <jra@samba.org>
Fri, 16 Jul 2010 18:05:34 +0000 (11:05 -0700)
and raw) under SMB2. Still need to investigate fixing this with krb5
auth (does this make sense ?).

Jeremy.

source3/include/proto.h
source3/smbd/sesssetup.c
source3/smbd/smb2_sesssetup.c

index ad16e7e52f7740a2682f1c0903320319e05c88e1..6f8eebb459119a305cf5d4a63312c6c9cd4e601c 100644 (file)
@@ -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);
index 80a5239de31c486727ea032a954100f1c1eb61b0..52fcd282a66e5e08ac3dd46e8afafc453d6f83c7 100644 (file)
@@ -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)) {
index 6586a454395d431a9c561ca24a2197ba3dc5dfe9..493e74802d501710948349e9bdc235065a878a74 100644 (file)
@@ -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) {
@@ -773,6 +786,11 @@ static NTSTATUS smbd_smb2_spnego_auth(struct smbd_smb2_session *session,
        status = auth_ntlmssp_update(session->auth_ntlmssp_state,
                                     auth,
                                     &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);
@@ -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);