1
0
mirror of https://github.com/InfrastructureServices/vsftpd.git synced 2025-04-19 01:24:02 +03:00

Fix rDNS with IPv6

Previously IPv6 addresses were not translated to hostnames for PAM to use.
This commit is contained in:
Ondřej Lysoněk 2018-04-26 10:00:19 +02:00
parent 765f99b267
commit 01b646d2af
5 changed files with 60 additions and 15 deletions

View File

@ -383,7 +383,8 @@ handle_local_login(struct vsf_session* p_sess,
struct mystr* p_user_str,
const struct mystr* p_pass_str)
{
if (!vsf_sysdep_check_auth(p_user_str, p_pass_str, &p_sess->remote_ip_str))
if (!vsf_sysdep_check_auth(p_sess, p_user_str, p_pass_str,
&p_sess->remote_ip_str))
{
return kVSFLoginFail;
}

View File

@ -16,10 +16,6 @@
#include "tunables.h"
#include "builddefs.h"
/* For gethostbyaddr, inet_addr */
#include <netdb.h>
#include <arpa/inet.h>
/* For Linux, this adds nothing :-) */
#include "port/porting_junk.h"
@ -242,13 +238,15 @@ void vsf_remove_uwtmp(void);
#ifndef VSF_SYSDEP_HAVE_PAM
int
vsf_sysdep_check_auth(struct mystr* p_user_str,
vsf_sysdep_check_auth(struct vsf_session* p_sess,
struct mystr* p_user_str,
const struct mystr* p_pass_str,
const struct mystr* p_remote_host)
{
const char* p_crypted;
const struct passwd* p_pwd = getpwnam(str_getbuf(p_user_str));
(void) p_remote_host;
(void) p_sess;
if (p_pwd == NULL)
{
return 0;
@ -322,14 +320,14 @@ static int pam_conv_func(int nmsg, const struct pam_message** p_msg,
static void vsf_auth_shutdown(void);
int
vsf_sysdep_check_auth(struct mystr* p_user_str,
vsf_sysdep_check_auth(struct vsf_session* p_sess,
struct mystr* p_user_str,
const struct mystr* p_pass_str,
const struct mystr* p_remote_host)
{
int retval = -1;
#ifdef PAM_RHOST
struct sockaddr_in sin;
struct hostent *host;
struct mystr hostname = INIT_MYSTR;
#endif
pam_item_t item;
const char* pam_user_name = 0;
@ -354,13 +352,17 @@ vsf_sysdep_check_auth(struct mystr* p_user_str,
return 0;
}
#ifdef PAM_RHOST
if (tunable_reverse_lookup_enable) {
sin.sin_addr.s_addr = inet_addr(str_getbuf(p_remote_host));
host = gethostbyaddr((char*)&sin.sin_addr.s_addr,sizeof(struct in_addr),AF_INET);
if (host != (struct hostent*)0)
retval = pam_set_item(s_pamh, PAM_RHOST, host->h_name);
if (tunable_reverse_lookup_enable)
{
if (vsf_sysutil_get_hostname(p_sess->p_remote_addr, &hostname) == 0)
{
retval = pam_set_item(s_pamh, PAM_RHOST, str_getbuf(&hostname));
str_free(&hostname);
}
else
{
retval = pam_set_item(s_pamh, PAM_RHOST, str_getbuf(p_remote_host));
}
} else {
retval = pam_set_item(s_pamh, PAM_RHOST, str_getbuf(p_remote_host));
}

View File

@ -5,6 +5,8 @@
#include "filesize.h"
#endif
#include "session.h"
/* VSF_SYSDEPUTIL_H:
* Support for highly system dependent features, and querying for support
* or lack thereof
@ -15,7 +17,8 @@ struct mystr;
/* Authentication of local users */
/* Return 0 for fail, 1 for success */
int vsf_sysdep_check_auth(struct mystr* p_user,
int vsf_sysdep_check_auth(struct vsf_session* p_sess,
struct mystr* p_user,
const struct mystr* p_pass,
const struct mystr* p_remote_host);

View File

@ -2356,6 +2356,41 @@ vsf_sysutil_dns_resolve(struct vsf_sysutil_sockaddr** p_sockptr,
}
}
int
vsf_sysutil_get_hostname(struct vsf_sysutil_sockaddr *p_addr,
struct mystr* p_str)
{
struct sockaddr *sa;
socklen_t sa_len = 0;
char hostname[NI_MAXHOST];
int res;
sa = &p_addr->u.u_sockaddr;
if (sa->sa_family == AF_INET)
{
sa_len = sizeof(struct sockaddr_in);
}
else if (sa->sa_family == AF_INET6)
{
sa_len = sizeof(struct sockaddr_in6);
}
else
{
die("can only support ipv4 and ipv6 currently");
}
res = getnameinfo(sa, sa_len, hostname, sizeof(hostname), NULL, 0,
NI_NAMEREQD);
if (res == 0)
{
str_alloc_text(p_str, hostname);
return 0;
}
else
{
return -1;
}
}
struct vsf_sysutil_user*
vsf_sysutil_getpwuid(const unsigned int uid)
{

View File

@ -7,6 +7,8 @@
#include "filesize.h"
#endif
#include "str.h"
/* Return value queries */
int vsf_sysutil_retval_is_error(int retval);
enum EVSFSysUtilError
@ -266,6 +268,8 @@ int vsf_sysutil_connect_timeout(int fd,
unsigned int wait_seconds);
void vsf_sysutil_dns_resolve(struct vsf_sysutil_sockaddr** p_sockptr,
const char* p_name);
int vsf_sysutil_get_hostname(struct vsf_sysutil_sockaddr *p_addr,
struct mystr* p_str);
/* Option setting on sockets */
void vsf_sysutil_activate_keepalive(int fd);
void vsf_sysutil_rcvtimeo(int fd);