LCOV - code coverage report
Current view: top level - source3/auth - auth_ntlmssp.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 109 125 87.2 %
Date: 2024-04-21 15:09:00 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             : #include "source3/lib/substitute.h"
      29             : 
      30       20899 : NTSTATUS auth3_generate_session_info(struct auth4_context *auth_context,
      31             :                                      TALLOC_CTX *mem_ctx,
      32             :                                      void *server_returned_info,
      33             :                                      const char *original_user_name,
      34             :                                      uint32_t session_info_flags,
      35             :                                      struct auth_session_info **session_info)
      36             : {
      37       20899 :         struct auth_user_info_dc *user_info = NULL;
      38       20899 :         struct auth_serversupplied_info *server_info = NULL;
      39           0 :         NTSTATUS nt_status;
      40             : 
      41             :         /*
      42             :          * This is a hack, some callers...
      43             :          *
      44             :          * Some callers pass auth_user_info_dc, the SCHANNEL and
      45             :          * NCALRPC_AS_SYSTEM gensec modules.
      46             :          *
      47             :          * While the rest passes auth3_check_password() returned.
      48             :          */
      49       20899 :         user_info = talloc_get_type(server_returned_info,
      50             :                                     struct auth_user_info_dc);
      51       20899 :         if (user_info != NULL) {
      52           0 :                 const struct dom_sid *sid;
      53           0 :                 int cmp;
      54             : 
      55             :                 /*
      56             :                  * This should only be called from SCHANNEL or NCALRPC_AS_SYSTEM
      57             :                  */
      58         225 :                 if (user_info->num_sids != 1) {
      59           0 :                         return NT_STATUS_INTERNAL_ERROR;
      60             :                 }
      61         225 :                 sid = &user_info->sids[PRIMARY_USER_SID_INDEX].sid;
      62             : 
      63         225 :                 cmp = dom_sid_compare(sid, &global_sid_System);
      64         225 :                 if (cmp == 0) {
      65         135 :                         return make_session_info_system(mem_ctx, session_info);
      66             :                 }
      67             : 
      68          90 :                 cmp = dom_sid_compare(sid, &global_sid_Anonymous);
      69          90 :                 if (cmp == 0) {
      70          90 :                         return make_session_info_anonymous(mem_ctx, session_info);
      71             :                 }
      72             : 
      73           0 :                 return NT_STATUS_INTERNAL_ERROR;
      74             :         }
      75             : 
      76       20674 :         server_info = talloc_get_type_abort(server_returned_info,
      77             :                                             struct auth_serversupplied_info);
      78       20674 :         nt_status = create_local_token(mem_ctx,
      79             :                                        server_info,
      80             :                                        NULL,
      81             :                                        original_user_name,
      82             :                                        session_info);
      83       20674 :         if (!NT_STATUS_IS_OK(nt_status)) {
      84           0 :                 DEBUG(10, ("create_local_token failed: %s\n",
      85             :                            nt_errstr(nt_status)));
      86           0 :                 return nt_status;
      87             :         }
      88             : 
      89       20674 :         return NT_STATUS_OK;
      90             : }
      91             : 
      92             : /**
      93             :  * Return the challenge as determined by the authentication subsystem 
      94             :  * @return an 8 byte random challenge
      95             :  */
      96             : 
      97       23430 : NTSTATUS auth3_get_challenge(struct auth4_context *auth4_context,
      98             :                                            uint8_t chal[8])
      99             : {
     100       23430 :         struct auth_context *auth_context = talloc_get_type_abort(auth4_context->private_data,
     101             :                                                                   struct auth_context);
     102       23430 :         auth_get_ntlm_challenge(auth_context, chal);
     103       23430 :         return NT_STATUS_OK;
     104             : }
     105             : 
     106             : /**
     107             :  * NTLM2 authentication modifies the effective challenge, 
     108             :  * @param challenge The new challenge value
     109             :  */
     110         165 : NTSTATUS auth3_set_challenge(struct auth4_context *auth4_context, const uint8_t *chal,
     111             :                              const char *challenge_set_by)
     112             : {
     113         165 :         struct auth_context *auth_context = talloc_get_type_abort(auth4_context->private_data,
     114             :                                                                   struct auth_context);
     115           0 :         bool ok;
     116             : 
     117         165 :         ok = auth3_context_set_challenge(auth_context, chal, challenge_set_by);
     118         165 :         if (!ok) {
     119             :                 /*
     120             :                  * This can only fail for ENOMEM
     121             :                  */
     122           0 :                 return NT_STATUS_NO_MEMORY;
     123             :         }
     124             : 
     125         165 :         DEBUG(5, ("auth_context challenge set by %s\n", auth_context->challenge_set_by));
     126         165 :         DEBUG(5, ("challenge is: \n"));
     127         165 :         dump_data(5, auth_context->challenge.data, auth_context->challenge.length);
     128         165 :         return NT_STATUS_OK;
     129             : }
     130             : 
     131             : /**
     132             :  * Check the password on an NTLMSSP login.  
     133             :  *
     134             :  * Return the session keys used on the connection.
     135             :  */
     136             : 
     137             : struct auth3_check_password_state {
     138             :         uint8_t authoritative;
     139             :         void *server_info;
     140             :         DATA_BLOB nt_session_key;
     141             :         DATA_BLOB lm_session_key;
     142             : };
     143             : 
     144       23371 : struct tevent_req *auth3_check_password_send(
     145             :         TALLOC_CTX *mem_ctx,
     146             :         struct tevent_context *ev,
     147             :         struct auth4_context *auth4_context,
     148             :         const struct auth_usersupplied_info *user_info)
     149             : {
     150       23371 :         struct tevent_req *req = NULL;
     151       23371 :         struct auth3_check_password_state *state = NULL;
     152       23371 :         struct auth_context *auth_context = talloc_get_type_abort(
     153             :                 auth4_context->private_data, struct auth_context);
     154       23371 :         struct auth_usersupplied_info *mapped_user_info = NULL;
     155       23371 :         struct auth_serversupplied_info *server_info = NULL;
     156       23371 :         char *sanitized_username = NULL;
     157           0 :         NTSTATUS nt_status;
     158           0 :         bool username_was_mapped;
     159             : 
     160       23371 :         req = tevent_req_create(
     161             :                 mem_ctx, &state, struct auth3_check_password_state);
     162       23371 :         if (req == NULL) {
     163           0 :                 return NULL;
     164             :         }
     165             : 
     166             :         /*
     167             :          * Be authoritative by default.
     168             :          */
     169       23371 :         state->authoritative = 1;
     170             : 
     171             :         /* The client has given us its machine name (which we only get over NBT transport).
     172             :            We need to possibly reload smb.conf if smb.conf includes depend on the machine name. */
     173             : 
     174       23371 :         set_remote_machine_name(user_info->workstation_name, True);
     175             : 
     176       70113 :         nt_status = make_user_info_map(talloc_tos(),
     177             :                                        &mapped_user_info,
     178       23371 :                                        user_info->client.account_name,
     179       23371 :                                        user_info->client.domain_name,
     180       23371 :                                        user_info->workstation_name,
     181       23371 :                                        user_info->remote_host,
     182       23371 :                                        user_info->local_host,
     183       23371 :                                        user_info->service_description,
     184       23371 :                                        user_info->password.response.lanman.data ? &user_info->password.response.lanman : NULL,
     185       23371 :                                        user_info->password.response.nt.data ? &user_info->password.response.nt : NULL,
     186             :                                        NULL, NULL, NULL,
     187             :                                        AUTH_PASSWORD_RESPONSE);
     188             : 
     189       23371 :         if (tevent_req_nterror(req, nt_status)) {
     190           0 :                 return tevent_req_post(req, ev);
     191             :         }
     192             : 
     193       23371 :         mapped_user_info->logon_parameters = user_info->logon_parameters;
     194             : 
     195       23371 :         mapped_user_info->flags = user_info->flags;
     196             : 
     197       23371 :         sanitized_username = talloc_alpha_strcpy(
     198             :                 state,
     199       23371 :                 user_info->client.account_name,
     200             :                 SAFE_NETBIOS_CHARS "$");
     201       23371 :         if (sanitized_username == NULL) {
     202           0 :                 tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
     203           0 :                 return tevent_req_post(req, ev);
     204             :         }
     205             : 
     206       23371 :         nt_status = auth_check_ntlm_password(state,
     207             :                                              auth_context,
     208             :                                              mapped_user_info,
     209             :                                              &server_info,
     210       23371 :                                              &state->authoritative);
     211             : 
     212       23371 :         if (!NT_STATUS_IS_OK(nt_status)) {
     213        2360 :                 DBG_INFO("Checking NTLMSSP password for %s\\%s failed: "
     214             :                          "%s, authoritative=%"PRIu8"\n",
     215             :                          user_info->client.domain_name,
     216             :                          user_info->client.account_name,
     217             :                          nt_errstr(nt_status),
     218             :                          state->authoritative);
     219             :         }
     220             : 
     221       23371 :         username_was_mapped = mapped_user_info->was_mapped;
     222             : 
     223       23371 :         TALLOC_FREE(mapped_user_info);
     224             : 
     225       23371 :         if (!NT_STATUS_IS_OK(nt_status)) {
     226        2360 :                 nt_status = do_map_to_guest_server_info(
     227             :                         state,
     228             :                         nt_status,
     229        2360 :                         user_info->client.account_name,
     230        2360 :                         user_info->client.domain_name,
     231             :                         &server_info);
     232        2360 :                 if (!tevent_req_nterror(req, nt_status)) {
     233          29 :                         state->authoritative = 1;
     234             : 
     235             :                         /* setup the string used by %U */
     236          29 :                         set_current_user_info(
     237             :                                 sanitized_username,
     238          29 :                                 server_info->unix_name,
     239          29 :                                 server_info->info3->base.logon_domain.string);
     240             : 
     241          29 :                         lp_load_with_shares(get_dyn_CONFIGFILE());
     242             : 
     243          29 :                         tevent_req_done(req);
     244             :                 }
     245        2360 :                 state->server_info = server_info;
     246        2360 :                 return tevent_req_post(req, ev);
     247             :         }
     248             : 
     249       21011 :         server_info->nss_token |= username_was_mapped;
     250             : 
     251             :         /* setup the string used by %U */
     252       21011 :         set_current_user_info(sanitized_username,
     253       21011 :                               server_info->unix_name,
     254       21011 :                               server_info->info3->base.logon_domain.string);
     255             : 
     256       21011 :         lp_load_with_shares(get_dyn_CONFIGFILE());
     257             : 
     258             :         /* Clear out the session keys, and pass them to the caller.
     259             :          * They will not be used in this form again - instead the
     260             :          * NTLMSSP code will decide on the final correct session key,
     261             :          * and supply it to create_local_token() */
     262             : 
     263       21011 :         DBG_DEBUG("Got NT session key of length %zu\n",
     264             :                   server_info->session_key.length);
     265       42022 :         state->nt_session_key = (DATA_BLOB) {
     266       21011 :                 .data = talloc_move(
     267             :                         state, &server_info->session_key.data),
     268       21011 :                 .length = server_info->session_key.length,
     269             :         };
     270       21011 :         server_info->session_key = data_blob_null;
     271             : 
     272       21011 :         DBG_DEBUG("Got LM session key of length %zu\n",
     273             :                   server_info->lm_session_key.length);
     274       42022 :         state->lm_session_key = (DATA_BLOB) {
     275       21011 :                 .data = talloc_move(
     276             :                         state, &server_info->lm_session_key.data),
     277       21011 :                 .length = server_info->lm_session_key.length,
     278             :         };
     279       21011 :         server_info->lm_session_key = data_blob_null;
     280             : 
     281       21011 :         state->server_info = server_info;
     282             : 
     283       21011 :         tevent_req_done(req);
     284       21011 :         return tevent_req_post(req, ev);
     285             : }
     286             : 
     287       23371 : NTSTATUS auth3_check_password_recv(struct tevent_req *req,
     288             :                                    TALLOC_CTX *mem_ctx,
     289             :                                    uint8_t *pauthoritative,
     290             :                                    void **server_returned_info,
     291             :                                    DATA_BLOB *nt_session_key,
     292             :                                    DATA_BLOB *lm_session_key)
     293             : {
     294       23371 :         struct auth3_check_password_state *state = tevent_req_data(
     295             :                 req, struct auth3_check_password_state);
     296           0 :         NTSTATUS status;
     297             : 
     298       23371 :         if (pauthoritative != NULL) {
     299       23371 :                 *pauthoritative = state->authoritative;
     300             :         }
     301             : 
     302       23371 :         if (tevent_req_is_nterror(req, &status)) {
     303        2331 :                 return status;
     304             :         }
     305             : 
     306       21040 :         if (server_returned_info != NULL) {
     307       21040 :                 *server_returned_info = talloc_move(
     308             :                         mem_ctx, &state->server_info);
     309             :         }
     310       21040 :         if (nt_session_key != NULL) {
     311       20955 :                 *nt_session_key = (DATA_BLOB) {
     312       20955 :                         .data = talloc_move(
     313             :                                 mem_ctx, &state->nt_session_key.data),
     314       20955 :                         .length = state->nt_session_key.length,
     315             :                 };
     316             :         }
     317       21040 :         if (lm_session_key != NULL) {
     318       20955 :                 *lm_session_key = (DATA_BLOB) {
     319       20955 :                         .data = talloc_move(
     320             :                                 mem_ctx, &state->lm_session_key.data),
     321       20955 :                         .length = state->lm_session_key.length,
     322             :                 };
     323             :         }
     324             : 
     325       21040 :         return NT_STATUS_OK;
     326             : }

Generated by: LCOV version 1.14