LCOV - code coverage report
Current view: top level - auth/ntlmssp - ntlmssp_util.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 67 80 83.8 %
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-2003
       8             :    Copyright (C) Andrew Bartlett 2005 (Updated from gensec).
       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/ntlmssp/ntlmssp.h"
      26             : #include "../auth/ntlmssp/ntlmssp_private.h"
      27             : 
      28             : #undef DBGC_CLASS
      29             : #define DBGC_CLASS DBGC_AUTH
      30             : 
      31      249439 : static void debug_ntlmssp_flags_raw(int level, uint32_t flags)
      32             : {
      33             : #define _PRINT_FLAG_LINE(v) do { \
      34             :         if (flags & (v)) { \
      35             :                 DEBUGADD(level, ("  " #v "\n")); \
      36             :         } \
      37             : } while (0)
      38      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_UNICODE);
      39      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_OEM);
      40      249439 :         _PRINT_FLAG_LINE(NTLMSSP_REQUEST_TARGET);
      41      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_SIGN);
      42      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_SEAL);
      43      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_DATAGRAM);
      44      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_LM_KEY);
      45      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_NETWARE);
      46      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_NTLM);
      47      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_NT_ONLY);
      48      249439 :         _PRINT_FLAG_LINE(NTLMSSP_ANONYMOUS);
      49      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED);
      50      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED);
      51      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL);
      52      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_ALWAYS_SIGN);
      53      249439 :         _PRINT_FLAG_LINE(NTLMSSP_TARGET_TYPE_DOMAIN);
      54      249439 :         _PRINT_FLAG_LINE(NTLMSSP_TARGET_TYPE_SERVER);
      55      249439 :         _PRINT_FLAG_LINE(NTLMSSP_TARGET_TYPE_SHARE);
      56      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY);
      57      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_IDENTIFY);
      58      249439 :         _PRINT_FLAG_LINE(NTLMSSP_REQUEST_NON_NT_SESSION_KEY);
      59      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_TARGET_INFO);
      60      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_VERSION);
      61      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_128);
      62      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_KEY_EXCH);
      63      249439 :         _PRINT_FLAG_LINE(NTLMSSP_NEGOTIATE_56);
      64      249439 : }
      65             : 
      66             : /**
      67             :  * Print out the NTLMSSP flags for debugging
      68             :  * @param neg_flags The flags from the packet
      69             :  */
      70      249439 : void debug_ntlmssp_flags(uint32_t neg_flags)
      71             : {
      72      249439 :         DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));
      73      249439 :         debug_ntlmssp_flags_raw(4, neg_flags);
      74      249439 : }
      75             : 
      76      112529 : NTSTATUS ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
      77             :                                   uint32_t flags, const char *name)
      78             : {
      79      112529 :         uint32_t missing_flags = ntlmssp_state->required_flags;
      80             : 
      81      112529 :         if (ntlmssp_state->use_ntlmv2) {
      82             :                 /*
      83             :                  * Using NTLMv2 as a client implies
      84             :                  * using NTLMSSP_NEGOTIATE_NTLM2
      85             :                  * (NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY)
      86             :                  *
      87             :                  * Note that 'use_ntlmv2' is only set
      88             :                  * true in the client case.
      89             :                  *
      90             :                  * Even if the server has a bug and does not announce
      91             :                  * it, we need to assume it's present.
      92             :                  *
      93             :                  * Note that we also have the flag
      94             :                  * in ntlmssp_state->required_flags,
      95             :                  * see gensec_ntlmssp_client_start().
      96             :                  *
      97             :                  * See bug #12862.
      98             :                  */
      99       36869 :                 flags |= NTLMSSP_NEGOTIATE_NTLM2;
     100             :         }
     101             : 
     102      112529 :         if (flags & NTLMSSP_NEGOTIATE_UNICODE) {
     103      112529 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
     104      112529 :                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
     105      112529 :                 ntlmssp_state->unicode = true;
     106             :         } else {
     107           0 :                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
     108           0 :                 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
     109           0 :                 ntlmssp_state->unicode = false;
     110             :         }
     111             : 
     112             :         /*
     113             :          * NTLMSSP_NEGOTIATE_NTLM2 (NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY)
     114             :          * has priority over NTLMSSP_NEGOTIATE_LM_KEY
     115             :          */
     116      112529 :         if (!(flags & NTLMSSP_NEGOTIATE_NTLM2)) {
     117        2731 :                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
     118             :         }
     119             : 
     120      112529 :         if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
     121      109798 :                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
     122             :         }
     123             : 
     124      112529 :         if (!(flags & NTLMSSP_NEGOTIATE_LM_KEY)) {
     125      112025 :                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
     126             :         }
     127             : 
     128      112529 :         if (!(flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) {
     129           0 :                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
     130             :         }
     131             : 
     132      112529 :         if (!(flags & NTLMSSP_NEGOTIATE_128)) {
     133        1280 :                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
     134             :         }
     135             : 
     136      112529 :         if (!(flags & NTLMSSP_NEGOTIATE_56)) {
     137      111761 :                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
     138             :         }
     139             : 
     140      112529 :         if (!(flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
     141           0 :                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
     142             :         }
     143             : 
     144      112529 :         if (!(flags & NTLMSSP_NEGOTIATE_SIGN)) {
     145         883 :                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
     146             :         }
     147             : 
     148      112529 :         if (!(flags & NTLMSSP_NEGOTIATE_SEAL)) {
     149       80682 :                 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
     150             :         }
     151             : 
     152      112529 :         if ((flags & NTLMSSP_REQUEST_TARGET)) {
     153      112529 :                 ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
     154             :         }
     155             : 
     156      112529 :         missing_flags &= ~ntlmssp_state->neg_flags;
     157      112529 :         if (missing_flags != 0) {
     158           0 :                 HRESULT hres = HRES_SEC_E_UNSUPPORTED_FUNCTION;
     159           0 :                 NTSTATUS status = NT_STATUS(HRES_ERROR_V(hres));
     160           0 :                 DEBUG(1, ("%s: Got %s flags[0x%08x] "
     161             :                           "- possible downgrade detected! "
     162             :                           "missing_flags[0x%08x] - %s\n",
     163             :                           __func__, name,
     164             :                           (unsigned)flags,
     165             :                           (unsigned)missing_flags,
     166             :                           nt_errstr(status)));
     167           0 :                 debug_ntlmssp_flags_raw(1, missing_flags);
     168           0 :                 DEBUGADD(4, ("neg_flags[0x%08x]\n",
     169             :                              (unsigned)ntlmssp_state->neg_flags));
     170           0 :                 debug_ntlmssp_flags_raw(4, ntlmssp_state->neg_flags);
     171           0 :                 return status;
     172             :         }
     173             : 
     174      112529 :         return NT_STATUS_OK;
     175             : }
     176             : 
     177             : /* Does this blob looks like it could be NTLMSSP? */
     178         102 : bool ntlmssp_blob_matches_magic(const DATA_BLOB *blob)
     179             : {
     180         102 :         if (blob->length > 8 && memcmp("NTLMSSP\0", blob->data, 8) == 0) {
     181         102 :                 return true;
     182             :         } else {
     183           0 :                 return false;
     184             :         }
     185             : }
     186             : 
     187      113869 : const DATA_BLOB ntlmssp_version_blob(void)
     188             : {
     189             :         /*
     190             :          * This is a simplified version of
     191             :          *
     192             :          * enum ndr_err_code err;
     193             :          * struct ntlmssp_VERSION vers;
     194             :          *
     195             :          * ZERO_STRUCT(vers);
     196             :          * vers.ProductMajorVersion = NTLMSSP_WINDOWS_MAJOR_VERSION_6;
     197             :          * vers.ProductMinorVersion = NTLMSSP_WINDOWS_MINOR_VERSION_1;
     198             :          * vers.ProductBuild = 0;
     199             :          * vers.NTLMRevisionCurrent = NTLMSSP_REVISION_W2K3;
     200             :          *
     201             :          * err = ndr_push_struct_blob(&version_blob,
     202             :          *                      ntlmssp_state,
     203             :          *                      &vers,
     204             :          *                      (ndr_push_flags_fn_t)ndr_push_ntlmssp_VERSION);
     205             :          *
     206             :          * if (!NDR_ERR_CODE_IS_SUCCESS(err)) {
     207             :          *      data_blob_free(&struct_blob);
     208             :          *      return NT_STATUS_NO_MEMORY;
     209             :          * }
     210             :          */
     211         592 :         static const uint8_t version_buffer[8] = {
     212             :                 NTLMSSP_WINDOWS_MAJOR_VERSION_6,
     213             :                 NTLMSSP_WINDOWS_MINOR_VERSION_1,
     214             :                 0x00, 0x00, /* product build */
     215             :                 0x00, 0x00, 0x00, /* reserved */
     216             :                 NTLMSSP_REVISION_W2K3
     217             :         };
     218             : 
     219      113869 :         return data_blob_const(version_buffer, ARRAY_SIZE(version_buffer));
     220             : }

Generated by: LCOV version 1.14