LCOV - code coverage report
Current view: top level - source3/auth - auth_ntlmssp.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 108 118 91.5 %
Date: 2021-09-23 10:06:22 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/Netbios implementation.
       3             :    Version 3.0
       4             :    handle NLTMSSP, server side
       5             : 
       6             :    Copyright (C) Andrew Tridgell      2001
       7             :    Copyright (C) Andrew Bartlett 2001-2005,2011
       8             :    Copyright (C) Stefan Metzmacher 2005
       9             : 
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             :    
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             :    
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "includes.h"
      25             : #include "auth.h"
      26             : #include "libcli/security/security.h"
      27             : #include "lib/util/tevent_ntstatus.h"
      28             : 
      29       17604 : NTSTATUS auth3_generate_session_info(struct auth4_context *auth_context,
      30             :                                      TALLOC_CTX *mem_ctx,
      31             :                                      void *server_returned_info,
      32             :                                      const char *original_user_name,
      33             :                                      uint32_t session_info_flags,
      34             :                                      struct auth_session_info **session_info)
      35             : {
      36       17604 :         struct auth_user_info_dc *user_info = NULL;
      37       17604 :         struct auth_serversupplied_info *server_info = NULL;
      38             :         NTSTATUS nt_status;
      39             : 
      40             :         /*
      41             :          * This is a hack, some callers...
      42             :          *
      43             :          * Some callers pass auth_user_info_dc, the SCHANNEL and
      44             :          * NCALRPC_AS_SYSTEM gensec modules.
      45             :          *
      46             :          * While the rest passes auth3_check_password() returned.
      47             :          */
      48       17604 :         user_info = talloc_get_type(server_returned_info,
      49             :                                     struct auth_user_info_dc);
      50       17604 :         if (user_info != NULL) {
      51             :                 const struct dom_sid *sid;
      52             :                 int cmp;
      53             : 
      54             :                 /*
      55             :                  * This should only be called from SCHANNEL or NCALRPC_AS_SYSTEM
      56             :                  */
      57          80 :                 if (user_info->num_sids != 1) {
      58           0 :                         return NT_STATUS_INTERNAL_ERROR;
      59             :                 }
      60          80 :                 sid = &user_info->sids[PRIMARY_USER_SID_INDEX];
      61             : 
      62          80 :                 cmp = dom_sid_compare(sid, &global_sid_System);
      63          80 :                 if (cmp == 0) {
      64           0 :                         return make_session_info_system(mem_ctx, session_info);
      65             :                 }
      66             : 
      67          80 :                 cmp = dom_sid_compare(sid, &global_sid_Anonymous);
      68          80 :                 if (cmp == 0) {
      69          80 :                         return make_session_info_anonymous(mem_ctx, session_info);
      70             :                 }
      71             : 
      72           0 :                 return NT_STATUS_INTERNAL_ERROR;
      73             :         }
      74             : 
      75       17524 :         server_info = talloc_get_type_abort(server_returned_info,
      76             :                                             struct auth_serversupplied_info);
      77       17524 :         nt_status = create_local_token(mem_ctx,
      78             :                                        server_info,
      79             :                                        NULL,
      80             :                                        original_user_name,
      81             :                                        session_info);
      82       17524 :         if (!NT_STATUS_IS_OK(nt_status)) {
      83           0 :                 DEBUG(10, ("create_local_token failed: %s\n",
      84             :                            nt_errstr(nt_status)));
      85           0 :                 return nt_status;
      86             :         }
      87             : 
      88       17524 :         return NT_STATUS_OK;
      89             : }
      90             : 
      91             : /**
      92             :  * Return the challenge as determined by the authentication subsystem 
      93             :  * @return an 8 byte random challenge
      94             :  */
      95             : 
      96       19723 : NTSTATUS auth3_get_challenge(struct auth4_context *auth4_context,
      97             :                                            uint8_t chal[8])
      98             : {
      99       19723 :         struct auth_context *auth_context = talloc_get_type_abort(auth4_context->private_data,
     100             :                                                                   struct auth_context);
     101       19723 :         auth_get_ntlm_challenge(auth_context, chal);
     102       19723 :         return NT_STATUS_OK;
     103             : }
     104             : 
     105             : /**
     106             :  * NTLM2 authentication modifies the effective challenge, 
     107             :  * @param challenge The new challenge value
     108             :  */
     109         165 : NTSTATUS auth3_set_challenge(struct auth4_context *auth4_context, const uint8_t *chal,
     110             :                              const char *challenge_set_by)
     111             : {
     112         165 :         struct auth_context *auth_context = talloc_get_type_abort(auth4_context->private_data,
     113             :                                                                   struct auth_context);
     114             :         bool ok;
     115             : 
     116         165 :         ok = auth3_context_set_challenge(auth_context, chal, challenge_set_by);
     117         165 :         if (!ok) {
     118             :                 /*
     119             :                  * This can only fail for ENOMEM
     120             :                  */
     121           0 :                 return NT_STATUS_NO_MEMORY;
     122             :         }
     123             : 
     124         165 :         DEBUG(5, ("auth_context challenge set by %s\n", auth_context->challenge_set_by));
     125         165 :         DEBUG(5, ("challenge is: \n"));
     126         165 :         dump_data(5, auth_context->challenge.data, auth_context->challenge.length);
     127         165 :         return NT_STATUS_OK;
     128             : }
     129             : 
     130             : /**
     131             :  * Check the password on an NTLMSSP login.  
     132             :  *
     133             :  * Return the session keys used on the connection.
     134             :  */
     135             : 
     136             : struct auth3_check_password_state {
     137             :         uint8_t authoritative;
     138             :         void *server_info;
     139             :         DATA_BLOB nt_session_key;
     140             :         DATA_BLOB lm_session_key;
     141             : };
     142             : 
     143       19693 : struct tevent_req *auth3_check_password_send(
     144             :         TALLOC_CTX *mem_ctx,
     145             :         struct tevent_context *ev,
     146             :         struct auth4_context *auth4_context,
     147             :         const struct auth_usersupplied_info *user_info)
     148             : {
     149       19693 :         struct tevent_req *req = NULL;
     150       19693 :         struct auth3_check_password_state *state = NULL;
     151       19693 :         struct auth_context *auth_context = talloc_get_type_abort(
     152             :                 auth4_context->private_data, struct auth_context);
     153       19693 :         struct auth_usersupplied_info *mapped_user_info = NULL;
     154       19693 :         struct auth_serversupplied_info *server_info = NULL;
     155       19693 :         char *sanitized_username = NULL;
     156             :         NTSTATUS nt_status;
     157             :         bool username_was_mapped;
     158             : 
     159       19693 :         req = tevent_req_create(
     160             :                 mem_ctx, &state, struct auth3_check_password_state);
     161       19693 :         if (req == NULL) {
     162           0 :                 return NULL;
     163             :         }
     164             : 
     165             :         /*
     166             :          * Be authoritative by default.
     167             :          */
     168       19693 :         state->authoritative = 1;
     169             : 
     170             :         /* The client has given us its machine name (which we only get over NBT transport).
     171             :            We need to possibly reload smb.conf if smb.conf includes depend on the machine name. */
     172             : 
     173       19693 :         set_remote_machine_name(user_info->workstation_name, True);
     174             : 
     175       39697 :         nt_status = make_user_info_map(talloc_tos(),
     176             :                                        &mapped_user_info,
     177         311 :                                        user_info->client.account_name,
     178         311 :                                        user_info->client.domain_name,
     179         311 :                                        user_info->workstation_name,
     180         311 :                                        user_info->remote_host,
     181         311 :                                        user_info->local_host,
     182         311 :                                        user_info->service_description,
     183       19693 :                                        user_info->password.response.lanman.data ? &user_info->password.response.lanman : NULL,
     184       19693 :                                        user_info->password.response.nt.data ? &user_info->password.response.nt : NULL,
     185             :                                        NULL, NULL, NULL,
     186             :                                        AUTH_PASSWORD_RESPONSE);
     187             : 
     188       19693 :         if (tevent_req_nterror(req, nt_status)) {
     189           0 :                 return tevent_req_post(req, ev);
     190             :         }
     191             : 
     192       19693 :         mapped_user_info->logon_parameters = user_info->logon_parameters;
     193             : 
     194       19693 :         mapped_user_info->flags = user_info->flags;
     195             : 
     196       19693 :         sanitized_username = talloc_alpha_strcpy(
     197             :                 state,
     198         311 :                 user_info->client.account_name,
     199             :                 SAFE_NETBIOS_CHARS "$");
     200       19693 :         if (sanitized_username == NULL) {
     201           0 :                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
     202           0 :                 return tevent_req_post(req, ev);
     203             :         }
     204             : 
     205       19693 :         nt_status = auth_check_ntlm_password(state,
     206             :                                              auth_context,
     207             :                                              mapped_user_info,
     208             :                                              &server_info,
     209       19693 :                                              &state->authoritative);
     210             : 
     211       19693 :         if (!NT_STATUS_IS_OK(nt_status)) {
     212        1859 :                 DBG_INFO("Checking NTLMSSP password for %s\\%s failed: "
     213             :                          "%s, authoritative=%"PRIu8"\n",
     214             :                          user_info->client.domain_name,
     215             :                          user_info->client.account_name,
     216             :                          nt_errstr(nt_status),
     217             :                          state->authoritative);
     218             :         }
     219             : 
     220       19693 :         username_was_mapped = mapped_user_info->was_mapped;
     221             : 
     222       19693 :         TALLOC_FREE(mapped_user_info);
     223             : 
     224       19693 :         if (!NT_STATUS_IS_OK(nt_status)) {
     225        1859 :                 nt_status = do_map_to_guest_server_info(
     226             :                         state,
     227             :                         nt_status,
     228          61 :                         user_info->client.account_name,
     229          61 :                         user_info->client.domain_name,
     230             :                         &server_info);
     231        1859 :                 if (!tevent_req_nterror(req, nt_status)) {
     232          21 :                         state->authoritative = 1;
     233             : 
     234             :                         /* setup the string used by %U */
     235          37 :                         set_current_user_info(
     236             :                                 sanitized_username,
     237          21 :                                 server_info->unix_name,
     238          21 :                                 server_info->info3->base.logon_domain.string);
     239             : 
     240          21 :                         lp_load_with_shares(get_dyn_CONFIGFILE());
     241             : 
     242          21 :                         tevent_req_done(req);
     243             :                 }
     244        1859 :                 state->server_info = server_info;
     245        1859 :                 return tevent_req_post(req, ev);
     246             :         }
     247             : 
     248       17834 :         server_info->nss_token |= username_was_mapped;
     249             : 
     250             :         /* setup the string used by %U */
     251       35418 :         set_current_user_info(sanitized_username,
     252       17834 :                               server_info->unix_name,
     253       17834 :                               server_info->info3->base.logon_domain.string);
     254             : 
     255       17834 :         lp_load_with_shares(get_dyn_CONFIGFILE());
     256             : 
     257             :         /* Clear out the session keys, and pass them to the caller.
     258             :          * They will not be used in this form again - instead the
     259             :          * NTLMSSP code will decide on the final correct session key,
     260             :          * and supply it to create_local_token() */
     261             : 
     262       17834 :         DBG_DEBUG("Got NT session key of length %zu\n",
     263             :                   server_info->session_key.length);
     264       35668 :         state->nt_session_key = (DATA_BLOB) {
     265       17834 :                 .data = talloc_move(
     266             :                         state, &server_info->session_key.data),
     267       17834 :                 .length = server_info->session_key.length,
     268             :         };
     269       17834 :         server_info->session_key = data_blob_null;
     270             : 
     271       17834 :         DBG_DEBUG("Got LM session key of length %zu\n",
     272             :                   server_info->lm_session_key.length);
     273       35668 :         state->lm_session_key = (DATA_BLOB) {
     274       17834 :                 .data = talloc_move(
     275             :                         state, &server_info->lm_session_key.data),
     276       17834 :                 .length = server_info->lm_session_key.length,
     277             :         };
     278       17834 :         server_info->lm_session_key = data_blob_null;
     279             : 
     280       17834 :         state->server_info = server_info;
     281             : 
     282       17834 :         tevent_req_done(req);
     283       17834 :         return tevent_req_post(req, ev);
     284             : }
     285             : 
     286       19693 : NTSTATUS auth3_check_password_recv(struct tevent_req *req,
     287             :                                    TALLOC_CTX *mem_ctx,
     288             :                                    uint8_t *pauthoritative,
     289             :                                    void **server_returned_info,
     290             :                                    DATA_BLOB *nt_session_key,
     291             :                                    DATA_BLOB *lm_session_key)
     292             : {
     293       19693 :         struct auth3_check_password_state *state = tevent_req_data(
     294             :                 req, struct auth3_check_password_state);
     295             :         NTSTATUS status;
     296             : 
     297       19693 :         if (pauthoritative != NULL) {
     298       19693 :                 *pauthoritative = state->authoritative;
     299             :         }
     300             : 
     301       19693 :         if (tevent_req_is_nterror(req, &status)) {
     302        1838 :                 return status;
     303             :         }
     304             : 
     305       17855 :         if (server_returned_info != NULL) {
     306       17855 :                 *server_returned_info = talloc_move(
     307             :                         mem_ctx, &state->server_info);
     308             :         }
     309       17855 :         if (nt_session_key != NULL) {
     310       17777 :                 *nt_session_key = (DATA_BLOB) {
     311       17777 :                         .data = talloc_move(
     312             :                                 mem_ctx, &state->nt_session_key.data),
     313       17777 :                         .length = state->nt_session_key.length,
     314             :                 };
     315             :         }
     316       17855 :         if (lm_session_key != NULL) {
     317       17777 :                 *lm_session_key = (DATA_BLOB) {
     318       17777 :                         .data = talloc_move(
     319             :                                 mem_ctx, &state->lm_session_key.data),
     320       17777 :                         .length = state->lm_session_key.length,
     321             :                 };
     322             :         }
     323             : 
     324       17855 :         return NT_STATUS_OK;
     325             : }

Generated by: LCOV version 1.13