NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/46564: yppush pushes map to himself triggering an error message each time



>Number:         46564
>Category:       bin
>Synopsis:       yppush pushes map to himself triggering an error message each 
>time
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Jun 08 12:25:00 +0000 2012
>Originator:     Dr. Wolfgang Stukenbrock
>Release:        NetBSD 5.1.2
>Organization:
Dr. Nagler & Company GmbH
>Environment:
        
        
System: NetBSD s011 5.1.2 NetBSD 5.1.2 (NSW-S011) #2: Tue Jun 5 15:02:21 CEST 
2012 wgstuken@s011:/usr/src/sys/arch/amd64/compile/NSW-S011 amd64
Architecture: x86_64
Machine: amd64
>Description:
        In a setup with one master and multiple slave-YP-servers the ypservers 
map is used to find the slave servers
        during yppush operation to inform them about map updates.
        It is common to have the master yp-server hostname in this map too.
        The implementation of yppush in NetBSD accedently does not check for 
the own hostname as other implementations do.
        (E.g. in OpenSolaris a simple strcmp() with the name returned from 
sysctl() is done)
        When trying to send the just build new map to ourself, the system 
detects that the map that should be transfered
        is not newver than the current one and yppush prints an error message.
        This is ugly, because this message will be seem by the caller of the 
make that updates some maps.
        It is stupid too, to send the map from the master to the master again.
>How-To-Repeat:
        setup a host with ypserv, add some host to ypservers map, including 
this host
        and try to update a map. You will get an error message that the new map 
is
        not newer than the current one.
>Fix:
        The following patch to /usr/src/usr.sbin/ypserv/yppush/yppush.c will 
fix this issue.
        The check is integrated by calling gethostbyname() in order to get the 
full calified name and to allow alias
        name expansion - e.g. an alias name is specified in the ypservers map.
        The check is omitted, if the internal variables cannot hold the data or 
the hostname lookup fails in order
        to preserve previous behaviour as much as possible (on "strange" input 
data).

--- yppush.c    2012/06/08 11:23:50     1.1
+++ yppush.c    2012/06/08 12:05:54
@@ -56,6 +56,8 @@
 #include <rpcsvc/yp_prot.h>
 #include <rpcsvc/ypclnt.h>
 
+#include <netdb.h>
+
 #include "ypdb.h"
 #include "ypdef.h"
 #include "yplib_host.h"
@@ -89,6 +91,13 @@
 int     verbo = 0;             /* verbose */
 
 /*
+ * remark: do not use YPMAXPEER here to allow longer canonical host names
+ *         as the relative short YP-limit.
+ */
+#define MY_MAX_HOST 256
+static char my_hostname[MY_MAX_HOST];
+
+/*
  * prototypes
  */
 
@@ -118,6 +127,27 @@
        struct timeval tv;
        enum clnt_stat retval;
        struct ypall_callback ypallcb;
+       struct hostent *he;
+
+       /*
+        * setup own host name
+        */
+
+       my_hostname[sizeof(my_hostname) - 1] = '\0';
+       if (gethostname(my_hostname, sizeof(my_hostname) - 1) != 0)
+         {
+           errx(1, "cannot determine own host name");
+         }
+       if ((he = gethostbyname(my_hostname)) == NULL)
+         {
+           errx(1, "cannot determine canonical host name for this host");
+         }
+       if (strlen(he->h_name) >= sizeof(my_hostname))
+         {
+           errx(1, "canonical host name to long (%lu - limit %lu)",
+             (unsigned long)strlen(he->h_name), sizeof(my_hostname) - 1);
+         }
+       strcpy(my_hostname, he->h_name); // save canonical name for later 
compare ...
 
        /*
          * parse command line
@@ -298,6 +328,28 @@
        int invallen, char *indata)
 {
        struct yppush_info *ypi = (struct yppush_info *) indata;
+       struct hostent *he;
+       char tmp_hname[MY_MAX_HOST];
+
+       /*
+        * check if for own host name and do not push to ourself ...
+        */
+       if (inkeylen < MY_MAX_HOST) {
+               /*
+                * perform the check only if we are able to store it
+                * preserv previous semantic for oversized host names ...
+                */
+               memcpy(tmp_hname, inkey, inkeylen);
+               tmp_hname[inkeylen] = '\0';
+               if ((he = gethostbyname(tmp_hname)) != NULL) {
+                       if (!strcmp(my_hostname, he->h_name)) {
+                               /*
+                                * skip own host name ....
+                                */
+                               return 0;
+                       }
+               }
+       }
 
        push(inkey, inkeylen, ypi);             /* do it! */
        return (0);

>Unformatted:
        
        


Home | Main Index | Thread Index | Old Index