Subject: bin/12876: NetBSD's INET6 patches to Postfix break non-INET6 features!
To: None <gnats-bugs@gnats.netbsd.org>
From: Greg A. Woods <woods@weird.com>
List: netbsd-bugs
Date: 05/08/2001 17:26:20
>Number:         12876
>Category:       bin
>Synopsis:       NetBSD's INET6 patches to Postfix break non-INET6 features!
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue May 08 14:43:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Greg A. Woods
>Release:        2001/03/24
>Organization:
Planix, Inc.; Toronto, Ontario; Canada
>Environment:

System: NetBSD proven 1.5T NetBSD 1.5T (PROVEN) #6: Mon Apr 23 00:31:12 EDT 2001 woods@proven:/work/woods/NetBSD-src/sys/arch/i386/compile/PROVEN i386
Architecture: i386
Machine: i386

>Description:

	suddenly as I added smtpd_client_restrictions to my postfix
	configuration, connections for many hosts were rejected even
	though they should not have been!

	the bug turns out not to be in Postfix, but rather in the
	NetBSD-specific changes to Postfix!

>How-To-Repeat:

	try enabling "smtpd_client_restrictions = reject_unknown_client"

	also set "smtpd_reject_delay = no" for best effect

	connect to the test postfix from a machine with a ``long''
	hostname....  (more than 17 characters will do fine)

	after finally finding the right place, and after finally
	realising that I'm not compiling with -DINET6, examine the
	source and note that some of the NetBSD changes to code around
	gethostbyaddr() and gethostbyname() are really quite wrong and
	may not have been fully tested.

>Fix:

	I've not yet examined the new version of NetBSD version of
	Postfix that should be arriving tomorrow in my rsync from
	cvs.netbsd.org, but I'm guessing these bugs still exist...

	Note that it's really really really important to identify
	modified versions of third-party software, especially when they
	(can) announce their release names to the world!!!!

	[Note: freebie included -- proper support for getdomainname()]

	[Also note:  I have not tested compiling with INET6....]

Index: src/global/mail_params.c
===================================================================
RCS file: /cvs/NetBSD/src/gnu/dist/postfix/src/global/mail_params.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 mail_params.c
*** src/global/mail_params.c	2001/03/25 06:59:01	1.1.1.1
--- src/global/mail_params.c	2001/05/07 20:27:10
***************
*** 105,110 ****
--- 105,111 ----
  #include <msg.h>
  #include <msg_syslog.h>
  #include <get_hostname.h>
+ #include <get_domainname.h>
  #include <valid_hostname.h>
  #include <stringops.h>
  
***************
*** 180,185 ****
--- 181,188 ----
  
  /* check_myhostname - lookup hostname and validate */
  
+ /* XXX this code is duplicated in ../postconf/postconf.c!!! */
+ 
  static const char *check_myhostname(void)
  {
      static const char *name;
***************
*** 197,204 ****
       * contents of $mydomain.
       */
      name = get_hostname();
      if ((dot = strchr(name, '.')) == 0) {
! 	if ((domain = mail_conf_lookup_eval(VAR_MYDOMAIN)) == 0)
  	    msg_fatal("My hostname %s is not a fully qualified name - set %s or %s in %s/main.cf",
  		      name, VAR_MYHOSTNAME, VAR_MYDOMAIN, var_config_dir);
  	name = concatenate(name, ".", domain, (char *) 0);
--- 200,211 ----
       * contents of $mydomain.
       */
      name = get_hostname();
+     domain = mail_conf_lookup_eval(VAR_MYDOMAIN);
+     if (!domain) {
+ 	domain = get_domainname();
+     }
      if ((dot = strchr(name, '.')) == 0) {
! 	if (domain == 0)
  	    msg_fatal("My hostname %s is not a fully qualified name - set %s or %s in %s/main.cf",
  		      name, VAR_MYHOSTNAME, VAR_MYDOMAIN, var_config_dir);
  	name = concatenate(name, ".", domain, (char *) 0);
***************
*** 208,224 ****
  
  /* check_mydomainname - lookup domain name and validate */
  
  static const char *check_mydomainname(void)
  {
!     char   *dot;
  
!     /*
!      * Use the hostname when it is not a FQDN ("foo"), or when the hostname
!      * actually is a domain name ("foo.com").
!      */
!     if ((dot = strchr(var_myhostname, '.')) == 0 || strchr(dot + 1, '.') == 0)
! 	return (var_myhostname);
!     return (dot + 1);
  }
  
  /* check_default_privs - lookup default user attributes and validate */
--- 215,230 ----
  
  /* check_mydomainname - lookup domain name and validate */
  
+ /* XXX this code is duplicated in ../postconf/postconf.c!!! */
+ 
  static const char *check_mydomainname(void)
  {
!     const char *name;
  
!     if ((name = get_domainname()) == 0) {
! 	name = mail_conf_lookup_eval(VAR_MYDOMAIN);
!     }
!     return name;
  }
  
  /* check_default_privs - lookup default user attributes and validate */
Index: src/global/mail_version.h
===================================================================
RCS file: /cvs/NetBSD/src/gnu/dist/postfix/src/global/mail_version.h,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 mail_version.h
*** src/global/mail_version.h	2001/03/25 06:59:02	1.1.1.1
--- src/global/mail_version.h	2001/05/08 19:07:38
***************
*** 15,21 ****
    * Version of this program.
    */
  #define VAR_MAIL_VERSION	"mail_version"
! #define DEF_MAIL_VERSION	"Release-20010228"
  extern char *var_mail_version;
  
  /* LICENSE
--- 15,25 ----
    * Version of this program.
    */
  #define VAR_MAIL_VERSION	"mail_version"
! #ifdef INET6
! # define DEF_MAIL_VERSION	"Release-20010228-NetBSD-INET6"
! #else
! # define DEF_MAIL_VERSION	"Release-20010228-NetBSD"
! #endif
  extern char *var_mail_version;
  
  /* LICENSE
Index: src/global/peer_name.c
===================================================================
RCS file: /cvs/NetBSD/src/gnu/dist/postfix/src/global/peer_name.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 peer_name.c
*** src/global/peer_name.c	2001/03/25 06:59:02	1.1.1.1
--- src/global/peer_name.c	2001/05/08 20:47:15
***************
*** 60,94 ****
  
  /* Utility library. */
  
  #include <msg.h>
  #include <valid_hostname.h>
  #include <peer_name.h>
  
  /* peer_name - produce printable peer name and address */
  
  PEER_NAME *peer_name(int sock)
  {
      static PEER_NAME peer;
      union sockunion {
- 	struct {
- 	    u_char si_len;
- 	    u_char si_family;
- 	    u_short si_port;
- 	} su_si;
  	struct sockaddr peer_un;
  	struct sockaddr_in peer_un4;
  #ifdef INET6
  	struct sockaddr_in6 peer_un6;
  #endif
      } p_un;
! #define sun p_un.peer_un
  #define sin p_un.peer_un4
  #ifdef INET6
  #define sin6 p_un.peer_un6
      static char hbuf[NI_MAXHOST];
!     static char abuf[NI_MAXHOST];
  #else
      struct hostent *hp;
  #endif
      SOCKADDR_SIZE len = sizeof(p_un);
  
--- 60,107 ----
  
  /* Utility library. */
  
+ #include <mymalloc.h>
  #include <msg.h>
  #include <valid_hostname.h>
  #include <peer_name.h>
  
+ #ifdef INET6
+ static char *
+ streiaret(eia, err)
+ 	int eia;
+ 	int err;
+ {
+ 	switch (eia) {
+ 	case EAI_SYSTEM:
+ 		return strerror(err);
+ 	default:
+ 		return gai_strerror(err);
+ 	}
+ }
+ #endif
+ 
  /* peer_name - produce printable peer name and address */
  
  PEER_NAME *peer_name(int sock)
  {
      static PEER_NAME peer;
      union sockunion {
  	struct sockaddr peer_un;
  	struct sockaddr_in peer_un4;
  #ifdef INET6
  	struct sockaddr_in6 peer_un6;
  #endif
      } p_un;
! #define sa p_un.peer_un
  #define sin p_un.peer_un4
  #ifdef INET6
  #define sin6 p_un.peer_un6
+     int eia;
      static char hbuf[NI_MAXHOST];
!     static char abuf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")+1];
  #else
      struct hostent *hp;
+     static char abuf[sizeof("255.255.255.255")+1];
  #endif
      SOCKADDR_SIZE len = sizeof(p_un);
  
***************
*** 97,124 ****
  #ifndef INET6
  	case AF_INET:
  	    peer.type = PEER_TYPE_INET;
  	    hp = gethostbyaddr((char *) &(sin.sin_addr),
  			       sizeof(sin.sin_addr), AF_INET);
! 	    peer.name = (hp && valid_hostname(hp->h_name, DO_GRIPE) ?
! 			 hp->h_name : "unknown");
! 	    peer.addr = inet_ntoa(sin.sin_addr);
  	    return (&peer);
  #else
  	case AF_INET:
  	    peer.type = PEER_TYPE_INET;
! 	    if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
  		peer.name = "unknown";
! 	    else
  		peer.name = hbuf;
- 	    peer.addr = abuf;
  	    return (&peer);
  	case AF_INET6:
  	    peer.type = PEER_TYPE_INET6;
! 	    if (getnameinfo(&sun, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD) != 0)
  		peer.name = "unknown";
! 	    else
  		peer.name = hbuf;
- 	    peer.addr = abuf;
  	    return (&peer);
  #endif
  	case AF_UNSPEC:
--- 110,192 ----
  #ifndef INET6
  	case AF_INET:
  	    peer.type = PEER_TYPE_INET;
+ 	    strcpy(abuf, inet_ntoa(sin.sin_addr));
+ 	    peer.addr = abuf;
+ 	    msg_info("DNS query from peer_name: gethostbyaddr(%s): %s", peer.addr);
  	    hp = gethostbyaddr((char *) &(sin.sin_addr),
  			       sizeof(sin.sin_addr), AF_INET);
! 	    if (!hp) {
! 		switch (h_errno) {
! 		case HOST_NOT_FOUND:
! 		    if (msg_verbose)
! 			msg_info("gethostbyaddr(%s): %s", peer.addr, hstrerror(h_errno));
! 		    break;
! 		default:
! 		    msg_warn("gethostbyaddr(%s): %s", peer.addr, hstrerror(h_errno));
! 		    break;
! 		}
! 		peer.name = "unknown";
! 	    } else {
! 		peer.name = (valid_hostname(hp->h_name, DO_GRIPE) ?
! 			     hp->h_name : "unknown");
! 	    }
  	    return (&peer);
  #else
  	case AF_INET:
  	    peer.type = PEER_TYPE_INET;
! 	    peer.addr = inet_ntop(AF_INET6, &sin6addr, abuf, sizeof(abuf));
! 	    if (!peer.addr)
! 		asprintf((char **) &peer.addr, "(%s)", strerror(errno)); /* XXX may leak/fail!!! */
! 	    if ((eia = getnameinfo(&sa, len, hbuf, sizeof(hbuf), (char *) NULL, 0, NI_NAMEREQD)) != 0) {
  		peer.name = "unknown";
! 		switch (eia) {
! 		case EAI_NONAME:
! 		    if (msg_verbose) {
! 			msg_info("%s: getnameinfo(AF_INET[%s], %d): %s\n",
! 				 myname,
! 				 peer.addr,
! 				 sa.sa_len,
! 				 streiaret(eia, errno));
! 		    }
! 		    break;
! 		default:
! 		    msg_warn("%s: getnameinfo(AF_INET[%s], %d): %s\n",
! 			     myname,
! 			     peer.addr,
! 			     sa.sa_len,
! 			     streiaret(eia, errno));
! 		    break;
! 		}
! 	    } else
  		peer.name = hbuf;
  	    return (&peer);
  	case AF_INET6:
  	    peer.type = PEER_TYPE_INET6;
! 	    peer.addr = inet_ntop(AF_INET6, &sin6addr, abuf, sizeof(abuf));
! 	    if (!peer.addr)
! 		asprintf((char **) &peer.addr, "(%s)", strerror(errno)); /* XXX may leak/fail!!! */
! 	    if ((eia = getnameinfo(&sa, len, hbuf, sizeof(hbuf), (char *) NULL, 0, NI_NAMEREQD)) != 0) {
  		peer.name = "unknown";
! 		switch (eia) {
! 		case EAI_NONAME:
! 		    if (msg_verbose) {
! 			msg_info("%s: getnameinfo(AF_INET6[%s], %d): %s\n",
! 				 myname,
! 				 peer.addr,
! 				 sa.sa_len,
! 				 streiaret(eia, errno));
! 		    }
! 		    break;
! 		default:
! 		    msg_warn("%s: getnameinfo(AF_INET6[%s], %d): %s\n",
! 			     myname,
! 			     peer.addr,
! 			     sa.sa_len,
! 			     streiaret(eia, errno));
! 		    break;
! 		}
! 	    } else
  		peer.name = hbuf;
  	    return (&peer);
  #endif
  	case AF_UNSPEC:
Index: src/postconf/postconf.c
===================================================================
RCS file: /cvs/NetBSD/src/gnu/dist/postfix/src/postconf/postconf.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 postconf.c
*** src/postconf/postconf.c	2001/03/25 06:59:11	1.1.1.1
--- src/postconf/postconf.c	2001/05/07 20:24:41
***************
*** 77,82 ****
--- 77,83 ----
  #include <vstream.h>
  #include <msg_vstream.h>
  #include <get_hostname.h>
+ #include <get_domainname.h>
  #include <stringops.h>
  #include <htable.h>
  #include <dict.h>
***************
*** 189,194 ****
--- 190,197 ----
  
  /* check_myhostname - lookup hostname and validate */
  
+ /* XXX this code is duplicated in ../global/mail_params.c!!! */
+ 
  static const char *check_myhostname(void)
  {
      static const char *name;
***************
*** 208,215 ****
       * XXX Do not complain when running as "postconf -d".
       */
      name = get_hostname();
      if ((mode & SHOW_DEFS) == 0 && (dot = strchr(name, '.')) == 0) {
! 	if ((domain = mail_conf_lookup_eval(VAR_MYDOMAIN)) == 0) {
  	    msg_warn("My hostname %s is not a fully qualified name - set %s or %s in %s/main.cf",
  		     name, VAR_MYHOSTNAME, VAR_MYDOMAIN, var_config_dir);
  	} else {
--- 211,222 ----
       * XXX Do not complain when running as "postconf -d".
       */
      name = get_hostname();
+     domain = mail_conf_lookup_eval(VAR_MYDOMAIN);
+     if (!domain) {
+ 	domain = get_domainname();
+     }
      if ((mode & SHOW_DEFS) == 0 && (dot = strchr(name, '.')) == 0) {
! 	if (domain == 0) {
  	    msg_warn("My hostname %s is not a fully qualified name - set %s or %s in %s/main.cf",
  		     name, VAR_MYHOSTNAME, VAR_MYDOMAIN, var_config_dir);
  	} else {
***************
*** 219,225 ****
      return (name);
  }
  
! /* get_myhostname - look up and store my hostname */
  
  static void get_myhostname(void)
  {
--- 226,232 ----
      return (name);
  }
  
! /* get_myhostname - look up and store my hostname XXX NOT USED!!! */
  
  static void get_myhostname(void)
  {
***************
*** 232,250 ****
  
  /* check_mydomainname - lookup domain name and validate */
  
  static const char *check_mydomainname(void)
  {
!     char   *dot;
  
!     /*
!      * Use the hostname when it is not a FQDN ("foo"), or when the hostname
!      * actually is a domain name ("foo.com").
!      */
!     if (var_myhostname == 0)
! 	get_myhostname();
!     if ((dot = strchr(var_myhostname, '.')) == 0 || strchr(dot + 1, '.') == 0)
! 	return (var_myhostname);
!     return (dot + 1);
  }
  
  /* check_mynetworks - lookup network address list */
--- 239,265 ----
  
  /* check_mydomainname - lookup domain name and validate */
  
+ /* XXX this code is duplicated in ../global/mail_params.c!!! */
+ 
  static const char *check_mydomainname(void)
  {
!     const char *name;
  
!     if ((name = get_domainname()) == 0) {
! 	name = mail_conf_lookup_eval(VAR_MYDOMAIN);
!     }
!     return name;
! }
! 
! /* get_mydomain - look up and store my domain XXX NOT USED!!! */
! 
! static void get_mydomain(void)
! {
!     const char *name;
! 
!     if ((name = dict_lookup(CONFIG_DICT, VAR_MYDOMAIN)) == 0)
! 	name = check_mydomainname();
!     var_mydomain = mystrdup(name);
  }
  
  /* check_mynetworks - lookup network address list */
Index: src/smtpd/smtpd_peer.c
===================================================================
RCS file: /cvs/NetBSD/src/gnu/dist/postfix/src/smtpd/smtpd_peer.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 smtpd_peer.c
*** src/smtpd/smtpd_peer.c	2001/03/25 06:59:14	1.1.1.1
--- src/smtpd/smtpd_peer.c	2001/05/08 20:52:45
***************
*** 115,120 ****
--- 115,122 ----
      sa = (struct sockaddr *)&ss;
      len = sizeof(ss);
  
+     /* XXX XXX !!! why the hell doesn't this call peer_name()!?!?!?!?!?!? */
+ 
      /*
       * Look up the peer address information.
       */
***************
*** 142,174 ****
  		    )) {
  #ifdef INET6
  	char hbuf[NI_MAXHOST];
  	struct addrinfo hints, *rnull = NULL;
  #else
! 	char hbuf[sizeof("255.255.255.255") + 1];
  #endif
  	int error = -1;
  
  #ifdef INET6
! 	(void)getnameinfo(sa, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST);
  #else
  	in = &((struct sockaddr_in *)sa)->sin_addr;
! 	inet_ntop(AF_INET, in, hbuf, sizeof(hbuf));
  #endif
! 	state->addr = mystrdup(hbuf);
  #ifdef INET6
! 	error = getnameinfo(sa, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD);
  #else
  	hp = gethostbyaddr((char *)in, sizeof(*in), AF_INET);
! 	if (hp && strlen(hp->h_name) < sizeof(hbuf) - 1) {
  	    error = 0;
! 	    strncpy(hbuf, hp->h_name, sizeof(hbuf) - 1);
! 	    hbuf[sizeof(hbuf) - 1] = '\0';
! 	} else
  	    error = 1;
  #endif
  	if (error) {
  	    state->name = mystrdup("unknown");
  	    state->peer_code = (h_errno == TRY_AGAIN ? 4 : 5);
  	} else if (!valid_hostname(hbuf, DONT_GRIPE)) {
  	    state->name = mystrdup("unknown");
  	    state->peer_code = 5;
--- 144,205 ----
  		    )) {
  #ifdef INET6
  	char hbuf[NI_MAXHOST];
+ 	char abuf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")+1];
  	struct addrinfo hints, *rnull = NULL;
  #else
! 	char *hbuf;
! 	char abuf[sizeof("255.255.255.255") + 1];
  #endif
  	int error = -1;
  
+ 	/*
+ 	 * First we make a printable form of the peer's address...
+ 	 */
  #ifdef INET6
! 	(void)getnameinfo(sa, len, abuf, sizeof(abuf), NULL, 0, NI_NUMERICHOST);
  #else
  	in = &((struct sockaddr_in *)sa)->sin_addr;
! 	if (!inet_ntop(AF_INET, in, abuf, sizeof(abuf))) {
! 	    snprintf((char *) abuf, sizeof(abuf), "(%s)", strerror(errno));
! 	    error = 1;
! 	}
  #endif
! 	state->addr = mystrdup(abuf);
! 
! 	/*
! 	 * Then we look up the peer's name from its address...
! 	 */
  #ifdef INET6
! 	if (msg_verbose)
! 	    msg_warn("%s: calling getnameinfo(%s[%s], %d)...",
! 		     "smtpd_peer_init",
! 		     sa->sa_family == AF_INET ? "AF_INET" : "AF_INET6",
! 		     state->addr,
! 		     sizeof(*in));
! 	if ((error = getnameinfo(sa, len, hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD)) != 0)
! 	    msg_warn("%s: hostname %s lookup failed: %s",
! 		     state->addr, state->name, error == EIA_SYSTEM : strerror(errno) : gai_strerror(error));
  #else
+ 	if (msg_verbose)
+ 	    msg_warn("%s: calling gethostbyaddr([%s], %d, AF_INET)...",
+ 		     "smtpd_peer_init", state->addr, sizeof(*in));
  	hp = gethostbyaddr((char *)in, sizeof(*in), AF_INET);
! 	if (hp) {
  	    error = 0;
! 	    hbuf = hp->h_name;
! 	} else {
! 	    msg_warn("%s: hostname %s lookup failed: %s",
! 		     state->addr, state->name, HSTRERROR(h_errno));
  	    error = 1;
+ 	}
  #endif
  	if (error) {
  	    state->name = mystrdup("unknown");
+ #ifdef INET6
+ 	    state->peer_code = (error == EAI_AGAIN ? 4 : 5);
+ #else
  	    state->peer_code = (h_errno == TRY_AGAIN ? 4 : 5);
+ #endif
  	} else if (!valid_hostname(hbuf, DONT_GRIPE)) {
  	    state->name = mystrdup("unknown");
  	    state->peer_code = 5;
***************
*** 189,204 ****
  	    memset(&hints, 0, sizeof(hints));
  	    hints.ai_family = AF_UNSPEC;
  	    hints.ai_socktype = SOCK_STREAM;
  	    error = getaddrinfo(state->name, NULL, &hints, &rnull);
  	    if (error) {
  		msg_warn("%s: hostname %s verification failed: %s",
! 			 state->addr, state->name, gai_strerror(error));
  		REJECT_PEER_NAME(state, (error == EAI_AGAIN ? 4 : 5));
  	    }
  	    /* memcmp() isn't needed if we use getaddrinfo */
  	    if (rnull)
  		freeaddrinfo(rnull);
  #else
  	    hp = gethostbyname(state->name);	/* clobbers hp->name!! */
  	    if (hp == 0) {
  		msg_warn("%s: hostname %s verification failed: %s",
--- 220,242 ----
  	    memset(&hints, 0, sizeof(hints));
  	    hints.ai_family = AF_UNSPEC;
  	    hints.ai_socktype = SOCK_STREAM;
+ 	    if (msg_verbose)
+ 		msg_warn("%s: calling getaddrinfo(%s)...",
+ 			 "smtpd_peer_init",
+ 			 state->name);
  	    error = getaddrinfo(state->name, NULL, &hints, &rnull);
  	    if (error) {
  		msg_warn("%s: hostname %s verification failed: %s",
! 			 state->addr, state->name, error == EIA_SYSTEM : strerror(errno) : gai_strerror(error));
  		REJECT_PEER_NAME(state, (error == EAI_AGAIN ? 4 : 5));
  	    }
  	    /* memcmp() isn't needed if we use getaddrinfo */
  	    if (rnull)
  		freeaddrinfo(rnull);
  #else
+ 	    if (msg_verbose)
+ 		msg_warn("%s: calling gethostbyname(%s)...",
+ 			 "smtpd_peer_init", state->name, sizeof(*in));
  	    hp = gethostbyname(state->name);	/* clobbers hp->name!! */
  	    if (hp == 0) {
  		msg_warn("%s: hostname %s verification failed: %s",
Index: src/util/get_domainname.c
===================================================================
RCS file: /cvs/NetBSD/src/gnu/dist/postfix/src/util/get_domainname.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 get_domainname.c
*** src/util/get_domainname.c	2001/03/25 06:59:18	1.1.1.1
--- src/util/get_domainname.c	2001/05/07 20:07:33
***************
*** 41,47 ****
  
  /* Local stuff. */
  
! static char *my_domain_name;
  
  /* get_domainname - look up my domain name */
  
--- 41,47 ----
  
  /* Local stuff. */
  
! static char *my_domain_name;		 /* XXX this should not be saved.... */
  
  /* get_domainname - look up my domain name */
  
***************
*** 50,65 ****
      const char *host;
      const char *dot;
  
-     /*
-      * Use the hostname when it is not a FQDN ("foo"), or when the hostname
-      * actually is a domain name ("foo.com").
-      */
      if (my_domain_name == 0) {
! 	host = get_hostname();
! 	if ((dot = strchr(host, '.')) == 0 || strchr(dot + 1, '.') == 0) {
! 	    my_domain_name = mystrdup(host);
  	} else {
! 	    my_domain_name = mystrdup(dot + 1);
  	}
      }
      return (my_domain_name);
--- 50,79 ----
      const char *host;
      const char *dot;
  
      if (my_domain_name == 0) {
! 	char domain[MAXHOSTNAMELEN];
! 
! 	if (getdomainname(domain, sizeof(domain)) == -1) {
! 	    msg_fatal("getdomainname(): %m");
! 	}
! 	if (*domain) {
! 		if (*domain == '.') {
! 		    dot = domain + 1;
! 		} else {
! 		    dot = domain;
! 		}
! 		my_domain_name = mystrdup(dot);
  	} else {
! 	    /*
! 	     * Use the hostname when it is not a FQDN ("foo"), or when the
! 	     * hostname actually is a domain name ("foo.com").
! 	     */
! 	    host = get_hostname();
! 	    if ((dot = strchr(host, '.')) == 0 || strchr(dot + 1, '.') == 0) {
! 		my_domain_name = mystrdup(host);
! 	    } else {
! 		my_domain_name = mystrdup(dot + 1);
! 	    }
  	}
      }
      return (my_domain_name);
Index: src/util/valid_hostname.c
===================================================================
RCS file: /cvs/NetBSD/src/gnu/dist/postfix/src/util/valid_hostname.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 valid_hostname.c
*** src/util/valid_hostname.c	2001/03/25 06:59:20	1.1.1.1
--- src/util/valid_hostname.c	2001/05/07 19:56:09
***************
*** 85,91 ****
       * Find bad characters or label lengths. Find adjacent delimiters.
       */
      for (cp = name; (ch = *(unsigned char *) cp) != 0; cp++) {
! 	if (ISALNUM(ch) || ch == '_') {		/* grr.. */
  	    if (label_length == 0)
  		label_count++;
  	    label_length++;
--- 85,91 ----
       * Find bad characters or label lengths. Find adjacent delimiters.
       */
      for (cp = name; (ch = *(unsigned char *) cp) != 0; cp++) {
! 	if (ISALNUM(ch)) {
  	    if (label_length == 0)
  		label_count++;
  	    label_length++;
>Release-Note:
>Audit-Trail:
>Unformatted: