This is a discussion on [PATCH 2/4] dns updates: Register name.dnsdomain instead ofgethostbyname(name). - Samba ; Previously, we would register the fqdn that is returned as an alias from doing a gethostbyname on our name. This is generally not going to work since it relies on DNS, which is exactly what we are trying dynamically configure. ...
Previously, we would register the fqdn that is returned as an alias
from doing a gethostbyname on our name. This is generally not going
to work since it relies on DNS, which is exactly what we are trying
dynamically configure. So we statically construct a DNS name using
our machine name and the realm -> DNS domain mapping and register
that.
---
source/configure.in | 1 +
source/utils/net_ads.c | 102 +++++++++++++++++++++++++++++++++++++++
+-------
2 files changed, 87 insertions(+), 16 deletions(-)
diff --git a/source/configure.in b/source/configure.in
index 5176dc1..b9d113f 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -3382,6 +3382,7 @@ if test x"$with_ads_support" != x"no"; then
AC_CHECK_FUNC_EXT(krb5_get_init_creds_opt_free, $KRB5_LIBS)
AC_CHECK_FUNC_EXT(krb5_get_init_creds_opt_get_erro r, $KRB5_LIBS)
AC_CHECK_FUNC_EXT(krb5_enctype_to_string, $KRB5_LIBS)
+ AC_CHECK_FUNC_EXT(krb5_get_realm_domain, $KRB5_LIBS)
LIBS="$KRB5_LIBS $LIBS"
diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c
index 96fa6ba..1add13f 100644
--- a/source/utils/net_ads.c
+++ b/source/utils/net_ads.c
@@ -956,27 +956,62 @@ DNS_ERROR DoDNSUpdate(char *pszServerName,
const struct sockaddr_storage *sslist,
size_t num_addrs );
+/* XXX The krb5_get_realm_domain symbol is currently a private MIT
symbol.
+ * We have asked for it to be make public or for an alternative API
to be
+ * provided.
+ */
+extern krb5_error_code KRB5_CALLCONV krb5_get_realm_domain
+ (krb5_context, const char *, char ** );
+
+#ifndef HAVE_KRB5_GET_REALM_DOMAIN
+extern krb5_error_code KRB5_CALLCONV krb5_get_realm_domain
+ (krb5_context ctx, const char * dns, char ** realm)
+{
+ return KRB5_ERR_HOST_REALM_UNKNOWN;
+}
+#endif
+
+static NTSTATUS map_krb_realm_to_dns_domain(ADS_STRUCT *ads,
+ char ** dnsdomain)
+{
+ krb5_error_code rc = 0;
+ krb5_context kctx = 0;
+
+ rc = krb5_init_context(&kctx);
+ if (rc) {
+ DEBUG(1,("krb5_init_context failed (%s)\n",
+ error_message(rc)));
+ return krb5_to_nt_status(rc);
+ }
+
+ /* Map the KRB5 realm to the DNS domain. */
+ rc = krb5_get_realm_domain(kctx, ads->config.realm, dnsdomain);
+ if (rc) {
+ d_printf("Unable to find DNS domain for the %s realm: %s\n",
+ ads->config.realm, error_message(rc));
+
+ krb5_free_context(kctx);
+ return krb5_to_nt_status(rc);
+ }
+
+ krb5_free_context(kctx);
+ return NT_STATUS_OK;
+}
+
+
static NTSTATUS net_update_dns_internal(TALLOC_CTX *ctx, ADS_STRUCT
*ads,
const char *machine_name,
+ const char *dnsdomain,
const struct sockaddr_storage *addrs,
int num_addrs)
{
struct dns_rr_ns *nameservers = NULL;
int ns_count = 0;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- DNS_ERROR dns_err;
+ DNS_ERROR dns_err = ERROR_DNS_SUCCESS;
fstring dns_server;
- const char *dnsdomain = NULL;
char *root_domain = NULL;
- if ( (dnsdomain = strchr_m( machine_name, '.')) == NULL ) {
- d_printf("No DNS domain configured for %s. "
- "Unable to perform DNS Update.\n", machine_name);
- status = NT_STATUS_INVALID_PARAMETER;
- goto done;
- }
- dnsdomain++;
-
status = ads_dns_lookup_ns( ctx, dnsdomain, &nameservers,
&ns_count );
if ( !NT_STATUS_IS_OK(status) || (ns_count == 0)) {
/* Child domains often do not have NS records. Look
@@ -1041,6 +1076,19 @@ static NTSTATUS
net_update_dns_internal(TALLOC_CTX *ctx, ADS_STRUCT *ads,
done:
+ if (!NT_STATUS_IS_OK(status)) {
+ if (!ERR_DNS_IS_OK(dns_err)) {
+ d_printf("DNS update for %s failed: %s\n",
+ machine_name,
+ dns_errstr(dns_err));
+ } else {
+ d_printf("DNS update for %s failed: %s\n",
+ machine_name,
+ get_friendly_nt_error_msg(status));
+ }
+ }
+
+
SAFE_FREE( root_domain );
return status;
@@ -1050,11 +1098,30 @@ static NTSTATUS net_update_dns(TALLOC_CTX
*mem_ctx, ADS_STRUCT *ads)
{
int num_addrs;
struct sockaddr_storage *iplist = NULL;
- fstring machine_name;
+ char * machine_fqdn = NULL;
+ char * dnsdomain = NULL;
NTSTATUS status;
- name_to_fqdn( machine_name, global_myname() );
- strlower_m( machine_name );
+ /* The name we register should be the computer name with the
+ * DNS domain appended. See http://support.microsoft.com/kb/317590.
+ * We derive the DNS domain from the KRB5 realm because we can't rely
+ * on the domain being configured correctly (or at all).
+ */
+ status = map_krb_realm_to_dns_domain(ads, &dnsdomain);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ machine_fqdn = talloc_asprintf(mem_ctx, "%s.%s",
+ global_myname(), dnsdomain);
+ if (machine_fqdn == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ strlower_m(machine_fqdn);
+ DEBUG(4, ("updating DNS registration for name '%s'\n",
+ machine_fqdn));
/* Get our ip address (not the 127.0.0.x address but a real ip
* address) */
@@ -1063,11 +1130,14 @@ static NTSTATUS net_update_dns(TALLOC_CTX
*mem_ctx, ADS_STRUCT *ads)
if ( num_addrs <= 0 ) {
DEBUG(4,("net_update_dns: Failed to find my non-loopback IP "
"addresses!\n"));
- return NT_STATUS_INVALID_PARAMETER;
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto done;
}
- status = net_update_dns_internal(mem_ctx, ads, machine_name,
- iplist, num_addrs);
+ status = net_update_dns_internal(mem_ctx, ads, machine_fqdn,
+ dnsdomain, iplist, num_addrs);
+
+done:
SAFE_FREE( iplist );
return status;
}
--
1.5.5.1