INN commit: branches/2.6 (8 files)
INN Commit
rra at isc.org
Sun Dec 2 14:05:50 UTC 2018
Date: Sunday, December 2, 2018 @ 06:05:50
Author: iulius
Revision: 10304
Rewrite GetFQDN and rename to inn_getfqdn
Use getaddrinfo with AI_CANONNAME instead of the tedious code to
find an FQDN in gethostbyname results. Return a newly-allocated
string instead of using a static buffer, since this function isn't
performance-critical, avoiding buffer management complexity. Adjust
call sites to do proper memory allocation handling of the return
value.
Remove some old disabled code to try to force canonicalization by
adding a period to the end of the DNS query.
Patch from Russ Allbery (backported from CURRENT).
Modified:
branches/2.6/doc/man/libinn.3
branches/2.6/doc/pod/inn.conf.pod
branches/2.6/frontends/inews.c
branches/2.6/include/inn/libinn.h
branches/2.6/lib/getfqdn.c
branches/2.6/lib/innconf.c
branches/2.6/lib/messageid.c
branches/2.6/nnrpd/post.c
----------------------+
doc/man/libinn.3 | 12 +++--
doc/pod/inn.conf.pod | 4 -
frontends/inews.c | 6 +-
include/inn/libinn.h | 11 +++-
lib/getfqdn.c | 110 +++++++++++++++----------------------------------
lib/innconf.c | 9 ++--
lib/messageid.c | 8 ++-
nnrpd/post.c | 11 +++-
8 files changed, 75 insertions(+), 96 deletions(-)
Modified: doc/man/libinn.3
===================================================================
--- doc/man/libinn.3 2018-11-11 14:43:41 UTC (rev 10303)
+++ doc/man/libinn.3 2018-12-02 14:05:50 UTC (rev 10304)
@@ -61,8 +61,8 @@
.B " bool block;"
.B "char *"
-.B "GetFQDN(domain)"
-.B " char *domain;"
+.B "inn_getfqdn(domain)"
+.B " const char *domain;"
.B "char *"
.B "GetModeratorAddress(FromServer, ToServer, group, moderatormailer)"
@@ -276,11 +276,13 @@
is one of: INN_LOCK_READ, INN_LOCK_WRITE, or INN_LOCK_UNLOCK.
It returns false on failure or true on success.
.PP
-.I GetFQDN
+.I inn_getfqdn
returns the fully qualified domain name of the local host.
.I Domain
-is used if local host can not be resolved.
-The returned value points to static space that is reused on subsequent calls,
+is used to qualify the local host name if local host can not be resolved
+in DNS.
+The returned value points to newly-allocated memory that the caller is
+responsible for freeing,
or NULL on error.
.PP
.I GetModeratorAddress
Modified: doc/pod/inn.conf.pod
===================================================================
--- doc/pod/inn.conf.pod 2018-11-11 14:43:41 UTC (rev 10303)
+++ doc/pod/inn.conf.pod 2018-12-02 14:05:50 UTC (rev 10304)
@@ -60,8 +60,8 @@
This should be the domain name of the local host. It should not have a
leading period, and it should not be a full host address. It is used only
-if the GetFQDN() routine in libinn(3) cannot get the fully qualified
-domain name by using either the gethostname(3) or gethostbyname(3) calls.
+if the inn_getfqdn() routine in libinn(3) cannot get the fully qualified
+domain name by using either the gethostname(3) or getaddrinfo(3) calls.
The check is very simple; if either routine returns a name with a period
in it, then it is assumed to have the full domain name. As this parameter
is rarely used, do not use it to affect the righthand side of
Modified: frontends/inews.c
===================================================================
--- frontends/inews.c 2018-11-11 14:43:41 UTC (rev 10303)
+++ frontends/inews.c 2018-12-02 14:05:50 UTC (rev 10304)
@@ -608,9 +608,11 @@
HDR(_path) = concat(Exclusions, PATHFLUFF, (char *) 0);
}
else if (innconf->server != NULL) {
- if ((p = GetFQDN(innconf->domain)) == NULL)
- sysdie("cannot get hostname");
+ p = inn_getfqdn(innconf->domain);
+ if (p == NULL)
+ sysdie("cannot get hostname");
HDR(_path) = concat(Exclusions, p, "!", PATHFLUFF, (char *) 0);
+ free(p);
}
else {
HDR(_path) = concat(Exclusions, PATHFLUFF, (char *) 0);
Modified: include/inn/libinn.h
===================================================================
--- include/inn/libinn.h 2018-11-11 14:43:41 UTC (rev 10303)
+++ include/inn/libinn.h 2018-12-02 14:05:50 UTC (rev 10304)
@@ -137,10 +137,15 @@
const char *request);
extern void CAclose(void);
-extern char * GetFQDN(char *domain);
-extern char * GetModeratorAddress(FILE *FromServer, FILE *ToServer,
- char *group, char *moderatormailer);
+/* Return the fully-qualified domain name of the local system in
+ newly-allocated memory, or NULL if it cannot be discovered. The caller is
+ responsible for freeing. If the host's domain cannot be found in DNS, use
+ the domain argument as a fallback. */
+extern char * inn_getfqdn(const char *domain);
+extern char * GetModeratorAddress(FILE *FromServer, FILE *ToServer,
+ char *group, char *moderatormailer);
+
#define TEMPORARYOPEN 0
#define INND_HISTORY 1
#define INND_HISLOG 2
Modified: lib/getfqdn.c
===================================================================
--- lib/getfqdn.c 2018-11-11 14:43:41 UTC (rev 10303)
+++ lib/getfqdn.c 2018-12-02 14:05:50 UTC (rev 10304)
@@ -1,96 +1,54 @@
/* $Id$
**
+** Discover the fully-qualified domain name of the local host.
*/
#include "config.h"
#include "clibrary.h"
-#include <netdb.h>
+#include "portable/socket.h"
#include "inn/libinn.h"
-#include "inn/paths.h"
+#include "inn/xmalloc.h"
/*
-** Get the fully qualified domain name for this host, as reported
-** by the system.
+** Return the fully-qualified domain name of the local system in
+** newly-allocated memory, or NULL if it cannot be discovered. The caller is
+** responsible for freeing. If the host's domain cannot be found in DNS, use
+** the domain argument as a fallback.
*/
-char *GetFQDN(char *domain)
+char *
+inn_getfqdn(const char *domain)
{
- static char buff[SMBUF];
- struct hostent *hp;
- char *p;
- char **ap;
-#if 0
- /* See comments below. */
- char temp[SMBUF + 2];
-#endif /* 0 */
+ char hostname[BUFSIZ];
+ struct addrinfo hints, *res;
+ char *fqdn, *canon;
- /* Return any old results. */
- if (buff[0])
- return buff;
+ /* If gethostname fails, there's nothing we can do. */
+ if (gethostname(hostname, sizeof(hostname)) < 0)
+ return NULL;
- /* Try gethostname. */
- if (gethostname(buff, (int)sizeof buff) < 0)
- return NULL;
- if (strchr(buff, '.') != NULL)
- return buff;
+ /* If the local hostname is already fully qualified, just return it. */
+ if (strchr(hostname, '.') != NULL)
+ return xstrdup(hostname);
- /*
- ** See if DNS (or /etc/hosts) gives us a full domain name. If the host
- ** doesn't exist in DNS at all but we were given a domain name, use the
- ** fallback of appending that domain to the hostname.
- */
- if ((hp = gethostbyname(buff)) == NULL)
- goto fallback;
-#if 0
- /* This code is a "feature" that allows multiple domains (NIS or
- * DNS, I'm not sure) to work with a single INN server. However,
- * it turns out to cause more problems for people, and they have to
- * use hacks like __switch_gethostbyname, etc. So if you need this,
- * turn it on, but don't complain to me. */
- if (strchr(hp->h_name, '.') == NULL) {
- /* Try to force DNS lookup if NIS/whatever gets in the way. */
- strlcpy(temp, buff, sizeof(temp));
- strlcat(temp, ".", sizeof(temp));
- hp = gethostbyname(temp);
- }
- if (hp == NULL) {
- return NULL;
- }
-#endif /* 0 */
-
- /* First, see if the main name is a FQDN. It should be. */
- if (strchr(hp->h_name, '.') != NULL) {
- if (strlen(hp->h_name) < sizeof buff - 1) {
- strlcpy(buff, hp->h_name, sizeof(buff));
- return buff;
+ /* Attempt to canonicalize with DNS. */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_flags = AI_CANONNAME;
+ if (getaddrinfo(hostname, NULL, &hints, &res) == 0) {
+ canon = res->ai_canonname;
+ if (canon != NULL && strchr(canon, '.') != NULL) {
+ fqdn = xstrdup(canon);
+ freeaddrinfo(res);
+ return fqdn;
}
- /* Doesn't fit; make sure we don't return bad data next time. */
- buff[0] = '\0';
- return hp->h_name;
+ freeaddrinfo(res);
}
- /* Second, see if any aliases are. */
- if ((ap = hp->h_aliases) != NULL)
- while ((p = *ap++) != NULL)
- if (strchr(p, '.') != NULL) {
- /* Deja-vous all over again. */
- if (strlen(p) < sizeof buff - 1) {
- strlcpy(buff, p, sizeof(buff));
- return buff;
- }
- buff[0] = '\0';
- return p ;
- }
-
- /* Give up: Get the domain config param and append it. */
-fallback:
- if ((p = domain) == NULL || *p == '\0')
- return NULL;
- if (strlen(buff) + 1 + strlen(p) > sizeof buff - 1)
- /* Doesn't fit. */
- return NULL;
- strlcat(buff, ".", sizeof(buff));
- strlcat(buff, p, sizeof(buff));
- return buff;
+ /* Fall back on canonicalizing with a provided domain. */
+ if (domain == NULL || domain[0] == '\0')
+ return NULL;
+ xasprintf(&fqdn, "%s.%s", hostname, domain);
+ return fqdn;
}
Modified: lib/innconf.c
===================================================================
--- lib/innconf.c 2018-11-11 14:43:41 UTC (rev 10303)
+++ lib/innconf.c 2018-12-02 14:05:50 UTC (rev 10304)
@@ -332,9 +332,9 @@
/* Some parameters have defaults that depend on other parameters. */
if (innconf->fromhost == NULL)
- innconf->fromhost = xstrdup(GetFQDN(innconf->domain));
+ innconf->fromhost = inn_getfqdn(innconf->domain);
if (innconf->pathhost == NULL)
- innconf->pathhost = xstrdup(GetFQDN(innconf->domain));
+ innconf->pathhost = inn_getfqdn(innconf->domain);
if (innconf->pathtmp == NULL)
innconf->pathtmp = xstrdup(INN_PATH_TMP);
@@ -472,11 +472,14 @@
innconf_validate(struct config_group *group)
{
bool okay = true;
+ char *fqdn;
- if (GetFQDN(innconf->domain) == NULL) {
+ fqdn = inn_getfqdn(innconf->domain);
+ if (fqdn == NULL) {
warn("hostname does not resolve or domain not set in inn.conf");
okay = false;
}
+ free(fqdn);
if (innconf->mta == NULL) {
warn("must set mta in inn.conf");
okay = false;
Modified: lib/messageid.c
===================================================================
--- lib/messageid.c 2018-11-11 14:43:41 UTC (rev 10303)
+++ lib/messageid.c 2018-12-02 14:05:50 UTC (rev 10304)
@@ -30,6 +30,7 @@
static char buff[SMBUF];
static int count;
char *p;
+ char *fqdn = NULL;
char sec32[10];
char pid32[10];
time_t now;
@@ -42,10 +43,13 @@
&& strcmp(domain, innconf->domain) != 0)) {
p = domain;
} else {
- if ((p = GetFQDN(domain)) == NULL)
- return NULL;
+ fqdn = inn_getfqdn(domain);
+ if (fqdn == NULL)
+ return NULL;
+ p = fqdn;
}
snprintf(buff, sizeof(buff), "<%s$%s$%d@%s>", sec32, pid32, ++count, p);
+ free(fqdn);
return buff;
}
Modified: nnrpd/post.c
===================================================================
--- nnrpd/post.c 2018-11-11 14:43:41 UTC (rev 10303)
+++ nnrpd/post.c 2018-12-02 14:05:50 UTC (rev 10304)
@@ -348,6 +348,7 @@
static char *newpath = NULL;
HEADER *hp;
char *p;
+ char *fqdn = NULL;
time_t t, now;
const char *error;
pid_t pid;
@@ -561,11 +562,15 @@
if (VirtualPathlen > 0) {
p = PERMaccessconf->domain;
} else {
- if ((p = GetFQDN(PERMaccessconf->domain)) == NULL) {
- p = (char *) "unknown";
- }
+ fqdn = inn_getfqdn(PERMaccessconf->domain);
+ if (fqdn == NULL)
+ p = (char *) "unknown";
+ else
+ p = fqdn;
}
snprintf(pathidentitybuff, sizeof(pathidentitybuff), "%s", p);
+ free(fqdn);
+ p = NULL;
/* Set the posting-account value. */
if (PERMaccessconf->addinjectionpostingaccount && PERMuser[0] != '\0') {
More information about the inn-committers
mailing list