|
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 |
*/ |
|
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 |
{ |
|
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=*))"); |
|
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", |
|
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; |
|
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 |
{ |
|
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", |
|
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)) { |
|
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) |
|
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))); |
|
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) |
|
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))); |
|
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 |
{ |
|
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 |
|
|
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 |
|