Changeset 740 for vendor/current/source3/smbd/negprot.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/smbd/negprot.c
r618 r740 4 4 Copyright (C) Andrew Tridgell 1992-1998 5 5 Copyright (C) Volker Lendecke 2007 6 6 7 7 This program is free software; you can redistribute it and/or modify 8 8 it under the terms of the GNU General Public License as published by 9 9 the Free Software Foundation; either version 3 of the License, or 10 10 (at your option) any later version. 11 11 12 12 This program is distributed in the hope that it will be useful, 13 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 15 GNU General Public License for more details. 16 16 17 17 You should have received a copy of the GNU General Public License 18 18 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 20 20 21 21 #include "includes.h" 22 #include "smbd/smbd.h" 22 23 #include "smbd/globals.h" 23 24 #include "../libcli/auth/spnego.h" 25 #include "serverid.h" 26 #include "auth.h" 27 #include "messages.h" 28 #include "smbprofile.h" 24 29 25 30 extern fstring remote_proto; 26 31 27 static void get_challenge( uint8 buff[8])32 static void get_challenge(struct smbd_server_connection *sconn, uint8 buff[8]) 28 33 { 29 34 NTSTATUS nt_status; 30 struct smbd_server_connection *sconn = smbd_server_conn;31 35 32 36 /* We might be called more than once, multiple negprots are … … 35 39 DEBUG(3, ("get challenge: is this a secondary negprot? " 36 40 "sconn->negprot.auth_context is non-NULL!\n")); 37 sconn->smb1.negprot.auth_context->free( 38 &sconn->smb1.negprot.auth_context); 41 TALLOC_FREE(sconn->smb1.negprot.auth_context); 39 42 } 40 43 41 44 DEBUG(10, ("get challenge: creating negprot_global_auth_context\n")); 42 45 nt_status = make_auth_context_subsystem( 43 &sconn->smb1.negprot.auth_context);46 sconn, &sconn->smb1.negprot.auth_context); 44 47 if (!NT_STATUS_IS_OK(nt_status)) { 45 48 DEBUG(0, ("make_auth_context_subsystem returned %s", … … 93 96 int secword=0; 94 97 time_t t = time(NULL); 95 struct smbd_server_connection *sconn = smbd_server_conn;98 struct smbd_server_connection *sconn = req->sconn; 96 99 97 100 sconn->smb1.negprot.encrypted_passwords = lp_encrypted_passwords(); … … 110 113 /* Create a token value and add it to the outgoing packet. */ 111 114 if (sconn->smb1.negprot.encrypted_passwords) { 112 get_challenge( (uint8 *)smb_buf(req->outbuf));115 get_challenge(sconn, (uint8 *)smb_buf(req->outbuf)); 113 116 SSVAL(req->outbuf,smb_vwv11, 8); 114 117 } … … 140 143 int secword=0; 141 144 time_t t = time(NULL); 142 struct smbd_server_connection *sconn = smbd_server_conn;145 struct smbd_server_connection *sconn = req->sconn; 143 146 144 147 sconn->smb1.negprot.encrypted_passwords = lp_encrypted_passwords(); 145 148 146 149 if (lp_security()>=SEC_USER) { 147 150 secword |= NEGOTIATE_SECURITY_USER_LEVEL; … … 159 162 /* Create a token value and add it to the outgoing packet. */ 160 163 if (sconn->smb1.negprot.encrypted_passwords) { 161 get_challenge( (uint8 *)smb_buf(req->outbuf));164 get_challenge(sconn, (uint8 *)smb_buf(req->outbuf)); 162 165 SSVAL(req->outbuf,smb_vwv11, 8); 163 166 } … … 179 182 ****************************************************************************/ 180 183 181 DATA_BLOB negprot_spnego( void)184 DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbd_server_connection *sconn) 182 185 { 183 DATA_BLOB blob; 186 DATA_BLOB blob = data_blob_null; 187 DATA_BLOB blob_out = data_blob_null; 184 188 nstring dos_name; 185 189 fstring unix_name; … … 187 191 size_t slen; 188 192 #endif 189 char guid[17];190 193 const char *OIDs_krb5[] = {OID_KERBEROS5, 191 194 OID_KERBEROS5_OLD, 192 195 OID_NTLMSSP, 193 196 NULL}; 194 const char *OIDs_plain[] = {OID_NTLMSSP, NULL}; 195 struct smbd_server_connection *sconn = smbd_server_conn; 197 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL}; 196 198 197 199 sconn->smb1.negprot.spnego = true; 198 199 memset(guid, '\0', sizeof(guid));200 201 safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1);202 strlower_m(unix_name);203 push_ascii_nstring(dos_name, unix_name);204 safe_strcpy(guid, dos_name, sizeof(guid)-1);205 206 #ifdef DEVELOPER207 /* Fix valgrind 'uninitialized bytes' issue. */208 slen = strlen(dos_name);209 if (slen < sizeof(guid)) {210 memset(guid+slen, '\0', sizeof(guid) - slen);211 }212 #endif213 214 200 /* strangely enough, NT does not sent the single OID NTLMSSP when 215 201 not a ADS member, it sends no OIDs at all … … 231 217 #else 232 218 /* Code for standalone WXP client */ 233 blob = spnego_gen_negTokenInit( guid, OIDs_plain, "NONE");219 blob = spnego_gen_negTokenInit(ctx, OIDs_ntlm, NULL, "NONE"); 234 220 #endif 221 } else if (!lp_send_spnego_principal()) { 222 /* By default, Windows 2008 and later sends not_defined_in_RFC4178@please_ignore */ 223 blob = spnego_gen_negTokenInit(ctx, OIDs_krb5, NULL, ADS_IGNORE_PRINCIPAL); 235 224 } else { 236 225 fstring myname; … … 242 231 return data_blob_null; 243 232 } 244 blob = spnego_gen_negTokenInit( guid, OIDs_krb5, host_princ_s);233 blob = spnego_gen_negTokenInit(ctx, OIDs_krb5, NULL, host_princ_s); 245 234 SAFE_FREE(host_princ_s); 246 235 } 247 236 248 return blob; 237 if (blob.length == 0 || blob.data == NULL) { 238 return data_blob_null; 239 } 240 241 blob_out = data_blob_talloc(ctx, NULL, 16 + blob.length); 242 if (blob_out.data == NULL) { 243 data_blob_free(&blob); 244 return data_blob_null; 245 } 246 247 memset(blob_out.data, '\0', 16); 248 249 safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1); 250 strlower_m(unix_name); 251 push_ascii_nstring(dos_name, unix_name); 252 strlcpy((char *)blob_out.data, dos_name, 17); 253 254 #ifdef DEVELOPER 255 /* Fix valgrind 'uninitialized bytes' issue. */ 256 slen = strlen(dos_name); 257 if (slen < 16) { 258 memset(blob_out.data+slen, '\0', 16 - slen); 259 } 260 #endif 261 262 memcpy(&blob_out.data[16], blob.data, blob.length); 263 264 data_blob_free(&blob); 265 266 return blob_out; 249 267 } 250 268 … … 260 278 261 279 int secword=0; 262 char *p, *q;263 280 bool negotiate_spnego = False; 264 time_t t = time(NULL);281 struct timespec ts; 265 282 ssize_t ret; 266 struct smbd_server_connection *sconn = smbd_server_conn;283 struct smbd_server_connection *sconn = req->sconn; 267 284 268 285 sconn->smb1.negprot.encrypted_passwords = lp_encrypted_passwords(); … … 284 301 /* do spnego in user level security if the client 285 302 supports it and we can do encrypted passwords */ 286 303 287 304 if (sconn->smb1.negprot.encrypted_passwords && 288 305 (lp_security() != SEC_SHARE) && … … 297 314 req->flags2 | FLAGS2_EXTENDED_SECURITY); 298 315 } 299 316 300 317 capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE; 301 318 … … 303 320 capabilities |= CAP_UNIX; 304 321 } 305 322 306 323 if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64)) 307 324 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS; 308 325 309 326 if (SMB_OFF_T_BITS == 64) 310 327 capabilities |= CAP_LARGE_FILES; … … 312 329 if (lp_readraw() && lp_writeraw()) 313 330 capabilities |= CAP_RAW_MODE; 314 331 315 332 if (lp_nt_status_support()) 316 333 capabilities |= CAP_STATUS32; 317 334 318 335 if (lp_host_msdfs()) 319 336 capabilities |= CAP_DFS; 320 337 321 338 if (lp_security() >= SEC_USER) { 322 339 secword |= NEGOTIATE_SECURITY_USER_LEVEL; … … 333 350 if (lp_server_signing() == Required) 334 351 secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED; 335 srv_set_signing_negotiated(s mbd_server_conn);352 srv_set_signing_negotiated(sconn); 336 353 } else { 337 354 DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n")); … … 344 361 SSVAL(req->outbuf,smb_vwv0,choice); 345 362 SCVAL(req->outbuf,smb_vwv1,secword); 346 363 347 364 set_Protocol(PROTOCOL_NT1); 348 365 349 366 SSVAL(req->outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */ 350 367 SSVAL(req->outbuf,smb_vwv2+1,1); /* num vcs */ … … 354 371 SIVAL(req->outbuf,smb_vwv7+1,sys_getpid()); /* session key */ 355 372 SIVAL(req->outbuf,smb_vwv9+1,capabilities); /* capabilities */ 356 put_long_date((char *)req->outbuf+smb_vwv11+1,t);357 SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(t)/60);358 359 p = q = smb_buf(req->outbuf); 373 clock_gettime(CLOCK_REALTIME,&ts); 374 put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER,(char *)req->outbuf+smb_vwv11+1,ts); 375 SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(ts.tv_sec)/60); 376 360 377 if (!negotiate_spnego) { 361 378 /* Create a token value and add it to the outgoing packet. */ … … 364 381 /* note that we do not send a challenge at all if 365 382 we are using plaintext */ 366 get_challenge( chal);383 get_challenge(sconn, chal); 367 384 ret = message_push_blob( 368 385 &req->outbuf, data_blob_const(chal, sizeof(chal))); … … 373 390 } 374 391 SCVAL(req->outbuf, smb_vwv16+1, ret); 375 p += ret;376 392 } 377 393 ret = message_push_string(&req->outbuf, lp_workgroup(), … … 379 395 |STR_NOALIGN); 380 396 if (ret == -1) { 381 DEBUG(0, ("Could not push challenge\n"));397 DEBUG(0, ("Could not push workgroup string\n")); 382 398 reply_nterror(req, NT_STATUS_NO_MEMORY); 383 399 return; 384 400 } 385 p += ret;386 401 DEBUG(3,("not using SPNEGO\n")); 387 402 } else { 388 DATA_BLOB spnego_blob = negprot_spnego( );403 DATA_BLOB spnego_blob = negprot_spnego(req, req->sconn); 389 404 390 405 if (spnego_blob.data == NULL) { … … 399 414 return; 400 415 } 401 p += ret;402 416 data_blob_free(&spnego_blob); 403 417 … … 405 419 DEBUG(3,("using SPNEGO\n")); 406 420 } 407 408 SSVAL(req->outbuf,smb_vwv17, p - q); /* length of challenge+domain409 * strings */410 421 411 422 return; … … 481 492 * Win2K added by matty 17/7/99 482 493 */ 483 494 484 495 #define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */ 485 496 #define ARCH_WIN95 0x2 … … 490 501 #define ARCH_CIFSFS 0x40 491 502 #define ARCH_VISTA 0x8C /* Vista is like XP/2K */ 492 503 493 504 #define ARCH_ALL 0x7F 494 505 495 506 /* List of supported protocols, most desired first */ 496 507 static const struct { … … 530 541 int i; 531 542 size_t converted_size; 532 struct smbd_server_connection *sconn = smbd_server_conn;543 struct smbd_server_connection *sconn = req->sconn; 533 544 534 545 START_PROFILE(SMBnegprot); … … 661 672 break; 662 673 } 663 674 664 675 /* possibly reload - change of architecture */ 665 reload_services( True);666 676 reload_services(sconn->msg_ctx, sconn->sock, True); 677 667 678 /* moved from the netbios session setup code since we don't have that 668 679 when the client connects to port 445. Of course there is a small 669 680 window where we are listening to messages -- jerry */ 670 681 671 claim_connection( 672 NULL,"",FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL); 673 682 serverid_register(sconn_server_id(sconn), 683 FLAG_MSG_GENERAL|FLAG_MSG_SMBD 684 |FLAG_MSG_PRINT_GENERAL); 685 674 686 /* Check for protocols, most desirable first */ 675 687 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) { … … 685 697 break; 686 698 } 687 699 688 700 if(choice != -1) { 689 701 fstrcpy(remote_proto,supported_protocols[protocol].short_name); 690 reload_services( True);702 reload_services(sconn->msg_ctx, sconn->sock, True); 691 703 supported_protocols[protocol].proto_reply_fn(req, choice); 692 704 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name)); … … 696 708 SSVAL(req->outbuf, smb_vwv0, choice); 697 709 } 698 710 699 711 DEBUG( 5, ( "negprot index=%d\n", choice ) ); 700 712
Note:
See TracChangeset
for help on using the changeset viewer.