00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "includes.h"
00025
00026 extern struct auth_context *negprot_global_auth_context;
00027 extern BOOL global_encrypted_passwords_negotiated;
00028 extern BOOL global_spnego_negotiated;
00029 extern enum protocol_types Protocol;
00030 extern int max_send;
00031
00032 uint32 global_client_caps = 0;
00033
00034
00035
00036
00037
00038 static NTSTATUS do_map_to_guest(NTSTATUS status, auth_serversupplied_info **server_info,
00039 const char *user, const char *domain)
00040 {
00041 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
00042 if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) ||
00043 (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) {
00044 DEBUG(3,("No such user %s [%s] - using guest account\n",
00045 user, domain));
00046 status = make_server_info_guest(server_info);
00047 }
00048 }
00049
00050 if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) {
00051 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) {
00052 DEBUG(3,("Registered username %s for guest access\n",user));
00053 status = make_server_info_guest(server_info);
00054 }
00055 }
00056
00057 return status;
00058 }
00059
00060
00061
00062
00063
00064 static int add_signature(char *outbuf, char *p)
00065 {
00066 char *start = p;
00067 fstring lanman;
00068
00069 fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING);
00070
00071 p += srvstr_push(outbuf, p, "Unix", BUFFER_SIZE - (p - outbuf), STR_TERMINATE);
00072 p += srvstr_push(outbuf, p, lanman, BUFFER_SIZE - (p - outbuf), STR_TERMINATE);
00073 p += srvstr_push(outbuf, p, lp_workgroup(), BUFFER_SIZE - (p - outbuf), STR_TERMINATE);
00074
00075 return PTR_DIFF(p, start);
00076 }
00077
00078
00079
00080
00081
00082 static void sessionsetup_start_signing_engine(const auth_serversupplied_info *server_info, char *inbuf)
00083 {
00084 if (!server_info->guest && !srv_signing_started()) {
00085
00086
00087
00088
00089
00090
00091 srv_check_sign_mac(inbuf, False);
00092 }
00093 }
00094
00095
00096
00097
00098
00099 static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf,
00100 DATA_BLOB blob, NTSTATUS nt_status)
00101 {
00102 char *p;
00103
00104 if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
00105 ERROR_NT(nt_status_squash(nt_status));
00106 } else {
00107 set_message(outbuf,4,0,True);
00108
00109 nt_status = nt_status_squash(nt_status);
00110 SIVAL(outbuf, smb_rcls, NT_STATUS_V(nt_status));
00111 SSVAL(outbuf, smb_vwv0, 0xFF);
00112 SSVAL(outbuf, smb_vwv3, blob.length);
00113 p = smb_buf(outbuf);
00114
00115
00116 memcpy(p, blob.data, blob.length);
00117 p += blob.length;
00118
00119 p += add_signature( outbuf, p );
00120
00121 set_message_end(outbuf,p);
00122 }
00123
00124 show_msg(outbuf);
00125 return send_smb(smbd_server_fd(),outbuf);
00126 }
00127
00128
00129
00130
00131
00132 static NTSTATUS check_guest_password(auth_serversupplied_info **server_info)
00133 {
00134 struct auth_context *auth_context;
00135 auth_usersupplied_info *user_info = NULL;
00136
00137 NTSTATUS nt_status;
00138 unsigned char chal[8];
00139
00140 ZERO_STRUCT(chal);
00141
00142 DEBUG(3,("Got anonymous request\n"));
00143
00144 if (!NT_STATUS_IS_OK(nt_status = make_auth_context_fixed(&auth_context, chal))) {
00145 return nt_status;
00146 }
00147
00148 if (!make_user_info_guest(&user_info)) {
00149 (auth_context->free)(&auth_context);
00150 return NT_STATUS_NO_MEMORY;
00151 }
00152
00153 nt_status = auth_context->check_ntlm_password(auth_context, user_info, server_info);
00154 (auth_context->free)(&auth_context);
00155 free_user_info(&user_info);
00156 return nt_status;
00157 }
00158
00159
00160 #ifdef HAVE_KRB5
00161
00162 #if 0
00163
00164
00165
00166
00167
00168 static BOOL make_krb5_skew_error(DATA_BLOB *pblob_out)
00169 {
00170 krb5_context context = NULL;
00171 krb5_error_code kerr = 0;
00172 krb5_data reply;
00173 krb5_principal host_princ = NULL;
00174 char *host_princ_s = NULL;
00175 BOOL ret = False;
00176
00177 *pblob_out = data_blob(NULL,0);
00178
00179 initialize_krb5_error_table();
00180 kerr = krb5_init_context(&context);
00181 if (kerr) {
00182 return False;
00183 }
00184
00185 asprintf(&host_princ_s, "%s$@%s", global_myname(), lp_realm());
00186 if (!host_princ_s) {
00187 goto out;
00188 }
00189 strlower_m(host_princ_s);
00190
00191 kerr = smb_krb5_parse_name(context, host_princ_s, &host_princ);
00192 if (kerr) {
00193 DEBUG(10,("make_krb5_skew_error: smb_krb5_parse_name failed for name %s: Error %s\n",
00194 host_princ_s, error_message(kerr) ));
00195 goto out;
00196 }
00197
00198 kerr = smb_krb5_mk_error(context, KRB5KRB_AP_ERR_SKEW, host_princ, &reply);
00199 if (kerr) {
00200 DEBUG(10,("make_krb5_skew_error: smb_krb5_mk_error failed: Error %s\n",
00201 error_message(kerr) ));
00202 goto out;
00203 }
00204
00205 *pblob_out = data_blob(reply.data, reply.length);
00206 kerberos_free_data_contents(context,&reply);
00207 ret = True;
00208
00209 out:
00210
00211 if (host_princ_s) {
00212 SAFE_FREE(host_princ_s);
00213 }
00214 if (host_princ) {
00215 krb5_free_principal(context, host_princ);
00216 }
00217 krb5_free_context(context);
00218 return ret;
00219 }
00220 #endif
00221
00222
00223
00224
00225
00226 static int reply_spnego_kerberos(connection_struct *conn,
00227 char *inbuf, char *outbuf,
00228 int length, int bufsize,
00229 DATA_BLOB *secblob,
00230 BOOL *p_invalidate_vuid)
00231 {
00232 TALLOC_CTX *mem_ctx;
00233 DATA_BLOB ticket;
00234 char *client, *p, *domain;
00235 fstring netbios_domain_name;
00236 struct passwd *pw;
00237 fstring user;
00238 int sess_vuid;
00239 NTSTATUS ret;
00240 PAC_DATA *pac_data;
00241 DATA_BLOB ap_rep, ap_rep_wrapped, response;
00242 auth_serversupplied_info *server_info = NULL;
00243 DATA_BLOB session_key = data_blob(NULL, 0);
00244 uint8 tok_id[2];
00245 DATA_BLOB nullblob = data_blob(NULL, 0);
00246 fstring real_username;
00247 BOOL map_domainuser_to_guest = False;
00248 BOOL username_was_mapped;
00249 PAC_LOGON_INFO *logon_info = NULL;
00250
00251 ZERO_STRUCT(ticket);
00252 ZERO_STRUCT(pac_data);
00253 ZERO_STRUCT(ap_rep);
00254 ZERO_STRUCT(ap_rep_wrapped);
00255 ZERO_STRUCT(response);
00256
00257
00258 *p_invalidate_vuid = True;
00259
00260 mem_ctx = talloc_init("reply_spnego_kerberos");
00261 if (mem_ctx == NULL) {
00262 return ERROR_NT(nt_status_squash(NT_STATUS_NO_MEMORY));
00263 }
00264
00265 if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) {
00266 talloc_destroy(mem_ctx);
00267 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
00268 }
00269
00270 ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket, &client, &pac_data, &ap_rep, &session_key);
00271
00272 data_blob_free(&ticket);
00273
00274 if (!NT_STATUS_IS_OK(ret)) {
00275 #if 0
00276
00277
00278 if (NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 BOOL ok = make_krb5_skew_error(&ap_rep);
00289 if (!ok) {
00290 talloc_destroy(mem_ctx);
00291 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
00292 }
00293 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_ERROR);
00294 response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD);
00295 reply_sesssetup_blob(conn, outbuf, response, NT_STATUS_MORE_PROCESSING_REQUIRED);
00296
00297
00298
00299
00300
00301
00302
00303 *p_invalidate_vuid = False;
00304
00305 data_blob_free(&ap_rep);
00306 data_blob_free(&ap_rep_wrapped);
00307 data_blob_free(&response);
00308 talloc_destroy(mem_ctx);
00309 return -1;
00310 }
00311 #else
00312 if (!NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) {
00313 ret = NT_STATUS_LOGON_FAILURE;
00314 }
00315 #endif
00316 DEBUG(1,("Failed to verify incoming ticket with error %s!\n", nt_errstr(ret)));
00317 talloc_destroy(mem_ctx);
00318 return ERROR_NT(nt_status_squash(ret));
00319 }
00320
00321 DEBUG(3,("Ticket name is [%s]\n", client));
00322
00323 p = strchr_m(client, '@');
00324 if (!p) {
00325 DEBUG(3,("Doesn't look like a valid principal\n"));
00326 data_blob_free(&ap_rep);
00327 data_blob_free(&session_key);
00328 SAFE_FREE(client);
00329 talloc_destroy(mem_ctx);
00330 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
00331 }
00332
00333 *p = 0;
00334
00335
00336
00337 if (pac_data) {
00338 logon_info = get_logon_info_from_pac(pac_data);
00339 if (logon_info) {
00340 netsamlogon_cache_store( client, &logon_info->info3 );
00341 }
00342 }
00343
00344 if (!strequal(p+1, lp_realm())) {
00345 DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1));
00346 if (!lp_allow_trusted_domains()) {
00347 data_blob_free(&ap_rep);
00348 data_blob_free(&session_key);
00349 SAFE_FREE(client);
00350 talloc_destroy(mem_ctx);
00351 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
00352 }
00353 }
00354
00355
00356
00357
00358 domain = p+1;
00359
00360 if (logon_info && logon_info->info3.hdr_logon_dom.uni_str_len) {
00361
00362 unistr2_to_ascii(netbios_domain_name, &logon_info->info3.uni_logon_dom, -1);
00363 domain = netbios_domain_name;
00364 DEBUG(10, ("Mapped to [%s] (using PAC)\n", domain));
00365
00366 } else {
00367
00368
00369
00370
00371
00372
00373
00374
00375 struct winbindd_request wb_request;
00376 struct winbindd_response wb_response;
00377 NSS_STATUS wb_result;
00378
00379 ZERO_STRUCT(wb_request);
00380 ZERO_STRUCT(wb_response);
00381
00382 DEBUG(10, ("Mapping [%s] to short name\n", domain));
00383
00384 fstrcpy(wb_request.domain_name, domain);
00385
00386 wb_result = winbindd_request_response(WINBINDD_DOMAIN_INFO,
00387 &wb_request, &wb_response);
00388
00389 if (wb_result == NSS_STATUS_SUCCESS) {
00390
00391 fstrcpy(netbios_domain_name,
00392 wb_response.data.domain_info.name);
00393 domain = netbios_domain_name;
00394
00395 DEBUG(10, ("Mapped to [%s] (using Winbind)\n", domain));
00396 } else {
00397 DEBUG(3, ("Could not find short name -- winbind "
00398 "not running?\n"));
00399 }
00400 }
00401
00402 fstr_sprintf(user, "%s%c%s", domain, *lp_winbind_separator(), client);
00403
00404
00405
00406 username_was_mapped = map_username( user );
00407
00408 pw = smb_getpwnam( mem_ctx, user, real_username, True );
00409
00410 if (pw) {
00411
00412
00413
00414 ret = smb_pam_accountcheck(pw->pw_name);
00415 if ( !NT_STATUS_IS_OK(ret)) {
00416 DEBUG(1, ("PAM account restriction prevents user login\n"));
00417 data_blob_free(&ap_rep);
00418 data_blob_free(&session_key);
00419 TALLOC_FREE(mem_ctx);
00420 return ERROR_NT(nt_status_squash(ret));
00421 }
00422 }
00423
00424 if (!pw) {
00425
00426
00427
00428
00429
00430 if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID){
00431 map_domainuser_to_guest = True;
00432 fstrcpy(user,lp_guestaccount());
00433 pw = smb_getpwnam( mem_ctx, user, real_username, True );
00434 }
00435
00436
00437
00438 if ( !pw ) {
00439 DEBUG(1,("Username %s is invalid on this system\n", user));
00440 SAFE_FREE(client);
00441 data_blob_free(&ap_rep);
00442 data_blob_free(&session_key);
00443 TALLOC_FREE(mem_ctx);
00444 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
00445 }
00446 }
00447
00448
00449
00450 sub_set_smb_name( real_username );
00451 reload_services(True);
00452
00453 if ( map_domainuser_to_guest ) {
00454 make_server_info_guest(&server_info);
00455 } else if (logon_info) {
00456
00457
00458
00459 ret = make_server_info_info3(mem_ctx, client, domain,
00460 &server_info, &logon_info->info3);
00461 if ( !NT_STATUS_IS_OK(ret) ) {
00462 DEBUG(1,("make_server_info_info3 failed: %s!\n",
00463 nt_errstr(ret)));
00464 SAFE_FREE(client);
00465 data_blob_free(&ap_rep);
00466 data_blob_free(&session_key);
00467 TALLOC_FREE(mem_ctx);
00468 return ERROR_NT(nt_status_squash(ret));
00469 }
00470
00471 } else {
00472 ret = make_server_info_pw(&server_info, real_username, pw);
00473
00474 if ( !NT_STATUS_IS_OK(ret) ) {
00475 DEBUG(1,("make_server_info_pw failed: %s!\n",
00476 nt_errstr(ret)));
00477 SAFE_FREE(client);
00478 data_blob_free(&ap_rep);
00479 data_blob_free(&session_key);
00480 TALLOC_FREE(mem_ctx);
00481 return ERROR_NT(nt_status_squash(ret));
00482 }
00483
00484
00485
00486
00487
00488 if (server_info->sam_account != NULL) {
00489 pdb_set_domain(server_info->sam_account, domain, PDB_SET);
00490 }
00491 }
00492
00493 server_info->was_mapped |= username_was_mapped;
00494
00495
00496
00497
00498 if ( !server_info->ptok ) {
00499 ret = create_local_token( server_info );
00500 if ( !NT_STATUS_IS_OK(ret) ) {
00501 SAFE_FREE(client);
00502 data_blob_free(&ap_rep);
00503 data_blob_free(&session_key);
00504 TALLOC_FREE( mem_ctx );
00505 TALLOC_FREE( server_info );
00506 return ERROR_NT(nt_status_squash(ret));
00507 }
00508 }
00509
00510
00511
00512
00513 sess_vuid = register_vuid(server_info, session_key, nullblob, client);
00514
00515 SAFE_FREE(client);
00516
00517 if (sess_vuid == UID_FIELD_INVALID ) {
00518 ret = NT_STATUS_LOGON_FAILURE;
00519 } else {
00520
00521 reload_services( True );
00522
00523 set_message(outbuf,4,0,True);
00524 SSVAL(outbuf, smb_vwv3, 0);
00525
00526 if (server_info->guest) {
00527 SSVAL(outbuf,smb_vwv2,1);
00528 }
00529
00530 SSVAL(outbuf, smb_uid, sess_vuid);
00531
00532 sessionsetup_start_signing_engine(server_info, inbuf);
00533 }
00534
00535
00536 if (NT_STATUS_IS_OK(ret)) {
00537 ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_AP_REP);
00538 } else {
00539 ap_rep_wrapped = data_blob(NULL, 0);
00540 }
00541 response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD);
00542 reply_sesssetup_blob(conn, outbuf, response, ret);
00543
00544 data_blob_free(&ap_rep);
00545 data_blob_free(&ap_rep_wrapped);
00546 data_blob_free(&response);
00547 TALLOC_FREE(mem_ctx);
00548
00549 return -1;
00550 }
00551 #endif
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *outbuf,
00562 uint16 vuid,
00563 AUTH_NTLMSSP_STATE **auth_ntlmssp_state,
00564 DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status,
00565 BOOL wrap)
00566 {
00567 BOOL ret;
00568 DATA_BLOB response;
00569 struct auth_serversupplied_info *server_info = NULL;
00570
00571 if (NT_STATUS_IS_OK(nt_status)) {
00572 server_info = (*auth_ntlmssp_state)->server_info;
00573 } else {
00574 nt_status = do_map_to_guest(nt_status,
00575 &server_info,
00576 (*auth_ntlmssp_state)->ntlmssp_state->user,
00577 (*auth_ntlmssp_state)->ntlmssp_state->domain);
00578 }
00579
00580 if (NT_STATUS_IS_OK(nt_status)) {
00581 int sess_vuid;
00582 DATA_BLOB nullblob = data_blob(NULL, 0);
00583 DATA_BLOB session_key = data_blob((*auth_ntlmssp_state)->ntlmssp_state->session_key.data, (*auth_ntlmssp_state)->ntlmssp_state->session_key.length);
00584
00585
00586 sess_vuid = register_vuid(server_info, session_key, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user);
00587 (*auth_ntlmssp_state)->server_info = NULL;
00588
00589 if (sess_vuid == UID_FIELD_INVALID ) {
00590 nt_status = NT_STATUS_LOGON_FAILURE;
00591 } else {
00592
00593
00594 reload_services( True );
00595
00596 set_message(outbuf,4,0,True);
00597 SSVAL(outbuf, smb_vwv3, 0);
00598
00599 if (server_info->guest) {
00600 SSVAL(outbuf,smb_vwv2,1);
00601 }
00602
00603 SSVAL(outbuf,smb_uid,sess_vuid);
00604
00605 sessionsetup_start_signing_engine(server_info, inbuf);
00606 }
00607 }
00608
00609 if (wrap) {
00610 response = spnego_gen_auth_response(ntlmssp_blob, nt_status, OID_NTLMSSP);
00611 } else {
00612 response = *ntlmssp_blob;
00613 }
00614
00615 ret = reply_sesssetup_blob(conn, outbuf, response, nt_status);
00616 if (wrap) {
00617 data_blob_free(&response);
00618 }
00619
00620
00621
00622
00623 if (!ret || !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
00624
00625 auth_ntlmssp_end(auth_ntlmssp_state);
00626
00627 invalidate_intermediate_vuid(vuid);
00628 }
00629
00630 return ret;
00631 }
00632
00633
00634
00635
00636
00637 static NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out, BOOL *p_is_krb5)
00638 {
00639 char *OIDs[ASN1_MAX_OIDS];
00640 int i;
00641
00642 *p_is_krb5 = False;
00643
00644
00645 if (!parse_negTokenTarg(blob_in, OIDs, pblob_out)) {
00646 return NT_STATUS_LOGON_FAILURE;
00647 }
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 #ifdef HAVE_KRB5
00660 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 ||
00661 strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
00662 *p_is_krb5 = True;
00663 }
00664 #endif
00665
00666 for (i=0;OIDs[i];i++) {
00667 DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i]));
00668 free(OIDs[i]);
00669 }
00670 return NT_STATUS_OK;
00671 }
00672
00673
00674
00675
00676
00677 static int reply_spnego_negotiate(connection_struct *conn,
00678 char *inbuf,
00679 char *outbuf,
00680 uint16 vuid,
00681 int length, int bufsize,
00682 DATA_BLOB blob1,
00683 AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
00684 {
00685 DATA_BLOB secblob;
00686 DATA_BLOB chal;
00687 BOOL got_kerberos_mechanism = False;
00688 NTSTATUS status;
00689
00690 status = parse_spnego_mechanisms(blob1, &secblob, &got_kerberos_mechanism);
00691 if (!NT_STATUS_IS_OK(status)) {
00692
00693 invalidate_intermediate_vuid(vuid);
00694 return ERROR_NT(nt_status_squash(status));
00695 }
00696
00697 DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n", (unsigned long)secblob.length));
00698
00699 #ifdef HAVE_KRB5
00700 if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) {
00701 BOOL destroy_vuid = True;
00702 int ret = reply_spnego_kerberos(conn, inbuf, outbuf,
00703 length, bufsize, &secblob, &destroy_vuid);
00704 data_blob_free(&secblob);
00705 if (destroy_vuid) {
00706
00707 invalidate_intermediate_vuid(vuid);
00708 }
00709 return ret;
00710 }
00711 #endif
00712
00713 if (got_kerberos_mechanism) {
00714 invalidate_intermediate_vuid(vuid);
00715 DEBUG(3,("reply_spnego_negotiate: network "
00716 "misconfiguration, client sent us a "
00717 "krb5 ticket and kerberos security "
00718 "not enabled"));
00719 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
00720 }
00721
00722 if (*auth_ntlmssp_state) {
00723 auth_ntlmssp_end(auth_ntlmssp_state);
00724 }
00725
00726 status = auth_ntlmssp_start(auth_ntlmssp_state);
00727 if (!NT_STATUS_IS_OK(status)) {
00728
00729 invalidate_intermediate_vuid(vuid);
00730 return ERROR_NT(nt_status_squash(status));
00731 }
00732
00733 status = auth_ntlmssp_update(*auth_ntlmssp_state,
00734 secblob, &chal);
00735
00736 data_blob_free(&secblob);
00737
00738 reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, auth_ntlmssp_state,
00739 &chal, status, True);
00740
00741 data_blob_free(&chal);
00742
00743
00744 return -1;
00745 }
00746
00747
00748
00749
00750
00751 static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
00752 uint16 vuid,
00753 int length, int bufsize,
00754 DATA_BLOB blob1,
00755 AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
00756 {
00757 DATA_BLOB auth = data_blob(NULL,0);
00758 DATA_BLOB auth_reply = data_blob(NULL,0);
00759 DATA_BLOB secblob = data_blob(NULL,0);
00760 NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
00761
00762 if (!spnego_parse_auth(blob1, &auth)) {
00763 #if 0
00764 file_save("auth.dat", blob1.data, blob1.length);
00765 #endif
00766
00767 invalidate_intermediate_vuid(vuid);
00768
00769 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
00770 }
00771
00772 if (auth.data[0] == ASN1_APPLICATION(0)) {
00773
00774
00775 BOOL got_krb5_mechanism = False;
00776 status = parse_spnego_mechanisms(auth, &secblob, &got_krb5_mechanism);
00777 if (NT_STATUS_IS_OK(status)) {
00778 DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n", (unsigned long)secblob.length));
00779 #ifdef HAVE_KRB5
00780 if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) {
00781 BOOL destroy_vuid = True;
00782 int ret = reply_spnego_kerberos(conn, inbuf, outbuf,
00783 length, bufsize, &secblob, &destroy_vuid);
00784 data_blob_free(&secblob);
00785 data_blob_free(&auth);
00786 if (destroy_vuid) {
00787
00788 invalidate_intermediate_vuid(vuid);
00789 }
00790 return ret;
00791 }
00792 #endif
00793 }
00794 }
00795
00796
00797 data_blob_free(&secblob);
00798
00799 if (!*auth_ntlmssp_state) {
00800
00801 invalidate_intermediate_vuid(vuid);
00802
00803
00804 return ERROR_NT(NT_STATUS_LOGON_FAILURE);
00805 }
00806
00807 status = auth_ntlmssp_update(*auth_ntlmssp_state,
00808 auth, &auth_reply);
00809
00810 data_blob_free(&auth);
00811
00812 reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid,
00813 auth_ntlmssp_state,
00814 &auth_reply, status, True);
00815
00816 data_blob_free(&auth_reply);
00817
00818
00819 return -1;
00820 }
00821
00822
00823
00824
00825
00826 static struct pending_auth_data *pd_list;
00827
00828
00829
00830
00831
00832 static void delete_partial_auth(struct pending_auth_data *pad)
00833 {
00834 if (!pad) {
00835 return;
00836 }
00837 DLIST_REMOVE(pd_list, pad);
00838 data_blob_free(&pad->partial_data);
00839 SAFE_FREE(pad);
00840 }
00841
00842
00843
00844
00845
00846 static struct pending_auth_data *get_pending_auth_data(uint16 smbpid)
00847 {
00848 struct pending_auth_data *pad;
00849
00850 for (pad = pd_list; pad; pad = pad->next) {
00851 if (pad->smbpid == smbpid) {
00852 break;
00853 }
00854 }
00855 return pad;
00856 }
00857
00858
00859
00860
00861
00862
00863 static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, DATA_BLOB *pblob)
00864 {
00865 struct pending_auth_data *pad = NULL;
00866 ASN1_DATA data;
00867 size_t needed_len = 0;
00868
00869 pad = get_pending_auth_data(smbpid);
00870
00871
00872 if (pblob->length == 0) {
00873
00874 DEBUG(2,("check_spnego_blob_complete: zero blob length !\n"));
00875 delete_partial_auth(pad);
00876 return NT_STATUS_OK;
00877 }
00878
00879
00880 if (pad) {
00881 DATA_BLOB tmp_blob;
00882 size_t copy_len = MIN(65536, pblob->length);
00883
00884
00885
00886 if (pad->partial_data.length + copy_len < pad->partial_data.length ||
00887 pad->partial_data.length + copy_len < copy_len) {
00888
00889 DEBUG(2,("check_spnego_blob_complete: integer wrap "
00890 "pad->partial_data.length = %u, "
00891 "copy_len = %u\n",
00892 (unsigned int)pad->partial_data.length,
00893 (unsigned int)copy_len ));
00894
00895 delete_partial_auth(pad);
00896 return NT_STATUS_INVALID_PARAMETER;
00897 }
00898
00899 DEBUG(10,("check_spnego_blob_complete: "
00900 "pad->partial_data.length = %u, "
00901 "pad->needed_len = %u, "
00902 "copy_len = %u, "
00903 "pblob->length = %u,\n",
00904 (unsigned int)pad->partial_data.length,
00905 (unsigned int)pad->needed_len,
00906 (unsigned int)copy_len,
00907 (unsigned int)pblob->length ));
00908
00909 tmp_blob = data_blob(NULL,
00910 pad->partial_data.length + copy_len);
00911
00912
00913 memcpy(tmp_blob.data,
00914 pad->partial_data.data,
00915 pad->partial_data.length);
00916 memcpy(tmp_blob.data + pad->partial_data.length,
00917 pblob->data,
00918 copy_len);
00919
00920
00921 data_blob_free(&pad->partial_data);
00922 pad->partial_data = tmp_blob;
00923 ZERO_STRUCT(tmp_blob);
00924
00925
00926 if (pblob->length >= pad->needed_len) {
00927
00928 data_blob_free(pblob);
00929 *pblob = pad->partial_data;
00930 ZERO_STRUCT(pad->partial_data);
00931 delete_partial_auth(pad);
00932 return NT_STATUS_OK;
00933 }
00934
00935
00936 pad->needed_len -= copy_len;
00937 return NT_STATUS_MORE_PROCESSING_REQUIRED;
00938 }
00939
00940 if ((pblob->data[0] != ASN1_APPLICATION(0)) &&
00941 (pblob->data[0] != ASN1_CONTEXT(1))) {
00942
00943
00944
00945 return NT_STATUS_OK;
00946 }
00947
00948
00949
00950
00951
00952 asn1_load(&data, *pblob);
00953 asn1_start_tag(&data, pblob->data[0]);
00954 if (data.has_error || data.nesting == NULL) {
00955 asn1_free(&data);
00956
00957 return NT_STATUS_OK;
00958 }
00959
00960
00961
00962 if (data.nesting->taglen + data.nesting->start < data.nesting->taglen ||
00963 data.nesting->taglen + data.nesting->start < data.nesting->start) {
00964
00965 DEBUG(2,("check_spnego_blob_complete: integer wrap "
00966 "data.nesting->taglen = %u, "
00967 "data.nesting->start = %u\n",
00968 (unsigned int)data.nesting->taglen,
00969 (unsigned int)data.nesting->start ));
00970
00971 asn1_free(&data);
00972 return NT_STATUS_INVALID_PARAMETER;
00973 }
00974
00975
00976
00977
00978 needed_len = data.nesting->taglen + data.nesting->start;
00979 asn1_free(&data);
00980
00981 DEBUG(10,("check_spnego_blob_complete: needed_len = %u, "
00982 "pblob->length = %u\n",
00983 (unsigned int)needed_len,
00984 (unsigned int)pblob->length ));
00985
00986 if (needed_len <= pblob->length) {
00987
00988 return NT_STATUS_OK;
00989 }
00990
00991
00992 if (needed_len > 65536) {
00993 DEBUG(2,("check_spnego_blob_complete: needed_len too large (%u)\n",
00994 (unsigned int)needed_len ));
00995 return NT_STATUS_INVALID_PARAMETER;
00996 }
00997
00998
00999 pad = SMB_MALLOC(sizeof(struct pending_auth_data));
01000 if (!pad) {
01001 return NT_STATUS_NO_MEMORY;
01002 }
01003 pad->needed_len = needed_len - pblob->length;
01004 pad->partial_data = data_blob(pblob->data, pblob->length);
01005 if (pad->partial_data.data == NULL) {
01006 SAFE_FREE(pad);
01007 return NT_STATUS_NO_MEMORY;
01008 }
01009 pad->smbpid = smbpid;
01010 pad->vuid = vuid;
01011 DLIST_ADD(pd_list, pad);
01012
01013 return NT_STATUS_MORE_PROCESSING_REQUIRED;
01014 }
01015
01016
01017
01018
01019
01020
01021 static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,
01022 char *outbuf,
01023 int length,int bufsize)
01024 {
01025 uint8 *p;
01026 DATA_BLOB blob1;
01027 int ret;
01028 size_t bufrem;
01029 fstring native_os, native_lanman, primary_domain;
01030 char *p2;
01031 uint16 data_blob_len = SVAL(inbuf, smb_vwv7);
01032 enum remote_arch_types ra_type = get_remote_arch();
01033 int vuid = SVAL(inbuf,smb_uid);
01034 user_struct *vuser = NULL;
01035 NTSTATUS status = NT_STATUS_OK;
01036 uint16 smbpid = SVAL(inbuf,smb_pid);
01037
01038 DEBUG(3,("Doing spnego session setup\n"));
01039
01040 if (global_client_caps == 0) {
01041 global_client_caps = IVAL(inbuf,smb_vwv10);
01042
01043 if (!(global_client_caps & CAP_STATUS32)) {
01044 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
01045 }
01046
01047 }
01048
01049 p = (uint8 *)smb_buf(inbuf);
01050
01051 if (data_blob_len == 0) {
01052
01053 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
01054 }
01055
01056 bufrem = smb_bufrem(inbuf, p);
01057
01058 blob1 = data_blob(p, MIN(bufrem, data_blob_len));
01059
01060 #if 0
01061 file_save("negotiate.dat", blob1.data, blob1.length);
01062 #endif
01063
01064 p2 = inbuf + smb_vwv13 + data_blob_len;
01065 p2 += srvstr_pull_buf(inbuf, native_os, p2, sizeof(native_os), STR_TERMINATE);
01066 p2 += srvstr_pull_buf(inbuf, native_lanman, p2, sizeof(native_lanman), STR_TERMINATE);
01067 p2 += srvstr_pull_buf(inbuf, primary_domain, p2, sizeof(primary_domain), STR_TERMINATE);
01068 DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
01069 native_os, native_lanman, primary_domain));
01070
01071 if ( ra_type == RA_WIN2K ) {
01072
01073
01074 if ( !strlen(native_os) && !strlen(native_lanman) )
01075 set_remote_arch(RA_VISTA);
01076
01077
01078
01079
01080 if ( !strlen(native_lanman) ) {
01081 ra_lanman_string( primary_domain );
01082 } else {
01083 ra_lanman_string( native_lanman );
01084 }
01085 }
01086
01087 vuser = get_partial_auth_user_struct(vuid);
01088 if (!vuser) {
01089 struct pending_auth_data *pad = get_pending_auth_data(smbpid);
01090 if (pad) {
01091 DEBUG(10,("reply_sesssetup_and_X_spnego: found pending vuid %u\n",
01092 (unsigned int)pad->vuid ));
01093 vuid = pad->vuid;
01094 vuser = get_partial_auth_user_struct(vuid);
01095 }
01096 }
01097
01098 if (!vuser) {
01099 vuid = register_vuid(NULL, data_blob(NULL, 0), data_blob(NULL, 0), NULL);
01100 if (vuid == UID_FIELD_INVALID ) {
01101 data_blob_free(&blob1);
01102 return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER));
01103 }
01104
01105 vuser = get_partial_auth_user_struct(vuid);
01106 }
01107
01108 if (!vuser) {
01109 data_blob_free(&blob1);
01110 return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER));
01111 }
01112
01113 SSVAL(outbuf,smb_uid,vuid);
01114
01115
01116
01117
01118
01119
01120 status = check_spnego_blob_complete(smbpid, vuid, &blob1);
01121 if (!NT_STATUS_IS_OK(status)) {
01122 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
01123
01124 invalidate_intermediate_vuid(vuid);
01125 }
01126 data_blob_free(&blob1);
01127 return ERROR_NT(nt_status_squash(status));
01128 }
01129
01130 if (blob1.data[0] == ASN1_APPLICATION(0)) {
01131
01132 ret = reply_spnego_negotiate(conn, inbuf, outbuf, vuid, length, bufsize, blob1,
01133 &vuser->auth_ntlmssp_state);
01134 data_blob_free(&blob1);
01135 return ret;
01136 }
01137
01138 if (blob1.data[0] == ASN1_CONTEXT(1)) {
01139
01140 ret = reply_spnego_auth(conn, inbuf, outbuf, vuid, length, bufsize, blob1,
01141 &vuser->auth_ntlmssp_state);
01142 data_blob_free(&blob1);
01143 return ret;
01144 }
01145
01146 if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) {
01147 DATA_BLOB chal;
01148 if (!vuser->auth_ntlmssp_state) {
01149 status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state);
01150 if (!NT_STATUS_IS_OK(status)) {
01151
01152 invalidate_intermediate_vuid(vuid);
01153 data_blob_free(&blob1);
01154 return ERROR_NT(nt_status_squash(status));
01155 }
01156 }
01157
01158 status = auth_ntlmssp_update(vuser->auth_ntlmssp_state,
01159 blob1, &chal);
01160
01161 data_blob_free(&blob1);
01162
01163 reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid,
01164 &vuser->auth_ntlmssp_state,
01165 &chal, status, False);
01166 data_blob_free(&chal);
01167 return -1;
01168 }
01169
01170
01171 DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n"));
01172
01173 data_blob_free(&blob1);
01174
01175 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
01176 }
01177
01178
01179
01180
01181
01182
01183
01184 static int shutdown_other_smbds(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
01185 void *p)
01186 {
01187 struct sessionid sessionid;
01188 const char *ip = (const char *)p;
01189
01190 SMB_ASSERT(dbuf.dsize == sizeof(sessionid));
01191 memcpy(&sessionid, dbuf.dptr, sizeof(sessionid));
01192
01193 if (!process_exists(pid_to_procid(sessionid.pid))) {
01194 return 0;
01195 }
01196
01197 if (sessionid.pid == sys_getpid()) {
01198 return 0;
01199 }
01200
01201 if (strcmp(ip, sessionid.ip_addr) != 0) {
01202 return 0;
01203 }
01204
01205 message_send_pid(pid_to_procid(sessionid.pid), MSG_SHUTDOWN,
01206 NULL, 0, True);
01207 return 0;
01208 }
01209
01210 static void setup_new_vc_session(void)
01211 {
01212 DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x compatible we would close all old resources.\n"));
01213 #if 0
01214 conn_close_all();
01215 invalidate_all_vuids();
01216 #endif
01217 if (lp_reset_on_zero_vc()) {
01218 session_traverse(shutdown_other_smbds, client_addr());
01219 }
01220 }
01221
01222
01223
01224
01225
01226 int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
01227 int length,int bufsize)
01228 {
01229 int sess_vuid;
01230 int smb_bufsize;
01231 DATA_BLOB lm_resp;
01232 DATA_BLOB nt_resp;
01233 DATA_BLOB plaintext_password;
01234 fstring user;
01235 fstring sub_user;
01236 fstring domain;
01237 fstring native_os;
01238 fstring native_lanman;
01239 fstring primary_domain;
01240 static BOOL done_sesssetup = False;
01241 auth_usersupplied_info *user_info = NULL;
01242 auth_serversupplied_info *server_info = NULL;
01243
01244 NTSTATUS nt_status;
01245
01246 BOOL doencrypt = global_encrypted_passwords_negotiated;
01247
01248 DATA_BLOB session_key;
01249
01250 START_PROFILE(SMBsesssetupX);
01251
01252 ZERO_STRUCT(lm_resp);
01253 ZERO_STRUCT(nt_resp);
01254 ZERO_STRUCT(plaintext_password);
01255
01256 DEBUG(3,("wct=%d flg2=0x%x\n", CVAL(inbuf, smb_wct), SVAL(inbuf, smb_flg2)));
01257
01258
01259
01260 if (CVAL(inbuf, smb_wct) == 12 &&
01261 (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
01262 if (!global_spnego_negotiated) {
01263 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at SPNEGO session setup when it was not negoitiated.\n"));
01264 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
01265 }
01266
01267 if (SVAL(inbuf,smb_vwv4) == 0) {
01268 setup_new_vc_session();
01269 }
01270 return reply_sesssetup_and_X_spnego(conn, inbuf, outbuf, length, bufsize);
01271 }
01272
01273 smb_bufsize = SVAL(inbuf,smb_vwv2);
01274
01275 if (Protocol < PROTOCOL_NT1) {
01276 uint16 passlen1 = SVAL(inbuf,smb_vwv7);
01277
01278
01279 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
01280
01281 if ((passlen1 > MAX_PASS_LEN) || (passlen1 > smb_bufrem(inbuf, smb_buf(inbuf)))) {
01282 return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER));
01283 }
01284
01285 if (doencrypt) {
01286 lm_resp = data_blob(smb_buf(inbuf), passlen1);
01287 } else {
01288 plaintext_password = data_blob(smb_buf(inbuf), passlen1+1);
01289
01290 plaintext_password.data[passlen1] = 0;
01291 }
01292
01293 srvstr_pull_buf(inbuf, user, smb_buf(inbuf)+passlen1, sizeof(user), STR_TERMINATE);
01294 *domain = 0;
01295
01296 } else {
01297 uint16 passlen1 = SVAL(inbuf,smb_vwv7);
01298 uint16 passlen2 = SVAL(inbuf,smb_vwv8);
01299 enum remote_arch_types ra_type = get_remote_arch();
01300 char *p = smb_buf(inbuf);
01301 char *save_p = smb_buf(inbuf);
01302 uint16 byte_count;
01303
01304
01305 if(global_client_caps == 0) {
01306 global_client_caps = IVAL(inbuf,smb_vwv11);
01307
01308 if (!(global_client_caps & CAP_STATUS32)) {
01309 remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
01310 }
01311
01312
01313
01314
01315
01316
01317 if(ra_type == RA_WINNT || ra_type == RA_WIN2K || ra_type == RA_WIN95) {
01318 if(!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))) {
01319 set_remote_arch( RA_WIN95);
01320 }
01321 }
01322 }
01323
01324 if (!doencrypt) {
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337 if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 && passlen2 != 1)
01338 passlen2 = 0;
01339 }
01340
01341
01342 if (passlen1 > MAX_PASS_LEN || passlen1 > smb_bufrem(inbuf, p)) {
01343 return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER));
01344 }
01345
01346 if (passlen2 > MAX_PASS_LEN || passlen2 > smb_bufrem(inbuf, p+passlen1)) {
01347 return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER));
01348 }
01349
01350
01351
01352 if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) {
01353 doencrypt = False;
01354 }
01355
01356 if (doencrypt) {
01357 lm_resp = data_blob(p, passlen1);
01358 nt_resp = data_blob(p+passlen1, passlen2);
01359 } else {
01360 pstring pass;
01361 BOOL unic=SVAL(inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS;
01362
01363 #if 0
01364
01365 if ((ra_type == RA_WINNT) && (passlen2 == 0) && unic && passlen1) {
01366
01367 srvstr_pull(inbuf, pass, smb_buf(inbuf) + 1,
01368 sizeof(pass), passlen1, STR_TERMINATE);
01369 #endif
01370
01371 if (unic && (passlen2 == 0) && passlen1) {
01372
01373 srvstr_pull(inbuf, pass, smb_buf(inbuf), sizeof(pass),
01374 passlen1, STR_TERMINATE|STR_ASCII);
01375 } else {
01376 srvstr_pull(inbuf, pass, smb_buf(inbuf),
01377 sizeof(pass), unic ? passlen2 : passlen1,
01378 STR_TERMINATE);
01379 }
01380 plaintext_password = data_blob(pass, strlen(pass)+1);
01381 }
01382
01383 p += passlen1 + passlen2;
01384 p += srvstr_pull_buf(inbuf, user, p, sizeof(user), STR_TERMINATE);
01385 p += srvstr_pull_buf(inbuf, domain, p, sizeof(domain), STR_TERMINATE);
01386 p += srvstr_pull_buf(inbuf, native_os, p, sizeof(native_os), STR_TERMINATE);
01387 p += srvstr_pull_buf(inbuf, native_lanman, p, sizeof(native_lanman), STR_TERMINATE);
01388
01389
01390
01391
01392
01393
01394
01395 byte_count = SVAL(inbuf, smb_vwv13);
01396 if ( PTR_DIFF(p, save_p) < byte_count)
01397 p += srvstr_pull_buf(inbuf, primary_domain, p, sizeof(primary_domain), STR_TERMINATE);
01398 else
01399 fstrcpy( primary_domain, "null" );
01400
01401 DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
01402 domain, native_os, native_lanman, primary_domain));
01403
01404 if ( ra_type == RA_WIN2K ) {
01405 if ( strlen(native_lanman) == 0 )
01406 ra_lanman_string( primary_domain );
01407 else
01408 ra_lanman_string( native_lanman );
01409 }
01410
01411 }
01412
01413 if (SVAL(inbuf,smb_vwv4) == 0) {
01414 setup_new_vc_session();
01415 }
01416
01417 DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, get_remote_machine_name()));
01418
01419 if (*user) {
01420 if (global_spnego_negotiated) {
01421
01422
01423
01424 DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at 'normal' session setup after negotiating spnego.\n"));
01425 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
01426 }
01427 fstrcpy(sub_user, user);
01428 } else {
01429 fstrcpy(sub_user, lp_guestaccount());
01430 }
01431
01432 sub_set_smb_name(sub_user);
01433
01434 reload_services(True);
01435
01436 if (lp_security() == SEC_SHARE) {
01437
01438
01439 data_blob_free(&lm_resp);
01440 data_blob_free(&nt_resp);
01441 data_blob_clear_free(&plaintext_password);
01442
01443 map_username(sub_user);
01444 add_session_user(sub_user);
01445 add_session_workgroup(domain);
01446
01447 *user = 0;
01448 }
01449
01450 if (!*user) {
01451
01452 nt_status = check_guest_password(&server_info);
01453
01454 } else if (doencrypt) {
01455 if (!negprot_global_auth_context) {
01456 DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted session setup without negprot denied!\n"));
01457 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
01458 }
01459 nt_status = make_user_info_for_reply_enc(&user_info, user, domain,
01460 lm_resp, nt_resp);
01461 if (NT_STATUS_IS_OK(nt_status)) {
01462 nt_status = negprot_global_auth_context->check_ntlm_password(negprot_global_auth_context,
01463 user_info,
01464 &server_info);
01465 }
01466 } else {
01467 struct auth_context *plaintext_auth_context = NULL;
01468 const uint8 *chal;
01469
01470 nt_status = make_auth_context_subsystem(&plaintext_auth_context);
01471
01472 if (NT_STATUS_IS_OK(nt_status)) {
01473 chal = plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context);
01474
01475 if (!make_user_info_for_reply(&user_info,
01476 user, domain, chal,
01477 plaintext_password)) {
01478 nt_status = NT_STATUS_NO_MEMORY;
01479 }
01480
01481 if (NT_STATUS_IS_OK(nt_status)) {
01482 nt_status = plaintext_auth_context->check_ntlm_password(plaintext_auth_context,
01483 user_info,
01484 &server_info);
01485
01486 (plaintext_auth_context->free)(&plaintext_auth_context);
01487 }
01488 }
01489 }
01490
01491 free_user_info(&user_info);
01492
01493 if (!NT_STATUS_IS_OK(nt_status)) {
01494 nt_status = do_map_to_guest(nt_status, &server_info, user, domain);
01495 }
01496
01497 if (!NT_STATUS_IS_OK(nt_status)) {
01498 data_blob_free(&nt_resp);
01499 data_blob_free(&lm_resp);
01500 data_blob_clear_free(&plaintext_password);
01501 return ERROR_NT(nt_status_squash(nt_status));
01502 }
01503
01504
01505 if (!server_info) {
01506 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
01507 }
01508
01509 if (!server_info->ptok) {
01510 nt_status = create_local_token(server_info);
01511 if (!NT_STATUS_IS_OK(nt_status)) {
01512 DEBUG(10, ("create_local_token failed: %s\n",
01513 nt_errstr(nt_status)));
01514 data_blob_free(&nt_resp);
01515 data_blob_free(&lm_resp);
01516 data_blob_clear_free(&plaintext_password);
01517 return ERROR_NT(nt_status_squash(nt_status));
01518 }
01519 }
01520
01521 if (server_info->user_session_key.data) {
01522 session_key = data_blob(server_info->user_session_key.data, server_info->user_session_key.length);
01523 } else {
01524 session_key = data_blob(NULL, 0);
01525 }
01526
01527 data_blob_clear_free(&plaintext_password);
01528
01529
01530 set_message(outbuf,3,0,True);
01531 if (Protocol >= PROTOCOL_NT1) {
01532 char *p = smb_buf( outbuf );
01533 p += add_signature( outbuf, p );
01534 set_message_end( outbuf, p );
01535
01536 }
01537
01538 if (server_info->guest) {
01539 SSVAL(outbuf,smb_vwv2,1);
01540 }
01541
01542
01543
01544
01545 if (lp_security() == SEC_SHARE) {
01546 sess_vuid = UID_FIELD_INVALID;
01547 data_blob_free(&session_key);
01548 TALLOC_FREE(server_info);
01549 } else {
01550
01551 sess_vuid = register_vuid(server_info, session_key,
01552 nt_resp.data ? nt_resp : lm_resp,
01553 sub_user);
01554 if (sess_vuid == UID_FIELD_INVALID) {
01555 data_blob_free(&nt_resp);
01556 data_blob_free(&lm_resp);
01557 return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE));
01558 }
01559
01560
01561 reload_services( True );
01562
01563 sessionsetup_start_signing_engine(server_info, inbuf);
01564 }
01565
01566 data_blob_free(&nt_resp);
01567 data_blob_free(&lm_resp);
01568
01569 SSVAL(outbuf,smb_uid,sess_vuid);
01570 SSVAL(inbuf,smb_uid,sess_vuid);
01571
01572 if (!done_sesssetup)
01573 max_send = MIN(max_send,smb_bufsize);
01574
01575 done_sesssetup = True;
01576
01577 END_PROFILE(SMBsesssetupX);
01578 return chain_reply(inbuf,outbuf,length,bufsize);
01579 }