From ff3390db7529a1ad76e25263b80463e37f555dae Mon Sep 17 00:00:00 2001
From: Samuel Cabrero <scabrero@suse.de>
Date: Mon, 13 Jan 2020 13:52:34 +0100
Subject: [PATCH] AD: use getaddrinfo with AI_CANONNAME to find the FQDN

In systems where gethostbyname() does not return the FQDN try calling
getaddrinfo().

Signed-off-by: Samuel Cabrero <scabrero@suse.de>

Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 2143c7276c7603520e2575ef6c9d93a5fc031256)
---
 src/man/sssd-ad.5.xml        | 14 ++++++------
 src/providers/ad/ad_common.c | 42 ++++++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml
index 77d7f948b..b7f312204 100644
--- a/src/man/sssd-ad.5.xml
+++ b/src/man/sssd-ad.5.xml
@@ -190,15 +190,17 @@ ad_enabled_domains = sales.example.com, eng.example.com
                     <term>ad_hostname (string)</term>
                     <listitem>
                         <para>
-                            Optional. May be set on machines where the
-                            hostname(5) does not reflect the fully qualified
-                            name used in the Active Directory domain to
-                            identify this host.
+                            Optional. On machines where the hostname(5) does
+                            not reflect the fully qualified name, sssd will try
+                            to expand the short name. If it is not possible or
+                            the short name should be really used instead, set
+                            this parameter explicitly.
                         </para>
                         <para>
                             This field is used to determine the host principal
-                            in use in the keytab. It must match the hostname
-                            for which the keytab was issued.
+                            in use in the keytab and to perform dynamic DNS
+                            updates. It must match the hostname for which the
+                            keytab was issued.
                         </para>
                     </listitem>
                 </varlistentry>
diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c
index 2a1647173..1708ca01f 100644
--- a/src/providers/ad/ad_common.c
+++ b/src/providers/ad/ad_common.c
@@ -398,6 +398,34 @@ ad_create_1way_trust_options(TALLOC_CTX *mem_ctx,
     return ad_options;
 }
 
+static errno_t
+ad_try_to_get_fqdn(const char *hostname,
+                   char *buf,
+                   size_t buflen)
+{
+    int ret;
+    struct addrinfo *res;
+    struct addrinfo hints;
+
+    memset(&hints, 0, sizeof(struct addrinfo));
+    hints.ai_socktype = SOCK_DGRAM;
+    hints.ai_flags = AI_CANONNAME;
+
+    ret = getaddrinfo(hostname, NULL, &hints, &res);
+    if (ret != 0) {
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "getaddrinfo failed: %s\n",
+              gai_strerror(ret));
+        return ret;
+    }
+
+    strncpy(buf, res->ai_canonname, buflen);
+
+    freeaddrinfo(res);
+
+    return EOK;
+}
+
 errno_t
 ad_get_common_options(TALLOC_CTX *mem_ctx,
                       struct confdb_ctx *cdb,
@@ -413,6 +441,7 @@ ad_get_common_options(TALLOC_CTX *mem_ctx,
     char *realm;
     char *ad_hostname;
     char hostname[HOST_NAME_MAX + 1];
+    char fqdn[HOST_NAME_MAX + 1];
     char *case_sensitive_opt;
     const char *opt_override;
 
@@ -460,6 +489,19 @@ ad_get_common_options(TALLOC_CTX *mem_ctx,
             goto done;
         }
         hostname[HOST_NAME_MAX] = '\0';
+
+        if (strchr(hostname, '.') == NULL) {
+            ret = ad_try_to_get_fqdn(hostname, fqdn, sizeof(fqdn));
+            if (ret == EOK) {
+                DEBUG(SSSDBG_CONF_SETTINGS,
+                      "The hostname [%s] has been expanded to FQDN [%s]. "
+                      "If sssd should really use the short hostname, please "
+                      "set ad_hostname explicitly.\n", hostname, fqdn);
+                strncpy(hostname, fqdn, sizeof(hostname));
+                hostname[HOST_NAME_MAX] = '\0';
+            }
+        }
+
         DEBUG(SSSDBG_CONF_SETTINGS,
               "Setting ad_hostname to [%s].\n", hostname);
         ret = dp_opt_set_string(opts->basic, AD_HOSTNAME, hostname);
-- 
2.25.1

