d7fdbd
From 01b646d2af0ed885d01d31a6479898a3c423a630 Mon Sep 17 00:00:00 2001
d7fdbd
From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= <olysonek@redhat.com>
d7fdbd
Date: Thu, 26 Apr 2018 10:00:19 +0200
d7fdbd
Subject: [PATCH 52/59] Fix rDNS with IPv6
d7fdbd
d7fdbd
Previously IPv6 addresses were not translated to hostnames for PAM to use.
d7fdbd
---
d7fdbd
 privops.c    |  3 ++-
d7fdbd
 sysdeputil.c | 28 +++++++++++++++-------------
d7fdbd
 sysdeputil.h |  5 ++++-
d7fdbd
 sysutil.c    | 35 +++++++++++++++++++++++++++++++++++
d7fdbd
 sysutil.h    |  4 ++++
d7fdbd
 5 files changed, 60 insertions(+), 15 deletions(-)
d7fdbd
d7fdbd
diff --git a/privops.c b/privops.c
d7fdbd
index f27c5c4..e577a27 100644
d7fdbd
--- a/privops.c
d7fdbd
+++ b/privops.c
d7fdbd
@@ -383,7 +383,8 @@ handle_local_login(struct vsf_session* p_sess,
d7fdbd
                    struct mystr* p_user_str,
d7fdbd
                    const struct mystr* p_pass_str)
d7fdbd
 {
d7fdbd
-  if (!vsf_sysdep_check_auth(p_user_str, p_pass_str, &p_sess->remote_ip_str))
d7fdbd
+  if (!vsf_sysdep_check_auth(p_sess, p_user_str, p_pass_str,
d7fdbd
+                             &p_sess->remote_ip_str))
d7fdbd
   {
d7fdbd
     return kVSFLoginFail;
d7fdbd
   }
d7fdbd
diff --git a/sysdeputil.c b/sysdeputil.c
d7fdbd
index 2063c87..4fe56c2 100644
d7fdbd
--- a/sysdeputil.c
d7fdbd
+++ b/sysdeputil.c
d7fdbd
@@ -16,10 +16,6 @@
d7fdbd
 #include "tunables.h"
d7fdbd
 #include "builddefs.h"
d7fdbd
 
d7fdbd
-/* For gethostbyaddr, inet_addr */
d7fdbd
-#include <netdb.h>
d7fdbd
-#include <arpa/inet.h>
d7fdbd
-
d7fdbd
 /* For Linux, this adds nothing :-) */
d7fdbd
 #include "port/porting_junk.h"
d7fdbd
 
d7fdbd
@@ -242,13 +238,15 @@ void vsf_remove_uwtmp(void);
d7fdbd
 
d7fdbd
 #ifndef VSF_SYSDEP_HAVE_PAM
d7fdbd
 int
d7fdbd
-vsf_sysdep_check_auth(struct mystr* p_user_str,
d7fdbd
+vsf_sysdep_check_auth(struct vsf_session* p_sess,
d7fdbd
+                      struct mystr* p_user_str,
d7fdbd
                       const struct mystr* p_pass_str,
d7fdbd
                       const struct mystr* p_remote_host)
d7fdbd
 {
d7fdbd
   const char* p_crypted;
d7fdbd
   const struct passwd* p_pwd = getpwnam(str_getbuf(p_user_str));
d7fdbd
   (void) p_remote_host;
d7fdbd
+  (void) p_sess;
d7fdbd
   if (p_pwd == NULL)
d7fdbd
   {
d7fdbd
     return 0;
d7fdbd
@@ -322,14 +320,14 @@ static int pam_conv_func(int nmsg, const struct pam_message** p_msg,
d7fdbd
 static void vsf_auth_shutdown(void);
d7fdbd
 
d7fdbd
 int
d7fdbd
-vsf_sysdep_check_auth(struct mystr* p_user_str,
d7fdbd
+vsf_sysdep_check_auth(struct vsf_session* p_sess,
d7fdbd
+                      struct mystr* p_user_str,
d7fdbd
                       const struct mystr* p_pass_str,
d7fdbd
                       const struct mystr* p_remote_host)
d7fdbd
 {
d7fdbd
   int retval = -1;
d7fdbd
 #ifdef PAM_RHOST
d7fdbd
-  struct sockaddr_in sin;
d7fdbd
-  struct hostent *host;
d7fdbd
+  struct mystr hostname = INIT_MYSTR;
d7fdbd
 #endif
d7fdbd
   pam_item_t item;
d7fdbd
   const char* pam_user_name = 0;
d7fdbd
@@ -354,13 +352,17 @@ vsf_sysdep_check_auth(struct mystr* p_user_str,
d7fdbd
     return 0;
d7fdbd
   }
d7fdbd
 #ifdef PAM_RHOST
d7fdbd
-  if (tunable_reverse_lookup_enable) {
d7fdbd
-    sin.sin_addr.s_addr = inet_addr(str_getbuf(p_remote_host));
d7fdbd
-    host = gethostbyaddr((char*)&sin.sin_addr.s_addr,sizeof(struct in_addr),AF_INET);
d7fdbd
-    if (host != (struct hostent*)0)
d7fdbd
-      retval = pam_set_item(s_pamh, PAM_RHOST, host->h_name);
d7fdbd
+  if (tunable_reverse_lookup_enable)
d7fdbd
+  {
d7fdbd
+    if (vsf_sysutil_get_hostname(p_sess->p_remote_addr, &hostname) == 0)
d7fdbd
+    {
d7fdbd
+      retval = pam_set_item(s_pamh, PAM_RHOST, str_getbuf(&hostname));
d7fdbd
+      str_free(&hostname);
d7fdbd
+    }
d7fdbd
     else
d7fdbd
+    {
d7fdbd
       retval = pam_set_item(s_pamh, PAM_RHOST, str_getbuf(p_remote_host));
d7fdbd
+    }
d7fdbd
   } else {
d7fdbd
     retval = pam_set_item(s_pamh, PAM_RHOST, str_getbuf(p_remote_host));
d7fdbd
   }
d7fdbd
diff --git a/sysdeputil.h b/sysdeputil.h
d7fdbd
index 3b6b30a..6f2aa0a 100644
d7fdbd
--- a/sysdeputil.h
d7fdbd
+++ b/sysdeputil.h
d7fdbd
@@ -5,6 +5,8 @@
d7fdbd
 #include "filesize.h"
d7fdbd
 #endif
d7fdbd
 
d7fdbd
+#include "session.h"
d7fdbd
+
d7fdbd
 /* VSF_SYSDEPUTIL_H:
d7fdbd
  * Support for highly system dependent features, and querying for support
d7fdbd
  * or lack thereof
d7fdbd
@@ -15,7 +17,8 @@ struct mystr;
d7fdbd
 
d7fdbd
 /* Authentication of local users */
d7fdbd
 /* Return 0 for fail, 1 for success */
d7fdbd
-int vsf_sysdep_check_auth(struct mystr* p_user,
d7fdbd
+int vsf_sysdep_check_auth(struct vsf_session* p_sess,
d7fdbd
+                          struct mystr* p_user,
d7fdbd
                           const struct mystr* p_pass,
d7fdbd
                           const struct mystr* p_remote_host);
d7fdbd
 
d7fdbd
diff --git a/sysutil.c b/sysutil.c
d7fdbd
index e847650..b68583b 100644
d7fdbd
--- a/sysutil.c
d7fdbd
+++ b/sysutil.c
d7fdbd
@@ -2356,6 +2356,41 @@ vsf_sysutil_dns_resolve(struct vsf_sysutil_sockaddr** p_sockptr,
d7fdbd
   }
d7fdbd
 }
d7fdbd
 
d7fdbd
+int
d7fdbd
+vsf_sysutil_get_hostname(struct vsf_sysutil_sockaddr *p_addr,
d7fdbd
+                         struct mystr* p_str)
d7fdbd
+{
d7fdbd
+  struct sockaddr *sa;
d7fdbd
+  socklen_t sa_len = 0;
d7fdbd
+  char hostname[NI_MAXHOST];
d7fdbd
+  int res;
d7fdbd
+
d7fdbd
+  sa = &p_addr->u.u_sockaddr;
d7fdbd
+  if (sa->sa_family == AF_INET)
d7fdbd
+  {
d7fdbd
+    sa_len = sizeof(struct sockaddr_in);
d7fdbd
+  }
d7fdbd
+  else if (sa->sa_family == AF_INET6)
d7fdbd
+  {
d7fdbd
+    sa_len = sizeof(struct sockaddr_in6);
d7fdbd
+  }
d7fdbd
+  else
d7fdbd
+  {
d7fdbd
+    die("can only support ipv4 and ipv6 currently");
d7fdbd
+  }
d7fdbd
+  res = getnameinfo(sa, sa_len, hostname, sizeof(hostname), NULL, 0,
d7fdbd
+                    NI_NAMEREQD);
d7fdbd
+  if (res == 0)
d7fdbd
+  {
d7fdbd
+    str_alloc_text(p_str, hostname);
d7fdbd
+    return 0;
d7fdbd
+  }
d7fdbd
+  else
d7fdbd
+  {
d7fdbd
+    return -1;
d7fdbd
+  }
d7fdbd
+}
d7fdbd
+
d7fdbd
 struct vsf_sysutil_user*
d7fdbd
 vsf_sysutil_getpwuid(const unsigned int uid)
d7fdbd
 {
d7fdbd
diff --git a/sysutil.h b/sysutil.h
d7fdbd
index 7a59f13..2df14ed 100644
d7fdbd
--- a/sysutil.h
d7fdbd
+++ b/sysutil.h
d7fdbd
@@ -7,6 +7,8 @@
d7fdbd
 #include "filesize.h"
d7fdbd
 #endif
d7fdbd
 
d7fdbd
+#include "str.h"
d7fdbd
+
d7fdbd
 /* Return value queries */
d7fdbd
 int vsf_sysutil_retval_is_error(int retval);
d7fdbd
 enum EVSFSysUtilError
d7fdbd
@@ -266,6 +268,8 @@ int vsf_sysutil_connect_timeout(int fd,
d7fdbd
                                 unsigned int wait_seconds);
d7fdbd
 void vsf_sysutil_dns_resolve(struct vsf_sysutil_sockaddr** p_sockptr,
d7fdbd
                              const char* p_name);
d7fdbd
+int vsf_sysutil_get_hostname(struct vsf_sysutil_sockaddr *p_addr,
d7fdbd
+                             struct mystr* p_str);
d7fdbd
 /* Option setting on sockets */
d7fdbd
 void vsf_sysutil_activate_keepalive(int fd);
d7fdbd
 void vsf_sysutil_rcvtimeo(int fd);
d7fdbd
-- 
d7fdbd
2.14.4
d7fdbd