00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "includes.h"
00026
00027 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
00028 DATA_BLOB reply, DATA_BLOB *next_request);
00029 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
00030 const DATA_BLOB in, DATA_BLOB *out);
00031 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
00032 const DATA_BLOB reply, DATA_BLOB *next_request);
00033 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
00034 const DATA_BLOB request, DATA_BLOB *reply);
00035
00036
00037
00038
00039
00040
00041 static const struct ntlmssp_callbacks {
00042 enum NTLMSSP_ROLE role;
00043 enum NTLM_MESSAGE_TYPE ntlmssp_command;
00044 NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state,
00045 DATA_BLOB in, DATA_BLOB *out);
00046 } ntlmssp_callbacks[] = {
00047 {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp_client_initial},
00048 {NTLMSSP_SERVER, NTLMSSP_NEGOTIATE, ntlmssp_server_negotiate},
00049 {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp_client_challenge},
00050 {NTLMSSP_SERVER, NTLMSSP_AUTH, ntlmssp_server_auth},
00051 {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL},
00052 {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL}
00053 };
00054
00055
00056
00057
00058
00059
00060
00061 void debug_ntlmssp_flags(uint32 neg_flags)
00062 {
00063 DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));
00064
00065 if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE)
00066 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n"));
00067 if (neg_flags & NTLMSSP_NEGOTIATE_OEM)
00068 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n"));
00069 if (neg_flags & NTLMSSP_REQUEST_TARGET)
00070 DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n"));
00071 if (neg_flags & NTLMSSP_NEGOTIATE_SIGN)
00072 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n"));
00073 if (neg_flags & NTLMSSP_NEGOTIATE_SEAL)
00074 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n"));
00075 if (neg_flags & NTLMSSP_NEGOTIATE_DATAGRAM_STYLE)
00076 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DATAGRAM_STYLE\n"));
00077 if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
00078 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n"));
00079 if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE)
00080 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n"));
00081 if (neg_flags & NTLMSSP_NEGOTIATE_NTLM)
00082 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n"));
00083 if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED)
00084 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n"));
00085 if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED)
00086 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n"));
00087 if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL)
00088 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));
00089 if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
00090 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));
00091 if (neg_flags & NTLMSSP_CHAL_ACCEPT_RESPONSE)
00092 DEBUGADD(4, (" NTLMSSP_CHAL_ACCEPT_RESPONSE\n"));
00093 if (neg_flags & NTLMSSP_CHAL_NON_NT_SESSION_KEY)
00094 DEBUGADD(4, (" NTLMSSP_CHAL_NON_NT_SESSION_KEY\n"));
00095 if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
00096 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n"));
00097 if (neg_flags & NTLMSSP_CHAL_TARGET_INFO)
00098 DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n"));
00099 if (neg_flags & NTLMSSP_NEGOTIATE_128)
00100 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n"));
00101 if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
00102 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n"));
00103 if (neg_flags & NTLMSSP_NEGOTIATE_56)
00104 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_56\n"));
00105 }
00106
00107
00108
00109
00110
00111
00112 static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state)
00113 {
00114 static uchar chal[8];
00115 generate_random_buffer(chal, sizeof(chal));
00116
00117 return chal;
00118 }
00119
00120
00121
00122
00123
00124
00125 static BOOL may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
00126 {
00127 return True;
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137 static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
00138 {
00139 SMB_ASSERT(challenge->length == 8);
00140 return NT_STATUS_OK;
00141 }
00142
00143
00144
00145
00146
00147
00148 NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user)
00149 {
00150 ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user ? user : "" );
00151 if (!ntlmssp_state->user) {
00152 return NT_STATUS_NO_MEMORY;
00153 }
00154 return NT_STATUS_OK;
00155 }
00156
00157
00158
00159
00160
00161 NTSTATUS ntlmssp_set_hashes(NTLMSSP_STATE *ntlmssp_state,
00162 const unsigned char lm_hash[16],
00163 const unsigned char nt_hash[16])
00164 {
00165 ntlmssp_state->lm_hash = (unsigned char *)
00166 TALLOC_MEMDUP(ntlmssp_state->mem_ctx, lm_hash, 16);
00167 ntlmssp_state->nt_hash = (unsigned char *)
00168 TALLOC_MEMDUP(ntlmssp_state->mem_ctx, nt_hash, 16);
00169 if (!ntlmssp_state->lm_hash || !ntlmssp_state->nt_hash) {
00170 TALLOC_FREE(ntlmssp_state->lm_hash);
00171 TALLOC_FREE(ntlmssp_state->nt_hash);
00172 return NT_STATUS_NO_MEMORY;
00173 }
00174 return NT_STATUS_OK;
00175 }
00176
00177
00178
00179
00180
00181 NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password)
00182 {
00183 if (!password) {
00184 ntlmssp_state->lm_hash = NULL;
00185 ntlmssp_state->nt_hash = NULL;
00186 } else {
00187 unsigned char lm_hash[16];
00188 unsigned char nt_hash[16];
00189
00190 E_deshash(password, lm_hash);
00191 E_md4hash(password, nt_hash);
00192 return ntlmssp_set_hashes(ntlmssp_state, lm_hash, nt_hash);
00193 }
00194 return NT_STATUS_OK;
00195 }
00196
00197
00198
00199
00200
00201 NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain)
00202 {
00203 ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain ? domain : "" );
00204 if (!ntlmssp_state->domain) {
00205 return NT_STATUS_NO_MEMORY;
00206 }
00207 return NT_STATUS_OK;
00208 }
00209
00210
00211
00212
00213
00214 NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation)
00215 {
00216 ntlmssp_state->workstation = talloc_strdup(ntlmssp_state->mem_ctx, workstation);
00217 if (!ntlmssp_state->workstation) {
00218 return NT_STATUS_NO_MEMORY;
00219 }
00220 return NT_STATUS_OK;
00221 }
00222
00223
00224
00225
00226
00227
00228 NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state,
00229 DATA_BLOB response)
00230 {
00231 ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state->mem_ctx,
00232 response.data, response.length);
00233 return NT_STATUS_OK;
00234 }
00235
00236
00237
00238
00239
00240
00241
00242 void ntlmssp_want_feature_list(NTLMSSP_STATE *ntlmssp_state, char *feature_list)
00243 {
00244
00245
00246
00247
00248
00249 if (in_list("NTLMSSP_FEATURE_SESSION_KEY", feature_list, True)) {
00250 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
00251 }
00252 if (in_list("NTLMSSP_FEATURE_SIGN", feature_list, True)) {
00253 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
00254 }
00255 if(in_list("NTLMSSP_FEATURE_SEAL", feature_list, True)) {
00256 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
00257 }
00258 }
00259
00260
00261
00262
00263
00264
00265
00266 void ntlmssp_want_feature(NTLMSSP_STATE *ntlmssp_state, uint32 feature)
00267 {
00268
00269 if (feature & NTLMSSP_FEATURE_SESSION_KEY) {
00270 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
00271 }
00272 if (feature & NTLMSSP_FEATURE_SIGN) {
00273 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
00274 }
00275 if (feature & NTLMSSP_FEATURE_SEAL) {
00276 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
00277 }
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state,
00290 const DATA_BLOB in, DATA_BLOB *out)
00291 {
00292 DATA_BLOB input;
00293 uint32 ntlmssp_command;
00294 int i;
00295
00296 if (ntlmssp_state->expected_state == NTLMSSP_DONE) {
00297
00298 DEBUG(1, ("Called NTLMSSP after state machine was 'done'\n"));
00299 return NT_STATUS_INVALID_PARAMETER;
00300 }
00301
00302 *out = data_blob(NULL, 0);
00303
00304 if (!in.length && ntlmssp_state->stored_response.length) {
00305 input = ntlmssp_state->stored_response;
00306
00307
00308 ntlmssp_state->stored_response = data_blob(NULL, 0);
00309 } else {
00310 input = in;
00311 }
00312
00313 if (!input.length) {
00314 switch (ntlmssp_state->role) {
00315 case NTLMSSP_CLIENT:
00316 ntlmssp_command = NTLMSSP_INITIAL;
00317 break;
00318 case NTLMSSP_SERVER:
00319
00320 ntlmssp_command = NTLMSSP_NEGOTIATE;
00321 break;
00322 }
00323 } else {
00324 if (!msrpc_parse(&input, "Cd",
00325 "NTLMSSP",
00326 &ntlmssp_command)) {
00327 DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n"));
00328 dump_data(2, (const char *)input.data, input.length);
00329 return NT_STATUS_INVALID_PARAMETER;
00330 }
00331 }
00332
00333 if (ntlmssp_command != ntlmssp_state->expected_state) {
00334 DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
00335 return NT_STATUS_INVALID_PARAMETER;
00336 }
00337
00338 for (i=0; ntlmssp_callbacks[i].fn; i++) {
00339 if (ntlmssp_callbacks[i].role == ntlmssp_state->role
00340 && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) {
00341 return ntlmssp_callbacks[i].fn(ntlmssp_state, input, out);
00342 }
00343 }
00344
00345 DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n",
00346 ntlmssp_state->role, ntlmssp_command));
00347
00348 return NT_STATUS_INVALID_PARAMETER;
00349 }
00350
00351
00352
00353
00354
00355
00356
00357 void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state)
00358 {
00359 TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx;
00360
00361 (*ntlmssp_state)->ref_count--;
00362
00363 if ((*ntlmssp_state)->ref_count == 0) {
00364 data_blob_free(&(*ntlmssp_state)->chal);
00365 data_blob_free(&(*ntlmssp_state)->lm_resp);
00366 data_blob_free(&(*ntlmssp_state)->nt_resp);
00367
00368 talloc_destroy(mem_ctx);
00369 }
00370
00371 *ntlmssp_state = NULL;
00372 return;
00373 }
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
00386 uint32 neg_flags, uint32 *chal_flags)
00387 {
00388 if (neg_flags & NTLMSSP_REQUEST_TARGET) {
00389 *chal_flags |= NTLMSSP_CHAL_TARGET_INFO;
00390 *chal_flags |= NTLMSSP_REQUEST_TARGET;
00391 if (ntlmssp_state->server_role == ROLE_STANDALONE) {
00392 *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
00393 return ntlmssp_state->get_global_myname();
00394 } else {
00395 *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
00396 return ntlmssp_state->get_domain();
00397 };
00398 } else {
00399 return "";
00400 }
00401 }
00402
00403 static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
00404 uint32 neg_flags, BOOL allow_lm) {
00405 if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
00406 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
00407 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
00408 ntlmssp_state->unicode = True;
00409 } else {
00410 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
00411 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
00412 ntlmssp_state->unicode = False;
00413 }
00414
00415 if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm) {
00416
00417 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
00418 ntlmssp_state->use_ntlmv2 = False;
00419 } else {
00420 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
00421 }
00422
00423 if (!(neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) {
00424 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
00425 }
00426
00427 if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
00428 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
00429 }
00430
00431 if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
00432 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
00433 }
00434
00435 if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {
00436 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
00437 }
00438
00439 if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
00440 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
00441 }
00442
00443 if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
00444 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
00445 }
00446
00447 if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
00448 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
00449 }
00450
00451
00452
00453 if (!(neg_flags & NTLMSSP_UNKNOWN_02000000)) {
00454 ntlmssp_state->neg_flags &= ~NTLMSSP_UNKNOWN_02000000;
00455 }
00456
00457 if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
00458 ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
00459 }
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 DATA_BLOB ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state, TALLOC_CTX *mem_ctx)
00471 {
00472 DATA_BLOB weakened_key = data_blob_talloc(mem_ctx,
00473 ntlmssp_state->session_key.data,
00474 ntlmssp_state->session_key.length);
00475
00476
00477 if (weakened_key.length < 16) {
00478
00479 return weakened_key;
00480 }
00481
00482
00483
00484
00485
00486
00487 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
00488
00489
00490
00491 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
00492 weakened_key.data[7] = 0xa0;
00493 } else {
00494 weakened_key.data[5] = 0xe5;
00495 weakened_key.data[6] = 0x38;
00496 weakened_key.data[7] = 0xb0;
00497 }
00498 weakened_key.length = 8;
00499 }
00500 return weakened_key;
00501 }
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
00513 const DATA_BLOB request, DATA_BLOB *reply)
00514 {
00515 DATA_BLOB struct_blob;
00516 fstring dnsname, dnsdomname;
00517 uint32 neg_flags = 0;
00518 uint32 ntlmssp_command, chal_flags;
00519 const uint8 *cryptkey;
00520 const char *target_name;
00521
00522
00523 #if 0
00524 file_save("ntlmssp_negotiate.dat", request.data, request.length);
00525 #endif
00526
00527 if (request.length) {
00528 if ((request.length < 16) || !msrpc_parse(&request, "Cdd",
00529 "NTLMSSP",
00530 &ntlmssp_command,
00531 &neg_flags)) {
00532 DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n",
00533 (unsigned int)request.length));
00534 dump_data(2, (const char *)request.data, request.length);
00535 return NT_STATUS_INVALID_PARAMETER;
00536 }
00537 debug_ntlmssp_flags(neg_flags);
00538 }
00539
00540 ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth());
00541
00542
00543 cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);
00544
00545
00546 if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
00547 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
00548 }
00549
00550
00551
00552
00553
00554
00555 chal_flags = ntlmssp_state->neg_flags;
00556
00557
00558 target_name = ntlmssp_target_name(ntlmssp_state,
00559 neg_flags, &chal_flags);
00560 if (target_name == NULL)
00561 return NT_STATUS_INVALID_PARAMETER;
00562
00563 ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
00564 ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
00565
00566
00567
00568 dnsdomname[0] = '\0';
00569 get_mydnsdomname(dnsdomname);
00570 strlower_m(dnsdomname);
00571
00572 dnsname[0] = '\0';
00573 get_mydnsfullname(dnsname);
00574
00575
00576 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO)
00577 {
00578 msrpc_gen(&struct_blob, "aaaaa",
00579 NTLMSSP_NAME_TYPE_DOMAIN, target_name,
00580 NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(),
00581 NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
00582 NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
00583 0, "");
00584 } else {
00585 struct_blob = data_blob(NULL, 0);
00586 }
00587
00588 {
00589
00590 const char *gen_string;
00591 if (ntlmssp_state->unicode) {
00592 gen_string = "CdUdbddB";
00593 } else {
00594 gen_string = "CdAdbddB";
00595 }
00596
00597 msrpc_gen(reply, gen_string,
00598 "NTLMSSP",
00599 NTLMSSP_CHALLENGE,
00600 target_name,
00601 chal_flags,
00602 cryptkey, 8,
00603 0, 0,
00604 struct_blob.data, struct_blob.length);
00605 }
00606
00607 data_blob_free(&struct_blob);
00608
00609 ntlmssp_state->expected_state = NTLMSSP_AUTH;
00610
00611 return NT_STATUS_MORE_PROCESSING_REQUIRED;
00612 }
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623 static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
00624 const DATA_BLOB request, DATA_BLOB *reply)
00625 {
00626 DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
00627 DATA_BLOB user_session_key = data_blob(NULL, 0);
00628 DATA_BLOB lm_session_key = data_blob(NULL, 0);
00629 DATA_BLOB session_key = data_blob(NULL, 0);
00630 uint32 ntlmssp_command, auth_flags;
00631 NTSTATUS nt_status = NT_STATUS_OK;
00632
00633
00634 BOOL doing_ntlm2 = False;
00635
00636 uchar session_nonce[16];
00637 uchar session_nonce_hash[16];
00638
00639 const char *parse_string;
00640 char *domain = NULL;
00641 char *user = NULL;
00642 char *workstation = NULL;
00643
00644
00645 *reply = data_blob(NULL, 0);
00646
00647 #if 0
00648 file_save("ntlmssp_auth.dat", request.data, request.length);
00649 #endif
00650
00651 if (ntlmssp_state->unicode) {
00652 parse_string = "CdBBUUUBd";
00653 } else {
00654 parse_string = "CdBBAAABd";
00655 }
00656
00657 data_blob_free(&ntlmssp_state->lm_resp);
00658 data_blob_free(&ntlmssp_state->nt_resp);
00659
00660 ntlmssp_state->user = NULL;
00661 ntlmssp_state->domain = NULL;
00662 ntlmssp_state->workstation = NULL;
00663
00664
00665 if (!msrpc_parse(&request, parse_string,
00666 "NTLMSSP",
00667 &ntlmssp_command,
00668 &ntlmssp_state->lm_resp,
00669 &ntlmssp_state->nt_resp,
00670 &domain,
00671 &user,
00672 &workstation,
00673 &encrypted_session_key,
00674 &auth_flags)) {
00675 SAFE_FREE(domain);
00676 SAFE_FREE(user);
00677 SAFE_FREE(workstation);
00678 data_blob_free(&encrypted_session_key);
00679 auth_flags = 0;
00680
00681
00682 if (ntlmssp_state->unicode) {
00683 parse_string = "CdBBUUU";
00684 } else {
00685 parse_string = "CdBBAAA";
00686 }
00687
00688
00689 if (!msrpc_parse(&request, parse_string,
00690 "NTLMSSP",
00691 &ntlmssp_command,
00692 &ntlmssp_state->lm_resp,
00693 &ntlmssp_state->nt_resp,
00694 &domain,
00695 &user,
00696 &workstation)) {
00697 DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n"));
00698 dump_data(2, (const char *)request.data, request.length);
00699 SAFE_FREE(domain);
00700 SAFE_FREE(user);
00701 SAFE_FREE(workstation);
00702
00703 return NT_STATUS_INVALID_PARAMETER;
00704 }
00705 }
00706
00707 if (auth_flags)
00708 ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, lp_lanman_auth());
00709
00710 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
00711 SAFE_FREE(domain);
00712 SAFE_FREE(user);
00713 SAFE_FREE(workstation);
00714 data_blob_free(&encrypted_session_key);
00715 return nt_status;
00716 }
00717
00718 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
00719 SAFE_FREE(domain);
00720 SAFE_FREE(user);
00721 SAFE_FREE(workstation);
00722 data_blob_free(&encrypted_session_key);
00723 return nt_status;
00724 }
00725
00726 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) {
00727 SAFE_FREE(domain);
00728 SAFE_FREE(user);
00729 SAFE_FREE(workstation);
00730 data_blob_free(&encrypted_session_key);
00731 return nt_status;
00732 }
00733
00734 SAFE_FREE(domain);
00735 SAFE_FREE(user);
00736 SAFE_FREE(workstation);
00737
00738 DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
00739 ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length));
00740
00741 #if 0
00742 file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length);
00743 file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length);
00744 #endif
00745
00746
00747
00748
00749
00750
00751 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
00752 if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) {
00753 struct MD5Context md5_session_nonce_ctx;
00754 SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8);
00755
00756 doing_ntlm2 = True;
00757
00758 memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8);
00759 memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8);
00760
00761 MD5Init(&md5_session_nonce_ctx);
00762 MD5Update(&md5_session_nonce_ctx, session_nonce, 16);
00763 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
00764
00765 ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, session_nonce_hash, 8);
00766
00767
00768 data_blob_free(&ntlmssp_state->lm_resp);
00769
00770
00771 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) {
00772 data_blob_free(&encrypted_session_key);
00773 return nt_status;
00774 }
00775
00776
00777 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
00778 }
00779 }
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state,
00791 &user_session_key, &lm_session_key))) {
00792 data_blob_free(&encrypted_session_key);
00793 return nt_status;
00794 }
00795
00796 dump_data_pw("NT session key:\n", user_session_key.data, user_session_key.length);
00797 dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length);
00798
00799
00800 if (doing_ntlm2) {
00801 if (user_session_key.data && user_session_key.length == 16) {
00802 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
00803 hmac_md5(user_session_key.data, session_nonce,
00804 sizeof(session_nonce), session_key.data);
00805 DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
00806 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
00807
00808 } else {
00809 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
00810 session_key = data_blob(NULL, 0);
00811 }
00812 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
00813 if (lm_session_key.data && lm_session_key.length >= 8) {
00814 if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
00815 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
00816 if (session_key.data == NULL) {
00817 return NT_STATUS_NO_MEMORY;
00818 }
00819 SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data,
00820 session_key.data);
00821 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
00822 } else {
00823 static const uint8 zeros[24] = { 0, };
00824 session_key = data_blob_talloc(
00825 ntlmssp_state->mem_ctx, NULL, 16);
00826 if (session_key.data == NULL) {
00827 return NT_STATUS_NO_MEMORY;
00828 }
00829 SMBsesskeygen_lm_sess_key(
00830 lm_session_key.data, zeros,
00831 session_key.data);
00832 }
00833 dump_data_pw("LM session key:\n", session_key.data,
00834 session_key.length);
00835 } else {
00836 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
00837 session_key = data_blob(NULL, 0);
00838 }
00839 } else if (user_session_key.data) {
00840 session_key = user_session_key;
00841 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
00842 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
00843 } else if (lm_session_key.data) {
00844 session_key = lm_session_key;
00845 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
00846 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
00847 } else {
00848 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
00849 session_key = data_blob(NULL, 0);
00850 }
00851
00852
00853
00854 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
00855 if (!encrypted_session_key.data || encrypted_session_key.length != 16) {
00856 data_blob_free(&encrypted_session_key);
00857 DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
00858 (unsigned int)encrypted_session_key.length));
00859 return NT_STATUS_INVALID_PARAMETER;
00860 } else if (!session_key.data || session_key.length != 16) {
00861 DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
00862 (unsigned int)session_key.length));
00863 ntlmssp_state->session_key = session_key;
00864 } else {
00865 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
00866 SamOEMhash(encrypted_session_key.data,
00867 session_key.data,
00868 encrypted_session_key.length);
00869 ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx,
00870 encrypted_session_key.data,
00871 encrypted_session_key.length);
00872 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data,
00873 encrypted_session_key.length);
00874 }
00875 } else {
00876 ntlmssp_state->session_key = session_key;
00877 }
00878
00879 if (!NT_STATUS_IS_OK(nt_status)) {
00880 ntlmssp_state->session_key = data_blob(NULL, 0);
00881 } else if (ntlmssp_state->session_key.length) {
00882 nt_status = ntlmssp_sign_init(ntlmssp_state);
00883 }
00884
00885 data_blob_free(&encrypted_session_key);
00886
00887
00888 ntlmssp_state->expected_state = NTLMSSP_DONE;
00889
00890 return nt_status;
00891 }
00892
00893
00894
00895
00896
00897
00898
00899 NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
00900 {
00901 TALLOC_CTX *mem_ctx;
00902
00903 mem_ctx = talloc_init("NTLMSSP context");
00904
00905 *ntlmssp_state = TALLOC_ZERO_P(mem_ctx, NTLMSSP_STATE);
00906 if (!*ntlmssp_state) {
00907 DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
00908 talloc_destroy(mem_ctx);
00909 return NT_STATUS_NO_MEMORY;
00910 }
00911
00912 (*ntlmssp_state)->role = NTLMSSP_SERVER;
00913
00914 (*ntlmssp_state)->mem_ctx = mem_ctx;
00915 (*ntlmssp_state)->get_challenge = get_challenge;
00916 (*ntlmssp_state)->set_challenge = set_challenge;
00917 (*ntlmssp_state)->may_set_challenge = may_set_challenge;
00918
00919 (*ntlmssp_state)->get_global_myname = global_myname;
00920 (*ntlmssp_state)->get_domain = lp_workgroup;
00921 (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER;
00922
00923 (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE;
00924
00925 (*ntlmssp_state)->ref_count = 1;
00926
00927 (*ntlmssp_state)->neg_flags =
00928 NTLMSSP_NEGOTIATE_128 |
00929 NTLMSSP_NEGOTIATE_56 |
00930 NTLMSSP_UNKNOWN_02000000 |
00931 NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
00932 NTLMSSP_NEGOTIATE_NTLM |
00933 NTLMSSP_NEGOTIATE_NTLM2 |
00934 NTLMSSP_NEGOTIATE_KEY_EXCH |
00935 NTLMSSP_NEGOTIATE_SIGN |
00936 NTLMSSP_NEGOTIATE_SEAL;
00937
00938 return NT_STATUS_OK;
00939 }
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
00955 DATA_BLOB reply, DATA_BLOB *next_request)
00956 {
00957 if (ntlmssp_state->unicode) {
00958 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
00959 } else {
00960 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
00961 }
00962
00963 if (ntlmssp_state->use_ntlmv2) {
00964 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
00965 }
00966
00967
00968 msrpc_gen(next_request, "CddAA",
00969 "NTLMSSP",
00970 NTLMSSP_NEGOTIATE,
00971 ntlmssp_state->neg_flags,
00972 ntlmssp_state->get_domain(),
00973 ntlmssp_state->get_global_myname());
00974
00975 ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
00976
00977 return NT_STATUS_MORE_PROCESSING_REQUIRED;
00978 }
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
00990 const DATA_BLOB reply, DATA_BLOB *next_request)
00991 {
00992 uint32 chal_flags, ntlmssp_command, unkn1, unkn2;
00993 DATA_BLOB server_domain_blob;
00994 DATA_BLOB challenge_blob;
00995 DATA_BLOB struct_blob = data_blob(NULL, 0);
00996 char *server_domain;
00997 const char *chal_parse_string;
00998 const char *auth_gen_string;
00999 DATA_BLOB lm_response = data_blob(NULL, 0);
01000 DATA_BLOB nt_response = data_blob(NULL, 0);
01001 DATA_BLOB session_key = data_blob(NULL, 0);
01002 DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
01003 NTSTATUS nt_status = NT_STATUS_OK;
01004
01005 if (!msrpc_parse(&reply, "CdBd",
01006 "NTLMSSP",
01007 &ntlmssp_command,
01008 &server_domain_blob,
01009 &chal_flags)) {
01010 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
01011 dump_data(2, (const char *)reply.data, reply.length);
01012
01013 return NT_STATUS_INVALID_PARAMETER;
01014 }
01015
01016 data_blob_free(&server_domain_blob);
01017
01018 DEBUG(3, ("Got challenge flags:\n"));
01019 debug_ntlmssp_flags(chal_flags);
01020
01021 ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth());
01022
01023 if (ntlmssp_state->unicode) {
01024 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
01025 chal_parse_string = "CdUdbddB";
01026 } else {
01027 chal_parse_string = "CdUdbdd";
01028 }
01029 auth_gen_string = "CdBBUUUBd";
01030 } else {
01031 if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) {
01032 chal_parse_string = "CdAdbddB";
01033 } else {
01034 chal_parse_string = "CdAdbdd";
01035 }
01036
01037 auth_gen_string = "CdBBAAABd";
01038 }
01039
01040 DEBUG(3, ("NTLMSSP: Set final flags:\n"));
01041 debug_ntlmssp_flags(ntlmssp_state->neg_flags);
01042
01043 if (!msrpc_parse(&reply, chal_parse_string,
01044 "NTLMSSP",
01045 &ntlmssp_command,
01046 &server_domain,
01047 &chal_flags,
01048 &challenge_blob, 8,
01049 &unkn1, &unkn2,
01050 &struct_blob)) {
01051 DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
01052 dump_data(2, (const char *)reply.data, reply.length);
01053 return NT_STATUS_INVALID_PARAMETER;
01054 }
01055
01056 ntlmssp_state->server_domain = talloc_strdup(ntlmssp_state->mem_ctx,
01057 server_domain);
01058
01059 SAFE_FREE(server_domain);
01060 if (challenge_blob.length != 8) {
01061 data_blob_free(&struct_blob);
01062 return NT_STATUS_INVALID_PARAMETER;
01063 }
01064
01065 if (!ntlmssp_state->nt_hash || !ntlmssp_state->lm_hash) {
01066 static const uchar zeros[16] = { 0, };
01067
01068
01069
01070 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16);
01071
01072
01073 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
01074 } else if (ntlmssp_state->use_ntlmv2) {
01075
01076 if (!struct_blob.length) {
01077
01078 DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n"));
01079 return NT_STATUS_INVALID_PARAMETER;
01080 }
01081
01082
01083
01084
01085 if (!SMBNTLMv2encrypt_hash(ntlmssp_state->user,
01086 ntlmssp_state->domain,
01087 ntlmssp_state->nt_hash, &challenge_blob,
01088 &struct_blob,
01089 &lm_response, &nt_response, &session_key)) {
01090 data_blob_free(&challenge_blob);
01091 data_blob_free(&struct_blob);
01092 return NT_STATUS_NO_MEMORY;
01093 }
01094 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
01095 struct MD5Context md5_session_nonce_ctx;
01096 uchar session_nonce[16];
01097 uchar session_nonce_hash[16];
01098 uchar user_session_key[16];
01099
01100 lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
01101 generate_random_buffer(lm_response.data, 8);
01102 memset(lm_response.data+8, 0, 16);
01103
01104 memcpy(session_nonce, challenge_blob.data, 8);
01105 memcpy(&session_nonce[8], lm_response.data, 8);
01106
01107 MD5Init(&md5_session_nonce_ctx);
01108 MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8);
01109 MD5Update(&md5_session_nonce_ctx, lm_response.data, 8);
01110 MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
01111
01112 DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
01113 DEBUG(5, ("challenge is: \n"));
01114 dump_data(5, (const char *)session_nonce_hash, 8);
01115
01116 nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
01117 SMBNTencrypt_hash(ntlmssp_state->nt_hash,
01118 session_nonce_hash,
01119 nt_response.data);
01120
01121 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
01122
01123 SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, NULL, user_session_key);
01124 hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
01125 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
01126 } else {
01127
01128 if (lp_client_lanman_auth()) {
01129 lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
01130 SMBencrypt_hash(ntlmssp_state->lm_hash,challenge_blob.data,
01131 lm_response.data);
01132 }
01133
01134 nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
01135 SMBNTencrypt_hash(ntlmssp_state->nt_hash,challenge_blob.data,
01136 nt_response.data);
01137
01138 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
01139 if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
01140 && lp_client_lanman_auth()) {
01141 SMBsesskeygen_lm_sess_key(ntlmssp_state->lm_hash, lm_response.data,
01142 session_key.data);
01143 dump_data_pw("LM session key\n", session_key.data, session_key.length);
01144 } else {
01145 SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, NULL, session_key.data);
01146 dump_data_pw("NT session key:\n", session_key.data, session_key.length);
01147 }
01148 }
01149 data_blob_free(&struct_blob);
01150
01151
01152
01153 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
01154
01155 uint8 client_session_key[16];
01156 generate_random_buffer(client_session_key, sizeof(client_session_key));
01157
01158
01159 encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key));
01160 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
01161 SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
01162 dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
01163
01164
01165 data_blob_free(&session_key);
01166 session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key));
01167 }
01168
01169
01170 if (!msrpc_gen(next_request, auth_gen_string,
01171 "NTLMSSP",
01172 NTLMSSP_AUTH,
01173 lm_response.data, lm_response.length,
01174 nt_response.data, nt_response.length,
01175 ntlmssp_state->domain,
01176 ntlmssp_state->user,
01177 ntlmssp_state->get_global_myname(),
01178 encrypted_session_key.data, encrypted_session_key.length,
01179 ntlmssp_state->neg_flags)) {
01180
01181 return NT_STATUS_NO_MEMORY;
01182 }
01183
01184 data_blob_free(&encrypted_session_key);
01185
01186 data_blob_free(&ntlmssp_state->chal);
01187
01188 ntlmssp_state->session_key = session_key;
01189
01190 ntlmssp_state->chal = challenge_blob;
01191 ntlmssp_state->lm_resp = lm_response;
01192 ntlmssp_state->nt_resp = nt_response;
01193
01194 ntlmssp_state->expected_state = NTLMSSP_DONE;
01195
01196 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) {
01197 DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status)));
01198 }
01199
01200 return nt_status;
01201 }
01202
01203 NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
01204 {
01205 TALLOC_CTX *mem_ctx;
01206
01207 mem_ctx = talloc_init("NTLMSSP Client context");
01208
01209 *ntlmssp_state = TALLOC_ZERO_P(mem_ctx, NTLMSSP_STATE);
01210 if (!*ntlmssp_state) {
01211 DEBUG(0,("ntlmssp_client_start: talloc failed!\n"));
01212 talloc_destroy(mem_ctx);
01213 return NT_STATUS_NO_MEMORY;
01214 }
01215
01216 (*ntlmssp_state)->role = NTLMSSP_CLIENT;
01217
01218 (*ntlmssp_state)->mem_ctx = mem_ctx;
01219
01220 (*ntlmssp_state)->get_global_myname = global_myname;
01221 (*ntlmssp_state)->get_domain = lp_workgroup;
01222
01223 (*ntlmssp_state)->unicode = True;
01224
01225 (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth();
01226
01227 (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL;
01228
01229 (*ntlmssp_state)->ref_count = 1;
01230
01231 (*ntlmssp_state)->neg_flags =
01232 NTLMSSP_NEGOTIATE_128 |
01233 NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
01234 NTLMSSP_NEGOTIATE_NTLM |
01235 NTLMSSP_NEGOTIATE_NTLM2 |
01236 NTLMSSP_NEGOTIATE_KEY_EXCH |
01237 NTLMSSP_REQUEST_TARGET;
01238
01239 return NT_STATUS_OK;
01240 }