Changeset 136 for trunk/samba/source/libsmb/dsgetdcname.c
- Timestamp:
- May 29, 2008, 12:22:03 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/samba/source/libsmb/dsgetdcname.c
r133 r136 32 32 const char *hostname; 33 33 }; 34 35 static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, 36 uint32_t flags, 37 struct sockaddr_storage *ss, 38 uint32_t nt_version, 39 union nbt_cldap_netlogon *r, 40 struct netr_DsRGetDCNameInfo **info); 34 41 35 42 /**************************************************************** … … 149 156 static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, 150 157 const char *domain_name, 151 struct netr_DsRGetDCNameInfo *info)158 const DATA_BLOB *blob) 152 159 { 153 160 time_t expire_time; 154 161 char *key; 155 162 bool ret = false; 156 DATA_BLOB blob;157 enum ndr_err_code ndr_err;158 163 159 164 if (!gencache_init()) { … … 168 173 expire_time = time(NULL) + DSGETDCNAME_CACHE_TTL; 169 174 170 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, info, 171 (ndr_push_flags_fn_t)ndr_push_netr_DsRGetDCNameInfo); 175 if (gencache_lock_entry(key) != 0) { 176 return NT_STATUS_LOCK_NOT_GRANTED; 177 } 178 179 ret = gencache_set_data_blob(key, blob, expire_time); 180 181 gencache_unlock_entry(key); 182 183 return ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; 184 } 185 186 /**************************************************************** 187 ****************************************************************/ 188 189 #define SET_STRING(x) \ 190 talloc_strdup(mem_ctx, x); \ 191 NT_STATUS_HAVE_NO_MEMORY(x); 192 193 static NTSTATUS map_logon29_from_cldap_reply(TALLOC_CTX *mem_ctx, 194 uint32_t flags, 195 struct sockaddr_storage *ss, 196 uint32_t nt_version, 197 union nbt_cldap_netlogon *r, 198 struct nbt_cldap_netlogon_29 *p) 199 { 200 char addr[INET6_ADDRSTRLEN]; 201 202 ZERO_STRUCTP(p); 203 204 print_sockaddr(addr, sizeof(addr), ss); 205 206 /* FIXME */ 207 p->dc_sock_addr_size = 0x10; /* the w32 winsock addr size */ 208 p->dc_sock_addr.sa_family = 2; /* AF_INET */ 209 p->dc_sock_addr.pdc_ip = talloc_strdup(mem_ctx, addr); 210 211 switch (nt_version & 0x0000001f) { 212 case 0: 213 return NT_STATUS_INVALID_PARAMETER; 214 case 1: 215 case 16: 216 case 17: 217 p->pdc_name = SET_STRING(r->logon1.pdc_name); 218 p->domain = SET_STRING(r->logon1.domain_name); 219 220 if (flags & DS_PDC_REQUIRED) { 221 p->server_type = NBT_SERVER_WRITABLE | 222 NBT_SERVER_PDC; 223 } 224 break; 225 case 2: 226 case 3: 227 case 18: 228 case 19: 229 p->pdc_name = SET_STRING(r->logon3.pdc_name); 230 p->domain = SET_STRING(r->logon3.domain_name); 231 p->pdc_dns_name = SET_STRING(r->logon3.pdc_dns_name); 232 p->dns_domain = SET_STRING(r->logon3.dns_domain); 233 p->server_type = r->logon3.server_type; 234 p->forest = SET_STRING(r->logon3.forest); 235 p->domain_uuid = r->logon3.domain_uuid; 236 237 break; 238 case 4: 239 case 5: 240 case 6: 241 case 7: 242 p->pdc_name = SET_STRING(r->logon5.pdc_name); 243 p->domain = SET_STRING(r->logon5.domain); 244 p->pdc_dns_name = SET_STRING(r->logon5.pdc_dns_name); 245 p->dns_domain = SET_STRING(r->logon5.dns_domain); 246 p->server_type = r->logon5.server_type; 247 p->forest = SET_STRING(r->logon5.forest); 248 p->domain_uuid = r->logon5.domain_uuid; 249 p->server_site = SET_STRING(r->logon5.server_site); 250 p->client_site = SET_STRING(r->logon5.client_site); 251 252 break; 253 case 8: 254 case 9: 255 case 10: 256 case 11: 257 case 12: 258 case 13: 259 case 14: 260 case 15: 261 p->pdc_name = SET_STRING(r->logon13.pdc_name); 262 p->domain = SET_STRING(r->logon13.domain); 263 p->pdc_dns_name = SET_STRING(r->logon13.pdc_dns_name); 264 p->dns_domain = SET_STRING(r->logon13.dns_domain); 265 p->server_type = r->logon13.server_type; 266 p->forest = SET_STRING(r->logon13.forest); 267 p->domain_uuid = r->logon13.domain_uuid; 268 p->server_site = SET_STRING(r->logon13.server_site); 269 p->client_site = SET_STRING(r->logon13.client_site); 270 271 break; 272 case 20: 273 case 21: 274 case 22: 275 case 23: 276 case 24: 277 case 25: 278 case 26: 279 case 27: 280 case 28: 281 p->pdc_name = SET_STRING(r->logon15.pdc_name); 282 p->domain = SET_STRING(r->logon15.domain); 283 p->pdc_dns_name = SET_STRING(r->logon15.pdc_dns_name); 284 p->dns_domain = SET_STRING(r->logon15.dns_domain); 285 p->server_type = r->logon15.server_type; 286 p->forest = SET_STRING(r->logon15.forest); 287 p->domain_uuid = r->logon15.domain_uuid; 288 p->server_site = SET_STRING(r->logon15.server_site); 289 p->client_site = SET_STRING(r->logon15.client_site); 290 291 break; 292 case 29: 293 case 30: 294 case 31: 295 p->pdc_name = SET_STRING(r->logon29.pdc_name); 296 p->domain = SET_STRING(r->logon29.domain); 297 p->pdc_dns_name = SET_STRING(r->logon29.pdc_dns_name); 298 p->dns_domain = SET_STRING(r->logon29.dns_domain); 299 p->server_type = r->logon29.server_type; 300 p->forest = SET_STRING(r->logon29.forest); 301 p->domain_uuid = r->logon29.domain_uuid; 302 p->server_site = SET_STRING(r->logon29.server_site); 303 p->client_site = SET_STRING(r->logon29.client_site); 304 p->next_closest_site = SET_STRING(r->logon29.next_closest_site); 305 306 break; 307 default: 308 return NT_STATUS_INVALID_PARAMETER; 309 } 310 311 return NT_STATUS_OK; 312 } 313 314 /**************************************************************** 315 ****************************************************************/ 316 317 static NTSTATUS store_cldap_reply(TALLOC_CTX *mem_ctx, 318 uint32_t flags, 319 struct sockaddr_storage *ss, 320 uint32_t nt_version, 321 union nbt_cldap_netlogon *r) 322 { 323 DATA_BLOB blob; 324 enum ndr_err_code ndr_err; 325 NTSTATUS status; 326 struct nbt_cldap_netlogon_29 logon29; 327 328 status = map_logon29_from_cldap_reply(mem_ctx, flags, ss, 329 nt_version, r, &logon29); 330 if (!NT_STATUS_IS_OK(status)) { 331 return status; 332 } 333 334 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &logon29, 335 (ndr_push_flags_fn_t)ndr_push_nbt_cldap_netlogon_29); 172 336 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 173 337 return ndr_map_error2ntstatus(ndr_err); 174 338 } 175 339 176 if (gencache_lock_entry(key) != 0) { 177 data_blob_free(&blob); 178 return NT_STATUS_LOCK_NOT_GRANTED; 179 } 180 181 ret = gencache_set_data_blob(key, &blob, expire_time); 340 if (logon29.domain) { 341 status = dsgetdcname_cache_store(mem_ctx, logon29.domain, &blob); 342 if (!NT_STATUS_IS_OK(status)) { 343 goto done; 344 } 345 if (logon29.client_site) { 346 sitename_store(logon29.domain, logon29.client_site); 347 } 348 } 349 if (logon29.dns_domain) { 350 status = dsgetdcname_cache_store(mem_ctx, logon29.dns_domain, &blob); 351 if (!NT_STATUS_IS_OK(status)) { 352 goto done; 353 } 354 if (logon29.client_site) { 355 sitename_store(logon29.dns_domain, logon29.client_site); 356 } 357 } 358 359 done: 182 360 data_blob_free(&blob); 183 361 184 gencache_unlock_entry(key); 185 186 return ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; 362 return status; 187 363 } 188 364 … … 191 367 192 368 static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx, 369 struct messaging_context *msg_ctx, 193 370 const char *domain_name, 194 371 struct GUID *domain_guid, … … 197 374 struct netr_DsRGetDCNameInfo *info) 198 375 { 199 struct nbt_cldap_netlogon_5 r; 200 201 /* check if matching entry is older then 15 minutes, if yes, send 202 * CLDAP/MAILSLOT ping again and store the cached data */ 203 204 ZERO_STRUCT(r); 205 206 if (ads_cldap_netlogon(mem_ctx, info->dc_unc, 207 info->domain_name, &r)) { 208 209 dsgetdcname_cache_delete(mem_ctx, domain_name); 210 211 return dsgetdcname_cache_store(mem_ctx, 212 info->domain_name, 213 info); 214 } 215 216 return NT_STATUS_INVALID_NETWORK_RESPONSE; 376 struct netr_DsRGetDCNameInfo *dc_info; 377 378 return dsgetdcname(mem_ctx, 379 msg_ctx, 380 domain_name, 381 domain_guid, 382 site_name, 383 flags | DS_FORCE_REDISCOVERY, 384 &dc_info); 385 } 386 387 /**************************************************************** 388 ****************************************************************/ 389 390 static uint32_t get_cldap_reply_server_flags(union nbt_cldap_netlogon *r, 391 uint32_t nt_version) 392 { 393 switch (nt_version & 0x0000001f) { 394 case 0: 395 case 1: 396 case 16: 397 case 17: 398 return 0; 399 case 2: 400 case 3: 401 case 18: 402 case 19: 403 return r->logon3.server_type; 404 case 4: 405 case 5: 406 case 6: 407 case 7: 408 return r->logon5.server_type; 409 case 8: 410 case 9: 411 case 10: 412 case 11: 413 case 12: 414 case 13: 415 case 14: 416 case 15: 417 return r->logon13.server_type; 418 case 20: 419 case 21: 420 case 22: 421 case 23: 422 case 24: 423 case 25: 424 case 26: 425 case 27: 426 case 28: 427 return r->logon15.server_type; 428 case 29: 429 case 30: 430 case 31: 431 return r->logon29.server_type; 432 default: 433 return 0; 434 } 217 435 } 218 436 … … 225 443 uint32_t req_flags) 226 444 { 445 if (ret_flags == 0) { 446 return true; 447 } 448 227 449 if (req_flags & DS_PDC_REQUIRED) 228 450 RETURN_ON_FALSE(ret_flags & NBT_SERVER_PDC); … … 265 487 enum ndr_err_code ndr_err; 266 488 struct netr_DsRGetDCNameInfo *info; 489 union nbt_cldap_netlogon p; 490 struct nbt_cldap_netlogon_29 r; 491 NTSTATUS status; 267 492 268 493 if (!gencache_init()) { … … 284 509 } 285 510 286 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, info,287 (ndr_pull_flags_fn_t)ndr_pull_n etr_DsRGetDCNameInfo);511 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r, 512 (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon_29); 288 513 289 514 data_blob_free(&blob); … … 293 518 } 294 519 520 p.logon29 = r; 521 522 status = make_dc_info_from_cldap_reply(mem_ctx, flags, NULL, 523 29, 524 &p, &info); 525 if (!NT_STATUS_IS_OK(status)) { 526 return status; 527 } 528 295 529 if (DEBUGLEVEL >= 10) { 296 530 NDR_PRINT_DEBUG(netr_DsRGetDCNameInfo, info); … … 317 551 318 552 static NTSTATUS dsgetdcname_cached(TALLOC_CTX *mem_ctx, 553 struct messaging_context *msg_ctx, 319 554 const char *domain_name, 320 555 struct GUID *domain_guid, … … 339 574 340 575 if (expired) { 341 status = dsgetdcname_cache_refresh(mem_ctx, domain_name, 576 status = dsgetdcname_cache_refresh(mem_ctx, msg_ctx, 577 domain_name, 342 578 domain_guid, flags, 343 579 site_name, *info); … … 353 589 ****************************************************************/ 354 590 355 static bool check_allowed_required_flags(uint32_t flags) 591 static bool check_allowed_required_flags(uint32_t flags, 592 const char *site_name) 356 593 { 357 594 uint32_t return_type = flags & (DS_RETURN_FLAT_NAME|DS_RETURN_DNS_NAME); … … 363 600 364 601 debug_dsdcinfo_flags(10, flags); 602 603 if ((flags & DS_TRY_NEXTCLOSEST_SITE) && site_name) { 604 return false; 605 } 365 606 366 607 if (return_type == (DS_RETURN_FLAT_NAME|DS_RETURN_DNS_NAME)) { … … 466 707 struct ip_service_name *dclist = NULL; 467 708 int count = 0; 468 469 if ((!(flags & DS_DIRECTORY_SERVICE_REQUIRED)) &&470 (!(flags & DS_KDC_REQUIRED)) &&471 (!(flags & DS_GC_SERVER_REQUIRED)) &&472 (!(flags & DS_PDC_REQUIRED))) {473 DEBUG(1,("discover_dc_dns: invalid flags\n"));474 return NT_STATUS_INVALID_PARAMETER;475 }476 709 477 710 if (flags & DS_PDC_REQUIRED) { … … 491 724 domain_guid, &dcs, &numdcs); 492 725 } else { 493 /* FIXME: ? */ 494 DEBUG(1,("discover_dc_dns: not enough input\n")); 495 status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; 726 status = ads_dns_query_dcs(mem_ctx, domain_name, site_name, 727 &dcs, &numdcs); 496 728 } 497 729 … … 527 759 r->port = dcs[count].port; 528 760 r->hostname = dcs[count].hostname; 529 530 if (!(flags & DS_IP_REQUIRED)) {531 count++;532 continue;533 }534 761 535 762 /* If we don't have an IP list for a name, lookup it up */ … … 602 829 603 830 if (dc_address) { 604 info->dc_address = talloc_strdup(mem_ctx, dc_address); 831 if (!(dc_address[0] == '\\' && dc_address[1] == '\\')) { 832 info->dc_address = talloc_asprintf(mem_ctx, "\\\\%s", 833 dc_address); 834 } else { 835 info->dc_address = talloc_strdup(mem_ctx, dc_address); 836 } 605 837 NT_STATUS_HAVE_NO_MEMORY(info->dc_address); 606 838 } … … 617 849 } 618 850 619 if (forest_name ) {851 if (forest_name && *forest_name) { 620 852 info->forest_name = talloc_strdup(mem_ctx, forest_name); 621 853 NT_STATUS_HAVE_NO_MEMORY(info->forest_name); 854 flags |= DS_DNS_FOREST; 622 855 } 623 856 … … 638 871 639 872 return NT_STATUS_OK; 873 } 874 875 /**************************************************************** 876 ****************************************************************/ 877 878 static void map_dc_and_domain_names(uint32_t flags, 879 const char *dc_name, 880 const char *domain_name, 881 const char *dns_dc_name, 882 const char *dns_domain_name, 883 uint32_t *dc_flags, 884 const char **hostname_p, 885 const char **domain_p) 886 { 887 switch (flags & 0xf0000000) { 888 case DS_RETURN_FLAT_NAME: 889 if (dc_name && domain_name && 890 *dc_name && *domain_name) { 891 *hostname_p = dc_name; 892 *domain_p = domain_name; 893 break; 894 } 895 case DS_RETURN_DNS_NAME: 896 default: 897 if (dns_dc_name && dns_domain_name && 898 *dns_dc_name && *dns_domain_name) { 899 *hostname_p = dns_dc_name; 900 *domain_p = dns_domain_name; 901 *dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; 902 break; 903 } 904 if (dc_name && domain_name && 905 *dc_name && *domain_name) { 906 *hostname_p = dc_name; 907 *domain_p = domain_name; 908 break; 909 } 910 } 911 } 912 913 /**************************************************************** 914 ****************************************************************/ 915 916 static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, 917 uint32_t flags, 918 struct sockaddr_storage *ss, 919 uint32_t nt_version, 920 union nbt_cldap_netlogon *r, 921 struct netr_DsRGetDCNameInfo **info) 922 { 923 const char *dc_hostname, *dc_domain_name; 924 const char *dc_address = NULL; 925 const char *dc_forest = NULL; 926 uint32_t dc_address_type = 0; 927 uint32_t dc_flags = 0; 928 struct GUID *dc_domain_guid = NULL; 929 const char *dc_server_site = NULL; 930 const char *dc_client_site = NULL; 931 932 char addr[INET6_ADDRSTRLEN]; 933 934 if (ss) { 935 print_sockaddr(addr, sizeof(addr), ss); 936 dc_address = addr; 937 dc_address_type = DS_ADDRESS_TYPE_INET; 938 } 939 940 switch (nt_version & 0x0000001f) { 941 case 0: 942 case 1: 943 case 16: 944 case 17: 945 if (!ss) { 946 dc_address = r->logon1.pdc_name; 947 dc_address_type = DS_ADDRESS_TYPE_NETBIOS; 948 } 949 950 map_dc_and_domain_names(flags, 951 r->logon1.pdc_name, 952 r->logon1.domain_name, 953 NULL, 954 NULL, 955 &dc_flags, 956 &dc_hostname, 957 &dc_domain_name); 958 959 if (flags & DS_PDC_REQUIRED) { 960 dc_flags = NBT_SERVER_WRITABLE | NBT_SERVER_PDC; 961 } 962 break; 963 case 2: 964 case 3: 965 case 18: 966 case 19: 967 if (!ss) { 968 dc_address = r->logon3.pdc_ip; 969 dc_address_type = DS_ADDRESS_TYPE_INET; 970 } 971 972 map_dc_and_domain_names(flags, 973 r->logon3.pdc_name, 974 r->logon3.domain_name, 975 r->logon3.pdc_dns_name, 976 r->logon3.dns_domain, 977 &dc_flags, 978 &dc_hostname, 979 &dc_domain_name); 980 981 dc_flags |= r->logon3.server_type; 982 dc_forest = r->logon3.forest; 983 dc_domain_guid = &r->logon3.domain_uuid; 984 985 break; 986 case 4: 987 case 5: 988 case 6: 989 case 7: 990 if (!ss) { 991 dc_address = r->logon5.pdc_name; 992 dc_address_type = DS_ADDRESS_TYPE_NETBIOS; 993 } 994 995 map_dc_and_domain_names(flags, 996 r->logon5.pdc_name, 997 r->logon5.domain, 998 r->logon5.pdc_dns_name, 999 r->logon5.dns_domain, 1000 &dc_flags, 1001 &dc_hostname, 1002 &dc_domain_name); 1003 1004 dc_flags |= r->logon5.server_type; 1005 dc_forest = r->logon5.forest; 1006 dc_domain_guid = &r->logon5.domain_uuid; 1007 dc_server_site = r->logon5.server_site; 1008 dc_client_site = r->logon5.client_site; 1009 1010 break; 1011 case 8: 1012 case 9: 1013 case 10: 1014 case 11: 1015 case 12: 1016 case 13: 1017 case 14: 1018 case 15: 1019 if (!ss) { 1020 dc_address = r->logon13.dc_sock_addr.pdc_ip; 1021 dc_address_type = DS_ADDRESS_TYPE_INET; 1022 } 1023 1024 map_dc_and_domain_names(flags, 1025 r->logon13.pdc_name, 1026 r->logon13.domain, 1027 r->logon13.pdc_dns_name, 1028 r->logon13.dns_domain, 1029 &dc_flags, 1030 &dc_hostname, 1031 &dc_domain_name); 1032 1033 dc_flags |= r->logon13.server_type; 1034 dc_forest = r->logon13.forest; 1035 dc_domain_guid = &r->logon13.domain_uuid; 1036 dc_server_site = r->logon13.server_site; 1037 dc_client_site = r->logon13.client_site; 1038 1039 break; 1040 case 20: 1041 case 21: 1042 case 22: 1043 case 23: 1044 case 24: 1045 case 25: 1046 case 26: 1047 case 27: 1048 case 28: 1049 if (!ss) { 1050 dc_address = r->logon15.pdc_name; 1051 dc_address_type = DS_ADDRESS_TYPE_NETBIOS; 1052 } 1053 1054 map_dc_and_domain_names(flags, 1055 r->logon15.pdc_name, 1056 r->logon15.domain, 1057 r->logon15.pdc_dns_name, 1058 r->logon15.dns_domain, 1059 &dc_flags, 1060 &dc_hostname, 1061 &dc_domain_name); 1062 1063 dc_flags |= r->logon15.server_type; 1064 dc_forest = r->logon15.forest; 1065 dc_domain_guid = &r->logon15.domain_uuid; 1066 dc_server_site = r->logon15.server_site; 1067 dc_client_site = r->logon15.client_site; 1068 1069 break; 1070 case 29: 1071 case 30: 1072 case 31: 1073 if (!ss) { 1074 dc_address = r->logon29.dc_sock_addr.pdc_ip; 1075 dc_address_type = DS_ADDRESS_TYPE_INET; 1076 } 1077 1078 map_dc_and_domain_names(flags, 1079 r->logon29.pdc_name, 1080 r->logon29.domain, 1081 r->logon29.pdc_dns_name, 1082 r->logon29.dns_domain, 1083 &dc_flags, 1084 &dc_hostname, 1085 &dc_domain_name); 1086 1087 dc_flags |= r->logon29.server_type; 1088 dc_forest = r->logon29.forest; 1089 dc_domain_guid = &r->logon29.domain_uuid; 1090 dc_server_site = r->logon29.server_site; 1091 dc_client_site = r->logon29.client_site; 1092 1093 break; 1094 default: 1095 return NT_STATUS_INVALID_PARAMETER; 1096 } 1097 1098 return make_domain_controller_info(mem_ctx, 1099 dc_hostname, 1100 dc_address, 1101 dc_address_type, 1102 dc_domain_guid, 1103 dc_domain_name, 1104 dc_forest, 1105 dc_flags, 1106 dc_server_site, 1107 dc_client_site, 1108 info); 1109 } 1110 1111 /**************************************************************** 1112 ****************************************************************/ 1113 1114 static uint32_t map_ds_flags_to_nt_version(uint32_t flags) 1115 { 1116 uint32_t nt_version = 0; 1117 1118 if (flags & DS_PDC_REQUIRED) { 1119 nt_version |= NETLOGON_VERSION_PDC; 1120 } 1121 1122 if (flags & DS_GC_SERVER_REQUIRED) { 1123 nt_version |= NETLOGON_VERSION_GC; 1124 } 1125 1126 if (flags & DS_TRY_NEXTCLOSEST_SITE) { 1127 nt_version |= NETLOGON_VERSION_WITH_CLOSEST_SITE; 1128 } 1129 1130 if (flags & DS_IP_REQUIRED) { 1131 nt_version |= NETLOGON_VERSION_IP; 1132 } 1133 1134 return nt_version; 640 1135 } 641 1136 … … 652 1147 int i = 0; 653 1148 bool valid_dc = false; 654 struct nbt_cldap_netlogon_5 r; 655 const char *dc_hostname, *dc_domain_name; 656 const char *dc_address; 657 uint32_t dc_address_type; 658 uint32_t dc_flags; 1149 union nbt_cldap_netlogon *r = NULL; 1150 uint32_t nt_version = NETLOGON_VERSION_5 | 1151 NETLOGON_VERSION_5EX; 1152 uint32_t ret_flags = 0; 1153 NTSTATUS status; 1154 1155 nt_version |= map_ds_flags_to_nt_version(flags); 659 1156 660 1157 for (i=0; i<num_dcs; i++) { 661 1158 662 ZERO_STRUCT(r);663 664 1159 DEBUG(10,("LDAP ping to %s\n", dclist[i].hostname)); 665 1160 666 if ((ads_cldap_netlogon(mem_ctx, dclist[i].hostname, 667 domain_name, &r)) && 668 (check_cldap_reply_required_flags(r.server_type, flags))) { 669 valid_dc = true; 670 break; 1161 if (ads_cldap_netlogon(mem_ctx, dclist[i].hostname, 1162 domain_name, 1163 &nt_version, 1164 &r)) 1165 { 1166 ret_flags = get_cldap_reply_server_flags(r, nt_version); 1167 1168 if (check_cldap_reply_required_flags(ret_flags, flags)) { 1169 valid_dc = true; 1170 break; 1171 } 671 1172 } 672 1173 … … 678 1179 } 679 1180 680 dc_flags = r.server_type; 681 682 if (flags & DS_RETURN_FLAT_NAME) { 683 if (!strlen(r.pdc_name) || !strlen(r.domain)) { 684 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; 685 } 686 dc_hostname = r.pdc_name; 687 dc_domain_name = r.domain; 688 } else if (flags & DS_RETURN_DNS_NAME) { 689 if (!strlen(r.pdc_dns_name) || !strlen(r.dns_domain)) { 690 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; 691 } 692 dc_hostname = r.pdc_dns_name; 693 dc_domain_name = r.dns_domain; 694 dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; 695 } else { 696 /* FIXME */ 697 dc_hostname = r.pdc_dns_name; 698 dc_domain_name = r.dns_domain; 699 dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; 700 } 701 702 if (flags & DS_IP_REQUIRED) { 703 char addr[INET6_ADDRSTRLEN]; 704 print_sockaddr(addr, sizeof(addr), &dclist[i].ss); 705 dc_address = talloc_asprintf(mem_ctx, "\\\\%s", 706 addr); 707 dc_address_type = DS_ADDRESS_TYPE_INET; 708 } else { 709 dc_address = talloc_asprintf(mem_ctx, "\\\\%s", 710 r.pdc_name); 711 dc_address_type = DS_ADDRESS_TYPE_NETBIOS; 712 } 713 NT_STATUS_HAVE_NO_MEMORY(dc_address); 714 715 if (r.forest) { 716 dc_flags |= DS_DNS_FOREST; 717 } 718 719 return make_domain_controller_info(mem_ctx, 720 dc_hostname, 721 dc_address, 722 dc_address_type, 723 &r.domain_uuid, 724 dc_domain_name, 725 r.forest, 726 dc_flags, 727 r.server_site, 728 r.client_site, 729 info); 730 1181 status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss, 1182 nt_version, r, info); 1183 if (NT_STATUS_IS_OK(status)) { 1184 return store_cldap_reply(mem_ctx, flags, &dclist[i].ss, 1185 nt_version, r); 1186 } 1187 1188 return status; 731 1189 } 732 1190 … … 762 1220 763 1221 static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, 1222 struct messaging_context *msg_ctx, 764 1223 const char *domain_name, 765 1224 uint32_t flags, … … 771 1230 struct ip_service ip_list; 772 1231 enum nbt_name_type name_type = NBT_NAME_LOGON; 773 1232 NTSTATUS status; 774 1233 int i; 775 const char *dc_hostname, *dc_domain_name;776 const char *dc_address;777 uint32_t dc_address_type;778 uint32_t dc_flags = 0;779 1234 const char *dc_name = NULL; 780 1235 fstring tmp_dc_name; 781 struct messaging_context *msg_ctx = msg_context(mem_ctx); 1236 union nbt_cldap_netlogon *r = NULL; 1237 bool store_cache = false; 1238 uint32_t nt_version = NETLOGON_VERSION_1 | 1239 NETLOGON_VERSION_5 | 1240 NETLOGON_VERSION_5EX_WITH_IP; 1241 1242 if (!msg_ctx) { 1243 msg_ctx = msg_context(mem_ctx); 1244 } 782 1245 783 1246 if (flags & DS_PDC_REQUIRED) { 784 1247 name_type = NBT_NAME_PDC; 785 1248 } 1249 1250 nt_version |= map_ds_flags_to_nt_version(flags); 786 1251 787 1252 DEBUG(10,("process_dc_netbios\n")); … … 797 1262 798 1263 if (send_getdc_request(mem_ctx, msg_ctx, 799 &dclist[i].ss, domain_name, NULL)) 1264 &dclist[i].ss, domain_name, 1265 NULL, nt_version)) 800 1266 { 801 1267 int k; 802 smb_msleep( 100);1268 smb_msleep(300); 803 1269 for (k=0; k<5; k++) { 804 1270 if (receive_getdc_response(mem_ctx, 805 1271 &dclist[i].ss, 806 1272 domain_name, 807 &dc_name)) { 1273 &nt_version, 1274 &dc_name, 1275 &r)) { 1276 store_cache = true; 808 1277 namecache_store(dc_name, NBT_NAME_SERVER, 1, &ip_list); 809 dc_hostname = dc_name;810 dc_domain_name = talloc_strdup_upper(mem_ctx, domain_name);811 NT_STATUS_HAVE_NO_MEMORY(dc_domain_name);812 1278 goto make_reply; 813 1279 } 814 smb_msleep( 500);1280 smb_msleep(1500); 815 1281 } 816 1282 } … … 822 1288 tmp_dc_name)) 823 1289 { 824 dc_hostname = tmp_dc_name; 825 dc_domain_name = talloc_strdup_upper(mem_ctx, domain_name); 826 namecache_store(dc_name, NBT_NAME_SERVER, 1, &ip_list); 1290 struct nbt_cldap_netlogon_1 logon1; 1291 1292 r = TALLOC_ZERO_P(mem_ctx, union nbt_cldap_netlogon); 1293 NT_STATUS_HAVE_NO_MEMORY(r); 1294 1295 ZERO_STRUCT(logon1); 1296 1297 nt_version = NETLOGON_VERSION_1; 1298 1299 logon1.nt_version = nt_version; 1300 logon1.pdc_name = tmp_dc_name; 1301 logon1.domain_name = talloc_strdup_upper(mem_ctx, domain_name); 1302 NT_STATUS_HAVE_NO_MEMORY(logon1.domain_name); 1303 1304 r->logon1 = logon1; 1305 1306 namecache_store(tmp_dc_name, NBT_NAME_SERVER, 1, &ip_list); 1307 827 1308 goto make_reply; 828 1309 } … … 833 1314 make_reply: 834 1315 835 if (flags & DS_IP_REQUIRED) { 836 char addr[INET6_ADDRSTRLEN]; 837 print_sockaddr(addr, sizeof(addr), &dclist[i].ss); 838 dc_address = talloc_asprintf(mem_ctx, "\\\\%s", addr); 839 dc_address_type = DS_ADDRESS_TYPE_INET; 840 } else { 841 dc_address = talloc_asprintf(mem_ctx, "\\\\%s", dc_hostname); 842 dc_address_type = DS_ADDRESS_TYPE_NETBIOS; 843 } 844 845 if (flags & DS_PDC_REQUIRED) { 846 dc_flags |= NBT_SERVER_PDC | NBT_SERVER_WRITABLE; 847 } 848 849 return make_domain_controller_info(mem_ctx, 850 dc_hostname, 851 dc_address, 852 dc_address_type, 853 NULL, 854 dc_domain_name, 855 NULL, 856 dc_flags, 857 NULL, 858 NULL, 859 info); 1316 status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss, 1317 nt_version, r, info); 1318 if (NT_STATUS_IS_OK(status) && store_cache) { 1319 return store_cldap_reply(mem_ctx, flags, &dclist[i].ss, 1320 nt_version, r); 1321 } 1322 1323 return status; 860 1324 } 861 1325 … … 864 1328 865 1329 static NTSTATUS dsgetdcname_rediscover(TALLOC_CTX *mem_ctx, 1330 struct messaging_context *msg_ctx, 866 1331 const char *domain_name, 867 1332 struct GUID *domain_guid, … … 882 1347 NT_STATUS_NOT_OK_RETURN(status); 883 1348 884 return process_dc_netbios(mem_ctx, domain_name, flags,1349 return process_dc_netbios(mem_ctx, msg_ctx, domain_name, flags, 885 1350 dclist, num_dcs, info); 886 1351 } … … 912 1377 NT_STATUS_NOT_OK_RETURN(status); 913 1378 914 return process_dc_netbios(mem_ctx, domain_name, flags, dclist,1379 return process_dc_netbios(mem_ctx, msg_ctx, domain_name, flags, dclist, 915 1380 num_dcs, info); 916 1381 } … … 923 1388 924 1389 NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, 1390 struct messaging_context *msg_ctx, 925 1391 const char *domain_name, 926 1392 struct GUID *domain_guid, … … 931 1397 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; 932 1398 struct netr_DsRGetDCNameInfo *myinfo = NULL; 1399 char *query_site = NULL; 933 1400 934 1401 DEBUG(10,("dsgetdcname: domain_name: %s, " … … 940 1407 *info = NULL; 941 1408 942 if (!check_allowed_required_flags(flags )) {1409 if (!check_allowed_required_flags(flags, site_name)) { 943 1410 DEBUG(0,("invalid flags specified\n")); 944 1411 return NT_STATUS_INVALID_PARAMETER; 945 1412 } 946 1413 1414 if (!site_name) { 1415 query_site = sitename_fetch(domain_name); 1416 } else { 1417 query_site = SMB_STRDUP(site_name); 1418 } 1419 947 1420 if (flags & DS_FORCE_REDISCOVERY) { 948 1421 goto rediscover; 949 1422 } 950 1423 951 status = dsgetdcname_cached(mem_ctx, domain_name, domain_guid,952 flags, site_name, &myinfo);1424 status = dsgetdcname_cached(mem_ctx, msg_ctx, domain_name, domain_guid, 1425 flags, query_site, &myinfo); 953 1426 if (NT_STATUS_IS_OK(status)) { 954 1427 *info = myinfo; 955 return status;1428 goto done; 956 1429 } 957 1430 958 1431 if (flags & DS_BACKGROUND_ONLY) { 959 return status;1432 goto done; 960 1433 } 961 1434 962 1435 rediscover: 963 status = dsgetdcname_rediscover(mem_ctx, domain_name,964 domain_guid, flags, site_name,1436 status = dsgetdcname_rediscover(mem_ctx, msg_ctx, domain_name, 1437 domain_guid, flags, query_site, 965 1438 &myinfo); 966 1439 967 1440 if (NT_STATUS_IS_OK(status)) { 968 dsgetdcname_cache_store(mem_ctx, domain_name, myinfo);969 1441 *info = myinfo; 970 1442 } 971 1443 1444 done: 1445 SAFE_FREE(query_site); 1446 972 1447 return status; 973 1448 }
Note:
See TracChangeset
for help on using the changeset viewer.