Changeset 740 for vendor/current/source4/auth/ntlmssp/ntlmssp.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified vendor/current/source4/auth/ntlmssp/ntlmssp.c ¶
r414 r740 24 24 #include "includes.h" 25 25 #include "auth/ntlmssp/ntlmssp.h" 26 #include "../librpc/gen_ndr/ntlmssp.h"27 26 #include "../libcli/auth/libcli_auth.h" 28 27 #include "librpc/gen_ndr/ndr_dcerpc.h" 29 #include "auth/credentials/credentials.h"30 28 #include "auth/gensec/gensec.h" 31 29 #include "auth/gensec/gensec_proto.h" 32 #include "param/param.h"33 30 34 31 /** … … 51 48 .role = NTLMSSP_SERVER, 52 49 .command = NTLMSSP_NEGOTIATE, 53 .sync_fn = ntlmssp_server_negotiate,50 .sync_fn = gensec_ntlmssp_server_negotiate, 54 51 },{ 55 52 .role = NTLMSSP_CLIENT, … … 59 56 .role = NTLMSSP_SERVER, 60 57 .command = NTLMSSP_AUTH, 61 .sync_fn = ntlmssp_server_auth,58 .sync_fn = gensec_ntlmssp_server_auth, 62 59 } 63 60 }; 64 61 65 66 /**67 * Print out the NTLMSSP flags for debugging68 * @param neg_flags The flags from the packet69 */70 71 void debug_ntlmssp_flags(uint32_t neg_flags)72 {73 DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));74 75 if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE)76 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n"));77 if (neg_flags & NTLMSSP_NEGOTIATE_OEM)78 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n"));79 if (neg_flags & NTLMSSP_REQUEST_TARGET)80 DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n"));81 if (neg_flags & NTLMSSP_NEGOTIATE_SIGN)82 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n"));83 if (neg_flags & NTLMSSP_NEGOTIATE_SEAL)84 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n"));85 if (neg_flags & NTLMSSP_NEGOTIATE_DATAGRAM)86 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DATAGRAM\n"));87 if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)88 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n"));89 if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE)90 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n"));91 if (neg_flags & NTLMSSP_NEGOTIATE_NTLM)92 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n"));93 if (neg_flags & NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED)94 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED\n"));95 if (neg_flags & NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED)96 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED\n"));97 if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL)98 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));99 if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)100 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));101 if (neg_flags & NTLMSSP_REQUEST_NON_NT_SESSION_KEY)102 DEBUGADD(4, (" NTLMSSP_REQUEST_NON_NT_SESSION_KEY\n"));103 if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2)104 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n"));105 if (neg_flags & NTLMSSP_NEGOTIATE_TARGET_INFO)106 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_TARGET_INFO\n"));107 if (neg_flags & NTLMSSP_NEGOTIATE_128)108 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n"));109 if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)110 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n"));111 if (neg_flags & NTLMSSP_NEGOTIATE_56)112 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_56\n"));113 }114 62 115 63 static NTSTATUS gensec_ntlmssp_magic(struct gensec_security *gensec_security, … … 123 71 } 124 72 125 static NTSTATUS gensec_ntlmssp_update_find(struct gensec_ntlmssp_state *gensec_ntlmssp_state,73 static NTSTATUS gensec_ntlmssp_update_find(struct ntlmssp_state *ntlmssp_state, 126 74 const DATA_BLOB input, uint32_t *idx) 127 75 { 128 struct gensec_security *gensec_security = gensec_ntlmssp_state->gensec_security; 76 struct gensec_ntlmssp_context *gensec_ntlmssp = 77 talloc_get_type_abort(ntlmssp_state->callback_private, 78 struct gensec_ntlmssp_context); 79 struct gensec_security *gensec_security = gensec_ntlmssp->gensec_security; 129 80 uint32_t ntlmssp_command; 130 81 uint32_t i; 131 82 132 if ( gensec_ntlmssp_state->expected_state == NTLMSSP_DONE) {83 if (ntlmssp_state->expected_state == NTLMSSP_DONE) { 133 84 /* We are strict here because other modules, which we 134 85 * don't fully control (such as GSSAPI) are also … … 140 91 141 92 if (!input.length) { 142 switch ( gensec_ntlmssp_state->role) {93 switch (ntlmssp_state->role) { 143 94 case NTLMSSP_CLIENT: 144 95 ntlmssp_command = NTLMSSP_INITIAL; … … 156 107 } 157 108 } else { 158 if (!msrpc_parse( gensec_ntlmssp_state,109 if (!msrpc_parse(ntlmssp_state, 159 110 &input, "Cd", 160 111 "NTLMSSP", … … 166 117 } 167 118 168 if (ntlmssp_command != gensec_ntlmssp_state->expected_state) {169 DEBUG(2, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, gensec_ntlmssp_state->expected_state));119 if (ntlmssp_command != ntlmssp_state->expected_state) { 120 DEBUG(2, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); 170 121 return NT_STATUS_INVALID_PARAMETER; 171 122 } 172 123 173 124 for (i=0; i < ARRAY_SIZE(ntlmssp_callbacks); i++) { 174 if (ntlmssp_callbacks[i].role == gensec_ntlmssp_state->role &&125 if (ntlmssp_callbacks[i].role == ntlmssp_state->role && 175 126 ntlmssp_callbacks[i].command == ntlmssp_command) { 176 127 *idx = i; … … 180 131 181 132 DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n", 182 gensec_ntlmssp_state->role, ntlmssp_command));133 ntlmssp_state->role, ntlmssp_command)); 183 134 184 135 return NT_STATUS_INVALID_PARAMETER; … … 200 151 const DATA_BLOB input, DATA_BLOB *out) 201 152 { 202 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; 153 struct gensec_ntlmssp_context *gensec_ntlmssp = 154 talloc_get_type_abort(gensec_security->private_data, 155 struct gensec_ntlmssp_context); 156 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; 203 157 NTSTATUS status; 204 158 uint32_t i; … … 209 163 /* if the caller doesn't want to manage/own the memory, 210 164 we can put it on our context */ 211 out_mem_ctx = gensec_ntlmssp_state;212 } 213 214 status = gensec_ntlmssp_update_find( gensec_ntlmssp_state, input, &i);165 out_mem_ctx = ntlmssp_state; 166 } 167 168 status = gensec_ntlmssp_update_find(ntlmssp_state, input, &i); 215 169 NT_STATUS_NOT_OK_RETURN(status); 216 170 … … 224 178 * Return the NTLMSSP master session key 225 179 * 226 * @param gensec_ntlmssp_state NTLMSSP State180 * @param ntlmssp_state NTLMSSP State 227 181 */ 228 182 … … 230 184 DATA_BLOB *session_key) 231 185 { 232 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; 233 234 if (gensec_ntlmssp_state->expected_state != NTLMSSP_DONE) { 186 struct gensec_ntlmssp_context *gensec_ntlmssp = 187 talloc_get_type_abort(gensec_security->private_data, 188 struct gensec_ntlmssp_context); 189 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; 190 191 if (ntlmssp_state->expected_state != NTLMSSP_DONE) { 235 192 return NT_STATUS_NO_USER_SESSION_KEY; 236 193 } 237 194 238 if (! gensec_ntlmssp_state->session_key.data) {195 if (!ntlmssp_state->session_key.data) { 239 196 return NT_STATUS_NO_USER_SESSION_KEY; 240 197 } 241 *session_key = gensec_ntlmssp_state->session_key;198 *session_key = ntlmssp_state->session_key; 242 199 243 200 return NT_STATUS_OK; 244 }245 246 void ntlmssp_handle_neg_flags(struct gensec_ntlmssp_state *gensec_ntlmssp_state,247 uint32_t neg_flags, bool allow_lm)248 {249 if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {250 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;251 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;252 gensec_ntlmssp_state->unicode = true;253 } else {254 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;255 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;256 gensec_ntlmssp_state->unicode = false;257 }258 259 if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm && !gensec_ntlmssp_state->use_ntlmv2) {260 /* other end forcing us to use LM */261 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;262 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;263 } else {264 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;265 }266 267 if (!(neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) {268 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN;269 }270 271 if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {272 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;273 }274 275 if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {276 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;277 }278 279 if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {280 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;281 }282 283 if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {284 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;285 }286 287 if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {288 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;289 }290 291 if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {292 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;293 }294 295 /* Woop Woop - unknown flag for Windows compatibility...296 What does this really do ? JRA. */297 if (!(neg_flags & NTLMSSP_NEGOTIATE_VERSION)) {298 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_VERSION;299 }300 301 if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {302 gensec_ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;303 }304 305 }306 307 /**308 Weaken NTLMSSP keys to cope with down-level clients and servers.309 310 We probably should have some parameters to control this, but as311 it only occours for LM_KEY connections, and this is controlled312 by the client lanman auth/lanman auth parameters, it isn't too bad.313 */314 315 DATA_BLOB ntlmssp_weakend_key(struct gensec_ntlmssp_state *gensec_ntlmssp_state,316 TALLOC_CTX *mem_ctx)317 {318 DATA_BLOB weakened_key = data_blob_talloc(mem_ctx,319 gensec_ntlmssp_state->session_key.data,320 gensec_ntlmssp_state->session_key.length);321 /* Nothing to weaken. We certainly don't want to 'extend' the length... */322 if (weakened_key.length < 16) {323 /* perhaps there was no key? */324 return weakened_key;325 }326 327 /* Key weakening not performed on the master key for NTLM2328 and does not occour for NTLM1. Therefore we only need329 to do this for the LM_KEY.330 */331 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {332 /* LM key doesn't support 128 bit crypto, so this is333 * the best we can do. If you negotiate 128 bit, but334 * not 56, you end up with 40 bit... */335 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {336 weakened_key.data[7] = 0xa0;337 weakened_key.length = 8;338 } else { /* forty bits */339 weakened_key.data[5] = 0xe5;340 weakened_key.data[6] = 0x38;341 weakened_key.data[7] = 0xb0;342 weakened_key.length = 8;343 }344 }345 return weakened_key;346 201 } 347 202 … … 349 204 uint32_t feature) 350 205 { 351 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; 206 struct gensec_ntlmssp_context *gensec_ntlmssp = 207 talloc_get_type_abort(gensec_security->private_data, 208 struct gensec_ntlmssp_context); 209 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; 210 352 211 if (feature & GENSEC_FEATURE_SIGN) { 353 if (! gensec_ntlmssp_state->session_key.length) {212 if (!ntlmssp_state->session_key.length) { 354 213 return false; 355 214 } 356 if ( gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {215 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) { 357 216 return true; 358 217 } 359 218 } 360 219 if (feature & GENSEC_FEATURE_SEAL) { 361 if (! gensec_ntlmssp_state->session_key.length) {220 if (!ntlmssp_state->session_key.length) { 362 221 return false; 363 222 } 364 if ( gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {223 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { 365 224 return true; 366 225 } 367 226 } 368 227 if (feature & GENSEC_FEATURE_SESSION_KEY) { 369 if ( gensec_ntlmssp_state->session_key.length) {228 if (ntlmssp_state->session_key.length) { 370 229 return true; 371 230 } … … 375 234 } 376 235 if (feature & GENSEC_FEATURE_ASYNC_REPLIES) { 377 if ( gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {236 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { 378 237 return true; 379 238 } … … 384 243 NTSTATUS gensec_ntlmssp_start(struct gensec_security *gensec_security) 385 244 { 386 struct gensec_ntlmssp_state *gensec_ntlmssp_state; 387 388 gensec_ntlmssp_state = talloc_zero(gensec_security, struct gensec_ntlmssp_state); 389 if (!gensec_ntlmssp_state) { 245 struct gensec_ntlmssp_context *gensec_ntlmssp; 246 struct ntlmssp_state *ntlmssp_state; 247 248 gensec_ntlmssp = talloc_zero(gensec_security, 249 struct gensec_ntlmssp_context); 250 if (!gensec_ntlmssp) { 390 251 return NT_STATUS_NO_MEMORY; 391 252 } 392 253 393 gensec_ntlmssp_state->gensec_security = gensec_security; 394 gensec_ntlmssp_state->auth_context = NULL; 395 gensec_ntlmssp_state->server_info = NULL; 396 397 gensec_security->private_data = gensec_ntlmssp_state; 254 gensec_ntlmssp->gensec_security = gensec_security; 255 256 ntlmssp_state = talloc_zero(gensec_ntlmssp, 257 struct ntlmssp_state); 258 if (!ntlmssp_state) { 259 return NT_STATUS_NO_MEMORY; 260 } 261 262 ntlmssp_state->callback_private = gensec_ntlmssp; 263 264 gensec_ntlmssp->ntlmssp_state = ntlmssp_state; 265 266 gensec_security->private_data = gensec_ntlmssp; 398 267 return NT_STATUS_OK; 399 268 } … … 406 275 static const struct gensec_security_ops gensec_ntlmssp_security_ops = { 407 276 .name = "ntlmssp", 408 .sasl_name = "NTLM",277 .sasl_name = GENSEC_SASL_NAME_NTLMSSP, /* "NTLM" */ 409 278 .auth_type = DCERPC_AUTH_TYPE_NTLMSSP, 410 279 .oid = gensec_ntlmssp_oids,
Note:
See TracChangeset
for help on using the changeset viewer.