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 : }