Changeset 745 for trunk/server/source3/nmbd/nmbd_processlogon.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/nmbd/nmbd_processlogon.c
r414 r745 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 NBT netbios routines and daemon - version 2 … … 6 6 Copyright (C) Jeremy Allison 1994-2003 7 7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002 8 8 9 9 This program is free software; you can redistribute it and/or modify 10 10 it under the terms of the GNU General Public License as published by 11 11 the Free Software Foundation; either version 3 of the License, or 12 12 (at your option) any later version. 13 13 14 14 This program is distributed in the hope that it will be useful, 15 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 17 GNU General Public License for more details. 18 18 19 19 You should have received a copy of the GNU General Public License 20 20 along with this program. If not, see <http://www.gnu.org/licenses/>. 21 21 22 22 Revision History: 23 23 … … 25 25 26 26 #include "includes.h" 27 #include "../libcli/netlogon .h"27 #include "../libcli/netlogon/netlogon.h" 28 28 #include "../libcli/cldap/cldap.h" 29 29 #include "../lib/tsocket/tsocket.h" 30 #include "../libcli/security/security.h" 31 #include "secrets.h" 32 #include "nmbd/nmbd.h" 30 33 31 34 struct sam_database_info { … … 184 187 185 188 ndr_err = ndr_pull_struct_blob( 186 &blob, state, NULL,&state->req,189 &blob, state, &state->req, 187 190 (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet); 188 191 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 270 273 DATA_BLOB response = data_blob_null; 271 274 272 status = cldap_netlogon_recv(subreq, NULL,state, &state->io);275 status = cldap_netlogon_recv(subreq, state, &state->io); 273 276 if (!NT_STATUS_IS_OK(status)) { 274 277 DEBUG(0,("failed to recv cldap netlogon call: %s\n", … … 278 281 } 279 282 280 status = push_netlogon_samlogon_response(&response, state, NULL,283 status = push_netlogon_samlogon_response(&response, state, 281 284 &state->io.out.netlogon); 282 285 if (!NT_STATUS_IS_OK(status)) { … … 302 305 **************************************************************************/ 303 306 304 void process_logon_packet(struct packet_struct *p, c har *buf,int len,307 void process_logon_packet(struct packet_struct *p, const char *buf,int len, 305 308 const char *mailslot) 306 309 { 310 fstring source_name; 307 311 struct dgram_packet *dgram = &p->packet.dgram; 308 fstring my_name;309 fstring reply_name;310 char outbuf[1024];311 int code;312 uint16 token = 0;313 uint32 ntversion = 0;314 uint16 lmnttoken = 0;315 uint16 lm20token = 0;316 uint32 domainsidsize;317 bool short_request = False;318 char *getdc;319 char *uniuser; /* Unicode user name. */320 fstring ascuser;321 char *unicomp; /* Unicode computer name. */322 size_t size;323 312 struct sockaddr_storage ss; 324 313 const struct sockaddr_storage *pss; 325 314 struct in_addr ip; 315 316 DATA_BLOB blob_in, blob_out; 317 enum ndr_err_code ndr_err; 318 struct nbt_netlogon_packet request; 319 struct nbt_netlogon_response response; 320 NTSTATUS status; 321 const char *pdc_name; 326 322 327 323 in_addr_to_sockaddr_storage(&ss, p->ip); … … 335 331 ip = ((struct sockaddr_in *)pss)->sin_addr; 336 332 337 memset(outbuf, 0, sizeof(outbuf));338 339 333 if (!lp_domain_logons()) { 340 334 DEBUG(5,("process_logon_packet: Logon packet received from IP %s and domain \ … … 343 337 } 344 338 345 fstrcpy(my_name, global_myname()); 346 347 code = get_safe_SVAL(buf,len,buf,0,-1); 348 DEBUG(4,("process_logon_packet: Logon from %s: code = 0x%x\n", inet_ntoa(p->ip), code)); 349 350 switch (code) { 351 case 0: 352 { 353 fstring mach_str, user_str, getdc_str; 354 char *q = buf + 2; 355 char *machine = q; 356 char *user = skip_string(buf,len,machine); 357 358 if (!user || PTR_DIFF(user, buf) >= len) { 359 DEBUG(0,("process_logon_packet: bad packet\n")); 360 return; 361 } 362 getdc = skip_string(buf,len,user); 363 364 if (!getdc || PTR_DIFF(getdc, buf) >= len) { 365 DEBUG(0,("process_logon_packet: bad packet\n")); 366 return; 367 } 368 q = skip_string(buf,len,getdc); 369 370 if (!q || PTR_DIFF(q + 5, buf) > len) { 371 DEBUG(0,("process_logon_packet: bad packet\n")); 372 return; 373 } 374 token = SVAL(q,3); 375 376 fstrcpy(reply_name,my_name); 377 378 pull_ascii_fstring(mach_str, machine); 379 pull_ascii_fstring(user_str, user); 380 pull_ascii_fstring(getdc_str, getdc); 381 382 DEBUG(5,("process_logon_packet: Domain login request from %s at IP %s user=%s token=%x\n", 383 mach_str,inet_ntoa(p->ip),user_str,token)); 384 385 q = outbuf; 386 SSVAL(q, 0, 6); 387 q += 2; 388 389 fstrcpy(reply_name, "\\\\"); 390 fstrcat(reply_name, my_name); 391 size = push_ascii(q,reply_name, 392 sizeof(outbuf)-PTR_DIFF(q, outbuf), 393 STR_TERMINATE); 394 if (size == (size_t)-1) { 395 return; 396 } 397 q = skip_string(outbuf,sizeof(outbuf),q); /* PDC name */ 398 399 SSVAL(q, 0, token); 400 q += 2; 401 402 dump_data(4, (uint8 *)outbuf, PTR_DIFF(q, outbuf)); 403 404 send_mailslot(True, getdc_str, 405 outbuf,PTR_DIFF(q,outbuf), 406 global_myname(), 0x0, 407 mach_str, 408 dgram->source_name.name_type, 409 p->ip, ip, p->port); 410 break; 339 pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name); 340 341 pdc_name = talloc_asprintf(talloc_tos(), "\\\\%s", global_myname()); 342 if (!pdc_name) { 343 return; 344 } 345 346 ZERO_STRUCT(request); 347 348 blob_in = data_blob_const(buf, len); 349 350 ndr_err = ndr_pull_struct_blob(&blob_in, talloc_tos(), &request, 351 (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet); 352 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 353 DEBUG(1,("process_logon_packet: Failed to pull logon packet\n")); 354 return; 355 } 356 357 if (DEBUGLEVEL >= 10) { 358 NDR_PRINT_DEBUG(nbt_netlogon_packet, &request); 359 } 360 361 DEBUG(4,("process_logon_packet: Logon from %s: code = 0x%x\n", 362 inet_ntoa(p->ip), request.command)); 363 364 switch (request.command) { 365 case LOGON_REQUEST: { 366 367 struct nbt_netlogon_response2 response2; 368 369 DEBUG(5,("process_logon_packet: Domain login request from %s at IP %s user=%s token=%x\n", 370 request.req.logon0.computer_name, inet_ntoa(p->ip), 371 request.req.logon0.user_name, 372 request.req.logon0.lm20_token)); 373 374 response2.command = LOGON_RESPONSE2; 375 response2.pdc_name = pdc_name; 376 response2.lm20_token = 0xffff; 377 378 response.response_type = NETLOGON_RESPONSE2; 379 response.data.response2 = response2; 380 381 status = push_nbt_netlogon_response(&blob_out, talloc_tos(), &response); 382 if (!NT_STATUS_IS_OK(status)) { 383 DEBUG(0,("process_logon_packet: failed to push packet\n")); 384 return; 385 } 386 387 if (DEBUGLEVEL >= 10) { 388 NDR_PRINT_DEBUG(nbt_netlogon_response2, &response.data.response2); 389 } 390 391 send_mailslot(True, request.req.logon0.mailslot_name, 392 (char *)blob_out.data, 393 blob_out.length, 394 global_myname(), 0x0, 395 source_name, 396 dgram->source_name.name_type, 397 p->ip, ip, p->port); 398 break; 399 } 400 401 case LOGON_PRIMARY_QUERY: { 402 403 struct nbt_netlogon_response_from_pdc get_pdc; 404 405 if (!lp_domain_master()) { 406 /* We're not Primary Domain Controller -- ignore this */ 407 return; 408 } 409 410 DEBUG(5,("process_logon_packet: GETDC request from %s at IP %s, " 411 "reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", 412 request.req.pdc.computer_name, 413 inet_ntoa(p->ip), 414 global_myname(), 415 lp_workgroup(), 416 NETLOGON_RESPONSE_FROM_PDC, 417 request.req.pdc.nt_version, 418 request.req.pdc.lmnt_token, 419 request.req.pdc.lm20_token)); 420 421 get_pdc.command = NETLOGON_RESPONSE_FROM_PDC; 422 get_pdc.pdc_name = global_myname(); 423 get_pdc._pad = data_blob_null; 424 get_pdc.unicode_pdc_name = global_myname(); 425 get_pdc.domain_name = lp_workgroup(); 426 get_pdc.nt_version = NETLOGON_NT_VERSION_1; 427 get_pdc.lmnt_token = 0xffff; 428 get_pdc.lm20_token = 0xffff; 429 430 response.response_type = NETLOGON_GET_PDC; 431 response.data.get_pdc = get_pdc; 432 433 status = push_nbt_netlogon_response(&blob_out, talloc_tos(), &response); 434 if (!NT_STATUS_IS_OK(status)) { 435 DEBUG(0,("process_logon_packet: failed to push packet\n")); 436 return; 437 } 438 439 if (DEBUGLEVEL >= 10) { 440 NDR_PRINT_DEBUG(nbt_netlogon_response_from_pdc, &response.data.get_pdc); 441 } 442 443 send_mailslot(True, request.req.pdc.mailslot_name, 444 (char *)blob_out.data, 445 blob_out.length, 446 global_myname(), 0x0, 447 source_name, 448 dgram->source_name.name_type, 449 p->ip, ip, p->port); 450 451 return; 452 } 453 454 case LOGON_SAM_LOGON_REQUEST: { 455 char *source_addr; 456 bool user_unknown = false; 457 458 struct netlogon_samlogon_response samlogon; 459 460 if (global_nmbd_proxy_logon) { 461 nmbd_proxy_logon(global_nmbd_proxy_logon, 462 ip, p, (uint8_t *)buf, len); 463 return; 464 } 465 466 source_addr = SMB_STRDUP(inet_ntoa(dgram->header.source_ip)); 467 if (source_addr == NULL) { 468 DEBUG(3, ("out of memory copying client" 469 " address string\n")); 470 return; 471 } 472 473 DEBUG(5,("process_logon_packet: LOGON_SAM_LOGON_REQUEST request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n", 474 request.req.logon.computer_name, 475 inet_ntoa(p->ip), 476 request.req.logon.user_name, 477 pdc_name, 478 lp_workgroup(), 479 LOGON_SAM_LOGON_RESPONSE, 480 request.req.logon.lmnt_token)); 481 482 if (!request.req.logon.user_name) { 483 user_unknown = true; 484 } 485 486 /* we want the simple version unless we are an ADS PDC..which means */ 487 /* never, at least for now */ 488 489 if ((request.req.logon.nt_version < (NETLOGON_NT_VERSION_1 | NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX_WITH_IP)) || 490 (SEC_ADS != lp_security()) || (ROLE_DOMAIN_PDC != lp_server_role())) { 491 492 struct NETLOGON_SAM_LOGON_RESPONSE_NT40 nt4; 493 494 nt4.command = user_unknown ? LOGON_SAM_LOGON_USER_UNKNOWN : 495 LOGON_SAM_LOGON_RESPONSE; 496 nt4.pdc_name = pdc_name; 497 nt4.user_name = request.req.logon.user_name; 498 nt4.domain_name = lp_workgroup(); 499 nt4.nt_version = NETLOGON_NT_VERSION_1; 500 nt4.lmnt_token = 0xffff; 501 nt4.lm20_token = 0xffff; 502 503 samlogon.ntver = NETLOGON_NT_VERSION_1; 504 samlogon.data.nt4 = nt4; 505 506 if (DEBUGLEVEL >= 10) { 507 NDR_PRINT_DEBUG(NETLOGON_SAM_LOGON_RESPONSE_NT40, &nt4); 411 508 } 412 413 case LOGON_PRIMARY_QUERY: 414 { 415 fstring mach_str, getdc_str; 416 fstring source_name; 417 char *q = buf + 2; 418 char *machine = q; 419 420 if (!lp_domain_master()) { 421 /* We're not Primary Domain Controller -- ignore this */ 422 return; 423 } 424 425 getdc = skip_string(buf,len,machine); 426 427 if (!getdc || PTR_DIFF(getdc, buf) >= len) { 428 DEBUG(0,("process_logon_packet: bad packet\n")); 429 return; 430 } 431 q = skip_string(buf,len,getdc); 432 433 if (!q || PTR_DIFF(q, buf) >= len) { 434 DEBUG(0,("process_logon_packet: bad packet\n")); 435 return; 436 } 437 q = ALIGN2(q, buf); 438 439 /* At this point we can work out if this is a W9X or NT style 440 request. Experiments show that the difference is wether the 441 packet ends here. For a W9X request we now end with a pair of 442 bytes (usually 0xFE 0xFF) whereas with NT we have two further 443 strings - the following is a simple way of detecting this */ 444 445 if (len - PTR_DIFF(q, buf) <= 3) { 446 short_request = True; 447 } else { 448 unicomp = q; 449 450 if (PTR_DIFF(q, buf) >= len) { 451 DEBUG(0,("process_logon_packet: bad packet\n")); 452 return; 453 } 454 455 /* A full length (NT style) request */ 456 q = skip_unibuf(unicomp, PTR_DIFF(buf + len, unicomp)); 457 458 if (PTR_DIFF(q, buf) >= len) { 459 DEBUG(0,("process_logon_packet: bad packet\n")); 460 return; 461 } 462 463 if (len - PTR_DIFF(q, buf) > 8) { 464 /* with NT5 clients we can sometimes 465 get additional data - a length specificed string 466 containing the domain name, then 16 bytes of 467 data (no idea what it is) */ 468 int dom_len = CVAL(q, 0); 469 q++; 470 if (dom_len != 0) { 471 q += dom_len + 1; 472 } 473 q += 16; 474 } 475 476 if (PTR_DIFF(q + 8, buf) > len) { 477 DEBUG(0,("process_logon_packet: bad packet\n")); 478 return; 479 } 480 481 ntversion = IVAL(q, 0); 482 lmnttoken = SVAL(q, 4); 483 lm20token = SVAL(q, 6); 484 } 485 486 /* Construct reply. */ 487 q = outbuf; 488 SSVAL(q, 0, NETLOGON_RESPONSE_FROM_PDC); 489 q += 2; 490 491 fstrcpy(reply_name,my_name); 492 size = push_ascii(q, reply_name, 493 sizeof(outbuf)-PTR_DIFF(q, outbuf), 494 STR_TERMINATE); 495 if (size == (size_t)-1) { 496 return; 497 } 498 q = skip_string(outbuf,sizeof(outbuf),q); /* PDC name */ 499 500 /* PDC and domain name */ 501 if (!short_request) { 502 /* Make a full reply */ 503 q = ALIGN2(q, outbuf); 504 505 q += dos_PutUniCode(q, my_name, 506 sizeof(outbuf) - PTR_DIFF(q, outbuf), 507 True); /* PDC name */ 508 q += dos_PutUniCode(q, lp_workgroup(), 509 sizeof(outbuf) - PTR_DIFF(q, outbuf), 510 True); /* Domain name*/ 511 if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 8) { 512 return; 513 } 514 SIVAL(q, 0, 1); /* our nt version */ 515 SSVAL(q, 4, 0xffff); /* our lmnttoken */ 516 SSVAL(q, 6, 0xffff); /* our lm20token */ 517 q += 8; 518 } 519 520 /* RJS, 21-Feb-2000, we send a short reply if the request was short */ 521 522 pull_ascii_fstring(mach_str, machine); 523 524 DEBUG(5,("process_logon_packet: GETDC request from %s at IP %s, \ 525 reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", 526 mach_str,inet_ntoa(p->ip), reply_name, lp_workgroup(), 527 NETLOGON_RESPONSE_FROM_PDC, (uint32)ntversion, (uint32)lmnttoken, 528 (uint32)lm20token )); 529 530 dump_data(4, (uint8 *)outbuf, PTR_DIFF(q, outbuf)); 531 532 pull_ascii_fstring(getdc_str, getdc); 533 pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name); 534 535 send_mailslot(True, getdc_str, 536 outbuf,PTR_DIFF(q,outbuf), 537 global_myname(), 0x0, 538 source_name, 539 dgram->source_name.name_type, 540 p->ip, ip, p->port); 509 } 510 #ifdef HAVE_ADS 511 else { 512 513 struct NETLOGON_SAM_LOGON_RESPONSE_EX nt5_ex; 514 struct GUID domain_guid; 515 struct nbt_sockaddr saddr; 516 char *domain; 517 const char *hostname; 518 519 saddr.sockaddr_family = 2; /* AF_INET */ 520 saddr.pdc_ip = inet_ntoa(ip); 521 saddr.remaining = data_blob_talloc_zero(talloc_tos(), 8); /* ??? */ 522 523 domain = get_mydnsdomname(talloc_tos()); 524 if (!domain) { 525 DEBUG(2,("get_mydnsdomname failed.\n")); 541 526 return; 542 527 } 543 528 544 case LOGON_SAM_LOGON_REQUEST: 545 546 { 547 fstring getdc_str; 548 fstring source_name; 549 char *source_addr; 550 char *q = buf + 2; 551 fstring asccomp; 552 553 if (global_nmbd_proxy_logon) { 554 nmbd_proxy_logon(global_nmbd_proxy_logon, 555 ip, p, (uint8_t *)buf, len); 556 return; 557 } 558 559 q += 2; 560 561 if (PTR_DIFF(q, buf) >= len) { 562 DEBUG(0,("process_logon_packet: bad packet\n")); 563 return; 564 } 565 566 unicomp = q; 567 uniuser = skip_unibuf(unicomp, PTR_DIFF(buf+len, unicomp)); 568 569 if (PTR_DIFF(uniuser, buf) >= len) { 570 DEBUG(0,("process_logon_packet: bad packet\n")); 571 return; 572 } 573 574 getdc = skip_unibuf(uniuser,PTR_DIFF(buf+len, uniuser)); 575 576 if (PTR_DIFF(getdc, buf) >= len) { 577 DEBUG(0,("process_logon_packet: bad packet\n")); 578 return; 579 } 580 581 q = skip_string(buf,len,getdc); 582 583 if (!q || PTR_DIFF(q + 8, buf) >= len) { 584 DEBUG(0,("process_logon_packet: bad packet\n")); 585 return; 586 } 587 588 q += 4; /* Account Control Bits - indicating username type */ 589 domainsidsize = IVAL(q, 0); 590 q += 4; 591 592 DEBUG(5,("process_logon_packet: LOGON_SAM_LOGON_REQUEST sidsize %d, len = %d\n", domainsidsize, len)); 593 594 if (domainsidsize < (len - PTR_DIFF(q, buf)) && (domainsidsize != 0)) { 595 q += domainsidsize; 596 q = ALIGN4(q, buf); 597 } 598 599 DEBUG(5,("process_logon_packet: len = %d PTR_DIFF(q, buf) = %ld\n", len, (unsigned long)PTR_DIFF(q, buf) )); 600 601 if (len - PTR_DIFF(q, buf) > 8) { 602 /* with NT5 clients we can sometimes 603 get additional data - a length specificed string 604 containing the domain name, then 16 bytes of 605 data (no idea what it is) */ 606 int dom_len = CVAL(q, 0); 607 q++; 608 if (dom_len < (len - PTR_DIFF(q, buf)) && (dom_len != 0)) { 609 q += dom_len + 1; 610 } 611 q += 16; 612 } 613 614 if (PTR_DIFF(q + 8, buf) > len) { 615 DEBUG(0,("process_logon_packet: bad packet\n")); 616 return; 617 } 618 619 ntversion = IVAL(q, 0); 620 lmnttoken = SVAL(q, 4); 621 lm20token = SVAL(q, 6); 622 q += 8; 623 624 DEBUG(3,("process_logon_packet: LOGON_SAM_LOGON_REQUEST sidsize %d ntv %d\n", domainsidsize, ntversion)); 625 626 /* 627 * we respond regadless of whether the machine is in our password 628 * database. If it isn't then we let smbd send an appropriate error. 629 * Let's ignore the SID. 630 */ 631 pull_ucs2_fstring(ascuser, uniuser); 632 pull_ucs2_fstring(asccomp, unicomp); 633 DEBUG(5,("process_logon_packet: LOGON_SAM_LOGON_REQUEST user %s\n", ascuser)); 634 635 fstrcpy(reply_name, "\\\\"); /* Here it wants \\LOGONSERVER. */ 636 fstrcat(reply_name, my_name); 637 638 DEBUG(5,("process_logon_packet: LOGON_SAM_LOGON_REQUEST request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n", 639 asccomp,inet_ntoa(p->ip), ascuser, reply_name, lp_workgroup(), 640 LOGON_SAM_LOGON_RESPONSE ,lmnttoken)); 641 642 /* Construct reply. */ 643 644 q = outbuf; 645 /* we want the simple version unless we are an ADS PDC..which means */ 646 /* never, at least for now */ 647 if ((ntversion < 11) || (SEC_ADS != lp_security()) || (ROLE_DOMAIN_PDC != lp_server_role())) { 648 if (SVAL(uniuser, 0) == 0) { 649 SSVAL(q, 0, LOGON_SAM_LOGON_USER_UNKNOWN); /* user unknown */ 650 } else { 651 SSVAL(q, 0, LOGON_SAM_LOGON_RESPONSE); 652 } 653 654 q += 2; 655 656 q += dos_PutUniCode(q, reply_name, 657 sizeof(outbuf) - PTR_DIFF(q, outbuf), 658 True); 659 q += dos_PutUniCode(q, ascuser, 660 sizeof(outbuf) - PTR_DIFF(q, outbuf), 661 True); 662 q += dos_PutUniCode(q, lp_workgroup(), 663 sizeof(outbuf) - PTR_DIFF(q, outbuf), 664 True); 665 } 666 #ifdef HAVE_ADS 667 else { 668 struct GUID domain_guid; 669 UUID_FLAT flat_guid; 670 char *domain; 671 char *hostname; 672 char *component, *dc, *q1; 673 char *q_orig = q; 674 int str_offset; 675 char *saveptr = NULL; 676 677 domain = get_mydnsdomname(talloc_tos()); 678 if (!domain) { 679 DEBUG(2, 680 ("get_mydnsdomname failed.\n")); 681 return; 682 } 683 hostname = get_myname(talloc_tos()); 684 if (!hostname) { 685 DEBUG(2, 686 ("get_myname failed.\n")); 687 return; 688 } 689 690 if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 8) { 691 return; 692 } 693 if (SVAL(uniuser, 0) == 0) { 694 SIVAL(q, 0, LOGON_SAM_LOGON_USER_UNKNOWN_EX); /* user unknown */ 695 } else { 696 SIVAL(q, 0, LOGON_SAM_LOGON_RESPONSE_EX); 697 } 698 q += 4; 699 700 SIVAL(q, 0, NBT_SERVER_PDC|NBT_SERVER_GC|NBT_SERVER_LDAP|NBT_SERVER_DS| 701 NBT_SERVER_KDC|NBT_SERVER_TIMESERV|NBT_SERVER_CLOSEST|NBT_SERVER_WRITABLE); 702 q += 4; 703 704 /* Push Domain GUID */ 705 if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < UUID_FLAT_SIZE) { 706 return; 707 } 708 if (False == secrets_fetch_domain_guid(domain, &domain_guid)) { 709 DEBUG(2, ("Could not fetch DomainGUID for %s\n", domain)); 710 return; 711 } 712 713 smb_uuid_pack(domain_guid, &flat_guid); 714 memcpy(q, &flat_guid.info, UUID_FLAT_SIZE); 715 q += UUID_FLAT_SIZE; 716 717 /* Forest */ 718 str_offset = q - q_orig; 719 dc = domain; 720 q1 = q; 721 while ((component = strtok_r(dc, ".", &saveptr)) != NULL) { 722 dc = NULL; 723 if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 1) { 724 return; 725 } 726 size = push_ascii(&q[1], component, 727 sizeof(outbuf) - PTR_DIFF(q+1, outbuf), 728 0); 729 if (size == (size_t)-1 || size > 0xff) { 730 return; 731 } 732 SCVAL(q, 0, size); 733 q += (size + 1); 734 } 735 736 /* Unk0 */ 737 if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 4) { 738 return; 739 } 740 SCVAL(q, 0, 0); 741 q++; 742 743 /* Domain */ 744 SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F)); 745 SCVAL(q, 1, str_offset & 0xFF); 746 q += 2; 747 748 /* Hostname */ 749 size = push_ascii(&q[1], hostname, 750 sizeof(outbuf) - PTR_DIFF(q+1, outbuf), 751 0); 752 if (size == (size_t)-1 || size > 0xff) { 753 return; 754 } 755 SCVAL(q, 0, size); 756 q += (size + 1); 757 758 if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 3) { 759 return; 760 } 761 762 SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F)); 763 SCVAL(q, 1, str_offset & 0xFF); 764 q += 2; 765 766 /* NETBIOS of domain */ 767 size = push_ascii(&q[1], lp_workgroup(), 768 sizeof(outbuf) - PTR_DIFF(q+1, outbuf), 769 STR_UPPER); 770 if (size == (size_t)-1 || size > 0xff) { 771 return; 772 } 773 SCVAL(q, 0, size); 774 q += (size + 1); 775 776 /* Unk1 */ 777 if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 2) { 778 return; 779 } 780 781 SCVAL(q, 0, 0); 782 q++; 783 784 /* NETBIOS of hostname */ 785 size = push_ascii(&q[1], my_name, 786 sizeof(outbuf) - PTR_DIFF(q+1, outbuf), 787 0); 788 if (size == (size_t)-1 || size > 0xff) { 789 return; 790 } 791 SCVAL(q, 0, size); 792 q += (size + 1); 793 794 /* Unk2 */ 795 if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 4) { 796 return; 797 } 798 799 SCVAL(q, 0, 0); 800 q++; 801 802 /* User name */ 803 if (SVAL(uniuser, 0) != 0) { 804 size = push_ascii(&q[1], ascuser, 805 sizeof(outbuf) - PTR_DIFF(q+1, outbuf), 806 0); 807 if (size == (size_t)-1 || size > 0xff) { 808 return; 809 } 810 SCVAL(q, 0, size); 811 q += (size + 1); 812 } 813 814 q_orig = q; 815 /* Site name */ 816 if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 1) { 817 return; 818 } 819 size = push_ascii(&q[1], "Default-First-Site-Name", 820 sizeof(outbuf) - PTR_DIFF(q+1, outbuf), 821 0); 822 if (size == (size_t)-1 || size > 0xff) { 823 return; 824 } 825 SCVAL(q, 0, size); 826 q += (size + 1); 827 828 if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 18) { 829 return; 830 } 831 832 /* Site name (2) */ 833 str_offset = q - q_orig; 834 SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F)); 835 SCVAL(q, 1, str_offset & 0xFF); 836 q += 2; 837 838 SCVAL(q, 0, PTR_DIFF(q,q1)); 839 SCVAL(q, 1, 0x10); /* unknown */ 840 841 SIVAL(q, 0, 0x00000002); 842 q += 4; /* unknown */ 843 SIVAL(q, 0, ntohl(ip.s_addr)); 844 q += 4; 845 SIVAL(q, 0, 0x00000000); 846 q += 4; /* unknown */ 847 SIVAL(q, 0, 0x00000000); 848 q += 4; /* unknown */ 849 } 850 #endif 851 852 if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 8) { 853 return; 854 } 855 856 /* tell the client what version we are */ 857 SIVAL(q, 0, ((ntversion < 11) || (SEC_ADS != lp_security())) ? 1 : 13); 858 /* our ntversion */ 859 SSVAL(q, 4, 0xffff); /* our lmnttoken */ 860 SSVAL(q, 6, 0xffff); /* our lm20token */ 861 q += 8; 862 863 dump_data(4, (uint8 *)outbuf, PTR_DIFF(q, outbuf)); 864 865 pull_ascii_fstring(getdc_str, getdc); 866 pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name); 867 source_addr = SMB_STRDUP(inet_ntoa(dgram->header.source_ip)); 868 if (source_addr == NULL) { 869 DEBUG(3, ("out of memory copying client" 870 " address string\n")); 871 return; 872 } 873 874 /* 875 * handle delay. 876 * packets requeued after delay are marked as 877 * locked. 878 */ 879 if ((p->locked == False) && 880 (strlen(ascuser) == 0) && 881 delay_logon(source_name, source_addr)) 882 { 883 struct timeval when; 884 885 DEBUG(3, ("process_logon_packet: " 886 "delaying initial logon " 887 "reply for client %s(%s) for " 888 "%u milliseconds\n", 889 source_name, source_addr, 890 lp_init_logon_delay())); 891 892 when = timeval_current_ofs(0, 893 lp_init_logon_delay() * 1000); 894 p->locked = true; 895 event_add_timed(nmbd_event_context(), 896 NULL, 897 when, 898 delayed_init_logon_handler, 899 p); 900 } else { 901 DEBUG(3, ("process_logon_packet: " 902 "processing delayed initial " 903 "logon reply for client " 904 "%s(%s)\n", 905 source_name, source_addr)); 906 907 p->locked = false; 908 send_mailslot(true, getdc, 909 outbuf,PTR_DIFF(q,outbuf), 910 global_myname(), 0x0, 911 source_name, 912 dgram->source_name.name_type, 913 p->ip, ip, p->port); 914 } 915 916 SAFE_FREE(source_addr); 917 918 break; 529 hostname = get_mydnsfullname(); 530 if (!hostname) { 531 DEBUG(2,("get_mydnsfullname failed.\n")); 532 return; 919 533 } 920 534 921 /* Announce change to UAS or SAM. Send by the domain controller when a 922 replication event is required. */ 923 924 case NETLOGON_ANNOUNCE_UAS: 925 DEBUG(5, ("Got NETLOGON_ANNOUNCE_UAS\n")); 926 break; 927 928 default: 929 DEBUG(3,("process_logon_packet: Unknown domain request %d\n",code)); 535 if (!secrets_fetch_domain_guid(domain, &domain_guid)) { 536 DEBUG(2,("Could not fetch DomainGUID for %s\n", domain)); 537 return; 538 } 539 540 nt5_ex.command = user_unknown ? LOGON_SAM_LOGON_USER_UNKNOWN_EX : 541 LOGON_SAM_LOGON_RESPONSE_EX; 542 nt5_ex.sbz = 0; 543 nt5_ex.server_type = NBT_SERVER_PDC | 544 NBT_SERVER_GC | 545 NBT_SERVER_LDAP | 546 NBT_SERVER_DS | 547 NBT_SERVER_KDC | 548 NBT_SERVER_TIMESERV | 549 NBT_SERVER_CLOSEST | 550 NBT_SERVER_WRITABLE; 551 nt5_ex.domain_uuid = domain_guid; 552 nt5_ex.forest = domain; 553 nt5_ex.dns_domain = domain; 554 nt5_ex.pdc_dns_name = hostname; 555 nt5_ex.domain_name = lp_workgroup(); 556 nt5_ex.pdc_name = global_myname(); 557 nt5_ex.user_name = request.req.logon.user_name; 558 nt5_ex.server_site = "Default-First-Site-Name"; 559 nt5_ex.client_site = "Default-First-Site-Name"; 560 nt5_ex.sockaddr_size = 0x10; /* the w32 winsock addr size */ 561 nt5_ex.sockaddr = saddr; 562 nt5_ex.next_closest_site= NULL; 563 nt5_ex.nt_version = NETLOGON_NT_VERSION_1 | 564 NETLOGON_NT_VERSION_5EX | 565 NETLOGON_NT_VERSION_5EX_WITH_IP; 566 nt5_ex.lmnt_token = 0xffff; 567 nt5_ex.lm20_token = 0xffff; 568 569 samlogon.ntver = NETLOGON_NT_VERSION_1 | 570 NETLOGON_NT_VERSION_5EX | 571 NETLOGON_NT_VERSION_5EX_WITH_IP; 572 samlogon.data.nt5_ex = nt5_ex; 573 574 if (DEBUGLEVEL >= 10) { 575 NDR_PRINT_DEBUG(NETLOGON_SAM_LOGON_RESPONSE_EX, &nt5_ex); 576 } 577 } 578 #endif /* HAVE_ADS */ 579 580 response.response_type = NETLOGON_SAMLOGON; 581 response.data.samlogon = samlogon; 582 583 status = push_nbt_netlogon_response(&blob_out, talloc_tos(), &response); 584 if (!NT_STATUS_IS_OK(status)) { 585 DEBUG(0,("process_logon_packet: failed to push packet\n")); 930 586 return; 587 } 588 589 /* 590 * handle delay. 591 * packets requeued after delay are marked as 592 * locked. 593 */ 594 if ((p->locked == False) && 595 (strlen(request.req.logon.user_name) == 0) && 596 delay_logon(source_name, source_addr)) 597 { 598 struct timeval when; 599 600 DEBUG(3, ("process_logon_packet: " 601 "delaying initial logon " 602 "reply for client %s(%s) for " 603 "%u milliseconds\n", 604 source_name, source_addr, 605 lp_init_logon_delay())); 606 607 when = timeval_current_ofs(0, 608 lp_init_logon_delay() * 1000); 609 p->locked = true; 610 event_add_timed(nmbd_event_context(), 611 NULL, 612 when, 613 delayed_init_logon_handler, 614 p); 615 } else { 616 DEBUG(3, ("process_logon_packet: " 617 "processing delayed initial " 618 "logon reply for client " 619 "%s(%s)\n", 620 source_name, source_addr)); 621 p->locked = false; 622 send_mailslot(true, request.req.logon.mailslot_name, 623 (char *)blob_out.data, 624 blob_out.length, 625 global_myname(), 0x0, 626 source_name, 627 dgram->source_name.name_type, 628 p->ip, ip, p->port); 629 } 630 631 SAFE_FREE(source_addr); 632 633 break; 634 } 635 636 /* Announce change to UAS or SAM. Send by the domain controller when a 637 replication event is required. */ 638 639 case NETLOGON_ANNOUNCE_UAS: 640 DEBUG(5, ("Got NETLOGON_ANNOUNCE_UAS\n")); 641 break; 642 643 default: 644 DEBUG(3,("process_logon_packet: Unknown domain request %d\n", 645 request.command)); 646 return; 931 647 } 932 648 }
Note:
See TracChangeset
for help on using the changeset viewer.