|
Lines 56-61
Link Here
|
| 56 |
} |
56 |
} |
| 57 |
} |
57 |
} |
| 58 |
|
58 |
|
|
|
59 |
static void shuffle_dc_set_preferred(struct dc_set *list, uint32_t preferred_index) |
| 60 |
{ |
| 61 |
uint32_t j; |
| 62 |
|
| 63 |
srandom(time(NULL)); |
| 64 |
|
| 65 |
const char *tmp; |
| 66 |
tmp = list->names[preferred_index]; |
| 67 |
list->names[preferred_index] = list->names[0]; |
| 68 |
list->names[0] = tmp; |
| 69 |
|
| 70 |
for (j = list->count - 1; j > 1; j--) { |
| 71 |
uint32_t r; |
| 72 |
|
| 73 |
r = 1 + random() % j; |
| 74 |
|
| 75 |
tmp = list->names[j]; |
| 76 |
list->names[j] = list->names[r]; |
| 77 |
list->names[r] = tmp; |
| 78 |
} |
| 79 |
} |
| 80 |
|
| 59 |
/* |
81 |
/* |
| 60 |
fill a referral type structure |
82 |
fill a referral type structure |
| 61 |
*/ |
83 |
*/ |
|
Lines 187-192
Link Here
|
| 187 |
get the DCs list within a site |
209 |
get the DCs list within a site |
| 188 |
*/ |
210 |
*/ |
| 189 |
static NTSTATUS get_dcs_insite(TALLOC_CTX *ctx, struct ldb_context *ldb, |
211 |
static NTSTATUS get_dcs_insite(TALLOC_CTX *ctx, struct ldb_context *ldb, |
|
|
212 |
const char *logon_server, |
| 190 |
struct ldb_dn *sitedn, struct dc_set *list, |
213 |
struct ldb_dn *sitedn, struct dc_set *list, |
| 191 |
bool dofqdn) |
214 |
bool dofqdn) |
| 192 |
{ |
215 |
{ |
|
Lines 196-201
Link Here
|
| 196 |
unsigned int i; |
219 |
unsigned int i; |
| 197 |
int ret; |
220 |
int ret; |
| 198 |
const char **dc_list; |
221 |
const char **dc_list; |
|
|
222 |
uint32_t preferred_index; |
| 223 |
bool preferred_dc = false; |
| 199 |
|
224 |
|
| 200 |
ret = ldb_search(ldb, ctx, &r, sitedn, LDB_SCOPE_SUBTREE, attrs, |
225 |
ret = ldb_search(ldb, ctx, &r, sitedn, LDB_SCOPE_SUBTREE, attrs, |
| 201 |
"(&(objectClass=server)(serverReference=*))"); |
226 |
"(&(objectClass=server)(serverReference=*))"); |
|
Lines 238-256
Link Here
|
| 238 |
return NT_STATUS_INTERNAL_ERROR; |
263 |
return NT_STATUS_INTERNAL_ERROR; |
| 239 |
} |
264 |
} |
| 240 |
|
265 |
|
| 241 |
if (dofqdn) { |
266 |
char *netbios_name = NULL; |
| 242 |
const char *dns = ldb_msg_find_attr_as_string(r2->msgs[0], "dNSHostName", NULL); |
267 |
if (!dofqdn || logon_server != NULL) { |
| 243 |
if (dns == NULL) { |
|
|
| 244 |
DEBUG(2,(__location__ ": dNSHostName missing on %s\n", |
| 245 |
ldb_dn_get_linearized(dn))); |
| 246 |
talloc_free(r); |
| 247 |
return NT_STATUS_INTERNAL_ERROR; |
| 248 |
} |
| 249 |
|
| 250 |
list->names[list->count] = talloc_strdup(list->names, dns); |
| 251 |
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(list->names[list->count], r); |
| 252 |
} else { |
| 253 |
char *tmp; |
| 254 |
const char *aname = ldb_msg_find_attr_as_string(r2->msgs[0], "sAMAccountName", NULL); |
268 |
const char *aname = ldb_msg_find_attr_as_string(r2->msgs[0], "sAMAccountName", NULL); |
| 255 |
if (aname == NULL) { |
269 |
if (aname == NULL) { |
| 256 |
DEBUG(2,(__location__ ": sAMAccountName missing on %s\n", |
270 |
DEBUG(2,(__location__ ": sAMAccountName missing on %s\n", |
|
Lines 259-276
Link Here
|
| 259 |
return NT_STATUS_INTERNAL_ERROR; |
273 |
return NT_STATUS_INTERNAL_ERROR; |
| 260 |
} |
274 |
} |
| 261 |
|
275 |
|
| 262 |
tmp = talloc_strdup(list->names, aname); |
276 |
netbios_name = talloc_strdup(list->names, aname); |
| 263 |
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(tmp, r); |
277 |
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(netbios_name, r); |
| 264 |
|
278 |
|
| 265 |
/* Netbios name is also the sAMAccountName for |
279 |
/* Netbios name is also the sAMAccountName for |
| 266 |
computer but without the final $ */ |
280 |
computer but without the final $ */ |
| 267 |
tmp[strlen(tmp) - 1] = '\0'; |
281 |
netbios_name[strlen(netbios_name) - 1] = '\0'; |
| 268 |
list->names[list->count] = tmp; |
282 |
|
|
|
283 |
if (logon_server != NULL && strcasecmp(logon_server, netbios_name) == 0) { |
| 284 |
preferred_index = list->count; |
| 285 |
preferred_dc = true; |
| 286 |
} |
| 287 |
|
| 288 |
if (!dofqdn) { |
| 289 |
list->names[list->count] = netbios_name; |
| 290 |
} else { |
| 291 |
talloc_free(netbios_name); |
| 292 |
} |
| 269 |
} |
293 |
} |
|
|
294 |
|
| 295 |
if (dofqdn) { |
| 296 |
const char *dns = ldb_msg_find_attr_as_string(r2->msgs[0], "dNSHostName", NULL); |
| 297 |
if (dns == NULL) { |
| 298 |
DEBUG(2,(__location__ ": dNSHostName missing on %s\n", |
| 299 |
ldb_dn_get_linearized(dn))); |
| 300 |
talloc_free(r); |
| 301 |
return NT_STATUS_INTERNAL_ERROR; |
| 302 |
} |
| 303 |
|
| 304 |
list->names[list->count] = talloc_strdup(list->names, dns); |
| 305 |
NT_STATUS_HAVE_NO_MEMORY_AND_FREE(list->names[list->count], r); |
| 306 |
} |
| 307 |
|
| 270 |
list->count++; |
308 |
list->count++; |
| 271 |
talloc_free(r2); |
309 |
talloc_free(r2); |
| 272 |
} |
310 |
} |
| 273 |
shuffle_dc_set(list); |
311 |
|
|
|
312 |
if (preferred_dc) { |
| 313 |
shuffle_dc_set_preferred(list, preferred_index); |
| 314 |
} else { |
| 315 |
shuffle_dc_set(list); |
| 316 |
} |
| 274 |
|
317 |
|
| 275 |
talloc_free(r); |
318 |
talloc_free(r); |
| 276 |
return NT_STATUS_OK; |
319 |
return NT_STATUS_OK; |
|
Lines 281-286
Link Here
|
| 281 |
get all DCs |
324 |
get all DCs |
| 282 |
*/ |
325 |
*/ |
| 283 |
static NTSTATUS get_dcs(TALLOC_CTX *ctx, struct ldb_context *ldb, |
326 |
static NTSTATUS get_dcs(TALLOC_CTX *ctx, struct ldb_context *ldb, |
|
|
327 |
const char *logon_server, |
| 284 |
const char *searched_site, bool need_fqdn, |
328 |
const char *searched_site, bool need_fqdn, |
| 285 |
struct dc_set ***pset_list, uint32_t flags) |
329 |
struct dc_set ***pset_list, uint32_t flags) |
| 286 |
{ |
330 |
{ |
|
Lines 361-367
Link Here
|
| 361 |
|
405 |
|
| 362 |
set_list[current_pos]->names = NULL; |
406 |
set_list[current_pos]->names = NULL; |
| 363 |
set_list[current_pos]->count = 0; |
407 |
set_list[current_pos]->count = 0; |
| 364 |
status = get_dcs_insite(subctx, ldb, sitedn, |
408 |
status = get_dcs_insite(subctx, ldb, logon_server, sitedn, |
| 365 |
set_list[current_pos], need_fqdn); |
409 |
set_list[current_pos], need_fqdn); |
| 366 |
if (!NT_STATUS_IS_OK(status)) { |
410 |
if (!NT_STATUS_IS_OK(status)) { |
| 367 |
DEBUG(2,(__location__ ": Failed to get DC from site %s - %s\n", |
411 |
DEBUG(2,(__location__ ": Failed to get DC from site %s - %s\n", |
|
Lines 434-440
Link Here
|
| 434 |
*/ |
478 |
*/ |
| 435 |
dn = r->msgs[i]->dn; |
479 |
dn = r->msgs[i]->dn; |
| 436 |
|
480 |
|
| 437 |
status = get_dcs_insite(subctx, ldb, dn, |
481 |
status = get_dcs_insite(subctx, ldb, logon_server, dn, |
| 438 |
set_list[current_pos], |
482 |
set_list[current_pos], |
| 439 |
need_fqdn); |
483 |
need_fqdn); |
| 440 |
if (!NT_STATUS_IS_OK(status)) { |
484 |
if (!NT_STATUS_IS_OK(status)) { |
|
Lines 534-539
Link Here
|
| 534 |
*/ |
578 |
*/ |
| 535 |
static NTSTATUS dodc_referral(struct loadparm_context *lp_ctx, |
579 |
static NTSTATUS dodc_referral(struct loadparm_context *lp_ctx, |
| 536 |
struct ldb_context *sam_ctx, |
580 |
struct ldb_context *sam_ctx, |
|
|
581 |
const char *logon_server, |
| 537 |
const struct tsocket_address *client, |
582 |
const struct tsocket_address *client, |
| 538 |
struct dfs_GetDFSReferral *r, |
583 |
struct dfs_GetDFSReferral *r, |
| 539 |
const char *domain_name) |
584 |
const char *domain_name) |
|
Lines 575-581
Link Here
|
| 575 |
|
620 |
|
| 576 |
site_name = samdb_client_site_name(sam_ctx, r, client_str, NULL); |
621 |
site_name = samdb_client_site_name(sam_ctx, r, client_str, NULL); |
| 577 |
|
622 |
|
| 578 |
status = get_dcs(r, sam_ctx, site_name, need_fqdn, &set, 0); |
623 |
status = get_dcs(r, sam_ctx, logon_server, site_name, need_fqdn, &set, 0); |
| 579 |
if (!NT_STATUS_IS_OK(status)) { |
624 |
if (!NT_STATUS_IS_OK(status)) { |
| 580 |
DEBUG(3,("Unable to get list of DCs - %s\n", |
625 |
DEBUG(3,("Unable to get list of DCs - %s\n", |
| 581 |
nt_errstr(status))); |
626 |
nt_errstr(status))); |
|
Lines 648-653
Link Here
|
| 648 |
static NTSTATUS dosysvol_referral(struct loadparm_context *lp_ctx, |
693 |
static NTSTATUS dosysvol_referral(struct loadparm_context *lp_ctx, |
| 649 |
struct ldb_context *sam_ctx, |
694 |
struct ldb_context *sam_ctx, |
| 650 |
const struct tsocket_address *client, |
695 |
const struct tsocket_address *client, |
|
|
696 |
const char *logon_server, |
| 651 |
struct dfs_GetDFSReferral *r, |
697 |
struct dfs_GetDFSReferral *r, |
| 652 |
const char *domain_name, |
698 |
const char *domain_name, |
| 653 |
const char *dfs_name) |
699 |
const char *dfs_name) |
|
Lines 686-692
Link Here
|
| 686 |
|
732 |
|
| 687 |
site_name = samdb_client_site_name(sam_ctx, r, client_str, NULL); |
733 |
site_name = samdb_client_site_name(sam_ctx, r, client_str, NULL); |
| 688 |
|
734 |
|
| 689 |
status = get_dcs(r, sam_ctx, site_name, need_fqdn, &set, 0); |
735 |
status = get_dcs(r, sam_ctx, logon_server, site_name, need_fqdn, &set, 0); |
| 690 |
if (!NT_STATUS_IS_OK(status)) { |
736 |
if (!NT_STATUS_IS_OK(status)) { |
| 691 |
DEBUG(3,("Unable to get list of DCs - %s\n", |
737 |
DEBUG(3,("Unable to get list of DCs - %s\n", |
| 692 |
nt_errstr(status))); |
738 |
nt_errstr(status))); |
|
Lines 760-765
Link Here
|
| 760 |
*/ |
806 |
*/ |
| 761 |
NTSTATUS dfs_server_ad_get_referrals(struct loadparm_context *lp_ctx, |
807 |
NTSTATUS dfs_server_ad_get_referrals(struct loadparm_context *lp_ctx, |
| 762 |
struct ldb_context *sam_ctx, |
808 |
struct ldb_context *sam_ctx, |
|
|
809 |
const char *logon_server, |
| 763 |
const struct tsocket_address *client, |
810 |
const struct tsocket_address *client, |
| 764 |
struct dfs_GetDFSReferral *r) |
811 |
struct dfs_GetDFSReferral *r) |
| 765 |
{ |
812 |
{ |
|
Lines 896-902
Link Here
|
| 896 |
* be just a sysvol/netlogon referral. |
943 |
* be just a sysvol/netlogon referral. |
| 897 |
*/ |
944 |
*/ |
| 898 |
if (dfs_name == NULL) { |
945 |
if (dfs_name == NULL) { |
| 899 |
return dodc_referral(lp_ctx, sam_ctx, |
946 |
return dodc_referral(lp_ctx, sam_ctx, logon_server, |
| 900 |
client, r, server_name); |
947 |
client, r, server_name); |
| 901 |
} |
948 |
} |
| 902 |
|
949 |
|
|
Lines 908-914
Link Here
|
| 908 |
*/ |
955 |
*/ |
| 909 |
if (strcasecmp(dfs_name, "sysvol") == 0 || |
956 |
if (strcasecmp(dfs_name, "sysvol") == 0 || |
| 910 |
strcasecmp(dfs_name, "netlogon") == 0) { |
957 |
strcasecmp(dfs_name, "netlogon") == 0) { |
| 911 |
return dosysvol_referral(lp_ctx, sam_ctx, client, r, |
958 |
return dosysvol_referral(lp_ctx, sam_ctx, client, logon_server, r, |
| 912 |
server_name, dfs_name); |
959 |
server_name, dfs_name); |
| 913 |
} |
960 |
} |
| 914 |
|
961 |
|