Changeset 745 for trunk/server/source3/libsmb/namequery.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/libsmb/namequery.c
r414 r745 20 20 21 21 #include "includes.h" 22 #include "../lib/util/tevent_ntstatus.h" 23 #include "libads/sitename_cache.h" 24 #include "libads/dns.h" 25 #include "../libcli/netlogon/netlogon.h" 26 #include "lib/async_req/async_sock.h" 27 #include "libsmb/nmblib.h" 22 28 23 29 /* nmbd.c sets this to True. */ … … 209 215 ****************************************************************************/ 210 216 211 static NODE_STATUS_STRUCT *parse_node_status(char *p,217 static struct node_status *parse_node_status(TALLOC_CTX *mem_ctx, char *p, 212 218 int *num_names, 213 219 struct node_status_extra *extra) 214 220 { 215 NODE_STATUS_STRUCT*ret;221 struct node_status *ret; 216 222 int i; 217 223 … … 221 227 return NULL; 222 228 223 ret = SMB_MALLOC_ARRAY(NODE_STATUS_STRUCT,*num_names);229 ret = TALLOC_ARRAY(mem_ctx, struct node_status,*num_names); 224 230 if (!ret) 225 231 return NULL; … … 244 250 } 245 251 252 struct sock_packet_read_state { 253 struct tevent_context *ev; 254 enum packet_type type; 255 int trn_id; 256 257 struct nb_packet_reader *reader; 258 struct tevent_req *reader_req; 259 260 int sock; 261 struct tevent_req *socket_req; 262 uint8_t buf[1024]; 263 struct sockaddr_storage addr; 264 socklen_t addr_len; 265 266 bool (*validator)(struct packet_struct *p, 267 void *private_data); 268 void *private_data; 269 270 struct packet_struct *packet; 271 }; 272 273 static int sock_packet_read_state_destructor(struct sock_packet_read_state *s); 274 static void sock_packet_read_got_packet(struct tevent_req *subreq); 275 static void sock_packet_read_got_socket(struct tevent_req *subreq); 276 277 static struct tevent_req *sock_packet_read_send( 278 TALLOC_CTX *mem_ctx, 279 struct tevent_context *ev, 280 int sock, /* dgram socket */ 281 struct nb_packet_reader *reader, 282 enum packet_type type, 283 int trn_id, 284 bool (*validator)(struct packet_struct *p, void *private_data), 285 void *private_data) 286 { 287 struct tevent_req *req; 288 struct sock_packet_read_state *state; 289 290 req = tevent_req_create(mem_ctx, &state, 291 struct sock_packet_read_state); 292 if (req == NULL) { 293 return NULL; 294 } 295 talloc_set_destructor(state, sock_packet_read_state_destructor); 296 state->ev = ev; 297 state->reader = reader; 298 state->sock = sock; 299 state->type = type; 300 state->trn_id = trn_id; 301 state->validator = validator; 302 state->private_data = private_data; 303 304 if (reader != NULL) { 305 state->reader_req = nb_packet_read_send(state, ev, reader); 306 if (tevent_req_nomem(state->reader_req, req)) { 307 return tevent_req_post(req, ev); 308 } 309 tevent_req_set_callback( 310 state->reader_req, sock_packet_read_got_packet, req); 311 } 312 313 state->addr_len = sizeof(state->addr); 314 state->socket_req = recvfrom_send(state, ev, sock, 315 state->buf, sizeof(state->buf), 0, 316 &state->addr, &state->addr_len); 317 if (tevent_req_nomem(state->socket_req, req)) { 318 return tevent_req_post(req, ev); 319 } 320 tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket, 321 req); 322 323 return req; 324 } 325 326 static int sock_packet_read_state_destructor(struct sock_packet_read_state *s) 327 { 328 if (s->packet != NULL) { 329 free_packet(s->packet); 330 s->packet = NULL; 331 } 332 return 0; 333 } 334 335 static void sock_packet_read_got_packet(struct tevent_req *subreq) 336 { 337 struct tevent_req *req = tevent_req_callback_data( 338 subreq, struct tevent_req); 339 struct sock_packet_read_state *state = tevent_req_data( 340 req, struct sock_packet_read_state); 341 NTSTATUS status; 342 343 status = nb_packet_read_recv(subreq, &state->packet); 344 345 TALLOC_FREE(state->reader_req); 346 347 if (!NT_STATUS_IS_OK(status)) { 348 if (state->socket_req != NULL) { 349 /* 350 * Still waiting for socket 351 */ 352 return; 353 } 354 /* 355 * Both socket and packet reader failed 356 */ 357 tevent_req_nterror(req, status); 358 return; 359 } 360 361 if ((state->validator != NULL) && 362 !state->validator(state->packet, state->private_data)) { 363 DEBUG(10, ("validator failed\n")); 364 365 free_packet(state->packet); 366 state->packet = NULL; 367 368 state->reader_req = nb_packet_read_send(state, state->ev, 369 state->reader); 370 if (tevent_req_nomem(state->reader_req, req)) { 371 return; 372 } 373 tevent_req_set_callback( 374 state->reader_req, sock_packet_read_got_packet, req); 375 return; 376 } 377 378 TALLOC_FREE(state->socket_req); 379 tevent_req_done(req); 380 } 381 382 static void sock_packet_read_got_socket(struct tevent_req *subreq) 383 { 384 struct tevent_req *req = tevent_req_callback_data( 385 subreq, struct tevent_req); 386 struct sock_packet_read_state *state = tevent_req_data( 387 req, struct sock_packet_read_state); 388 struct sockaddr_in *in_addr; 389 ssize_t received; 390 int err; 391 392 received = recvfrom_recv(subreq, &err); 393 394 TALLOC_FREE(state->socket_req); 395 396 if (received == -1) { 397 if (state->reader_req != NULL) { 398 /* 399 * Still waiting for reader 400 */ 401 return; 402 } 403 /* 404 * Both socket and reader failed 405 */ 406 tevent_req_nterror(req, map_nt_error_from_unix(err)); 407 return; 408 } 409 if (state->addr.ss_family != AF_INET) { 410 goto retry; 411 } 412 in_addr = (struct sockaddr_in *)(void *)&state->addr; 413 414 state->packet = parse_packet((char *)state->buf, received, state->type, 415 in_addr->sin_addr, in_addr->sin_port); 416 if (state->packet == NULL) { 417 DEBUG(10, ("parse_packet failed\n")); 418 goto retry; 419 } 420 if ((state->trn_id != -1) && 421 (state->trn_id != packet_trn_id(state->packet))) { 422 DEBUG(10, ("Expected transaction id %d, got %d\n", 423 state->trn_id, packet_trn_id(state->packet))); 424 goto retry; 425 } 426 427 if ((state->validator != NULL) && 428 !state->validator(state->packet, state->private_data)) { 429 DEBUG(10, ("validator failed\n")); 430 goto retry; 431 } 432 433 tevent_req_done(req); 434 return; 435 436 retry: 437 if (state->packet != NULL) { 438 free_packet(state->packet); 439 state->packet = NULL; 440 } 441 state->socket_req = recvfrom_send(state, state->ev, state->sock, 442 state->buf, sizeof(state->buf), 0, 443 &state->addr, &state->addr_len); 444 if (tevent_req_nomem(state->socket_req, req)) { 445 return; 446 } 447 tevent_req_set_callback(state->socket_req, sock_packet_read_got_socket, 448 req); 449 } 450 451 static NTSTATUS sock_packet_read_recv(struct tevent_req *req, 452 struct packet_struct **ppacket) 453 { 454 struct sock_packet_read_state *state = tevent_req_data( 455 req, struct sock_packet_read_state); 456 NTSTATUS status; 457 458 if (tevent_req_is_nterror(req, &status)) { 459 return status; 460 } 461 *ppacket = state->packet; 462 state->packet = NULL; 463 return NT_STATUS_OK; 464 } 465 466 struct nb_trans_state { 467 struct tevent_context *ev; 468 int sock; 469 struct nb_packet_reader *reader; 470 471 const struct sockaddr_storage *dst_addr; 472 uint8_t *buf; 473 size_t buflen; 474 enum packet_type type; 475 int trn_id; 476 477 bool (*validator)(struct packet_struct *p, 478 void *private_data); 479 void *private_data; 480 481 struct packet_struct *packet; 482 }; 483 484 static int nb_trans_state_destructor(struct nb_trans_state *s); 485 static void nb_trans_got_reader(struct tevent_req *subreq); 486 static void nb_trans_done(struct tevent_req *subreq); 487 static void nb_trans_sent(struct tevent_req *subreq); 488 static void nb_trans_send_next(struct tevent_req *subreq); 489 490 static struct tevent_req *nb_trans_send( 491 TALLOC_CTX *mem_ctx, 492 struct tevent_context *ev, 493 const struct sockaddr_storage *my_addr, 494 const struct sockaddr_storage *dst_addr, 495 bool bcast, 496 uint8_t *buf, size_t buflen, 497 enum packet_type type, int trn_id, 498 bool (*validator)(struct packet_struct *p, 499 void *private_data), 500 void *private_data) 501 { 502 struct tevent_req *req, *subreq; 503 struct nb_trans_state *state; 504 505 req = tevent_req_create(mem_ctx, &state, struct nb_trans_state); 506 if (req == NULL) { 507 return NULL; 508 } 509 talloc_set_destructor(state, nb_trans_state_destructor); 510 state->ev = ev; 511 state->dst_addr = dst_addr; 512 state->buf = buf; 513 state->buflen = buflen; 514 state->type = type; 515 state->trn_id = trn_id; 516 state->validator = validator; 517 state->private_data = private_data; 518 519 state->sock = open_socket_in(SOCK_DGRAM, 0, 3, my_addr, True); 520 if (state->sock == -1) { 521 tevent_req_nterror(req, map_nt_error_from_unix(errno)); 522 DEBUG(10, ("open_socket_in failed: %s\n", strerror(errno))); 523 return tevent_req_post(req, ev); 524 } 525 526 if (bcast) { 527 set_socket_options(state->sock,"SO_BROADCAST"); 528 } 529 530 subreq = nb_packet_reader_send(state, ev, type, state->trn_id, NULL); 531 if (tevent_req_nomem(subreq, req)) { 532 return tevent_req_post(req, ev); 533 } 534 tevent_req_set_callback(subreq, nb_trans_got_reader, req); 535 return req; 536 } 537 538 static int nb_trans_state_destructor(struct nb_trans_state *s) 539 { 540 if (s->sock != -1) { 541 close(s->sock); 542 s->sock = -1; 543 } 544 if (s->packet != NULL) { 545 free_packet(s->packet); 546 s->packet = NULL; 547 } 548 return 0; 549 } 550 551 static void nb_trans_got_reader(struct tevent_req *subreq) 552 { 553 struct tevent_req *req = tevent_req_callback_data( 554 subreq, struct tevent_req); 555 struct nb_trans_state *state = tevent_req_data( 556 req, struct nb_trans_state); 557 NTSTATUS status; 558 559 status = nb_packet_reader_recv(subreq, state, &state->reader); 560 TALLOC_FREE(subreq); 561 562 if (!NT_STATUS_IS_OK(status)) { 563 DEBUG(10, ("nmbd not around\n")); 564 state->reader = NULL; 565 } 566 567 subreq = sock_packet_read_send( 568 state, state->ev, state->sock, 569 state->reader, state->type, state->trn_id, 570 state->validator, state->private_data); 571 if (tevent_req_nomem(subreq, req)) { 572 return; 573 } 574 tevent_req_set_callback(subreq, nb_trans_done, req); 575 576 subreq = sendto_send(state, state->ev, state->sock, 577 state->buf, state->buflen, 0, state->dst_addr); 578 if (tevent_req_nomem(subreq, req)) { 579 return; 580 } 581 tevent_req_set_callback(subreq, nb_trans_sent, req); 582 } 583 584 static void nb_trans_sent(struct tevent_req *subreq) 585 { 586 struct tevent_req *req = tevent_req_callback_data( 587 subreq, struct tevent_req); 588 struct nb_trans_state *state = tevent_req_data( 589 req, struct nb_trans_state); 590 ssize_t sent; 591 int err; 592 593 sent = sendto_recv(subreq, &err); 594 TALLOC_FREE(subreq); 595 if (sent == -1) { 596 DEBUG(10, ("sendto failed: %s\n", strerror(err))); 597 tevent_req_nterror(req, map_nt_error_from_unix(err)); 598 return; 599 } 600 subreq = tevent_wakeup_send(state, state->ev, 601 timeval_current_ofs(1, 0)); 602 if (tevent_req_nomem(subreq, req)) { 603 return; 604 } 605 tevent_req_set_callback(subreq, nb_trans_send_next, req); 606 } 607 608 static void nb_trans_send_next(struct tevent_req *subreq) 609 { 610 struct tevent_req *req = tevent_req_callback_data( 611 subreq, struct tevent_req); 612 struct nb_trans_state *state = tevent_req_data( 613 req, struct nb_trans_state); 614 bool ret; 615 616 ret = tevent_wakeup_recv(subreq); 617 TALLOC_FREE(subreq); 618 if (!ret) { 619 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); 620 return; 621 } 622 subreq = sendto_send(state, state->ev, state->sock, 623 state->buf, state->buflen, 0, state->dst_addr); 624 if (tevent_req_nomem(subreq, req)) { 625 return; 626 } 627 tevent_req_set_callback(subreq, nb_trans_sent, req); 628 } 629 630 static void nb_trans_done(struct tevent_req *subreq) 631 { 632 struct tevent_req *req = tevent_req_callback_data( 633 subreq, struct tevent_req); 634 struct nb_trans_state *state = tevent_req_data( 635 req, struct nb_trans_state); 636 NTSTATUS status; 637 638 status = sock_packet_read_recv(subreq, &state->packet); 639 TALLOC_FREE(subreq); 640 if (tevent_req_nterror(req, status)) { 641 return; 642 } 643 tevent_req_done(req); 644 } 645 646 static NTSTATUS nb_trans_recv(struct tevent_req *req, 647 struct packet_struct **ppacket) 648 { 649 struct nb_trans_state *state = tevent_req_data( 650 req, struct nb_trans_state); 651 NTSTATUS status; 652 653 if (tevent_req_is_nterror(req, &status)) { 654 return status; 655 } 656 *ppacket = state->packet; 657 state->packet = NULL; 658 return NT_STATUS_OK; 659 } 246 660 247 661 /**************************************************************************** … … 250 664 **************************************************************************/ 251 665 252 NODE_STATUS_STRUCT *node_status_query(int fd, 253 struct nmb_name *name, 254 const struct sockaddr_storage *to_ss, 255 int *num_names, 256 struct node_status_extra *extra) 257 { 258 bool found=False; 259 int retries = 2; 260 int retry_time = 2000; 261 struct timeval tval; 666 struct node_status_query_state { 667 struct sockaddr_storage my_addr; 668 struct sockaddr_storage addr; 669 uint8_t buf[1024]; 670 ssize_t buflen; 671 struct packet_struct *packet; 672 }; 673 674 static int node_status_query_state_destructor( 675 struct node_status_query_state *s); 676 static bool node_status_query_validator(struct packet_struct *p, 677 void *private_data); 678 static void node_status_query_done(struct tevent_req *subreq); 679 680 struct tevent_req *node_status_query_send(TALLOC_CTX *mem_ctx, 681 struct tevent_context *ev, 682 struct nmb_name *name, 683 const struct sockaddr_storage *addr) 684 { 685 struct tevent_req *req, *subreq; 686 struct node_status_query_state *state; 262 687 struct packet_struct p; 263 struct packet_struct *p2;264 688 struct nmb_packet *nmb = &p.packet.nmb; 265 NODE_STATUS_STRUCT *ret; 689 struct sockaddr_in *in_addr; 690 691 req = tevent_req_create(mem_ctx, &state, 692 struct node_status_query_state); 693 if (req == NULL) { 694 return NULL; 695 } 696 talloc_set_destructor(state, node_status_query_state_destructor); 697 698 if (addr->ss_family != AF_INET) { 699 /* Can't do node status to IPv6 */ 700 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS); 701 return tevent_req_post(req, ev); 702 } 703 704 state->addr = *addr; 705 in_addr = (struct sockaddr_in *)(void *)&state->addr; 706 in_addr->sin_port = htons(NMB_PORT); 707 708 if (!interpret_string_addr(&state->my_addr, lp_socket_address(), 709 AI_NUMERICHOST|AI_PASSIVE)) { 710 zero_sockaddr(&state->my_addr); 711 } 266 712 267 713 ZERO_STRUCT(p); 268 269 if (to_ss->ss_family != AF_INET) {270 /* Can't do node status to IPv6 */271 return NULL;272 }273 714 nmb->header.name_trn_id = generate_trn_id(); 274 715 nmb->header.opcode = 0; … … 288 729 nmb->question.question_class = 0x1; 289 730 290 p.ip = ((const struct sockaddr_in *)to_ss)->sin_addr; 291 p.port = NMB_PORT; 292 p.recv_fd = -1; 293 p.send_fd = fd; 294 p.timestamp = time(NULL); 295 p.packet_type = NMB_PACKET; 296 297 GetTimeOfDay(&tval); 298 299 if (!send_packet(&p)) 300 return NULL; 301 302 retries--; 303 304 while (1) { 305 struct timeval tval2; 306 GetTimeOfDay(&tval2); 307 if (TvalDiff(&tval,&tval2) > retry_time) { 308 if (!retries) 309 break; 310 if (!found && !send_packet(&p)) 311 return NULL; 312 GetTimeOfDay(&tval); 313 retries--; 314 } 315 316 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { 317 struct nmb_packet *nmb2 = &p2->packet.nmb; 318 debug_nmb_packet(p2); 319 320 if (nmb2->header.opcode != 0 || 321 nmb2->header.nm_flags.bcast || 322 nmb2->header.rcode || 323 !nmb2->header.ancount || 324 nmb2->answers->rr_type != 0x21) { 325 /* XXXX what do we do with this? could be a 326 redirect, but we'll discard it for the 327 moment */ 328 free_packet(p2); 329 continue; 330 } 331 332 ret = parse_node_status(&nmb2->answers->rdata[0], 333 num_names, extra); 334 free_packet(p2); 335 return ret; 336 } 337 } 338 339 return NULL; 731 state->buflen = build_packet((char *)state->buf, sizeof(state->buf), 732 &p); 733 if (state->buflen == 0) { 734 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); 735 DEBUG(10, ("build_packet failed\n")); 736 return tevent_req_post(req, ev); 737 } 738 739 subreq = nb_trans_send(state, ev, &state->my_addr, &state->addr, false, 740 state->buf, state->buflen, 741 NMB_PACKET, nmb->header.name_trn_id, 742 node_status_query_validator, NULL); 743 if (tevent_req_nomem(subreq, req)) { 744 DEBUG(10, ("nb_trans_send failed\n")); 745 return tevent_req_post(req, ev); 746 } 747 if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(10, 0))) { 748 return tevent_req_post(req, ev); 749 } 750 tevent_req_set_callback(subreq, node_status_query_done, req); 751 return req; 752 } 753 754 static bool node_status_query_validator(struct packet_struct *p, 755 void *private_data) 756 { 757 struct nmb_packet *nmb = &p->packet.nmb; 758 debug_nmb_packet(p); 759 760 if (nmb->header.opcode != 0 || 761 nmb->header.nm_flags.bcast || 762 nmb->header.rcode || 763 !nmb->header.ancount || 764 nmb->answers->rr_type != 0x21) { 765 /* 766 * XXXX what do we do with this? could be a redirect, 767 * but we'll discard it for the moment 768 */ 769 return false; 770 } 771 return true; 772 } 773 774 static int node_status_query_state_destructor( 775 struct node_status_query_state *s) 776 { 777 if (s->packet != NULL) { 778 free_packet(s->packet); 779 s->packet = NULL; 780 } 781 return 0; 782 } 783 784 static void node_status_query_done(struct tevent_req *subreq) 785 { 786 struct tevent_req *req = tevent_req_callback_data( 787 subreq, struct tevent_req); 788 struct node_status_query_state *state = tevent_req_data( 789 req, struct node_status_query_state); 790 NTSTATUS status; 791 792 status = nb_trans_recv(subreq, &state->packet); 793 TALLOC_FREE(subreq); 794 if (tevent_req_nterror(req, status)) { 795 return; 796 } 797 tevent_req_done(req); 798 } 799 800 NTSTATUS node_status_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 801 struct node_status **pnode_status, 802 int *pnum_names, 803 struct node_status_extra *extra) 804 { 805 struct node_status_query_state *state = tevent_req_data( 806 req, struct node_status_query_state); 807 struct node_status *node_status; 808 int num_names; 809 NTSTATUS status; 810 811 if (tevent_req_is_nterror(req, &status)) { 812 return status; 813 } 814 node_status = parse_node_status( 815 mem_ctx, &state->packet->packet.nmb.answers->rdata[0], 816 &num_names, extra); 817 if (node_status == NULL) { 818 return NT_STATUS_NO_MEMORY; 819 } 820 *pnode_status = node_status; 821 *pnum_names = num_names; 822 return NT_STATUS_OK; 823 } 824 825 NTSTATUS node_status_query(TALLOC_CTX *mem_ctx, struct nmb_name *name, 826 const struct sockaddr_storage *addr, 827 struct node_status **pnode_status, 828 int *pnum_names, 829 struct node_status_extra *extra) 830 { 831 TALLOC_CTX *frame = talloc_stackframe(); 832 struct tevent_context *ev; 833 struct tevent_req *req; 834 NTSTATUS status = NT_STATUS_NO_MEMORY; 835 836 ev = tevent_context_init(frame); 837 if (ev == NULL) { 838 goto fail; 839 } 840 req = node_status_query_send(ev, ev, name, addr); 841 if (req == NULL) { 842 goto fail; 843 } 844 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 845 goto fail; 846 } 847 status = node_status_query_recv(req, mem_ctx, pnode_status, 848 pnum_names, extra); 849 fail: 850 TALLOC_FREE(frame); 851 return status; 340 852 } 341 853 … … 353 865 char addr[INET6_ADDRSTRLEN]; 354 866 struct sockaddr_storage ss; 355 NODE_STATUS_STRUCT *status = NULL;867 struct node_status *addrs = NULL; 356 868 struct nmb_name nname; 357 869 int count, i; 358 int sock;359 870 bool result = false; 871 NTSTATUS status; 360 872 361 873 if (lp_disable_netbios()) { … … 386 898 } 387 899 388 sock = open_socket_in(SOCK_DGRAM, 0, 3, &ss, True);389 if (sock == -1)390 goto done;391 392 900 /* W2K PDC's seem not to respond to '*'#0. JRA */ 393 901 make_nmb_name(&nname, q_name, q_type); 394 status = node_status_query( sock, &nname, to_ss, &count, NULL);395 close(sock);396 if (! status)902 status = node_status_query(talloc_tos(), &nname, to_ss, 903 &addrs, &count, NULL); 904 if (!NT_STATUS_IS_OK(status)) { 397 905 goto done; 906 } 398 907 399 908 for (i=0;i<count;i++) { 400 909 /* Find first one of the requested type that's not a GROUP. */ 401 if ( status[i].type == type && ! (status[i].flags & 0x80))910 if (addrs[i].type == type && ! (addrs[i].flags & 0x80)) 402 911 break; 403 912 } … … 405 914 goto done; 406 915 407 pull_ascii_nstring(name, sizeof(fstring), status[i].name);916 pull_ascii_nstring(name, sizeof(fstring), addrs[i].name); 408 917 409 918 /* Store the result in the cache. */ … … 418 927 419 928 done: 420 SAFE_FREE(status);929 TALLOC_FREE(addrs); 421 930 422 931 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not ")); … … 434 943 */ 435 944 436 static int addr_compare(const struct sockaddr *ss1,437 const struct sockaddr*ss2)945 static int addr_compare(const struct sockaddr_storage *ss1, 946 const struct sockaddr_storage *ss2) 438 947 { 439 948 int max_bits1=0, max_bits2=0; … … 442 951 443 952 /* Sort IPv4 addresses first. */ 444 if (ss1->s a_family != ss2->sa_family) {445 if (ss2->s a_family == AF_INET) {953 if (ss1->ss_family != ss2->ss_family) { 954 if (ss2->ss_family == AF_INET) { 446 955 return 1; 447 956 } else { … … 461 970 int bits1, bits2; 462 971 463 if (pss->ss_family != ss1->s a_family) {972 if (pss->ss_family != ss1->ss_family) { 464 973 /* Ignore interfaces of the wrong type. */ 465 974 continue; … … 495 1004 496 1005 /* Bias towards directly reachable IPs */ 497 if (iface_local( ss1)) {498 if (ss1->s a_family == AF_INET) {1006 if (iface_local((struct sockaddr *)ss1)) { 1007 if (ss1->ss_family == AF_INET) { 499 1008 max_bits1 += 32; 500 1009 } else { … … 502 1011 } 503 1012 } 504 if (iface_local( ss2)) {505 if (ss2->s a_family == AF_INET) {1013 if (iface_local((struct sockaddr *)ss2)) { 1014 if (ss2->ss_family == AF_INET) { 506 1015 max_bits2 += 32; 507 1016 } else { … … 520 1029 int result; 521 1030 522 if ((result = addr_compare( (struct sockaddr *)&ss1->ss, (struct sockaddr *)&ss2->ss)) != 0) {1031 if ((result = addr_compare(&ss1->ss, &ss2->ss)) != 0) { 523 1032 return result; 524 1033 } … … 547 1056 } 548 1057 549 qsort(sslist, count, sizeof(struct sockaddr_storage), 550 QSORT_CAST addr_compare); 1058 TYPESAFE_QSORT(sslist, count, addr_compare); 551 1059 } 552 1060 … … 557 1065 } 558 1066 559 qsort(servlist, count, sizeof(struct ip_service), 560 QSORT_CAST ip_service_compare); 1067 TYPESAFE_QSORT(servlist, count, ip_service_compare); 561 1068 } 562 1069 … … 574 1081 /* one loop to remove duplicates */ 575 1082 for ( i=0; i<count; i++ ) { 576 if ( is_zero_addr( (struct sockaddr *)&iplist[i].ss)) {1083 if ( is_zero_addr(&iplist[i].ss)) { 577 1084 continue; 578 1085 } … … 589 1096 /* first ip should never be a zero_ip() */ 590 1097 for (i = 0; i<count; ) { 591 if (is_zero_addr( (struct sockaddr *)&iplist[i].ss) ) {1098 if (is_zero_addr(&iplist[i].ss) ) { 592 1099 if (i != count-1) { 593 1100 memmove(&iplist[i], &iplist[i+1], … … 642 1149 ****************************************************************************/ 643 1150 644 struct sockaddr_storage *name_query(int fd, 645 const char *name, 646 int name_type, 647 bool bcast, 648 bool recurse, 649 const struct sockaddr_storage *to_ss, 650 int *count, 651 int *flags, 652 bool *timed_out) 653 { 654 bool found=false; 655 int i, retries = 3; 656 int retry_time = bcast?250:2000; 657 struct timeval tval; 1151 struct name_query_state { 1152 struct sockaddr_storage my_addr; 1153 struct sockaddr_storage addr; 1154 bool bcast; 1155 1156 1157 uint8_t buf[1024]; 1158 ssize_t buflen; 1159 1160 NTSTATUS validate_error; 1161 uint8_t flags; 1162 1163 struct sockaddr_storage *addrs; 1164 int num_addrs; 1165 }; 1166 1167 static bool name_query_validator(struct packet_struct *p, void *private_data); 1168 static void name_query_done(struct tevent_req *subreq); 1169 1170 struct tevent_req *name_query_send(TALLOC_CTX *mem_ctx, 1171 struct tevent_context *ev, 1172 const char *name, int name_type, 1173 bool bcast, bool recurse, 1174 const struct sockaddr_storage *addr) 1175 { 1176 struct tevent_req *req, *subreq; 1177 struct name_query_state *state; 658 1178 struct packet_struct p; 659 struct packet_struct *p2;660 1179 struct nmb_packet *nmb = &p.packet.nmb; 661 struct sockaddr_storage *ss_list = NULL; 1180 struct sockaddr_in *in_addr; 1181 1182 req = tevent_req_create(mem_ctx, &state, struct name_query_state); 1183 if (req == NULL) { 1184 return NULL; 1185 } 1186 state->bcast = bcast; 1187 1188 if (addr->ss_family != AF_INET) { 1189 /* Can't do node status to IPv6 */ 1190 tevent_req_nterror(req, NT_STATUS_INVALID_ADDRESS); 1191 return tevent_req_post(req, ev); 1192 } 662 1193 663 1194 if (lp_disable_netbios()) { 664 1195 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", 665 1196 name, name_type)); 666 return NULL; 667 } 668 669 if (to_ss->ss_family != AF_INET) { 670 return NULL; 671 } 672 673 if (timed_out) { 674 *timed_out = false; 675 } 676 677 memset((char *)&p,'\0',sizeof(p)); 678 (*count) = 0; 679 (*flags) = 0; 680 1197 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); 1198 return tevent_req_post(req, ev); 1199 } 1200 1201 state->addr = *addr; 1202 in_addr = (struct sockaddr_in *)(void *)&state->addr; 1203 in_addr->sin_port = htons(NMB_PORT); 1204 1205 if (!interpret_string_addr(&state->my_addr, lp_socket_address(), 1206 AI_NUMERICHOST|AI_PASSIVE)) { 1207 zero_sockaddr(&state->my_addr); 1208 } 1209 1210 ZERO_STRUCT(p); 681 1211 nmb->header.name_trn_id = generate_trn_id(); 682 1212 nmb->header.opcode = 0; … … 698 1228 nmb->question.question_class = 0x1; 699 1229 700 p.ip = ((struct sockaddr_in *)to_ss)->sin_addr; 701 p.port = NMB_PORT; 702 p.recv_fd = -1; 703 p.send_fd = fd; 704 p.timestamp = time(NULL); 705 p.packet_type = NMB_PACKET; 706 707 GetTimeOfDay(&tval); 708 709 if (!send_packet(&p)) 710 return NULL; 711 712 retries--; 713 714 while (1) { 715 struct timeval tval2; 716 717 GetTimeOfDay(&tval2); 718 if (TvalDiff(&tval,&tval2) > retry_time) { 719 if (!retries) 1230 state->buflen = build_packet((char *)state->buf, sizeof(state->buf), 1231 &p); 1232 if (state->buflen == 0) { 1233 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); 1234 DEBUG(10, ("build_packet failed\n")); 1235 return tevent_req_post(req, ev); 1236 } 1237 1238 subreq = nb_trans_send(state, ev, &state->my_addr, &state->addr, bcast, 1239 state->buf, state->buflen, 1240 NMB_PACKET, nmb->header.name_trn_id, 1241 name_query_validator, state); 1242 if (tevent_req_nomem(subreq, req)) { 1243 DEBUG(10, ("nb_trans_send failed\n")); 1244 return tevent_req_post(req, ev); 1245 } 1246 tevent_req_set_callback(subreq, name_query_done, req); 1247 return req; 1248 } 1249 1250 static bool name_query_validator(struct packet_struct *p, void *private_data) 1251 { 1252 struct name_query_state *state = talloc_get_type_abort( 1253 private_data, struct name_query_state); 1254 struct nmb_packet *nmb = &p->packet.nmb; 1255 struct sockaddr_storage *tmp_addrs; 1256 bool got_unique_netbios_name = false; 1257 int i; 1258 1259 debug_nmb_packet(p); 1260 1261 /* 1262 * If we get a Negative Name Query Response from a WINS 1263 * server, we should report it and give up. 1264 */ 1265 if( 0 == nmb->header.opcode /* A query response */ 1266 && !state->bcast /* from a WINS server */ 1267 && nmb->header.rcode /* Error returned */ 1268 ) { 1269 1270 if( DEBUGLVL( 3 ) ) { 1271 /* Only executed if DEBUGLEVEL >= 3 */ 1272 dbgtext( "Negative name query " 1273 "response, rcode 0x%02x: ", 1274 nmb->header.rcode ); 1275 switch( nmb->header.rcode ) { 1276 case 0x01: 1277 dbgtext("Request was invalidly formatted.\n"); 720 1278 break; 721 if (!found && !send_packet(&p)) 722 return NULL; 723 GetTimeOfDay(&tval); 724 retries--; 725 } 726 727 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { 728 struct nmb_packet *nmb2 = &p2->packet.nmb; 729 debug_nmb_packet(p2); 730 731 /* If we get a Negative Name Query Response from a WINS 732 * server, we should report it and give up. 733 */ 734 if( 0 == nmb2->header.opcode /* A query response */ 735 && !(bcast) /* from a WINS server */ 736 && nmb2->header.rcode /* Error returned */ 737 ) { 738 739 if( DEBUGLVL( 3 ) ) { 740 /* Only executed if DEBUGLEVEL >= 3 */ 741 dbgtext( "Negative name query " 742 "response, rcode 0x%02x: ", 743 nmb2->header.rcode ); 744 switch( nmb2->header.rcode ) { 745 case 0x01: 746 dbgtext( "Request " 747 "was invalidly formatted.\n" ); 748 break; 749 case 0x02: 750 dbgtext( "Problem with NBNS, " 751 "cannot process name.\n"); 752 break; 753 case 0x03: 754 dbgtext( "The name requested " 755 "does not exist.\n" ); 756 break; 757 case 0x04: 758 dbgtext( "Unsupported request " 759 "error.\n" ); 760 break; 761 case 0x05: 762 dbgtext( "Query refused " 763 "error.\n" ); 764 break; 765 default: 766 dbgtext( "Unrecognized error " 767 "code.\n" ); 768 break; 769 } 770 } 771 free_packet(p2); 772 return( NULL ); 1279 case 0x02: 1280 dbgtext("Problem with NBNS, cannot process " 1281 "name.\n"); 1282 break; 1283 case 0x03: 1284 dbgtext("The name requested does not " 1285 "exist.\n"); 1286 break; 1287 case 0x04: 1288 dbgtext("Unsupported request error.\n"); 1289 break; 1290 case 0x05: 1291 dbgtext("Query refused error.\n"); 1292 break; 1293 default: 1294 dbgtext("Unrecognized error code.\n" ); 1295 break; 773 1296 } 774 775 if (nmb2->header.opcode != 0 || 776 nmb2->header.nm_flags.bcast || 777 nmb2->header.rcode || 778 !nmb2->header.ancount) { 779 /* 780 * XXXX what do we do with this? Could be a 781 * redirect, but we'll discard it for the 782 * moment. 783 */ 784 free_packet(p2); 785 continue; 1297 } 1298 1299 /* 1300 * We accept this packet as valid, but tell the upper 1301 * layers that it's a negative response. 1302 */ 1303 state->validate_error = NT_STATUS_NOT_FOUND; 1304 return true; 1305 } 1306 1307 if (nmb->header.opcode != 0 || 1308 nmb->header.nm_flags.bcast || 1309 nmb->header.rcode || 1310 !nmb->header.ancount) { 1311 /* 1312 * XXXX what do we do with this? Could be a redirect, 1313 * but we'll discard it for the moment. 1314 */ 1315 return false; 1316 } 1317 1318 tmp_addrs = TALLOC_REALLOC_ARRAY( 1319 state, state->addrs, struct sockaddr_storage, 1320 state->num_addrs + nmb->answers->rdlength/6); 1321 if (tmp_addrs == NULL) { 1322 state->validate_error = NT_STATUS_NO_MEMORY; 1323 return true; 1324 } 1325 state->addrs = tmp_addrs; 1326 1327 DEBUG(2,("Got a positive name query response " 1328 "from %s ( ", inet_ntoa(p->ip))); 1329 1330 for (i=0; i<nmb->answers->rdlength/6; i++) { 1331 uint16_t flags; 1332 struct in_addr ip; 1333 struct sockaddr_storage addr; 1334 int j; 1335 1336 flags = RSVAL(&nmb->answers->rdata[i*6], 0); 1337 got_unique_netbios_name |= ((flags & 0x8000) == 0); 1338 1339 putip((char *)&ip,&nmb->answers->rdata[2+i*6]); 1340 in_addr_to_sockaddr_storage(&addr, ip); 1341 1342 for (j=0; j<state->num_addrs; j++) { 1343 if (sockaddr_equal( 1344 (struct sockaddr *)&addr, 1345 (struct sockaddr *)&state->addrs[j])) { 1346 break; 786 1347 } 787 788 ss_list = SMB_REALLOC_ARRAY(ss_list, 789 struct sockaddr_storage, 790 (*count) + 791 nmb2->answers->rdlength/6); 792 793 if (!ss_list) { 794 DEBUG(0,("name_query: Realloc failed.\n")); 795 free_packet(p2); 796 return NULL; 797 } 798 799 DEBUG(2,("Got a positive name query response " 800 "from %s ( ", 801 inet_ntoa(p2->ip))); 802 803 for (i=0;i<nmb2->answers->rdlength/6;i++) { 804 struct in_addr ip; 805 putip((char *)&ip,&nmb2->answers->rdata[2+i*6]); 806 in_addr_to_sockaddr_storage(&ss_list[(*count)], 807 ip); 808 DEBUGADD(2,("%s ",inet_ntoa(ip))); 809 (*count)++; 810 } 811 DEBUGADD(2,(")\n")); 812 813 found=true; 814 retries=0; 815 /* We add the flags back ... */ 816 if (nmb2->header.response) 817 (*flags) |= NM_FLAGS_RS; 818 if (nmb2->header.nm_flags.authoritative) 819 (*flags) |= NM_FLAGS_AA; 820 if (nmb2->header.nm_flags.trunc) 821 (*flags) |= NM_FLAGS_TC; 822 if (nmb2->header.nm_flags.recursion_desired) 823 (*flags) |= NM_FLAGS_RD; 824 if (nmb2->header.nm_flags.recursion_available) 825 (*flags) |= NM_FLAGS_RA; 826 if (nmb2->header.nm_flags.bcast) 827 (*flags) |= NM_FLAGS_B; 828 free_packet(p2); 829 /* 830 * If we're doing a unicast lookup we only 831 * expect one reply. Don't wait the full 2 832 * seconds if we got one. JRA. 833 */ 834 if(!bcast && found) 835 break; 836 } 837 } 838 839 /* only set timed_out if we didn't fund what we where looking for*/ 840 841 if ( !found && timed_out ) { 842 *timed_out = true; 843 } 844 845 /* sort the ip list so we choose close servers first if possible */ 846 sort_addr_list(ss_list, *count); 847 848 return ss_list; 1348 } 1349 if (j < state->num_addrs) { 1350 /* Already got it */ 1351 continue; 1352 } 1353 1354 DEBUGADD(2,("%s ",inet_ntoa(ip))); 1355 1356 state->addrs[state->num_addrs] = addr; 1357 state->num_addrs += 1; 1358 } 1359 DEBUGADD(2,(")\n")); 1360 1361 /* We add the flags back ... */ 1362 if (nmb->header.response) 1363 state->flags |= NM_FLAGS_RS; 1364 if (nmb->header.nm_flags.authoritative) 1365 state->flags |= NM_FLAGS_AA; 1366 if (nmb->header.nm_flags.trunc) 1367 state->flags |= NM_FLAGS_TC; 1368 if (nmb->header.nm_flags.recursion_desired) 1369 state->flags |= NM_FLAGS_RD; 1370 if (nmb->header.nm_flags.recursion_available) 1371 state->flags |= NM_FLAGS_RA; 1372 if (nmb->header.nm_flags.bcast) 1373 state->flags |= NM_FLAGS_B; 1374 1375 if (state->bcast) { 1376 /* 1377 * We have to collect all entries coming in from broadcast 1378 * queries. If we got a unique name, we're done. 1379 */ 1380 return got_unique_netbios_name; 1381 } 1382 /* 1383 * WINS responses are accepted when they are received 1384 */ 1385 return true; 1386 } 1387 1388 static void name_query_done(struct tevent_req *subreq) 1389 { 1390 struct tevent_req *req = tevent_req_callback_data( 1391 subreq, struct tevent_req); 1392 struct name_query_state *state = tevent_req_data( 1393 req, struct name_query_state); 1394 NTSTATUS status; 1395 struct packet_struct *p = NULL; 1396 1397 status = nb_trans_recv(subreq, &p); 1398 TALLOC_FREE(subreq); 1399 if (tevent_req_nterror(req, status)) { 1400 return; 1401 } 1402 if (!NT_STATUS_IS_OK(state->validate_error)) { 1403 tevent_req_nterror(req, state->validate_error); 1404 return; 1405 } 1406 if (p != NULL) { 1407 /* 1408 * Free the packet here, we've collected the response in the 1409 * validator 1410 */ 1411 free_packet(p); 1412 } 1413 tevent_req_done(req); 1414 } 1415 1416 NTSTATUS name_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 1417 struct sockaddr_storage **addrs, int *num_addrs, 1418 uint8_t *flags) 1419 { 1420 struct name_query_state *state = tevent_req_data( 1421 req, struct name_query_state); 1422 NTSTATUS status; 1423 1424 if (tevent_req_is_nterror(req, &status) 1425 && !NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { 1426 return status; 1427 } 1428 if (state->num_addrs == 0) { 1429 return NT_STATUS_NOT_FOUND; 1430 } 1431 *addrs = talloc_move(mem_ctx, &state->addrs); 1432 sort_addr_list(*addrs, state->num_addrs); 1433 *num_addrs = state->num_addrs; 1434 if (flags != NULL) { 1435 *flags = state->flags; 1436 } 1437 return NT_STATUS_OK; 1438 } 1439 1440 NTSTATUS name_query(const char *name, int name_type, 1441 bool bcast, bool recurse, 1442 const struct sockaddr_storage *to_ss, 1443 TALLOC_CTX *mem_ctx, 1444 struct sockaddr_storage **addrs, 1445 int *num_addrs, uint8_t *flags) 1446 { 1447 TALLOC_CTX *frame = talloc_stackframe(); 1448 struct tevent_context *ev; 1449 struct tevent_req *req; 1450 struct timeval timeout; 1451 NTSTATUS status = NT_STATUS_NO_MEMORY; 1452 1453 ev = tevent_context_init(frame); 1454 if (ev == NULL) { 1455 goto fail; 1456 } 1457 req = name_query_send(ev, ev, name, name_type, bcast, recurse, to_ss); 1458 if (req == NULL) { 1459 goto fail; 1460 } 1461 if (bcast) { 1462 timeout = timeval_current_ofs(0, 250000); 1463 } else { 1464 timeout = timeval_current_ofs(2, 0); 1465 } 1466 if (!tevent_req_set_endtime(req, ev, timeout)) { 1467 goto fail; 1468 } 1469 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 1470 goto fail; 1471 } 1472 status = name_query_recv(req, mem_ctx, addrs, num_addrs, flags); 1473 fail: 1474 TALLOC_FREE(frame); 1475 return status; 849 1476 } 850 1477 … … 885 1512 NTSTATUS name_resolve_bcast(const char *name, 886 1513 int name_type, 887 struct ip_service **return_iplist, 1514 TALLOC_CTX *mem_ctx, 1515 struct sockaddr_storage **return_iplist, 888 1516 int *return_count) 889 1517 { 890 int sock,i;1518 int i; 891 1519 int num_interfaces = iface_count(); 892 1520 struct sockaddr_storage *ss_list; 893 struct sockaddr_storage ss; 894 NTSTATUS status; 1521 NTSTATUS status = NT_STATUS_NOT_FOUND; 895 1522 896 1523 if (lp_disable_netbios()) { … … 910 1537 "for name %s<0x%x>\n", name, name_type)); 911 1538 912 if (!interpret_string_addr(&ss, lp_socket_address(),913 AI_NUMERICHOST|AI_PASSIVE)) {914 zero_sockaddr(&ss);915 }916 917 sock = open_socket_in( SOCK_DGRAM, 0, 3, &ss, true );918 if (sock == -1) {919 return NT_STATUS_UNSUCCESSFUL;920 }921 922 set_socket_options(sock,"SO_BROADCAST");923 1539 /* 924 1540 * Lookup the name on all the interfaces, return on … … 927 1543 for( i = num_interfaces-1; i >= 0; i--) { 928 1544 const struct sockaddr_storage *pss = iface_n_bcast(i); 929 int flags;930 1545 931 1546 /* Done this way to fix compiler error on IRIX 5.x */ … … 933 1548 continue; 934 1549 } 935 ss_list = name_query(sock, name, name_type, true, 936 true, pss, return_count, &flags, NULL); 937 if (ss_list) { 1550 status = name_query(name, name_type, true, true, pss, 1551 talloc_tos(), &ss_list, return_count, 1552 NULL); 1553 if (NT_STATUS_IS_OK(status)) { 938 1554 goto success; 939 1555 } … … 942 1558 /* failed - no response */ 943 1559 944 close(sock); 945 return NT_STATUS_UNSUCCESSFUL; 1560 return status; 946 1561 947 1562 success: 948 949 status = NT_STATUS_OK; 950 if (!convert_ss2service(return_iplist, ss_list, *return_count) ) 951 status = NT_STATUS_INVALID_PARAMETER; 952 953 SAFE_FREE(ss_list); 954 close(sock); 1563 *return_iplist = ss_list; 955 1564 return status; 956 1565 } … … 965 1574 int *return_count) 966 1575 { 967 int sock,t, i;1576 int t, i; 968 1577 char **wins_tags; 969 1578 struct sockaddr_storage src_ss, *ss_list = NULL; … … 1022 1631 struct sockaddr_storage wins_ss; 1023 1632 struct in_addr wins_ip; 1024 int flags;1025 bool timed_out;1026 1633 1027 1634 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip); … … 1041 1648 inet_ntoa(wins_ip), wins_tags[t])); 1042 1649 1043 sock = open_socket_in(SOCK_DGRAM, 0, 3, &src_ss, true);1044 if (sock == -1) {1045 continue;1046 }1047 1048 1650 in_addr_to_sockaddr_storage(&wins_ss, wins_ip); 1049 ss_list = name_query(sock, 1050 name, 1651 status = name_query(name, 1051 1652 name_type, 1052 1653 false, 1053 1654 true, 1054 1655 &wins_ss, 1656 talloc_tos(), 1657 &ss_list, 1055 1658 return_count, 1056 &flags, 1057 &timed_out); 1659 NULL); 1058 1660 1059 1661 /* exit loop if we got a list of addresses */ 1060 1662 1061 if ( ss_list)1663 if (NT_STATUS_IS_OK(status)) { 1062 1664 goto success; 1063 1064 close(sock); 1065 1066 if (timed_out) { 1067 /* Timed out wating for WINS server to respond. 1665 } 1666 1667 if (NT_STATUS_EQUAL(status, 1668 NT_STATUS_IO_TIMEOUT)) { 1669 /* Timed out waiting for WINS server to 1670 * respond. 1068 1671 * Mark it dead. */ 1069 1672 wins_srv_died(wins_ip, src_ip); 1070 1673 } else { 1071 /* The name defin ately isn't in this1674 /* The name definitely isn't in this 1072 1675 group of WINS servers. 1073 1676 goto the next group */ … … 1086 1689 status = NT_STATUS_INVALID_PARAMETER; 1087 1690 1088 SAFE_FREE(ss_list);1691 TALLOC_FREE(ss_list); 1089 1692 wins_srv_tags_free(wins_tags); 1090 close(sock);1091 1693 1092 1694 return status; … … 1104 1706 * "lmhosts" means parse the local lmhosts file. 1105 1707 */ 1106 1107 XFILE *fp; 1108 char *lmhost_name = NULL; 1109 int name_type2; 1110 struct sockaddr_storage return_ss; 1708 struct sockaddr_storage *ss_list; 1111 1709 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; 1112 1710 TALLOC_CTX *ctx = NULL; … … 1119 1717 name, name_type)); 1120 1718 1121 fp = startlmhosts(get_dyn_LMHOSTSFILE());1122 1123 if ( fp == NULL )1124 return NT_STATUS_NO_SUCH_FILE;1125 1126 1719 ctx = talloc_init("resolve_lmhosts"); 1127 1720 if (!ctx) { 1128 endlmhosts(fp);1129 1721 return NT_STATUS_NO_MEMORY; 1130 1722 } 1131 1723 1132 while (getlmhostsent(ctx, fp, &lmhost_name, &name_type2, &return_ss)) { 1133 1134 if (!strequal(name, lmhost_name)) { 1135 TALLOC_FREE(lmhost_name); 1136 continue; 1137 } 1138 1139 if ((name_type2 != -1) && (name_type != name_type2)) { 1140 TALLOC_FREE(lmhost_name); 1141 continue; 1142 } 1143 1144 *return_iplist = SMB_REALLOC_ARRAY((*return_iplist), 1145 struct ip_service, 1146 (*return_count)+1); 1147 1148 if ((*return_iplist) == NULL) { 1149 TALLOC_FREE(ctx); 1150 endlmhosts(fp); 1151 DEBUG(3,("resolve_lmhosts: malloc fail !\n")); 1724 status = resolve_lmhosts_file_as_sockaddr(get_dyn_LMHOSTSFILE(), 1725 name, name_type, 1726 ctx, 1727 &ss_list, 1728 return_count); 1729 if (NT_STATUS_IS_OK(status)) { 1730 if (convert_ss2service(return_iplist, 1731 ss_list, 1732 *return_count)) { 1733 talloc_free(ctx); 1734 return NT_STATUS_OK; 1735 } else { 1736 talloc_free(ctx); 1152 1737 return NT_STATUS_NO_MEMORY; 1153 1738 } 1154 1155 (*return_iplist)[*return_count].ss = return_ss; 1156 (*return_iplist)[*return_count].port = PORT_NONE; 1157 *return_count += 1; 1158 1159 /* we found something */ 1160 status = NT_STATUS_OK; 1161 1162 /* Multiple names only for DC lookup */ 1163 if (name_type != 0x1c) 1164 break; 1165 } 1166 1167 TALLOC_FREE(ctx); 1168 endlmhosts(fp); 1739 } 1740 talloc_free(ctx); 1169 1741 return status; 1170 1742 } … … 1257 1829 Resolve via "ADS" method. 1258 1830 *********************************************************/ 1831 1832 /* Special name type used to cause a _kerberos DNS lookup. */ 1833 #define KDC_NAME_TYPE 0xDCDC 1259 1834 1260 1835 static NTSTATUS resolve_ads(const char *name, … … 1361 1936 * doesn't know anything about the DC's -- jerry */ 1362 1937 1363 if (!is_zero_addr( (struct sockaddr *)&r->ss)) {1938 if (!is_zero_addr(&r->ss)) { 1364 1939 (*return_count)++; 1365 1940 } … … 1493 2068 } 1494 2069 } else if(strequal( tok, "bcast")) { 1495 status = name_resolve_bcast(name, name_type, 1496 return_iplist, 1497 return_count); 2070 struct sockaddr_storage *ss_list; 2071 status = name_resolve_bcast( 2072 name, name_type, talloc_tos(), 2073 &ss_list, return_count); 1498 2074 if (NT_STATUS_IS_OK(status)) { 2075 if (!convert_ss2service(return_iplist, 2076 ss_list, 2077 *return_count)) { 2078 status = NT_STATUS_NO_MEMORY; 2079 } 1499 2080 goto done; 1500 2081 } … … 1591 2172 if (prefer_ipv4) { 1592 2173 for (i=0; i<count; i++) { 1593 if (!is_zero_addr( (struct sockaddr *)&ss_list[i].ss) &&2174 if (!is_zero_addr(&ss_list[i].ss) && 1594 2175 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss) && 1595 2176 (ss_list[i].ss.ss_family == AF_INET)) { … … 1604 2185 /* only return valid addresses for TCP connections */ 1605 2186 for (i=0; i<count; i++) { 1606 if (!is_zero_addr( (struct sockaddr *)&ss_list[i].ss) &&2187 if (!is_zero_addr(&ss_list[i].ss) && 1607 2188 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) { 1608 2189 *return_ss = ss_list[i].ss; … … 1668 2249 /* only return valid addresses for TCP connections */ 1669 2250 for (i=0, num_entries = 0; i<count; i++) { 1670 if (!is_zero_addr( (struct sockaddr *)&ss_list[i].ss) &&2251 if (!is_zero_addr(&ss_list[i].ss) && 1671 2252 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) { 1672 2253 num_entries++; … … 1687 2268 1688 2269 for (i=0, num_entries = 0; i<count; i++) { 1689 if (!is_zero_addr( (struct sockaddr *)&ss_list[i].ss) &&2270 if (!is_zero_addr(&ss_list[i].ss) && 1690 2271 !is_broadcast_addr((struct sockaddr *)&ss_list[i].ss)) { 1691 2272 (*return_ss_arr)[num_entries++] = ss_list[i].ss; … … 1855 2436 1856 2437 if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) { 1857 pserver = talloc_asprintf( NULL, "%s, %s",2438 pserver = talloc_asprintf(ctx, "%s, %s", 1858 2439 saf_servername ? saf_servername : "", 1859 2440 lp_passwordserver()); 1860 2441 } else { 1861 pserver = talloc_asprintf( NULL, "%s, *",2442 pserver = talloc_asprintf(ctx, "%s, *", 1862 2443 saf_servername ? saf_servername : ""); 1863 2444 }
Note:
See TracChangeset
for help on using the changeset viewer.