Changeset 988 for vendor/current/source4/libcli/resolve
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/source4/libcli/resolve
- Files:
-
- 1 added
- 1 deleted
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/libcli/resolve/bcast.c
r740 r988 48 48 struct resolve_bcast_data *data = talloc_get_type(userdata, struct resolve_bcast_data); 49 49 50 num_interfaces = iface_ count(data->ifaces);50 num_interfaces = iface_list_count(data->ifaces); 51 51 52 52 address_list = talloc_array(mem_ctx, const char *, num_interfaces+1); … … 54 54 55 55 for (i=0;i<num_interfaces;i++) { 56 const char *bcast = iface_n_bcast(data->ifaces, i); 57 if (bcast == NULL) continue; 56 bool ipv4 = iface_list_n_is_v4(data->ifaces, i); 57 const char *bcast; 58 59 if (!ipv4) { 60 continue; 61 } 62 63 bcast = iface_list_n_bcast(data->ifaces, i); 64 if (bcast == NULL) { 65 continue; 66 } 67 58 68 address_list[count] = talloc_strdup(address_list, bcast); 59 69 if (address_list[count] == NULL) { … … 102 112 { 103 113 struct interface *ifaces; 104 load_interface s(ctx, lpcfg_interfaces(lp_ctx), &ifaces);114 load_interface_list(ctx, lp_ctx, &ifaces); 105 115 return resolve_context_add_bcast_method(ctx, ifaces, lpcfg_nbt_port(lp_ctx), lpcfg_parm_int(lp_ctx, NULL, "nbt", "timeout", 1)); 106 116 } -
vendor/current/source4/libcli/resolve/dns_ex.c
r740 r988 6 6 Copyright (C) Andrew Tridgell 2005 7 7 Copyright (C) Stefan Metzmacher 2008 8 Copyright (C) Matthieu Patou 2011 8 9 9 10 This program is free software; you can redistribute it and/or modify … … 38 39 #include "librpc/gen_ndr/ndr_nbt.h" 39 40 #include "libcli/resolve/resolve.h" 40 41 #ifdef class 42 #undef class 43 #endif 44 45 #include "heimdal/lib/roken/resolve.h" 41 #include "lib/util/util_net.h" 42 #include "lib/addns/dnsquery.h" 43 #include "lib/addns/dns.h" 44 #include <arpa/nameser.h> 45 #include <resolv.h> 46 46 47 47 struct dns_ex_state { … … 76 76 } 77 77 78 struct dns_records_container { 79 char **list; 80 uint32_t count; 81 }; 82 83 static int reply_to_addrs(TALLOC_CTX *mem_ctx, uint32_t *a_num, 84 char ***cur_addrs, uint32_t total, 85 struct dns_request *reply, int port) 86 { 87 char addrstr[INET6_ADDRSTRLEN]; 88 struct dns_rrec *rr; 89 char **addrs; 90 uint32_t i; 91 const char *addr; 92 93 /* at most we over-allocate here, but not by much */ 94 addrs = talloc_realloc(mem_ctx, *cur_addrs, char *, 95 total + reply->num_answers); 96 if (!addrs) { 97 return 0; 98 } 99 *cur_addrs = addrs; 100 101 for (i = 0; i < reply->num_answers; i++) { 102 rr = reply->answers[i]; 103 104 /* we are only interested in the IN class */ 105 if (rr->r_class != DNS_CLASS_IN) { 106 continue; 107 } 108 109 if (rr->type == QTYPE_NS) { 110 /* 111 * After the record for NS will come the A or AAAA 112 * record of the NS. 113 */ 114 break; 115 } 116 117 /* verify we actually have a record here */ 118 if (!rr->data) { 119 continue; 120 } 121 122 /* we are only interested in A and AAAA records */ 123 switch (rr->type) { 124 case QTYPE_A: 125 addr = inet_ntop(AF_INET, 126 (struct in_addr *)rr->data, 127 addrstr, sizeof(addrstr)); 128 if (addr == NULL) { 129 continue; 130 } 131 break; 132 case QTYPE_AAAA: 133 #ifdef HAVE_IPV6 134 addr = inet_ntop(AF_INET6, 135 (struct in6_addr *)rr->data, 136 addrstr, sizeof(addrstr)); 137 #else 138 addr = NULL; 139 #endif 140 if (addr == NULL) { 141 continue; 142 } 143 break; 144 default: 145 continue; 146 } 147 148 addrs[total] = talloc_asprintf(addrs, "%s@%u/%s", 149 addrstr, port, 150 rr->name->pLabelList->label); 151 if (addrs[total]) { 152 total++; 153 if (rr->type == QTYPE_A) { 154 (*a_num)++; 155 } 156 } 157 } 158 159 return total; 160 } 161 162 static DNS_ERROR dns_lookup(TALLOC_CTX *mem_ctx, const char* name, 163 uint16_t q_type, struct dns_request **reply) 164 { 165 int len, rlen; 166 uint8_t *answer; 167 bool loop; 168 struct dns_buffer buf; 169 DNS_ERROR err; 170 171 /* give space for a good sized answer by default */ 172 answer = NULL; 173 len = 1500; 174 do { 175 answer = talloc_realloc(mem_ctx, answer, uint8_t, len); 176 if (!answer) { 177 return ERROR_DNS_NO_MEMORY; 178 } 179 rlen = res_search(name, DNS_CLASS_IN, q_type, answer, len); 180 if (rlen == -1) { 181 if (len >= 65535) { 182 return ERROR_DNS_SOCKET_ERROR; 183 } 184 /* retry once with max packet size */ 185 len = 65535; 186 loop = true; 187 } else if (rlen > len) { 188 len = rlen; 189 loop = true; 190 } else { 191 loop = false; 192 } 193 } while(loop); 194 195 buf.data = answer; 196 buf.size = rlen; 197 buf.offset = 0; 198 buf.error = ERROR_DNS_SUCCESS; 199 200 err = dns_unmarshall_request(mem_ctx, &buf, reply); 201 202 TALLOC_FREE(answer); 203 return err; 204 } 205 206 static struct dns_records_container get_a_aaaa_records(TALLOC_CTX *mem_ctx, 207 const char* name, 208 int port) 209 { 210 struct dns_request *reply; 211 struct dns_records_container ret; 212 char **addrs = NULL; 213 uint32_t a_num, total; 214 uint16_t qtype; 215 TALLOC_CTX *tmp_ctx; 216 DNS_ERROR err; 217 218 memset(&ret, 0, sizeof(struct dns_records_container)); 219 220 tmp_ctx = talloc_new(mem_ctx); 221 if (!tmp_ctx) { 222 return ret; 223 } 224 225 qtype = QTYPE_AAAA; 226 227 /* this is the blocking call we are going to lots of trouble 228 to avoid them in the parent */ 229 err = dns_lookup(tmp_ctx, name, qtype, &reply); 230 if (!ERR_DNS_IS_OK(err)) { 231 qtype = QTYPE_A; 232 err = dns_lookup(tmp_ctx, name, qtype, &reply); 233 if (!ERR_DNS_IS_OK(err)) { 234 goto done; 235 } 236 } 237 238 a_num = total = 0; 239 total = reply_to_addrs(tmp_ctx, &a_num, &addrs, total, reply, port); 240 241 if (qtype == QTYPE_AAAA && a_num == 0) { 242 /* 243 * DNS server didn't returned A when asked for AAAA records. 244 * Most of the server do it, let's ask for A specificaly. 245 */ 246 err = dns_lookup(tmp_ctx, name, QTYPE_A, &reply); 247 if (!ERR_DNS_IS_OK(err)) { 248 goto done; 249 } 250 251 total = reply_to_addrs(tmp_ctx, &a_num, &addrs, total, 252 reply, port); 253 254 } 255 256 if (total) { 257 talloc_steal(mem_ctx, addrs); 258 ret.count = total; 259 ret.list = addrs; 260 } 261 262 done: 263 TALLOC_FREE(tmp_ctx); 264 return ret; 265 } 266 267 static struct dns_records_container get_srv_records(TALLOC_CTX *mem_ctx, 268 const char* name) 269 { 270 struct dns_records_container ret; 271 char **addrs = NULL; 272 struct dns_rr_srv *dclist; 273 NTSTATUS status; 274 uint32_t total; 275 unsigned i; 276 int count; 277 278 memset(&ret, 0, sizeof(struct dns_records_container)); 279 /* this is the blocking call we are going to lots of trouble 280 to avoid them in the parent */ 281 status = ads_dns_lookup_srv(mem_ctx, name, &dclist, &count); 282 if (!NT_STATUS_IS_OK(status)) { 283 return ret; 284 } 285 total = 0; 286 if (count == 0) { 287 return ret; 288 } 289 290 /* Loop over all returned records and pick the records */ 291 for (i = 0; i < count; i++) { 292 struct dns_records_container c; 293 const char* tmp_str; 294 295 tmp_str = dclist[i].hostname; 296 if (strchr(tmp_str, '.') && tmp_str[strlen(tmp_str)-1] != '.') { 297 /* we are asking for a fully qualified name, but the 298 name doesn't end in a '.'. We need to prevent the 299 DNS library trying the search domains configured in 300 resolv.conf */ 301 tmp_str = talloc_asprintf(mem_ctx, "%s.", tmp_str); 302 } 303 304 c = get_a_aaaa_records(mem_ctx, tmp_str, dclist[i].port); 305 total += c.count; 306 if (addrs == NULL) { 307 addrs = c.list; 308 } else { 309 unsigned j; 310 311 addrs = talloc_realloc(mem_ctx, addrs, char*, total); 312 for (j=0; j < c.count; j++) { 313 addrs[total - j - 1] = talloc_steal(addrs, c.list[j]); 314 } 315 } 316 } 317 318 if (total) { 319 ret.count = total; 320 ret.list = addrs; 321 } 322 323 return ret; 324 } 78 325 /* 79 326 the blocking child … … 81 328 static void run_child_dns_lookup(struct dns_ex_state *state, int fd) 82 329 { 83 struct rk_dns_reply *reply;84 struct rk_resource_record *rr;85 uint32_t count = 0;86 uint32_t srv_valid = 0;87 struct rk_resource_record **srv_rr;88 uint32_t addrs_valid = 0;89 struct rk_resource_record **addrs_rr;90 char *addrs;91 330 bool first; 92 uint32_t i;93 331 bool do_srv = (state->flags & RESOLVE_NAME_FLAG_DNS_SRV); 332 struct dns_records_container c; 333 char* addrs = NULL; 334 unsigned int i; 94 335 95 336 if (strchr(state->name.name, '.') && state->name.name[strlen(state->name.name)-1] != '.') { … … 102 343 } 103 344 104 /* this is the blocking call we are going to lots of trouble105 to avoid in the parent */106 reply = rk_dns_lookup(state->name.name, do_srv?"SRV":"A");107 if (!reply) {108 goto done;109 }110 345 111 346 if (do_srv) { 112 rk_dns_srv_order(reply); 113 } 114 115 /* Loop over all returned records and pick the "srv" records */ 116 for (rr=reply->head; rr; rr=rr->next) { 117 /* we are only interested in the IN class */ 118 if (rr->class != rk_ns_c_in) { 119 continue; 120 } 121 122 if (do_srv) { 123 /* we are only interested in SRV records */ 124 if (rr->type != rk_ns_t_srv) { 125 continue; 126 } 127 128 /* verify we actually have a SRV record here */ 129 if (!rr->u.srv) { 130 continue; 131 } 132 133 /* Verify we got a port */ 134 if (rr->u.srv->port == 0) { 135 continue; 136 } 137 } else { 138 /* we are only interested in A records */ 139 /* TODO: add AAAA support */ 140 if (rr->type != rk_ns_t_a) { 141 continue; 142 } 143 144 /* verify we actually have a A record here */ 145 if (!rr->u.a) { 146 continue; 147 } 148 } 149 count++; 150 } 151 152 if (count == 0) { 153 goto done; 154 } 155 156 srv_rr = talloc_zero_array(state, 157 struct rk_resource_record *, 158 count); 159 if (!srv_rr) { 160 goto done; 161 } 162 163 addrs_rr = talloc_zero_array(state, 164 struct rk_resource_record *, 165 count); 166 if (!addrs_rr) { 167 goto done; 168 } 169 170 /* Loop over all returned records and pick the records */ 171 for (rr=reply->head;rr;rr=rr->next) { 172 /* we are only interested in the IN class */ 173 if (rr->class != rk_ns_c_in) { 174 continue; 175 } 176 177 if (do_srv) { 178 /* we are only interested in SRV records */ 179 if (rr->type != rk_ns_t_srv) { 180 continue; 181 } 182 183 /* verify we actually have a srv record here */ 184 if (!rr->u.srv) { 185 continue; 186 } 187 188 /* Verify we got a port */ 189 if (rr->u.srv->port == 0) { 190 continue; 191 } 192 193 srv_rr[srv_valid] = rr; 194 srv_valid++; 195 } else { 196 /* we are only interested in A records */ 197 /* TODO: add AAAA support */ 198 if (rr->type != rk_ns_t_a) { 199 continue; 200 } 201 202 /* verify we actually have a A record here */ 203 if (!rr->u.a) { 204 continue; 205 } 206 207 addrs_rr[addrs_valid] = rr; 208 addrs_valid++; 209 } 210 } 211 212 for (i=0; i < srv_valid; i++) { 213 for (rr=reply->head;rr;rr=rr->next) { 214 215 if (rr->class != rk_ns_c_in) { 216 continue; 217 } 218 219 /* we are only interested in A records */ 220 if (rr->type != rk_ns_t_a) { 221 continue; 222 } 223 224 /* verify we actually have a srv record here */ 225 if (strcmp(&srv_rr[i]->u.srv->target[0], rr->domain) != 0) { 226 continue; 227 } 228 229 addrs_rr[i] = rr; 230 addrs_valid++; 231 break; 232 } 233 } 234 235 if (addrs_valid == 0) { 347 c = get_srv_records(state, state->name.name); 348 } else { 349 c = get_a_aaaa_records(state, state->name.name, state->port); 350 } 351 352 /* This line in critical - if we return without writing to the 353 * pipe, this is the signal that the name did not exist */ 354 if (c.count == 0) { 236 355 goto done; 237 356 } … … 242 361 } 243 362 first = true; 244 for (i=0; i < count; i++) { 245 uint16_t port; 246 if (!addrs_rr[i]) { 247 continue; 248 } 249 250 if (srv_rr[i] && 251 (state->flags & RESOLVE_NAME_FLAG_OVERWRITE_PORT)) { 252 port = srv_rr[i]->u.srv->port; 253 } else { 254 port = state->port; 255 } 256 257 addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u/%s", 258 first?"":",", 259 inet_ntoa(*addrs_rr[i]->u.a), 260 port, 261 addrs_rr[i]->domain); 262 if (!addrs) { 263 goto done; 264 } 363 364 for (i=0; i < c.count; i++) { 365 addrs = talloc_asprintf_append_buffer(addrs, "%s%s", 366 first?"":",", 367 c.list[i]); 265 368 first = false; 266 369 } 267 370 268 371 if (addrs) { 372 DEBUG(11, ("Addrs = %s\n", addrs)); 269 373 write(fd, addrs, talloc_get_size(addrs)); 270 374 } … … 288 392 ZERO_STRUCT(hints); 289 393 hints.ai_socktype = SOCK_STREAM; 290 hints.ai_family = AF_INET;/* TODO: add AF_INET6 support */291 394 hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV; 292 395 … … 298 401 case EAI_NODATA: 299 402 #endif 403 case EAI_FAIL: 404 /* Linux returns EAI_NODATA on non-RFC1034-compliant names. FreeBSD returns EAI_FAIL */ 300 405 case EAI_NONAME: 301 /* getaddrinfo() doesn't handle CNAME records */406 /* getaddrinfo() doesn't handle CNAME or non-RFC1034 compatible records */ 302 407 run_child_dns_lookup(state, fd); 303 408 return; … … 316 421 first = true; 317 422 for (res = res_list; res; res = res->ai_next) { 318 struct sockaddr_in *in; 319 320 if (res->ai_family != AF_INET) { 423 char addrstr[INET6_ADDRSTRLEN]; 424 if (!print_sockaddr_len(addrstr, sizeof(addrstr), (struct sockaddr *)res->ai_addr, res->ai_addrlen)) { 321 425 continue; 322 426 } 323 in = (struct sockaddr_in *)res->ai_addr; 324 325 addrs = talloc_asprintf_append_buffer(addrs, "%s%s:%u/%s", 427 addrs = talloc_asprintf_append_buffer(addrs, "%s%s@%u/%s", 326 428 first?"":",", 327 inet_ntoa(in->sin_addr),429 addrstr, 328 430 state->port, 329 431 state->name.name); … … 384 486 385 487 if (ret <= 0) { 488 /* The check for ret == 0 here is important, if the 489 * name does not exist, then no bytes are written to 490 * the pipe */ 386 491 DEBUG(3,("dns child failed to find name '%s' of type %s\n", 387 492 state->name.name, (state->flags & RESOLVE_NAME_FLAG_DNS_SRV)?"SRV":"A")); … … 390 495 } 391 496 392 /* en usre the address looks good */497 /* ensure the address looks good */ 393 498 address[ret] = 0; 394 499 … … 407 512 for (i=0; i < num_addrs; i++) { 408 513 uint32_t port = 0; 409 char *p = strrchr(addrs[i], ' :');514 char *p = strrchr(addrs[i], '@'); 410 515 char *n; 411 516 … … 427 532 n++; 428 533 429 if (strcmp(addrs[i], "0.0.0.0") == 0 || 430 inet_addr(addrs[i]) == INADDR_NONE) { 534 if (strcmp(addrs[i], "0.0.0.0") == 0) { 431 535 composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND); 432 536 return; … … 438 542 } 439 543 state->addrs[i] = socket_address_from_strings(state->addrs, 440 "ip v4",544 "ip", 441 545 addrs[i], 442 546 port); … … 486 590 ret = pipe(fd); 487 591 if (ret == -1) { 488 composite_error(c, map_nt_error_from_unix (errno));592 composite_error(c, map_nt_error_from_unix_common(errno)); 489 593 return c; 490 594 } … … 499 603 /* we need to put the child in our event context so 500 604 we know when the dns_lookup() has finished */ 501 state->fde = event_add_fd(c->event_ctx, c, state->child_fd, EVENT_FD_READ,605 state->fde = tevent_add_fd(c->event_ctx, c, state->child_fd, TEVENT_FD_READ, 502 606 pipe_handler, c); 503 607 if (composite_nomem(state->fde, c)) { … … 510 614 state->child = fork(); 511 615 if (state->child == (pid_t)-1) { 512 composite_error(c, map_nt_error_from_unix (errno));616 composite_error(c, map_nt_error_from_unix_common(errno)); 513 617 return c; 514 618 } -
vendor/current/source4/libcli/resolve/nbtlist.c
r740 r988 112 112 uint16_t port, 113 113 struct nbt_name *name, 114 const char * *address_list,114 const char * const *address_list, 115 115 struct interface *ifaces, 116 116 uint16_t nbt_port, -
vendor/current/source4/libcli/resolve/resolve.c
r740 r988 76 76 method->recv_fn = recv_fn; 77 77 method->privdata = userdata; 78 DLIST_ADD_END(ctx->methods, method , struct resolve_method *);78 DLIST_ADD_END(ctx->methods, method); 79 79 return true; 80 80 } … … 172 172 if (is_ipaddress(state->name.name) || 173 173 strcasecmp(state->name.name, "localhost") == 0) { 174 struct in_addr ip = interpret_addr2(state->name.name);175 176 174 state->addrs = talloc_array(state, struct socket_address *, 2); 177 175 if (composite_nomem(state->addrs, c)) return c; 178 state->addrs[0] = socket_address_from_strings(state->addrs, "ip v4",179 inet_ntoa(ip), 0);176 state->addrs[0] = socket_address_from_strings(state->addrs, "ip", 177 state->name.name, 0); 180 178 if (composite_nomem(state->addrs[0], c)) return c; 181 179 state->addrs[1] = NULL; … … 317 315 318 316 319 /*320 general name resolution - sync call321 */322 NTSTATUS resolve_name(struct resolve_context *ctx,323 struct nbt_name *name,324 TALLOC_CTX *mem_ctx,325 const char **reply_addr,326 struct tevent_context *ev)327 {328 return resolve_name_ex(ctx, 0, 0, name, mem_ctx, reply_addr, ev);329 }330 331 317 /* Initialise a struct nbt_name with a NULL scope */ 332 318 -
vendor/current/source4/libcli/resolve/resolve_lp.c
r740 r988 33 33 for (i = 0; methods != NULL && methods[i] != NULL; i++) { 34 34 if (!strcmp(methods[i], "wins")) { 35 resolve_context_add_wins_method_lp(ret, lp_ctx); 35 if (lpcfg_disable_netbios(lp_ctx) == false) { 36 resolve_context_add_wins_method_lp(ret, lp_ctx); 37 } 36 38 } else if (!strcmp(methods[i], "bcast")) { 37 resolve_context_add_bcast_method_lp(ret, lp_ctx); 38 } else if (!strcmp(methods[i], "file")) { 39 resolve_context_add_file_method_lp(ret, lp_ctx); 39 if (lpcfg_disable_netbios(lp_ctx) == false) { 40 resolve_context_add_bcast_method_lp(ret, lp_ctx); 41 } 42 } else if (!strcmp(methods[i], "lmhosts")) { 43 resolve_context_add_lmhosts_method(ret); 40 44 } else if (!strcmp(methods[i], "host")) { 41 45 resolve_context_add_host_method(ret); -
vendor/current/source4/libcli/resolve/testsuite.c
r740 r988 24 24 #include "libcli/resolve/resolve.h" 25 25 #include "torture/torture.h" 26 #include "torture/local/proto.h" 26 27 #include "system/network.h" 27 28 #include "lib/util/util_net.h" -
vendor/current/source4/libcli/resolve/wins.c
r740 r988 28 28 29 29 struct resolve_wins_data { 30 c onst char **address_list;30 char **address_list; 31 31 struct interface *ifaces; 32 32 uint16_t nbt_port; … … 48 48 if (wins_data->address_list == NULL) return NULL; 49 49 return resolve_name_nbtlist_send(mem_ctx, event_ctx, flags, port, name, 50 wins_data->address_list, wins_data->ifaces, 50 (const char * const *)wins_data->address_list, 51 wins_data->ifaces, 51 52 wins_data->nbt_port, wins_data->nbt_timeout, 52 53 false, true); … … 67 68 { 68 69 struct resolve_wins_data *wins_data = talloc(ctx, struct resolve_wins_data); 69 wins_data->address_list = (const char **)str_list_copy(wins_data, address_list);70 wins_data->address_list = str_list_copy(wins_data, address_list); 70 71 wins_data->ifaces = talloc_reference(wins_data, ifaces); 71 72 wins_data->nbt_port = nbt_port; … … 78 79 { 79 80 struct interface *ifaces; 80 load_interface s(ctx, lpcfg_interfaces(lp_ctx), &ifaces);81 load_interface_list(ctx, lp_ctx, &ifaces); 81 82 return resolve_context_add_wins_method(ctx, lpcfg_wins_server_list(lp_ctx), ifaces, lpcfg_nbt_port(lp_ctx), lpcfg_parm_int(lp_ctx, NULL, "nbt", "timeout", 1)); 82 83 }
Note:
See TracChangeset
for help on using the changeset viewer.