diff options
author | Jeremy Allison <jra@samba.org> | 2006-09-02 19:27:44 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 11:39:47 -0500 |
commit | 0f1bc28744d8c7cae2fe2774b50fc4336408a74d (patch) | |
tree | 124fd73f24ecac3aff19bad4e55e21f5c1a7538c /source3/libads | |
parent | bd5fca847a33ddef7d73ad8c6932ee2f6685054a (diff) | |
download | samba-0f1bc28744d8c7cae2fe2774b50fc4336408a74d.tar.gz samba-0f1bc28744d8c7cae2fe2774b50fc4336408a74d.tar.bz2 samba-0f1bc28744d8c7cae2fe2774b50fc4336408a74d.zip |
r18006: Actually a smaller change than it looks. Leverage
the get_dc_list code to get the _kerberos. names
for site support. This way we don't depend on one
KDC to do ticket refresh. Even though we know it's
up when we add it, it may go down when we're trying
to refresh.
Jeremy.
(This used to be commit 77fe2a3d7418012a8dbfb6aaeb2a8dd57c6e1a5d)
Diffstat (limited to 'source3/libads')
-rw-r--r-- | source3/libads/dns.c | 45 | ||||
-rw-r--r-- | source3/libads/kerberos.c | 51 |
2 files changed, 86 insertions, 10 deletions
diff --git a/source3/libads/dns.c b/source3/libads/dns.c index 579296ea1f..d5c851d5ca 100644 --- a/source3/libads/dns.c +++ b/source3/libads/dns.c @@ -649,18 +649,20 @@ BOOL stored_sitename_changed(const char *sitename) Query with optional sitename. ********************************************************************/ -NTSTATUS ads_dns_query_dcs_internal(TALLOC_CTX *ctx, - const char *domain, +NTSTATUS ads_dns_query_internal(TALLOC_CTX *ctx, + const char *servicename, + const char *realm, const char *sitename, struct dns_rr_srv **dclist, int *numdcs ) { char *name; if (sitename) { - name = talloc_asprintf(ctx, "_ldap._tcp.%s._sites.dc._msdcs.%s", - sitename, domain ); + name = talloc_asprintf(ctx, "%s._tcp.%s._sites.dc._msdcs.%s", + servicename, sitename, realm ); } else { - name = talloc_asprintf(ctx, "_ldap._tcp.dc._msdcs.%s", domain ); + name = talloc_asprintf(ctx, "%s._tcp.dc._msdcs.%s", + servicename, realm ); } if (!name) { return NT_STATUS_NO_MEMORY; @@ -673,17 +675,44 @@ NTSTATUS ads_dns_query_dcs_internal(TALLOC_CTX *ctx, ********************************************************************/ NTSTATUS ads_dns_query_dcs(TALLOC_CTX *ctx, - const char *domain, + const char *realm, struct dns_rr_srv **dclist, int *numdcs ) { NTSTATUS status; char *sitename = sitename_fetch(); - status = ads_dns_query_dcs_internal(ctx, domain, sitename, dclist, numdcs); + status = ads_dns_query_internal(ctx, "_ldap", realm, sitename, + dclist, numdcs); if (sitename && !NT_STATUS_IS_OK(status)) { /* Sitename DNS query may have failed. Try without. */ - status = ads_dns_query_dcs_internal(ctx, domain, NULL, dclist, numdcs); + status = ads_dns_query_internal(ctx, "_ldap", realm, NULL, + dclist, numdcs); + } + SAFE_FREE(sitename); + return status; +} + +/******************************************************************** + Query for AD KDC's. Transparently use sitename. + Even if our underlying kerberos libraries are UDP only, this + is pretty safe as it's unlikely that a KDC supports TCP and not UDP. +********************************************************************/ + +NTSTATUS ads_dns_query_kdcs(TALLOC_CTX *ctx, + const char *realm, + struct dns_rr_srv **dclist, + int *numdcs ) +{ + NTSTATUS status; + char *sitename = sitename_fetch(); + + status = ads_dns_query_internal(ctx, "_kerberos", realm, sitename, + dclist, numdcs); + if (sitename && !NT_STATUS_IS_OK(status)) { + /* Sitename DNS query may have failed. Try without. */ + status = ads_dns_query_internal(ctx, "_kerberos", realm, NULL, + dclist, numdcs); } SAFE_FREE(sitename); return status; diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 4801aec23e..c872508fe8 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -465,6 +465,46 @@ int kerberos_kinit_password(const char *principal, } /************************************************************************ + Create a string list of available kdc's, possibly searching by sitename. + Does DNS queries. +************************************************************************/ + +static char *get_kdc_ip_string(char *mem_ctx, const char *realm, struct in_addr primary_ip) +{ + struct ip_service *ip_srv; + int count, i; + char *kdc_str = talloc_asprintf(mem_ctx, "\tkdc = %s\n", + inet_ntoa(primary_ip)); + + if (kdc_str == NULL) { + return NULL; + } + + if (!NT_STATUS_IS_OK(get_kdc_list(realm, &ip_srv, &count))) { + DEBUG(10,("get_kdc_ip_string: get_kdc_list failed. Returning %s\n", + kdc_str )); + return kdc_str; + } + + for (i = 0; i < count; i++) { + if (ip_equal(ip_srv[i].ip, primary_ip)) { + continue; + } + /* Append to the string - inefficient but not done often. */ + kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", + kdc_str, inet_ntoa(ip_srv[i].ip)); + if (!kdc_str) { + return NULL; + } + } + + DEBUG(10,("get_kdc_ip_string: Returning %s\n", + kdc_str )); + + return kdc_str; +} + +/************************************************************************ Create a specific krb5.conf file in the private directory pointing at a specific kdc for a realm. Keyed off domain name. Sets KRB5_CONFIG environment variable to point to this file. Must be @@ -477,6 +517,7 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do char *dname = talloc_asprintf(NULL, "%s/smb_krb5", lp_lockdir()); char *fname = NULL; char *file_contents = NULL; + char *kdc_ip_string; size_t flen = 0; size_t ret; char *realm_upper = NULL; @@ -505,10 +546,16 @@ BOOL create_local_private_krb5_conf_for_domain(const char *realm, const char *do realm_upper = talloc_strdup(fname, realm); strupper_m(realm_upper); + kdc_ip_string = get_kdc_ip_string(dname, realm, ip); + if (!kdc_ip_string) { + TALLOC_FREE(dname); + return False; + } + file_contents = talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n\n" "[realms]\n\t%s = {\n" - "\t\tkdc = %s\n\t}\n", - realm_upper, realm_upper, inet_ntoa(ip)); + "\t\t%s\t}\n", + realm_upper, realm_upper, kdc_ip_string); if (!file_contents) { TALLOC_FREE(dname); |