Changeset 988 for vendor/current/source3/libsmb/namequery.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/libsmb/namequery.c
r746 r988 22 22 #include "../lib/util/tevent_ntstatus.h" 23 23 #include "libads/sitename_cache.h" 24 #include " libads/dns.h"24 #include "../lib/addns/dnsquery.h" 25 25 #include "../libcli/netlogon/netlogon.h" 26 26 #include "lib/async_req/async_sock.h" 27 #include "lib/tsocket/tsocket.h" 27 28 #include "libsmb/nmblib.h" 29 #include "../libcli/nbt/libnbt.h" 30 #include "libads/kerberos_proto.h" 28 31 29 32 /* nmbd.c sets this to True. */ … … 44 47 #define SAFJOIN_TTL 3600 45 48 46 static char *saf_key(const char *domain) 47 { 48 char *keystr; 49 50 asprintf_strupper_m(&keystr, SAFKEY_FMT, domain); 51 52 return keystr; 53 } 54 55 static char *saf_join_key(const char *domain) 56 { 57 char *keystr; 58 59 asprintf_strupper_m(&keystr, SAFJOINKEY_FMT, domain); 60 61 return keystr; 49 static char *saf_key(TALLOC_CTX *mem_ctx, const char *domain) 50 { 51 return talloc_asprintf_strupper_m(mem_ctx, SAFKEY_FMT, domain); 52 } 53 54 static char *saf_join_key(TALLOC_CTX *mem_ctx, const char *domain) 55 { 56 return talloc_asprintf_strupper_m(mem_ctx, SAFJOINKEY_FMT, domain); 62 57 } 63 58 … … 83 78 } 84 79 85 key = saf_key( domain ); 80 key = saf_key(talloc_tos(), domain); 81 if (key == NULL) { 82 DEBUG(1, ("saf_key() failed\n")); 83 return false; 84 } 86 85 expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL); 87 86 … … 91 90 ret = gencache_set( key, servername, expire ); 92 91 93 SAFE_FREE( key );92 TALLOC_FREE( key ); 94 93 95 94 return ret; … … 112 111 } 113 112 114 key = saf_join_key( domain ); 113 key = saf_join_key(talloc_tos(), domain); 114 if (key == NULL) { 115 DEBUG(1, ("saf_join_key() failed\n")); 116 return false; 117 } 115 118 expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL); 116 119 … … 120 123 ret = gencache_set( key, servername, expire ); 121 124 122 SAFE_FREE( key );125 TALLOC_FREE( key ); 123 126 124 127 return ret; … … 135 138 } 136 139 137 key = saf_join_key(domain); 140 key = saf_join_key(talloc_tos(), domain); 141 if (key == NULL) { 142 DEBUG(1, ("saf_join_key() failed\n")); 143 return false; 144 } 138 145 ret = gencache_del(key); 139 SAFE_FREE(key);146 TALLOC_FREE(key); 140 147 141 148 if (ret) { … … 143 150 } 144 151 145 key = saf_key(domain); 152 key = saf_key(talloc_tos(), domain); 153 if (key == NULL) { 154 DEBUG(1, ("saf_key() failed\n")); 155 return false; 156 } 146 157 ret = gencache_del(key); 147 SAFE_FREE(key);158 TALLOC_FREE(key); 148 159 149 160 if (ret) { … … 157 168 ****************************************************************************/ 158 169 159 char *saf_fetch( const char *domain )170 char *saf_fetch(TALLOC_CTX *mem_ctx, const char *domain ) 160 171 { 161 172 char *server = NULL; … … 169 180 } 170 181 171 key = saf_join_key( domain ); 172 173 ret = gencache_get( key, &server, &timeout ); 174 175 SAFE_FREE( key ); 182 key = saf_join_key(talloc_tos(), domain); 183 if (key == NULL) { 184 DEBUG(1, ("saf_join_key() failed\n")); 185 return NULL; 186 } 187 188 ret = gencache_get( key, mem_ctx, &server, &timeout ); 189 190 TALLOC_FREE( key ); 176 191 177 192 if ( ret ) { … … 181 196 } 182 197 183 key = saf_key( domain ); 184 185 ret = gencache_get( key, &server, &timeout ); 186 187 SAFE_FREE( key ); 198 key = saf_key(talloc_tos(), domain); 199 if (key == NULL) { 200 DEBUG(1, ("saf_key() failed\n")); 201 return NULL; 202 } 203 204 ret = gencache_get( key, mem_ctx, &server, &timeout ); 205 206 TALLOC_FREE( key ); 188 207 189 208 if ( !ret ) { … … 198 217 } 199 218 219 static void set_socket_addr_v4(struct sockaddr_storage *addr) 220 { 221 if (!interpret_string_addr(addr, lp_nbt_client_socket_address(), 222 AI_NUMERICHOST|AI_PASSIVE)) { 223 zero_sockaddr(addr); 224 } 225 if (addr->ss_family != AF_INET) { 226 zero_sockaddr(addr); 227 } 228 } 229 230 static struct in_addr my_socket_addr_v4(void) 231 { 232 struct sockaddr_storage my_addr; 233 struct sockaddr_in *in_addr = (struct sockaddr_in *)((char *)&my_addr); 234 235 set_socket_addr_v4(&my_addr); 236 return in_addr->sin_addr; 237 } 238 200 239 /**************************************************************************** 201 240 Generate a random trn_id. … … 204 243 static int generate_trn_id(void) 205 244 { 206 uint16 id;207 208 generate_random_buffer((uint8 *)&id, sizeof(id));245 uint16_t id; 246 247 generate_random_buffer((uint8_t *)&id, sizeof(id)); 209 248 210 249 return id % (unsigned)0x7FFF; … … 227 266 return NULL; 228 267 229 ret = TALLOC_ARRAY(mem_ctx, struct node_status,*num_names);268 ret = talloc_array(mem_ctx, struct node_status,*num_names); 230 269 if (!ret) 231 270 return NULL; … … 258 297 struct tevent_req *reader_req; 259 298 260 intsock;299 struct tdgram_context *sock; 261 300 struct tevent_req *socket_req; 262 uint8_t buf[1024]; 263 struct sockaddr_storage addr; 264 socklen_t addr_len; 301 uint8_t *buf; 302 struct tsocket_address *addr; 265 303 266 304 bool (*validator)(struct packet_struct *p, … … 278 316 TALLOC_CTX *mem_ctx, 279 317 struct tevent_context *ev, 280 int sock, /* dgram socket */318 struct tdgram_context *sock, 281 319 struct nb_packet_reader *reader, 282 320 enum packet_type type, … … 311 349 } 312 350 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); 351 state->socket_req = tdgram_recvfrom_send(state, ev, state->sock); 317 352 if (tevent_req_nomem(state->socket_req, req)) { 318 353 return tevent_req_post(req, ev); … … 386 421 struct sock_packet_read_state *state = tevent_req_data( 387 422 req, struct sock_packet_read_state); 388 struct sockaddr_in *in_addr; 423 union { 424 struct sockaddr sa; 425 struct sockaddr_in sin; 426 } addr; 427 ssize_t ret; 389 428 ssize_t received; 390 429 int err; 391 392 received = recvfrom_recv(subreq, &err); 430 bool ok; 431 432 received = tdgram_recvfrom_recv(subreq, &err, state, 433 &state->buf, &state->addr); 393 434 394 435 TALLOC_FREE(state->socket_req); … … 407 448 return; 408 449 } 409 if (state->addr.ss_family != AF_INET) { 450 ok = tsocket_address_is_inet(state->addr, "ipv4"); 451 if (!ok) { 410 452 goto retry; 411 453 } 412 in_addr = (struct sockaddr_in *)(void *)&state->addr; 454 ret = tsocket_address_bsd_sockaddr(state->addr, 455 &addr.sa, 456 sizeof(addr.sin)); 457 if (ret == -1) { 458 tevent_req_nterror(req, map_nt_error_from_unix(errno)); 459 return; 460 } 413 461 414 462 state->packet = parse_packet((char *)state->buf, received, state->type, 415 in_addr->sin_addr, in_addr->sin_port);463 addr.sin.sin_addr, addr.sin.sin_port); 416 464 if (state->packet == NULL) { 417 465 DEBUG(10, ("parse_packet failed\n")); … … 439 487 state->packet = NULL; 440 488 } 441 state->socket_req = recvfrom_send(state, state->ev, state->sock, 442 state->buf, sizeof(state->buf), 0, 443 &state->addr, &state->addr_len); 489 TALLOC_FREE(state->buf); 490 TALLOC_FREE(state->addr); 491 492 state->socket_req = tdgram_recvfrom_send(state, state->ev, state->sock); 444 493 if (tevent_req_nomem(state->socket_req, req)) { 445 494 return; … … 466 515 struct nb_trans_state { 467 516 struct tevent_context *ev; 468 intsock;517 struct tdgram_context *sock; 469 518 struct nb_packet_reader *reader; 470 519 471 const struct sockaddr_storage *dst_addr; 520 struct tsocket_address *src_addr; 521 struct tsocket_address *dst_addr; 472 522 uint8_t *buf; 473 523 size_t buflen; … … 491 541 TALLOC_CTX *mem_ctx, 492 542 struct tevent_context *ev, 493 const struct sockaddr_storage * my_addr,494 const struct sockaddr_storage * dst_addr,543 const struct sockaddr_storage *_my_addr, 544 const struct sockaddr_storage *_dst_addr, 495 545 bool bcast, 496 546 uint8_t *buf, size_t buflen, … … 500 550 void *private_data) 501 551 { 552 const struct sockaddr *my_addr = 553 discard_const_p(const struct sockaddr, _my_addr); 554 size_t my_addr_len = sizeof(*_my_addr); 555 const struct sockaddr *dst_addr = 556 discard_const_p(const struct sockaddr, _dst_addr); 557 size_t dst_addr_len = sizeof(*_dst_addr); 502 558 struct tevent_req *req, *subreq; 503 559 struct nb_trans_state *state; 560 int ret; 504 561 505 562 req = tevent_req_create(mem_ctx, &state, struct nb_trans_state); … … 509 566 talloc_set_destructor(state, nb_trans_state_destructor); 510 567 state->ev = ev; 511 state->dst_addr = dst_addr;512 568 state->buf = buf; 513 569 state->buflen = buflen; … … 517 573 state->private_data = private_data; 518 574 519 state->sock = open_socket_in(SOCK_DGRAM, 0, 3, my_addr, True); 520 if (state->sock == -1) { 575 ret = tsocket_address_bsd_from_sockaddr(state, 576 my_addr, my_addr_len, 577 &state->src_addr); 578 if (ret == -1) { 521 579 tevent_req_nterror(req, map_nt_error_from_unix(errno)); 522 DEBUG(10, ("open_socket_in failed: %s\n", strerror(errno)));523 580 return tevent_req_post(req, ev); 524 581 } 525 582 526 if (bcast) { 527 set_socket_options(state->sock,"SO_BROADCAST"); 583 ret = tsocket_address_bsd_from_sockaddr(state, 584 dst_addr, dst_addr_len, 585 &state->dst_addr); 586 if (ret == -1) { 587 tevent_req_nterror(req, map_nt_error_from_unix(errno)); 588 return tevent_req_post(req, ev); 589 } 590 591 ret = tdgram_inet_udp_broadcast_socket(state->src_addr, state, 592 &state->sock); 593 if (ret == -1) { 594 tevent_req_nterror(req, map_nt_error_from_unix(errno)); 595 return tevent_req_post(req, ev); 528 596 } 529 597 … … 538 606 static int nb_trans_state_destructor(struct nb_trans_state *s) 539 607 { 540 if (s->sock != -1) {541 close(s->sock);542 s->sock = -1;543 }544 608 if (s->packet != NULL) { 545 609 free_packet(s->packet); … … 574 638 tevent_req_set_callback(subreq, nb_trans_done, req); 575 639 576 subreq = sendto_send(state, state->ev, state->sock, 577 state->buf, state->buflen, 0, state->dst_addr); 640 subreq = tdgram_sendto_send(state, state->ev, 641 state->sock, 642 state->buf, state->buflen, 643 state->dst_addr); 578 644 if (tevent_req_nomem(subreq, req)) { 579 645 return; … … 591 657 int err; 592 658 593 sent = sendto_recv(subreq, &err);659 sent = tdgram_sendto_recv(subreq, &err); 594 660 TALLOC_FREE(subreq); 595 661 if (sent == -1) { … … 620 686 return; 621 687 } 622 subreq = sendto_send(state, state->ev, state->sock, 623 state->buf, state->buflen, 0, state->dst_addr); 688 subreq = tdgram_sendto_send(state, state->ev, 689 state->sock, 690 state->buf, state->buflen, 691 state->dst_addr); 624 692 if (tevent_req_nomem(subreq, req)) { 625 693 return; … … 706 774 in_addr->sin_port = htons(NMB_PORT); 707 775 708 if (!interpret_string_addr(&state->my_addr, lp_socket_address(), 709 AI_NUMERICHOST|AI_PASSIVE)) { 710 zero_sockaddr(&state->my_addr); 711 } 776 set_socket_addr_v4(&state->my_addr); 712 777 713 778 ZERO_STRUCT(p); … … 834 899 NTSTATUS status = NT_STATUS_NO_MEMORY; 835 900 836 ev = tevent_context_init(frame);901 ev = samba_tevent_context_init(frame); 837 902 if (ev == NULL) { 838 903 goto fail; … … 893 958 } 894 959 895 if (!interpret_string_addr(&ss, lp_socket_address(), 896 AI_NUMERICHOST|AI_PASSIVE)) { 897 zero_sockaddr(&ss); 898 } 960 set_socket_addr_v4(&ss); 899 961 900 962 /* W2K PDC's seem not to respond to '*'#0. JRA */ … … 964 1026 for (i=0;i<num_interfaces;i++) { 965 1027 const struct sockaddr_storage *pss = iface_n_bcast(i); 966 unsigned char *p_ss1 = NULL;967 unsigned char *p_ss2 = NULL;968 unsigned char *p_if = NULL;1028 const unsigned char *p_ss1 = NULL; 1029 const unsigned char *p_ss2 = NULL; 1030 const unsigned char *p_if = NULL; 969 1031 size_t len = 0; 970 1032 int bits1, bits2; … … 975 1037 } 976 1038 if (pss->ss_family == AF_INET) { 977 p_if = ( unsigned char *)1039 p_if = (const unsigned char *) 978 1040 &((const struct sockaddr_in *)pss)->sin_addr; 979 p_ss1 = ( unsigned char *)1041 p_ss1 = (const unsigned char *) 980 1042 &((const struct sockaddr_in *)ss1)->sin_addr; 981 p_ss2 = ( unsigned char *)1043 p_ss2 = (const unsigned char *) 982 1044 &((const struct sockaddr_in *)ss2)->sin_addr; 983 1045 len = 4; … … 985 1047 #if defined(HAVE_IPV6) 986 1048 if (pss->ss_family == AF_INET6) { 987 p_if = ( unsigned char *)1049 p_if = (const unsigned char *) 988 1050 &((const struct sockaddr_in6 *)pss)->sin6_addr; 989 p_ss1 = ( unsigned char *)1051 p_ss1 = (const unsigned char *) 990 1052 &((const struct sockaddr_in6 *)ss1)->sin6_addr; 991 p_ss2 = ( unsigned char *)1053 p_ss2 = (const unsigned char *) 992 1054 &((const struct sockaddr_in6 *)ss2)->sin6_addr; 993 1055 len = 16; … … 1004 1066 1005 1067 /* Bias towards directly reachable IPs */ 1006 if (iface_local(( struct sockaddr *)ss1)) {1068 if (iface_local((const struct sockaddr *)ss1)) { 1007 1069 if (ss1->ss_family == AF_INET) { 1008 1070 max_bits1 += 32; … … 1011 1073 } 1012 1074 } 1013 if (iface_local(( struct sockaddr *)ss2)) {1075 if (iface_local((const struct sockaddr *)ss2)) { 1014 1076 if (ss2->ss_family == AF_INET) { 1015 1077 max_bits2 += 32; … … 1025 1087 *******************************************************************/ 1026 1088 1027 int ip_service_compare(struct ip_service *ss1, struct ip_service *ss2)1089 static int ip_service_compare(struct ip_service *ss1, struct ip_service *ss2) 1028 1090 { 1029 1091 int result; … … 1072 1134 *********************************************************************/ 1073 1135 1074 staticint remove_duplicate_addrs2(struct ip_service *iplist, int count )1136 int remove_duplicate_addrs2(struct ip_service *iplist, int count ) 1075 1137 { 1076 1138 int i, j; … … 1086 1148 1087 1149 for ( j=i+1; j<count; j++ ) { 1088 if (sockaddr_equal((struct sockaddr *)&iplist[i].ss, (struct sockaddr *)&iplist[j].ss) && 1150 if (sockaddr_equal((struct sockaddr *)(void *)&iplist[i].ss, 1151 (struct sockaddr *)(void *)&iplist[j].ss) && 1089 1152 iplist[i].port == iplist[j].port) { 1090 1153 zero_sockaddr(&iplist[j].ss); … … 1112 1175 { 1113 1176 TALLOC_CTX *frame = talloc_stackframe(); 1114 struct ip_service *iplist_new = TALLOC_ARRAY(frame, struct ip_service, count);1177 struct ip_service *iplist_new = talloc_array(frame, struct ip_service, count); 1115 1178 int i, j; 1116 1179 … … 1202 1265 in_addr->sin_port = htons(NMB_PORT); 1203 1266 1204 if (!interpret_string_addr(&state->my_addr, lp_socket_address(), 1205 AI_NUMERICHOST|AI_PASSIVE)) { 1206 zero_sockaddr(&state->my_addr); 1207 } 1267 set_socket_addr_v4(&state->my_addr); 1208 1268 1209 1269 ZERO_STRUCT(p); … … 1315 1375 } 1316 1376 1317 tmp_addrs = TALLOC_REALLOC_ARRAY(1377 tmp_addrs = talloc_realloc( 1318 1378 state, state->addrs, struct sockaddr_storage, 1319 1379 state->num_addrs + nmb->answers->rdlength/6); … … 1345 1405 for (j=0; j<state->num_addrs; j++) { 1346 1406 if (sockaddr_equal( 1347 (struct sockaddr *) &addr,1348 (struct sockaddr *) &state->addrs[j])) {1407 (struct sockaddr *)(void *)&addr, 1408 (struct sockaddr *)(void *)&state->addrs[j])) { 1349 1409 break; 1350 1410 } … … 1425 1485 NTSTATUS status; 1426 1486 1427 if (tevent_req_is_nterror(req, &status) 1428 && !NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { 1429 return status; 1487 if (tevent_req_is_nterror(req, &status)) { 1488 if (state->bcast && 1489 NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { 1490 /* 1491 * In the broadcast case we collect replies until the 1492 * timeout. 1493 */ 1494 status = NT_STATUS_OK; 1495 } 1496 if (!NT_STATUS_IS_OK(status)) { 1497 return status; 1498 } 1430 1499 } 1431 1500 if (state->num_addrs == 0) { … … 1454 1523 NTSTATUS status = NT_STATUS_NO_MEMORY; 1455 1524 1456 ev = tevent_context_init(frame);1525 ev = samba_tevent_context_init(frame); 1457 1526 if (ev == NULL) { 1458 1527 goto fail; … … 1524 1593 (*return_iplist)[real_count].port = PORT_NONE; 1525 1594 real_count++; 1526 1595 } 1527 1596 1528 1597 *pcount = real_count; 1529 1598 return true; 1599 } 1600 1601 struct name_queries_state { 1602 struct tevent_context *ev; 1603 const char *name; 1604 int name_type; 1605 bool bcast; 1606 bool recurse; 1607 const struct sockaddr_storage *addrs; 1608 int num_addrs; 1609 int wait_msec; 1610 int timeout_msec; 1611 1612 struct tevent_req **subreqs; 1613 int num_received; 1614 int num_sent; 1615 1616 int received_index; 1617 struct sockaddr_storage *result_addrs; 1618 int num_result_addrs; 1619 uint8_t flags; 1620 }; 1621 1622 static void name_queries_done(struct tevent_req *subreq); 1623 static void name_queries_next(struct tevent_req *subreq); 1624 1625 /* 1626 * Send a name query to multiple destinations with a wait time in between 1627 */ 1628 1629 static struct tevent_req *name_queries_send( 1630 TALLOC_CTX *mem_ctx, struct tevent_context *ev, 1631 const char *name, int name_type, 1632 bool bcast, bool recurse, 1633 const struct sockaddr_storage *addrs, 1634 int num_addrs, int wait_msec, int timeout_msec) 1635 { 1636 struct tevent_req *req, *subreq; 1637 struct name_queries_state *state; 1638 1639 req = tevent_req_create(mem_ctx, &state, 1640 struct name_queries_state); 1641 if (req == NULL) { 1642 return NULL; 1643 } 1644 state->ev = ev; 1645 state->name = name; 1646 state->name_type = name_type; 1647 state->bcast = bcast; 1648 state->recurse = recurse; 1649 state->addrs = addrs; 1650 state->num_addrs = num_addrs; 1651 state->wait_msec = wait_msec; 1652 state->timeout_msec = timeout_msec; 1653 1654 state->subreqs = talloc_zero_array( 1655 state, struct tevent_req *, num_addrs); 1656 if (tevent_req_nomem(state->subreqs, req)) { 1657 return tevent_req_post(req, ev); 1658 } 1659 state->num_sent = 0; 1660 1661 subreq = name_query_send( 1662 state->subreqs, state->ev, name, name_type, bcast, recurse, 1663 &state->addrs[state->num_sent]); 1664 if (tevent_req_nomem(subreq, req)) { 1665 return tevent_req_post(req, ev); 1666 } 1667 if (!tevent_req_set_endtime( 1668 subreq, state->ev, 1669 timeval_current_ofs(0, state->timeout_msec * 1000))) { 1670 tevent_req_oom(req); 1671 return tevent_req_post(req, ev); 1672 } 1673 tevent_req_set_callback(subreq, name_queries_done, req); 1674 1675 state->subreqs[state->num_sent] = subreq; 1676 state->num_sent += 1; 1677 1678 if (state->num_sent < state->num_addrs) { 1679 subreq = tevent_wakeup_send( 1680 state, state->ev, 1681 timeval_current_ofs(0, state->wait_msec * 1000)); 1682 if (tevent_req_nomem(subreq, req)) { 1683 return tevent_req_post(req, ev); 1684 } 1685 tevent_req_set_callback(subreq, name_queries_next, req); 1686 } 1687 return req; 1688 } 1689 1690 static void name_queries_done(struct tevent_req *subreq) 1691 { 1692 struct tevent_req *req = tevent_req_callback_data( 1693 subreq, struct tevent_req); 1694 struct name_queries_state *state = tevent_req_data( 1695 req, struct name_queries_state); 1696 int i; 1697 NTSTATUS status; 1698 1699 status = name_query_recv(subreq, state, &state->result_addrs, 1700 &state->num_result_addrs, &state->flags); 1701 1702 for (i=0; i<state->num_sent; i++) { 1703 if (state->subreqs[i] == subreq) { 1704 break; 1705 } 1706 } 1707 if (i == state->num_sent) { 1708 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); 1709 return; 1710 } 1711 TALLOC_FREE(state->subreqs[i]); 1712 1713 state->num_received += 1; 1714 1715 if (!NT_STATUS_IS_OK(status)) { 1716 1717 if (state->num_received >= state->num_addrs) { 1718 tevent_req_nterror(req, status); 1719 return; 1720 } 1721 /* 1722 * Still outstanding requests, just wait 1723 */ 1724 return; 1725 } 1726 state->received_index = i; 1727 tevent_req_done(req); 1728 } 1729 1730 static void name_queries_next(struct tevent_req *subreq) 1731 { 1732 struct tevent_req *req = tevent_req_callback_data( 1733 subreq, struct tevent_req); 1734 struct name_queries_state *state = tevent_req_data( 1735 req, struct name_queries_state); 1736 1737 if (!tevent_wakeup_recv(subreq)) { 1738 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); 1739 return; 1740 } 1741 1742 subreq = name_query_send( 1743 state->subreqs, state->ev, 1744 state->name, state->name_type, state->bcast, state->recurse, 1745 &state->addrs[state->num_sent]); 1746 if (tevent_req_nomem(subreq, req)) { 1747 return; 1748 } 1749 tevent_req_set_callback(subreq, name_queries_done, req); 1750 if (!tevent_req_set_endtime( 1751 subreq, state->ev, 1752 timeval_current_ofs(0, state->timeout_msec * 1000))) { 1753 tevent_req_oom(req); 1754 return; 1755 } 1756 state->subreqs[state->num_sent] = subreq; 1757 state->num_sent += 1; 1758 1759 if (state->num_sent < state->num_addrs) { 1760 subreq = tevent_wakeup_send( 1761 state, state->ev, 1762 timeval_current_ofs(0, state->wait_msec * 1000)); 1763 if (tevent_req_nomem(subreq, req)) { 1764 return; 1765 } 1766 tevent_req_set_callback(subreq, name_queries_next, req); 1767 } 1768 } 1769 1770 static NTSTATUS name_queries_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 1771 struct sockaddr_storage **result_addrs, 1772 int *num_result_addrs, uint8_t *flags, 1773 int *received_index) 1774 { 1775 struct name_queries_state *state = tevent_req_data( 1776 req, struct name_queries_state); 1777 NTSTATUS status; 1778 1779 if (tevent_req_is_nterror(req, &status)) { 1780 return status; 1781 } 1782 1783 if (result_addrs != NULL) { 1784 *result_addrs = talloc_move(mem_ctx, &state->result_addrs); 1785 } 1786 if (num_result_addrs != NULL) { 1787 *num_result_addrs = state->num_result_addrs; 1788 } 1789 if (flags != NULL) { 1790 *flags = state->flags; 1791 } 1792 if (received_index != NULL) { 1793 *received_index = state->received_index; 1794 } 1795 return NT_STATUS_OK; 1530 1796 } 1531 1797 … … 1533 1799 Resolve via "bcast" method. 1534 1800 *********************************************************/ 1801 1802 struct name_resolve_bcast_state { 1803 struct sockaddr_storage *addrs; 1804 int num_addrs; 1805 }; 1806 1807 static void name_resolve_bcast_done(struct tevent_req *subreq); 1808 1809 struct tevent_req *name_resolve_bcast_send(TALLOC_CTX *mem_ctx, 1810 struct tevent_context *ev, 1811 const char *name, 1812 int name_type) 1813 { 1814 struct tevent_req *req, *subreq; 1815 struct name_resolve_bcast_state *state; 1816 struct sockaddr_storage *bcast_addrs; 1817 int i, num_addrs, num_bcast_addrs; 1818 1819 req = tevent_req_create(mem_ctx, &state, 1820 struct name_resolve_bcast_state); 1821 if (req == NULL) { 1822 return NULL; 1823 } 1824 1825 if (lp_disable_netbios()) { 1826 DEBUG(5, ("name_resolve_bcast(%s#%02x): netbios is disabled\n", 1827 name, name_type)); 1828 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 1829 return tevent_req_post(req, ev); 1830 } 1831 1832 /* 1833 * "bcast" means do a broadcast lookup on all the local interfaces. 1834 */ 1835 1836 DEBUG(3, ("name_resolve_bcast: Attempting broadcast lookup " 1837 "for name %s<0x%x>\n", name, name_type)); 1838 1839 num_addrs = iface_count(); 1840 bcast_addrs = talloc_array(state, struct sockaddr_storage, num_addrs); 1841 if (tevent_req_nomem(bcast_addrs, req)) { 1842 return tevent_req_post(req, ev); 1843 } 1844 1845 /* 1846 * Lookup the name on all the interfaces, return on 1847 * the first successful match. 1848 */ 1849 num_bcast_addrs = 0; 1850 1851 for (i=0; i<num_addrs; i++) { 1852 const struct sockaddr_storage *pss = iface_n_bcast(i); 1853 1854 if (pss->ss_family != AF_INET) { 1855 continue; 1856 } 1857 bcast_addrs[num_bcast_addrs] = *pss; 1858 num_bcast_addrs += 1; 1859 } 1860 1861 subreq = name_queries_send(state, ev, name, name_type, true, true, 1862 bcast_addrs, num_bcast_addrs, 0, 1000); 1863 if (tevent_req_nomem(subreq, req)) { 1864 return tevent_req_post(req, ev); 1865 } 1866 tevent_req_set_callback(subreq, name_resolve_bcast_done, req); 1867 return req; 1868 } 1869 1870 static void name_resolve_bcast_done(struct tevent_req *subreq) 1871 { 1872 struct tevent_req *req = tevent_req_callback_data( 1873 subreq, struct tevent_req); 1874 struct name_resolve_bcast_state *state = tevent_req_data( 1875 req, struct name_resolve_bcast_state); 1876 NTSTATUS status; 1877 1878 status = name_queries_recv(subreq, state, 1879 &state->addrs, &state->num_addrs, 1880 NULL, NULL); 1881 TALLOC_FREE(subreq); 1882 if (tevent_req_nterror(req, status)) { 1883 return; 1884 } 1885 tevent_req_done(req); 1886 } 1887 1888 NTSTATUS name_resolve_bcast_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 1889 struct sockaddr_storage **addrs, 1890 int *num_addrs) 1891 { 1892 struct name_resolve_bcast_state *state = tevent_req_data( 1893 req, struct name_resolve_bcast_state); 1894 NTSTATUS status; 1895 1896 if (tevent_req_is_nterror(req, &status)) { 1897 return status; 1898 } 1899 *addrs = talloc_move(mem_ctx, &state->addrs); 1900 *num_addrs = state->num_addrs; 1901 return NT_STATUS_OK; 1902 } 1535 1903 1536 1904 NTSTATUS name_resolve_bcast(const char *name, … … 1540 1908 int *return_count) 1541 1909 { 1542 int i; 1543 int num_interfaces = iface_count(); 1544 struct sockaddr_storage *ss_list; 1545 NTSTATUS status = NT_STATUS_NOT_FOUND; 1546 1547 if (lp_disable_netbios()) { 1548 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", 1549 name, name_type)); 1550 return NT_STATUS_INVALID_PARAMETER; 1551 } 1552 1553 *return_iplist = NULL; 1554 *return_count = 0; 1555 1556 /* 1557 * "bcast" means do a broadcast lookup on all the local interfaces. 1558 */ 1559 1560 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup " 1561 "for name %s<0x%x>\n", name, name_type)); 1562 1563 /* 1564 * Lookup the name on all the interfaces, return on 1565 * the first successful match. 1566 */ 1567 for( i = num_interfaces-1; i >= 0; i--) { 1568 const struct sockaddr_storage *pss = iface_n_bcast(i); 1569 1570 /* Done this way to fix compiler error on IRIX 5.x */ 1571 if (!pss) { 1572 continue; 1573 } 1574 status = name_query(name, name_type, true, true, pss, 1575 talloc_tos(), &ss_list, return_count, 1576 NULL); 1577 if (NT_STATUS_IS_OK(status)) { 1578 goto success; 1579 } 1580 } 1581 1582 /* failed - no response */ 1583 1910 TALLOC_CTX *frame = talloc_stackframe(); 1911 struct tevent_context *ev; 1912 struct tevent_req *req; 1913 NTSTATUS status = NT_STATUS_NO_MEMORY; 1914 1915 ev = samba_tevent_context_init(frame); 1916 if (ev == NULL) { 1917 goto fail; 1918 } 1919 req = name_resolve_bcast_send(frame, ev, name, name_type); 1920 if (req == NULL) { 1921 goto fail; 1922 } 1923 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 1924 goto fail; 1925 } 1926 status = name_resolve_bcast_recv(req, mem_ctx, return_iplist, 1927 return_count); 1928 fail: 1929 TALLOC_FREE(frame); 1584 1930 return status; 1585 1586 success: 1587 *return_iplist = ss_list; 1588 return status; 1589 } 1590 1591 /******************************************************** 1592 Resolve via "wins" method. 1593 *********************************************************/ 1594 1595 NTSTATUS resolve_wins(const char *name, 1596 int name_type, 1597 struct ip_service **return_iplist, 1598 int *return_count) 1599 { 1600 int t, i; 1601 char **wins_tags; 1602 struct sockaddr_storage src_ss, *ss_list = NULL; 1931 } 1932 1933 struct query_wins_list_state { 1934 struct tevent_context *ev; 1935 const char *name; 1936 uint8_t name_type; 1937 struct in_addr *servers; 1938 uint32_t num_servers; 1939 struct sockaddr_storage server; 1940 uint32_t num_sent; 1941 1942 struct sockaddr_storage *addrs; 1943 int num_addrs; 1944 uint8_t flags; 1945 }; 1946 1947 static void query_wins_list_done(struct tevent_req *subreq); 1948 1949 /* 1950 * Query a list of (replicating) wins servers in sequence, call them 1951 * dead if they don't reply 1952 */ 1953 1954 static struct tevent_req *query_wins_list_send( 1955 TALLOC_CTX *mem_ctx, struct tevent_context *ev, 1956 struct in_addr src_ip, const char *name, uint8_t name_type, 1957 struct in_addr *servers, int num_servers) 1958 { 1959 struct tevent_req *req, *subreq; 1960 struct query_wins_list_state *state; 1961 1962 req = tevent_req_create(mem_ctx, &state, 1963 struct query_wins_list_state); 1964 if (req == NULL) { 1965 return NULL; 1966 } 1967 state->ev = ev; 1968 state->name = name; 1969 state->name_type = name_type; 1970 state->servers = servers; 1971 state->num_servers = num_servers; 1972 1973 if (state->num_servers == 0) { 1974 tevent_req_nterror(req, NT_STATUS_NOT_FOUND); 1975 return tevent_req_post(req, ev); 1976 } 1977 1978 in_addr_to_sockaddr_storage( 1979 &state->server, state->servers[state->num_sent]); 1980 1981 subreq = name_query_send(state, state->ev, 1982 state->name, state->name_type, 1983 false, true, &state->server); 1984 state->num_sent += 1; 1985 if (tevent_req_nomem(subreq, req)) { 1986 return tevent_req_post(req, ev); 1987 } 1988 if (!tevent_req_set_endtime(subreq, state->ev, 1989 timeval_current_ofs(2, 0))) { 1990 tevent_req_oom(req); 1991 return tevent_req_post(req, ev); 1992 } 1993 tevent_req_set_callback(subreq, query_wins_list_done, req); 1994 return req; 1995 } 1996 1997 static void query_wins_list_done(struct tevent_req *subreq) 1998 { 1999 struct tevent_req *req = tevent_req_callback_data( 2000 subreq, struct tevent_req); 2001 struct query_wins_list_state *state = tevent_req_data( 2002 req, struct query_wins_list_state); 2003 NTSTATUS status; 2004 2005 status = name_query_recv(subreq, state, 2006 &state->addrs, &state->num_addrs, 2007 &state->flags); 2008 TALLOC_FREE(subreq); 2009 if (NT_STATUS_IS_OK(status)) { 2010 tevent_req_done(req); 2011 return; 2012 } 2013 if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { 2014 tevent_req_nterror(req, status); 2015 return; 2016 } 2017 wins_srv_died(state->servers[state->num_sent-1], 2018 my_socket_addr_v4()); 2019 2020 if (state->num_sent == state->num_servers) { 2021 tevent_req_nterror(req, NT_STATUS_NOT_FOUND); 2022 return; 2023 } 2024 2025 in_addr_to_sockaddr_storage( 2026 &state->server, state->servers[state->num_sent]); 2027 2028 subreq = name_query_send(state, state->ev, 2029 state->name, state->name_type, 2030 false, true, &state->server); 2031 state->num_sent += 1; 2032 if (tevent_req_nomem(subreq, req)) { 2033 return; 2034 } 2035 if (!tevent_req_set_endtime(subreq, state->ev, 2036 timeval_current_ofs(2, 0))) { 2037 tevent_req_oom(req); 2038 return; 2039 } 2040 tevent_req_set_callback(subreq, query_wins_list_done, req); 2041 } 2042 2043 static NTSTATUS query_wins_list_recv(struct tevent_req *req, 2044 TALLOC_CTX *mem_ctx, 2045 struct sockaddr_storage **addrs, 2046 int *num_addrs, 2047 uint8_t *flags) 2048 { 2049 struct query_wins_list_state *state = tevent_req_data( 2050 req, struct query_wins_list_state); 2051 NTSTATUS status; 2052 2053 if (tevent_req_is_nterror(req, &status)) { 2054 return status; 2055 } 2056 if (addrs != NULL) { 2057 *addrs = talloc_move(mem_ctx, &state->addrs); 2058 } 2059 if (num_addrs != NULL) { 2060 *num_addrs = state->num_addrs; 2061 } 2062 if (flags != NULL) { 2063 *flags = state->flags; 2064 } 2065 return NT_STATUS_OK; 2066 } 2067 2068 struct resolve_wins_state { 2069 int num_sent; 2070 int num_received; 2071 2072 struct sockaddr_storage *addrs; 2073 int num_addrs; 2074 uint8_t flags; 2075 }; 2076 2077 static void resolve_wins_done(struct tevent_req *subreq); 2078 2079 struct tevent_req *resolve_wins_send(TALLOC_CTX *mem_ctx, 2080 struct tevent_context *ev, 2081 const char *name, 2082 int name_type) 2083 { 2084 struct tevent_req *req, *subreq; 2085 struct resolve_wins_state *state; 2086 char **wins_tags = NULL; 2087 struct sockaddr_storage src_ss; 1603 2088 struct in_addr src_ip; 1604 NTSTATUS status; 1605 1606 if (lp_disable_netbios()) { 1607 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", 1608 name, name_type)); 1609 return NT_STATUS_INVALID_PARAMETER; 1610 } 1611 1612 *return_iplist = NULL; 1613 *return_count = 0; 1614 1615 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", 1616 name, name_type)); 2089 int i, num_wins_tags; 2090 2091 req = tevent_req_create(mem_ctx, &state, 2092 struct resolve_wins_state); 2093 if (req == NULL) { 2094 return NULL; 2095 } 1617 2096 1618 2097 if (wins_srv_count() < 1) { 1619 2098 DEBUG(3,("resolve_wins: WINS server resolution selected " 1620 2099 "and no WINS servers listed.\n")); 1621 return NT_STATUS_INVALID_PARAMETER; 1622 } 1623 1624 /* we try a lookup on each of the WINS tags in turn */ 1625 wins_tags = wins_srv_tags(); 1626 1627 if (!wins_tags) { 1628 /* huh? no tags?? give up in disgust */ 1629 return NT_STATUS_INVALID_PARAMETER; 2100 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 2101 goto fail; 1630 2102 } 1631 2103 1632 2104 /* the address we will be sending from */ 1633 if (!interpret_string_addr(&src_ss, lp_ socket_address(),2105 if (!interpret_string_addr(&src_ss, lp_nbt_client_socket_address(), 1634 2106 AI_NUMERICHOST|AI_PASSIVE)) { 1635 2107 zero_sockaddr(&src_ss); … … 1642 2114 "on IPv6 address %s\n", 1643 2115 addr)); 1644 wins_srv_tags_free(wins_tags); 1645 return NT_STATUS_INVALID_PARAMETER; 1646 } 1647 1648 src_ip = ((struct sockaddr_in *)&src_ss)->sin_addr; 1649 1650 /* in the worst case we will try every wins server with every 1651 tag! */ 1652 for (t=0; wins_tags && wins_tags[t]; t++) { 1653 int srv_count = wins_srv_count_tag(wins_tags[t]); 1654 for (i=0; i<srv_count; i++) { 1655 struct sockaddr_storage wins_ss; 1656 struct in_addr wins_ip; 1657 1658 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip); 2116 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 2117 goto fail; 2118 } 2119 2120 src_ip = ((const struct sockaddr_in *)(void *)&src_ss)->sin_addr; 2121 2122 wins_tags = wins_srv_tags(); 2123 if (wins_tags == NULL) { 2124 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 2125 goto fail; 2126 } 2127 2128 num_wins_tags = 0; 2129 while (wins_tags[num_wins_tags] != NULL) { 2130 num_wins_tags += 1; 2131 } 2132 2133 for (i=0; i<num_wins_tags; i++) { 2134 int num_servers, num_alive; 2135 struct in_addr *servers, *alive; 2136 int j; 2137 2138 if (!wins_server_tag_ips(wins_tags[i], talloc_tos(), 2139 &servers, &num_servers)) { 2140 DEBUG(10, ("wins_server_tag_ips failed for tag %s\n", 2141 wins_tags[i])); 2142 continue; 2143 } 2144 2145 alive = talloc_array(state, struct in_addr, num_servers); 2146 if (tevent_req_nomem(alive, req)) { 2147 goto fail; 2148 } 2149 2150 num_alive = 0; 2151 for (j=0; j<num_servers; j++) { 2152 struct in_addr wins_ip = servers[j]; 1659 2153 1660 2154 if (global_in_nmbd && ismyip_v4(wins_ip)) { … … 1662 2156 continue; 1663 2157 } 1664 1665 2158 /* skip any that have been unresponsive lately */ 1666 2159 if (wins_srv_is_dead(wins_ip, src_ip)) { 1667 2160 continue; 1668 2161 } 1669 1670 DEBUG(3,("resolve_wins: using WINS server %s " 1671 "and tag '%s'\n", 1672 inet_ntoa(wins_ip), wins_tags[t])); 1673 1674 in_addr_to_sockaddr_storage(&wins_ss, wins_ip); 1675 status = name_query(name, 1676 name_type, 1677 false, 1678 true, 1679 &wins_ss, 1680 talloc_tos(), 1681 &ss_list, 1682 return_count, 1683 NULL); 1684 1685 /* exit loop if we got a list of addresses */ 1686 1687 if (NT_STATUS_IS_OK(status)) { 1688 goto success; 1689 } 1690 1691 if (NT_STATUS_EQUAL(status, 1692 NT_STATUS_IO_TIMEOUT)) { 1693 /* Timed out waiting for WINS server to 1694 * respond. 1695 * Mark it dead. */ 1696 wins_srv_died(wins_ip, src_ip); 1697 } else { 1698 /* The name definitely isn't in this 1699 group of WINS servers. 1700 goto the next group */ 1701 break; 1702 } 1703 } 2162 DEBUG(3, ("resolve_wins: using WINS server %s " 2163 "and tag '%s'\n", 2164 inet_ntoa(wins_ip), wins_tags[i])); 2165 alive[num_alive] = wins_ip; 2166 num_alive += 1; 2167 } 2168 TALLOC_FREE(servers); 2169 2170 if (num_alive == 0) { 2171 continue; 2172 } 2173 2174 subreq = query_wins_list_send( 2175 state, ev, src_ip, name, name_type, 2176 alive, num_alive); 2177 if (tevent_req_nomem(subreq, req)) { 2178 goto fail; 2179 } 2180 tevent_req_set_callback(subreq, resolve_wins_done, req); 2181 state->num_sent += 1; 2182 } 2183 2184 if (state->num_sent == 0) { 2185 tevent_req_nterror(req, NT_STATUS_NOT_FOUND); 2186 goto fail; 1704 2187 } 1705 2188 1706 2189 wins_srv_tags_free(wins_tags); 1707 return NT_STATUS_NO_LOGON_SERVERS; 1708 1709 success: 1710 1711 status = NT_STATUS_OK; 1712 if (!convert_ss2service(return_iplist, ss_list, return_count)) 1713 status = NT_STATUS_INVALID_PARAMETER; 1714 1715 TALLOC_FREE(ss_list); 2190 return req; 2191 fail: 1716 2192 wins_srv_tags_free(wins_tags); 1717 2193 return tevent_req_post(req, ev); 2194 } 2195 2196 static void resolve_wins_done(struct tevent_req *subreq) 2197 { 2198 struct tevent_req *req = tevent_req_callback_data( 2199 subreq, struct tevent_req); 2200 struct resolve_wins_state *state = tevent_req_data( 2201 req, struct resolve_wins_state); 2202 NTSTATUS status; 2203 2204 status = query_wins_list_recv(subreq, state, &state->addrs, 2205 &state->num_addrs, &state->flags); 2206 if (NT_STATUS_IS_OK(status)) { 2207 tevent_req_done(req); 2208 return; 2209 } 2210 2211 state->num_received += 1; 2212 2213 if (state->num_received < state->num_sent) { 2214 /* 2215 * Wait for the others 2216 */ 2217 return; 2218 } 2219 tevent_req_nterror(req, status); 2220 } 2221 2222 NTSTATUS resolve_wins_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 2223 struct sockaddr_storage **addrs, 2224 int *num_addrs, uint8_t *flags) 2225 { 2226 struct resolve_wins_state *state = tevent_req_data( 2227 req, struct resolve_wins_state); 2228 NTSTATUS status; 2229 2230 if (tevent_req_is_nterror(req, &status)) { 2231 return status; 2232 } 2233 if (addrs != NULL) { 2234 *addrs = talloc_move(mem_ctx, &state->addrs); 2235 } 2236 if (num_addrs != NULL) { 2237 *num_addrs = state->num_addrs; 2238 } 2239 if (flags != NULL) { 2240 *flags = state->flags; 2241 } 2242 return NT_STATUS_OK; 2243 } 2244 2245 /******************************************************** 2246 Resolve via "wins" method. 2247 *********************************************************/ 2248 2249 NTSTATUS resolve_wins(const char *name, 2250 int name_type, 2251 TALLOC_CTX *mem_ctx, 2252 struct sockaddr_storage **return_iplist, 2253 int *return_count) 2254 { 2255 struct tevent_context *ev; 2256 struct tevent_req *req; 2257 NTSTATUS status = NT_STATUS_NO_MEMORY; 2258 2259 ev = samba_tevent_context_init(talloc_tos()); 2260 if (ev == NULL) { 2261 goto fail; 2262 } 2263 req = resolve_wins_send(ev, ev, name, name_type); 2264 if (req == NULL) { 2265 goto fail; 2266 } 2267 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 2268 goto fail; 2269 } 2270 status = resolve_wins_recv(req, mem_ctx, return_iplist, return_count, 2271 NULL); 2272 fail: 2273 TALLOC_FREE(ev); 1718 2274 return status; 1719 2275 } 1720 1721 /********************************************************1722 Resolve via "lmhosts" method.1723 *********************************************************/1724 1725 static NTSTATUS resolve_lmhosts(const char *name, int name_type,1726 struct ip_service **return_iplist,1727 int *return_count)1728 {1729 /*1730 * "lmhosts" means parse the local lmhosts file.1731 */1732 struct sockaddr_storage *ss_list;1733 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;1734 TALLOC_CTX *ctx = NULL;1735 1736 *return_iplist = NULL;1737 *return_count = 0;1738 1739 DEBUG(3,("resolve_lmhosts: "1740 "Attempting lmhosts lookup for name %s<0x%x>\n",1741 name, name_type));1742 1743 ctx = talloc_init("resolve_lmhosts");1744 if (!ctx) {1745 return NT_STATUS_NO_MEMORY;1746 }1747 1748 status = resolve_lmhosts_file_as_sockaddr(get_dyn_LMHOSTSFILE(),1749 name, name_type,1750 ctx,1751 &ss_list,1752 return_count);1753 if (NT_STATUS_IS_OK(status)) {1754 if (convert_ss2service(return_iplist,1755 ss_list,1756 return_count)) {1757 talloc_free(ctx);1758 return NT_STATUS_OK;1759 } else {1760 talloc_free(ctx);1761 return NT_STATUS_NO_MEMORY;1762 }1763 }1764 talloc_free(ctx);1765 return status;1766 }1767 1768 2276 1769 2277 /******************************************************** … … 1772 2280 1773 2281 static NTSTATUS resolve_hosts(const char *name, int name_type, 1774 struct ip_service **return_iplist, 2282 TALLOC_CTX *mem_ctx, 2283 struct sockaddr_storage **return_iplist, 1775 2284 int *return_count) 1776 2285 { … … 1833 2342 *return_count += 1; 1834 2343 1835 *return_iplist = SMB_REALLOC_ARRAY(*return_iplist,1836 struct ip_service,1837 2344 *return_iplist = talloc_realloc( 2345 mem_ctx, *return_iplist, struct sockaddr_storage, 2346 *return_count); 1838 2347 if (!*return_iplist) { 1839 2348 DEBUG(3,("resolve_hosts: malloc fail !\n")); … … 1841 2350 return NT_STATUS_NO_MEMORY; 1842 2351 } 1843 (*return_iplist)[i].ss = ss; 1844 (*return_iplist)[i].port = PORT_NONE; 2352 (*return_iplist)[i] = ss; 1845 2353 i++; 1846 2354 } … … 1885 2393 1886 2394 /* The DNS code needs fixing to find IPv6 addresses... JRA. */ 1887 1888 2395 switch (name_type) { 1889 2396 case 0x1b: 1890 2397 DEBUG(5,("resolve_ads: Attempting to resolve " 1891 2398 "PDC for %s using DNS\n", name)); 1892 status = ads_dns_query_pdc(ctx, name, &dcs, &numdcs); 2399 status = ads_dns_query_pdc(ctx, 2400 name, 2401 &dcs, 2402 &numdcs); 1893 2403 break; 1894 2404 … … 1896 2406 DEBUG(5,("resolve_ads: Attempting to resolve " 1897 2407 "DCs for %s using DNS\n", name)); 1898 status = ads_dns_query_dcs(ctx, name, sitename, &dcs, 2408 status = ads_dns_query_dcs(ctx, 2409 name, 2410 sitename, 2411 &dcs, 1899 2412 &numdcs); 1900 2413 break; … … 1902 2415 DEBUG(5,("resolve_ads: Attempting to resolve " 1903 2416 "KDCs for %s using DNS\n", name)); 1904 status = ads_dns_query_kdcs(ctx, name, sitename, &dcs, 2417 status = ads_dns_query_kdcs(ctx, 2418 name, 2419 sitename, 2420 &dcs, 1905 2421 &numdcs); 1906 2422 break; … … 1913 2429 talloc_destroy(ctx); 1914 2430 return status; 2431 } 2432 2433 if (numdcs == 0) { 2434 *return_iplist = NULL; 2435 *return_count = 0; 2436 talloc_destroy(ctx); 2437 return NT_STATUS_OK; 1915 2438 } 1916 2439 … … 2012 2535 } 2013 2536 2537 static const char **filter_out_nbt_lookup(TALLOC_CTX *mem_ctx, 2538 const char **resolve_order) 2539 { 2540 size_t i, len, result_idx; 2541 const char **result; 2542 2543 len = 0; 2544 while (resolve_order[len] != NULL) { 2545 len += 1; 2546 } 2547 2548 result = talloc_array(mem_ctx, const char *, len+1); 2549 if (result == NULL) { 2550 return NULL; 2551 } 2552 2553 result_idx = 0; 2554 2555 for (i=0; i<len; i++) { 2556 const char *tok = resolve_order[i]; 2557 2558 if (strequal(tok, "lmhosts") || strequal(tok, "wins") || 2559 strequal(tok, "bcast")) { 2560 continue; 2561 } 2562 result[result_idx++] = tok; 2563 } 2564 result[result_idx] = NULL; 2565 2566 return result; 2567 } 2568 2014 2569 /******************************************************************* 2015 2570 Internal interface to resolve a name into an IP address. … … 2028 2583 struct ip_service **return_iplist, 2029 2584 int *return_count, 2030 const char *resolve_order) 2031 { 2032 char *tok; 2033 const char *ptr; 2585 const char **resolve_order) 2586 { 2587 const char *tok; 2034 2588 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 2035 2589 int i; … … 2084 2638 /* set the name resolution order */ 2085 2639 2086 if ( strcmp( resolve_order, "NULL") == 0) {2640 if (resolve_order && strcmp(resolve_order[0], "NULL") == 0) { 2087 2641 DEBUG(8,("internal_resolve_name: all lookups disabled\n")); 2088 2642 return NT_STATUS_INVALID_PARAMETER; 2089 2643 } 2090 2644 2091 if (!resolve_order[0]) { 2092 ptr = "host"; 2093 } else { 2094 ptr = resolve_order; 2645 if (!resolve_order || !resolve_order[0]) { 2646 static const char *host_order[] = { "host", NULL }; 2647 resolve_order = host_order; 2648 } 2649 2650 frame = talloc_stackframe(); 2651 2652 if ((strlen(name) > MAX_NETBIOSNAME_LEN - 1) || 2653 (strchr(name, '.') != NULL)) { 2654 /* 2655 * Don't do NBT lookup, the name would not fit anyway 2656 */ 2657 resolve_order = filter_out_nbt_lookup(frame, resolve_order); 2658 if (resolve_order == NULL) { 2659 TALLOC_FREE(frame); 2660 return NT_STATUS_NO_MEMORY; 2661 } 2095 2662 } 2096 2663 2097 2664 /* iterate through the name resolution backends */ 2098 2665 2099 frame = talloc_stackframe(); 2100 while (next_token_talloc(frame, &ptr, &tok, LIST_SEP)) { 2666 for (i=0; resolve_order[i]; i++) { 2667 tok = resolve_order[i]; 2668 2101 2669 if((strequal(tok, "host") || strequal(tok, "hosts"))) { 2102 status = resolve_hosts(name, name_type, return_iplist, 2670 struct sockaddr_storage *ss_list; 2671 status = resolve_hosts(name, name_type, 2672 talloc_tos(), &ss_list, 2103 2673 return_count); 2104 2674 if (NT_STATUS_IS_OK(status)) { 2675 if (!convert_ss2service(return_iplist, 2676 ss_list, 2677 return_count)) { 2678 status = NT_STATUS_NO_MEMORY; 2679 } 2105 2680 goto done; 2106 2681 } … … 2124 2699 goto done; 2125 2700 } 2126 } else if(strequal( tok, "lmhosts")) { 2127 status = resolve_lmhosts(name, name_type, 2128 return_iplist, return_count); 2701 } else if (strequal(tok, "lmhosts")) { 2702 struct sockaddr_storage *ss_list; 2703 status = resolve_lmhosts_file_as_sockaddr( 2704 get_dyn_LMHOSTSFILE(), name, name_type, 2705 talloc_tos(), &ss_list, return_count); 2129 2706 if (NT_STATUS_IS_OK(status)) { 2707 if (!convert_ss2service(return_iplist, 2708 ss_list, 2709 return_count)) { 2710 status = NT_STATUS_NO_MEMORY; 2711 } 2130 2712 goto done; 2131 2713 } 2132 } else if (strequal(tok, "wins")) {2714 } else if (strequal(tok, "wins")) { 2133 2715 /* don't resolve 1D via WINS */ 2716 struct sockaddr_storage *ss_list; 2134 2717 if (name_type != 0x1D) { 2135 2718 status = resolve_wins(name, name_type, 2136 return_iplist, 2719 talloc_tos(), 2720 &ss_list, 2137 2721 return_count); 2138 2722 if (NT_STATUS_IS_OK(status)) { 2723 if (!convert_ss2service(return_iplist, 2724 ss_list, 2725 return_count)) { 2726 status = NT_STATUS_NO_MEMORY; 2727 } 2139 2728 goto done; 2140 2729 } 2141 2730 } 2142 } else if (strequal(tok, "bcast")) {2731 } else if (strequal(tok, "bcast")) { 2143 2732 struct sockaddr_storage *ss_list; 2144 2733 status = name_resolve_bcast( … … 2230 2819 char *sitename = NULL; 2231 2820 int count = 0; 2821 NTSTATUS status; 2232 2822 2233 2823 if (is_ipaddress(name)) { … … 2235 2825 } 2236 2826 2237 sitename = sitename_fetch(lp_realm()); /* wild guess */ 2238 2239 if (NT_STATUS_IS_OK(internal_resolve_name(name, name_type, sitename, 2240 &ss_list, &count, 2241 lp_name_resolve_order()))) { 2827 sitename = sitename_fetch(talloc_tos(), lp_realm()); /* wild guess */ 2828 2829 status = internal_resolve_name(name, name_type, sitename, 2830 &ss_list, &count, 2831 lp_name_resolve_order()); 2832 if (NT_STATUS_IS_OK(status)) { 2242 2833 int i; 2243 2834 … … 2245 2836 for (i=0; i<count; i++) { 2246 2837 if (!is_zero_addr(&ss_list[i].ss) && 2247 !is_broadcast_addr((struct sockaddr*)&ss_list[i].ss) &&2838 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss) && 2248 2839 (ss_list[i].ss.ss_family == AF_INET)) { 2249 2840 *return_ss = ss_list[i].ss; 2250 2841 SAFE_FREE(ss_list); 2251 SAFE_FREE(sitename);2842 TALLOC_FREE(sitename); 2252 2843 return True; 2253 2844 } … … 2258 2849 for (i=0; i<count; i++) { 2259 2850 if (!is_zero_addr(&ss_list[i].ss) && 2260 !is_broadcast_addr((struct sockaddr*)&ss_list[i].ss)) {2851 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) { 2261 2852 *return_ss = ss_list[i].ss; 2262 2853 SAFE_FREE(ss_list); 2263 SAFE_FREE(sitename);2854 TALLOC_FREE(sitename); 2264 2855 return True; 2265 2856 } … … 2268 2859 2269 2860 SAFE_FREE(ss_list); 2270 SAFE_FREE(sitename);2861 TALLOC_FREE(sitename); 2271 2862 return False; 2272 2863 } … … 2296 2887 2297 2888 if (is_ipaddress(name)) { 2298 *return_ss_arr = TALLOC_P(ctx, struct sockaddr_storage);2889 *return_ss_arr = talloc(ctx, struct sockaddr_storage); 2299 2890 if (!*return_ss_arr) { 2300 2891 return NT_STATUS_NO_MEMORY; … … 2308 2899 } 2309 2900 2310 sitename = sitename_fetch( lp_realm()); /* wild guess */2901 sitename = sitename_fetch(ctx, lp_realm()); /* wild guess */ 2311 2902 2312 2903 status = internal_resolve_name(name, name_type, sitename, 2313 2904 &ss_list, &count, 2314 2905 lp_name_resolve_order()); 2315 SAFE_FREE(sitename);2906 TALLOC_FREE(sitename); 2316 2907 2317 2908 if (!NT_STATUS_IS_OK(status)) { … … 2322 2913 for (i=0, num_entries = 0; i<count; i++) { 2323 2914 if (!is_zero_addr(&ss_list[i].ss) && 2324 !is_broadcast_addr((struct sockaddr*)&ss_list[i].ss)) {2915 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) { 2325 2916 num_entries++; 2326 2917 } … … 2331 2922 } 2332 2923 2333 *return_ss_arr = TALLOC_ARRAY(ctx,2924 *return_ss_arr = talloc_array(ctx, 2334 2925 struct sockaddr_storage, 2335 2926 num_entries); … … 2341 2932 for (i=0, num_entries = 0; i<count; i++) { 2342 2933 if (!is_zero_addr(&ss_list[i].ss) && 2343 !is_broadcast_addr((struct sockaddr*)&ss_list[i].ss)) {2934 !is_broadcast_addr((struct sockaddr *)(void *)&ss_list[i].ss)) { 2344 2935 (*return_ss_arr)[num_entries++] = ss_list[i].ss; 2345 2936 } … … 2398 2989 int count = 0; 2399 2990 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; 2400 2991 static const char *ads_order[] = { "ads", NULL }; 2401 2992 /* Look up #1B name */ 2402 2993 2403 2994 if (lp_security() == SEC_ADS) { 2404 2995 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list, 2405 &count, "ads");2996 &count, ads_order); 2406 2997 } 2407 2998 … … 2411 3002 lp_name_resolve_order()); 2412 3003 if (!NT_STATUS_IS_OK(status)) { 3004 SAFE_FREE(ip_list); 2413 3005 return false; 2414 3006 } … … 2444 3036 bool *ordered) 2445 3037 { 2446 c har*resolve_order = NULL;3038 const char **resolve_order = NULL; 2447 3039 char *saf_servername = NULL; 2448 3040 char *pserver = NULL; … … 2459 3051 NTSTATUS status; 2460 3052 TALLOC_CTX *ctx = talloc_init("get_dc_list"); 3053 int auto_name_type = 0x1C; 2461 3054 2462 3055 *ip_list = NULL; … … 2475 3068 NULL. */ 2476 3069 2477 resolve_order = talloc_strdup(ctx, lp_name_resolve_order());3070 resolve_order = lp_name_resolve_order(); 2478 3071 if (!resolve_order) { 2479 3072 status = NT_STATUS_NO_MEMORY; 2480 3073 goto out; 2481 3074 } 2482 strlower_m(resolve_order);2483 3075 if (lookup_type == DC_ADS_ONLY) { 2484 if (strstr( resolve_order, "host")) { 2485 resolve_order = talloc_strdup(ctx, "ads"); 3076 if (str_list_check_ci(resolve_order, "host")) { 3077 static const char *ads_order[] = { "ads", NULL }; 3078 resolve_order = ads_order; 2486 3079 2487 3080 /* DNS SRV lookups used by the ads resolver … … 2489 3082 *ordered = true; 2490 3083 } else { 2491 resolve_order = talloc_strdup(ctx, "NULL"); 3084 /* this is quite bizarre! */ 3085 static const char *null_order[] = { "NULL", NULL }; 3086 resolve_order = null_order; 2492 3087 } 2493 3088 } else if (lookup_type == DC_KDC_ONLY) { 3089 static const char *kdc_order[] = { "kdc", NULL }; 2494 3090 /* DNS SRV lookups used by the ads/kdc resolver 2495 3091 are already sorted by priority and weight */ 2496 3092 *ordered = true; 2497 resolve_order = talloc_strdup(ctx, "kdc"); 2498 } 2499 if (!resolve_order) { 2500 status = NT_STATUS_NO_MEMORY; 2501 goto out; 3093 resolve_order = kdc_order; 3094 auto_name_type = KDC_NAME_TYPE; 2502 3095 } 2503 3096 … … 2505 3098 'password server' list to a search for our domain controllers */ 2506 3099 2507 saf_servername = saf_fetch( domain);3100 saf_servername = saf_fetch(ctx, domain); 2508 3101 2509 3102 if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) { 2510 3103 pserver = talloc_asprintf(ctx, "%s, %s", 2511 3104 saf_servername ? saf_servername : "", 2512 lp_password server());3105 lp_password_server()); 2513 3106 } else { 2514 3107 pserver = talloc_asprintf(ctx, "%s, *", … … 2516 3109 } 2517 3110 2518 SAFE_FREE(saf_servername);3111 TALLOC_FREE(saf_servername); 2519 3112 if (!pserver) { 2520 3113 status = NT_STATUS_NO_MEMORY; 2521 goto out;2522 }2523 2524 /* if we are starting from scratch, just lookup DOMAIN<0x1c> */2525 2526 if (!*pserver ) {2527 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));2528 status = internal_resolve_name(domain, 0x1C, sitename, ip_list,2529 count, resolve_order);2530 3114 goto out; 2531 3115 } … … 2543 3127 while (next_token_talloc(ctx, &p, &name, LIST_SEP)) { 2544 3128 if (!done_auto_lookup && strequal(name, "*")) { 2545 status = internal_resolve_name(domain, 0x1C, sitename, 3129 status = internal_resolve_name(domain, auto_name_type, 3130 sitename, 2546 3131 &auto_ip_list, 2547 3132 &auto_count, … … 2561 3146 just return the list of DC's. Or maybe we just failed. */ 2562 3147 2563 if ( (num_addresses == 0)) {3148 if (num_addresses == 0) { 2564 3149 if (done_auto_lookup) { 2565 3150 DEBUG(4,("get_dc_list: no servers found\n")); … … 2567 3152 goto out; 2568 3153 } 2569 status = internal_resolve_name(domain, 0x1C, sitename, ip_list, 3154 status = internal_resolve_name(domain, auto_name_type, 3155 sitename, ip_list, 2570 3156 count, resolve_order); 2571 3157 goto out; … … 2619 3205 * (not that I think anyone will ever run the LDAP 2620 3206 * server in an AD domain on something other than 2621 * port 389 */ 2622 2623 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE; 3207 * port 389 3208 * However, the port should not be used for kerberos 3209 */ 3210 3211 port = (lookup_type == DC_ADS_ONLY) ? LDAP_PORT : 3212 ((lookup_type == DC_KDC_ONLY) ? DEFAULT_KRB5_PORT : 3213 PORT_NONE); 2624 3214 if ((port_str=strchr(name, ':')) != NULL) { 2625 3215 *port_str = '\0'; 2626 port_str++; 2627 port = atoi(port_str); 3216 if (lookup_type != DC_KDC_ONLY) { 3217 port_str++; 3218 port = atoi(port_str); 3219 } 2628 3220 } 2629 3221 … … 2716 3308 2717 3309 DEBUG(8,("get_sorted_dc_list: attempting lookup " 2718 "for name %s (sitename %s) using [%s]\n",3310 "for name %s (sitename %s)\n", 2719 3311 domain, 2720 sitename ? sitename : "NULL", 2721 (ads_only ? "ads" : lp_name_resolve_order()))); 3312 sitename ? sitename : "NULL")); 2722 3313 2723 3314 if (ads_only) {
Note:
See TracChangeset
for help on using the changeset viewer.