Subject: bin/4023: amd don't work with NIS maps from a NIS+ server
To: None <gnats-bugs@gnats.netbsd.org>
From: Matthieu Herrb <matthieu@laas.fr>
List: netbsd-bugs
Date: 08/21/1997 13:56:34
>Number:         4023
>Category:       bin
>Synopsis:       amd don't work with NIS maps from a NIS+ server
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Aug 21 05:05:00 1997
>Last-Modified:
>Originator:     
>Organization:
 Matthieu Herrb   |  e-mail: matthieu@laas.fr
 CNRS/LAAS        |     url: <A HREF="http://www.laas.fr/~matthieu">
 Toulouse, France |  War, what is it good for ? Absolutely nothing !
>Release:        NetBSD-current 08/18
>Environment:
System: NetBSD abel 1.2G NetBSD 1.2G (ABEL) #1: Wed Jul 2 13:35:44 MEST 1997 matthieu@abel:/usr/src/sys/arch/sparc/compile/ABEL sparc


>Description:
	NIS+ servers in NIS compatibility mode don't implement the 
	yp_order() function. This makes amd fail on NIS maps when they
	are handled by a NIS+ server.

	A patch for this was integrated in NetBSD's amd, but was lost
	with the integration of am-tools-6.0a8.

>How-To-Repeat:
	try to use a NIS map from a NIS+ server with amd.
>Fix:
	Here's a patch to reintroduce the previous modification:

--- usr.sbin/amd/amd/info_nis.c.orig	Thu Aug 21 11:59:53 1997
+++ usr.sbin/amd/amd/info_nis.c	Thu Aug 21 12:39:02 1997
@@ -51,6 +51,12 @@
 #endif /* HAVE_CONFIG_H */
 #include <am_defs.h>
 #include <amd.h>
+#include <time.h>
+
+/*
+ * NIS+ servers in NIS compat mode don't have yp_order()
+ */
+static int has_yp_order = FALSE;
 
 struct nis_callback_data {
   mnt_map *ncd_m;
@@ -187,16 +193,28 @@
       return error;
   }
 
-  /*
-   * Check if map has changed
-   */
-  if (yp_order(gopt.nis_domain, map, &order))
-    return EIO;
-  if ((time_t) order > *tp) {
-    *tp = (time_t) order;
-    return -1;
-  }
 
+  if (has_yp_order) {
+      /*
+       * Check if map has changed
+       */
+      if (yp_order(gopt.nis_domain, map, &order))
+	  return EIO;
+      if ((time_t) order > *tp) {
+	  *tp = (time_t) order;
+	  return -1;
+      }
+  } else {
+      /*
+       * NIS+ server without yp_order
+       * Check if timeout has expired to invalidate the cache 
+       */
+      order = time(NULL);
+      if ((time_t)order - *tp > gopt.am_timeo) {
+	  *tp = (time_t)order;
+	  return(-1);
+      }
+  }
   /*
    * Lookup key
    */
@@ -223,6 +241,8 @@
 nis_init(mnt_map *m, char *map, time_t *tp)
 {
   YP_ORDER_OUTORDER_TYPE order;
+  int yp_order_result;
+  char *master;
 
   if (!gopt.nis_domain) {
     int error = determine_nis_domain();
@@ -233,12 +253,34 @@
    * To see if the map exists, try to find
    * a master for it.
    */
-  if (yp_order(gopt.nis_domain, map, &order))
-    return ENOENT;
-  *tp = (time_t) order;
+  yp_order_result = yp_order(gopt.nis_domain, map, &order);
+  switch (yp_order_result) {
+    case 0:
+      has_yp_order = TRUE;
+      *tp = (time_t)order;
 #ifdef DEBUG
   dlog("NIS master for %s@%s has order %d", map, gopt.nis_domain, order);
 #endif /* DEBUG */
+  break;
+  
+    case  YPERR_YPERR:
+      /* NIS+ server found ! */
+      has_yp_order = FALSE;
+      /* try yp_master() instead */
+      if (yp_master(gopt.nis_domain, map, &master)) {
+	  return ENOENT;
+      } else {
+#ifdef DEBUG
+	  dlog("NIS master for %s@%s is a NIS+ server", 
+	       map, domain);
+#endif
+	  /* Use fake timestamps */
+	  *tp = time(NULL);
+      }
+      break;
+    default:
+      return ENOENT;
+  }
   return 0;
 }
 

>Audit-Trail:
>Unformatted: