about summary refs log tree commit diff
path: root/nis
diff options
context:
space:
mode:
Diffstat (limited to 'nis')
-rw-r--r--nis/Banner2
-rw-r--r--nis/Makefile9
-rw-r--r--nis/TODO25
-rw-r--r--nis/nis_add.c71
-rw-r--r--nis/nis_addmember.c69
-rw-r--r--nis/nis_call.c9
-rw-r--r--nis/nis_checkpoint.c71
-rw-r--r--nis/nis_creategroup.c66
-rw-r--r--nis/nis_defaults.c466
-rw-r--r--nis/nis_destroygroup.c52
-rw-r--r--nis/nis_domain_of.c29
-rw-r--r--nis/nis_domain_of_r.c58
-rw-r--r--nis/nis_getservlist.c115
-rw-r--r--nis/nis_intern.c24
-rw-r--r--nis/nis_ismember.c142
-rw-r--r--nis/nis_lookup.c157
-rw-r--r--nis/nis_mkdir.c46
-rw-r--r--nis/nis_modify.c47
-rw-r--r--nis/nis_ping.c63
-rw-r--r--nis/nis_print_group_entry.c59
-rw-r--r--nis/nis_remove.c55
-rw-r--r--nis/nis_removemember.c80
-rw-r--r--nis/nis_rmdir.c46
-rw-r--r--nis/nis_server.c154
-rw-r--r--nis/nis_subr.c44
-rw-r--r--nis/nis_verifygroup.c51
-rw-r--r--nis/rpcsvc/nislib.h89
27 files changed, 1879 insertions, 220 deletions
diff --git a/nis/Banner b/nis/Banner
index f03f4ea3f5..b5aedc2b97 100644
--- a/nis/Banner
+++ b/nis/Banner
@@ -1 +1 @@
-NIS(YP)/NIS+ NSS modules 0.10 by Thorsten Kukuk
+NIS(YP)/NIS+ NSS modules 0.11 by Thorsten Kukuk
diff --git a/nis/Makefile b/nis/Makefile
index 64925bb70d..a5a591e1b7 100644
--- a/nis/Makefile
+++ b/nis/Makefile
@@ -43,8 +43,13 @@ vpath %.c $(subdir-dirs)
 
 libnsl-routines = yp_xdr ypclnt ypupdate_xdr \
                   nis_subr nis_local_names nis_free nis_file \
-                  nis_print nis_error nis_call nis_names nis_clone\
-                  nis_table nis_xdr nis_intern nis_server
+                  nis_print nis_error nis_call nis_lookup nis_clone\
+                  nis_table nis_xdr nis_intern nis_server nis_ping\
+		  nis_checkpoint nis_mkdir nis_rmdir nis_getservlist\
+		  nis_verifygroup nis_ismember nis_addmember \
+		  nis_removemember nis_creategroup nis_destroygroup\
+		  nis_print_group_entry nis_domain_of nis_domain_of_r\
+		  nis_modify nis_remove nis_add nis_defaults
 
 libnss_compat-routines	:= $(addprefix compat-,grp pwd spwd)
 libnss_compat-inhibit-o	= $(filter-out .so,$(object-suffixes))
diff --git a/nis/TODO b/nis/TODO
index 628e646d15..33072fa730 100644
--- a/nis/TODO
+++ b/nis/TODO
@@ -4,15 +4,6 @@
  * nss_nisplus: Search the data in the complete NIS+ namespace
 		specified by NIS_PATH
  
- * nis_server: implement nis_getservlist, nis_stats, nis_servstate
-
- * nis_groups: implement it
-
- * nis_ping: implement it
-
- * __start_clock(), __stop_clock(): Test the interface and
-                                    implement it
- 
  * What does nis_list give back, if rpc.nisd is not running or
    if /var/nis/NIS_START_FILE does not exist ?
 
@@ -20,21 +11,7 @@
 	Missing flags: FOLLOW_PATH, ALL_RESULTS
 	callback: Don't simulate it, use server callback thread
 
- * Possible flags:
-	- FOLLOW_LINKS	(nis_list, nis_lookup)
+ * Missing flags:
 	- FOLLOW_PATH	(nis_list, not supported)
-	- HARD_LOOKUP	(__do_niscall)
 	- ALL_RESULTS	(nis_list, not supported, needs server callback)
 	- NO_CACHE	(__do_niscall, cache not supported yet)
-	- MASTER_ONLY	(__do_niscall)
-	- EXPAND_NAME	(nis_lookup, nis_list)
-	- RETURN_RESULT (nis_table.c)
-	- ADD_OVERWRITE	(nis_table.c)
-	- REM_MULTIPLE	(nis_table.c)
-	- MOD_SAMEOBJ 	(nis_table.c)
-	- ADD_RESERVED	(nis_table.c)
-	- REM_RESERVED	(nis_table.c)
-	- MOD_EXCLUSIVE	(nis_table.c)
-	- USE_DGRAM	(__do_niscall)
-	- NO_AUTHINFO 	(__do_niscall)
-	
diff --git a/nis/nis_add.c b/nis/nis_add.c
new file mode 100644
index 0000000000..0eb838efed
--- /dev/null
+++ b/nis/nis_add.c
@@ -0,0 +1,71 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+#include "nis_intern.h"
+
+nis_result *
+nis_add (const_nis_name name, const nis_object *obj)
+{
+  nis_result *res;
+  nis_error status;
+  struct ns_request req;
+  char *p1, *p2, *p3, *p4;
+  char buf1 [strlen (name) + 20];
+  char buf4 [strlen (name) + 20];
+
+  res = calloc (1, sizeof (nis_result));
+
+  req.ns_name = (char *)name;
+
+  req.ns_object.ns_object_len = 1;
+  req.ns_object.ns_object_val = nis_clone_object (obj, NULL);
+
+  p1 = req.ns_object.ns_object_val[0].zo_name;
+  req.ns_object.ns_object_val[0].zo_name =
+    nis_name_of_r (name, buf1, sizeof (buf1));
+
+  p2 = req.ns_object.ns_object_val[0].zo_owner;
+  if (p2 == NULL || strlen (p2) == 0)
+    req.ns_object.ns_object_val[0].zo_owner = nis_local_principal ();
+
+  p3 = req.ns_object.ns_object_val[0].zo_group;
+  if (p3 == NULL || strlen (p3) == 0)
+    req.ns_object.ns_object_val[0].zo_group = nis_local_group ();
+
+  p4 = req.ns_object.ns_object_val[0].zo_domain;
+  req.ns_object.ns_object_val[0].zo_domain =
+    nis_domain_of_r (name, buf4, sizeof (buf4));
+
+  if ((status = __do_niscall (NULL, 0, NIS_ADD, (xdrproc_t) xdr_ns_request,
+			      (caddr_t) &req, (xdrproc_t) xdr_nis_result,
+			      (caddr_t) res, MASTER_ONLY)) != RPC_SUCCESS)
+    res->status = status;
+
+  req.ns_object.ns_object_val[0].zo_name = p1;
+  req.ns_object.ns_object_val[0].zo_owner = p2;
+  req.ns_object.ns_object_val[0].zo_group = p3;
+  req.ns_object.ns_object_val[0].zo_domain = p4;
+
+  nis_destroy_object (req.ns_object.ns_object_val);
+
+  return res;
+}
diff --git a/nis/nis_addmember.c b/nis/nis_addmember.c
new file mode 100644
index 0000000000..2eee9cc8bf
--- /dev/null
+++ b/nis/nis_addmember.c
@@ -0,0 +1,69 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+nis_error
+nis_addmember (const_nis_name member, const_nis_name group)
+{
+  if (group != NULL && strlen (group) > 0)
+    {
+      char buf[strlen (group) + 50];
+      char leafbuf[strlen (group) + 2];
+      char domainbuf[strlen (group) + 2];
+      nis_result *res, *res2;
+      nis_error status;
+      char *cp, *cp2;
+
+      cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1));
+      cp = stpcpy (cp, ".groups_dir");
+      cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1);
+      if (cp2 != NULL && strlen (cp2) > 0)
+        {
+          cp = stpcpy (cp, ".");
+          strcpy (cp, cp2);
+        }
+      res = nis_lookup (buf, FOLLOW_LINKS|EXPAND_NAME);
+      if (res->status != NIS_SUCCESS)
+	{
+	  status = res->status;
+	  nis_freeresult (res);
+	  return status;
+	}
+      if ((res->objects.objects_len != 1) ||
+          (res->objects.objects_val[0].zo_data.zo_type != GROUP_OBJ))
+        return NIS_INVALIDOBJ;
+
+      res->objects.objects_val[0].GR_data.gr_members.gr_members_val
+	= realloc (res->objects.objects_val[0].GR_data.gr_members.gr_members_val, res->objects.objects_val[0].GR_data.gr_members.gr_members_len + 1);
+      ++res->objects.objects_val[0].GR_data.gr_members.gr_members_len;
+      res->objects.objects_val[0].GR_data.gr_members.gr_members_val[res->objects.objects_val[0].GR_data.gr_members.gr_members_len] = strdup (member);
+
+      res2 = nis_modify (buf, res->objects.objects_val);
+      status = res2->status;
+      nis_freeresult (res);
+      nis_freeresult (res2);
+
+      return status;
+    }
+  else
+    return NIS_FAIL;
+}
diff --git a/nis/nis_call.c b/nis/nis_call.c
index 12b3ab265e..a92f1445f4 100644
--- a/nis/nis_call.c
+++ b/nis/nis_call.c
@@ -134,7 +134,7 @@ __nis_dobind (const nis_server *server, u_long flags)
       if ((flags & NO_AUTHINFO) != NO_AUTHINFO)
 	{
 #if defined(HAVE_SECURE_RPC)
-	  if (server->key_type == NIS_PK_DH)
+	  if (server->key_type == NIS_PK_DH && getenv ("NO_SECURE_RPC") == NULL)
 	    {
 	      char netname[MAXNETNAMELEN+1];
 	      char *p;
@@ -173,11 +173,8 @@ __do_niscall (const nis_server *serv, int serv_len, u_long prog,
   if (serv == NULL || serv_len == 0)
     {
       dir = readColdStartFile ();
-      if (dir == NULL)
-	{
-	  fputs (_("Error: could not find a NIS_COLD_START file\n"), stderr);
-	  return NIS_UNAVAIL;
-	}
+      if (dir == NULL) /* No /var/nis/NIS_COLD_START -> no NIS+ installed */
+	return NIS_UNAVAIL;
       server = dir->do_servers.do_servers_val;
       server_len = dir->do_servers.do_servers_len;
     }
diff --git a/nis/nis_checkpoint.c b/nis/nis_checkpoint.c
new file mode 100644
index 0000000000..56e98b2ac5
--- /dev/null
+++ b/nis/nis_checkpoint.c
@@ -0,0 +1,71 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA. */
+
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+#include "nis_intern.h"
+
+nis_result *
+nis_checkpoint(const_nis_name dirname)
+{
+  nis_result *res;
+
+  res = calloc (1, sizeof (nis_result));
+
+  if (dirname != NULL)
+    {
+      cp_result *cpres = NULL;
+      nis_result *res2;
+      u_int i;
+
+      res2 = nis_lookup (dirname, EXPAND_NAME);
+      if (res2->status != NIS_SUCCESS && res2->status != NIS_S_SUCCESS)
+        return res2;
+
+      /* Check if obj is really a diryectory object */
+      if (res2->objects.objects_val[0].zo_data.zo_type != DIRECTORY_OBJ)
+	{
+	  nis_freeresult (res);
+	  res->status = NIS_INVALIDOBJ;
+	  return res;
+	}
+
+      for (i = 0;
+	   i < res2->objects.objects_val[0].DI_data.do_servers.do_servers_len;
+	   ++i)
+	{
+	  if (__do_niscall (&res2->objects.objects_val[0].DI_data.do_servers.do_servers_val[i],
+			    1, NIS_CHECKPOINT, (xdrproc_t) xdr_nis_name,
+			    (caddr_t) &dirname, (xdrproc_t) xdr_cp_result,
+			    (caddr_t) &cpres, 0) != RPC_SUCCESS)
+	    res->status = NIS_RPCERROR;
+	  else
+	    {
+	      res->status += cpres->cp_status;
+	      res->zticks += cpres->cp_zticks;
+	      res->dticks += cpres->cp_dticks;
+	    }
+	}
+      nis_freeresult (res2);
+    }
+  else
+    res->status = NIS_NOSUCHNAME;
+
+  return res;
+}
diff --git a/nis/nis_creategroup.c b/nis/nis_creategroup.c
new file mode 100644
index 0000000000..c62b039b5e
--- /dev/null
+++ b/nis/nis_creategroup.c
@@ -0,0 +1,66 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+nis_error
+nis_creategroup (const_nis_name group, u_long flags)
+{
+  if (group != NULL && strlen (group) > 0)
+    {
+      char buf[strlen (group) + 50];
+      char leafbuf[strlen (group) + 2];
+      char domainbuf[strlen (group) + 2];
+      nis_error status;
+      nis_result *res;
+      char *cp, *cp2;
+      nis_object *obj;
+
+      cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1));
+      cp = stpcpy (cp, ".groups_dir");
+      cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1);
+      if (cp2 != NULL && strlen (cp2) > 0)
+        {
+          cp = stpcpy (cp, ".");
+          strcpy (cp, cp2);
+        }
+      else
+	return NIS_BADNAME;
+
+      obj = calloc (1, sizeof (nis_object));
+      obj->zo_owner = strdup (__nis_default_owner (NULL));
+      obj->zo_group = strdup (__nis_default_group (NULL));
+      obj->zo_access = __nis_default_access (NULL, 0);
+      obj->zo_ttl = __nis_default_ttl (0);
+      obj->zo_data.zo_type = GROUP_OBJ;
+      obj->zo_data.objdata_u.gr_data.gr_flags = flags;
+      obj->zo_data.objdata_u.gr_data.gr_members.gr_members_len = 0;
+      obj->zo_data.objdata_u.gr_data.gr_members.gr_members_val = NULL;
+
+      res = nis_add (buf, obj);
+      status = res->status;
+      nis_freeresult (res);
+      nis_free_object (obj);
+
+      return status;
+    }
+  return NIS_FAIL;
+}
diff --git a/nis/nis_defaults.c b/nis/nis_defaults.c
new file mode 100644
index 0000000000..9d152d1f11
--- /dev/null
+++ b/nis/nis_defaults.c
@@ -0,0 +1,466 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <rpc/rpc.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+#define DEFAULT_TTL 43200
+
+/*
+** Some functions for parsing the -D param and NIS_DEFAULTS Environ
+*/
+static nis_name
+searchgroup (char *str)
+{
+  static char default_group[NIS_MAXNAMELEN];
+ char *cptr;
+  int i;
+
+  cptr = strstr (str, "group=");
+  if (cptr == NULL)
+    return NULL;
+
+  cptr += 6;			/* points to the begin of the group string */
+  i = 0;
+  while (cptr[i] != '\0' && cptr[i] != ':')
+    i++;
+  if (i == 0)			/* only "group=" ? */
+    return (nis_name)"";
+
+  strncpy (default_group, cptr, i);
+
+  return default_group;
+}
+
+static nis_name
+searchowner (char *str)
+{
+  static char default_owner[NIS_MAXNAMELEN];
+  char *cptr;
+  int i;
+
+  cptr = strstr (str, "owner=");
+  if (cptr == NULL)
+    return NULL;
+
+  cptr += 6;			/* points to the begin of the owner string */
+  i = 0;
+  while (cptr[i] != '\0' && cptr[i] != ':')
+    i++;
+  if (i == 0)			/* only "owner=" ? */
+    return (nis_name)"";
+
+  strncpy (default_owner, cptr, i);
+
+  return default_owner;
+}
+
+static u_long
+searchttl (char *str)
+{
+  char buf[1024];
+  char *cptr, *dptr;
+  u_long time;
+  int i;
+
+  dptr = strstr (str, "ttl=");
+  if (dptr == NULL)		/* should (could) not happen */
+    return DEFAULT_TTL;;
+
+  dptr += 4;			/* points to the begin of the new ttl */
+  i = 0;
+  while (dptr[i] != '\0' && dptr[i] != ':')
+    i++;
+  if (i == 0)			/* only "ttl=" ? */
+    return DEFAULT_TTL;
+
+  strncpy (buf, dptr, i);
+  time = 0;
+
+  dptr = buf;
+  cptr = strchr (dptr, 'd');
+  if (cptr != NULL)
+    {
+      *cptr = '\0';
+      cptr++;
+      time += atoi (dptr) * 60 * 60 * 24;
+      dptr = cptr;
+    }
+
+  cptr = strchr (dptr, 'h');
+  if (cptr != NULL)
+    {
+      *cptr = '\0';
+      cptr++;
+      time += atoi (dptr) * 60 * 60;
+      dptr = cptr;
+    }
+
+  cptr = strchr (dptr, 'm');
+  if (cptr != NULL)
+    {
+      *cptr = '\0';
+      cptr++;
+      time += atoi (dptr) * 60;
+      dptr = cptr;
+    }
+
+  cptr = strchr (dptr, 's');
+  if (cptr != NULL)
+    *cptr = '\0';
+
+  time += atoi (dptr);
+
+  return time;
+}
+
+static u_long
+searchaccess (char *str, u_long access)
+{
+  static char buf[NIS_MAXNAMELEN];
+  char *cptr;
+  u_long result;
+  int i;
+  int n, o, g, w;
+
+  cptr = strstr (str, "access=");
+  if (cptr == NULL)
+    return 0;
+
+  cptr += 7;			/* points to the begin of the access string */
+  i = 0;
+  while (cptr[i] != '\0' && cptr[i] != ':')
+    i++;
+  if (i == 0)			/* only "access=" ? */
+    return 0;
+
+  strncpy (buf, cptr, i);
+
+  result = n = o = g = w = 0;
+  cptr = buf;
+  while (*cptr != '\0')
+    {
+      switch (*cptr)
+	{
+	case 'n':
+	  n = 1;
+	  break;
+	case 'o':
+	  o = 1;
+	  break;
+	case 'g':
+	  g = 1;
+	  break;
+	case 'w':
+	  w = 1;
+	  break;
+	case 'a':
+	  o = g = w = 1;
+	  break;
+	case '-':
+	  cptr++;		/* Remove "=" from beginning */
+	  while (*cptr != '\0' && *cptr != ',')
+	    {
+	      switch (*cptr)
+		{
+		case 'r':
+		  if (n)
+		    result = result & ~(NIS_READ_ACC << 24);
+		  if (o)
+		    result = result & ~(NIS_READ_ACC << 16);
+		  if (g)
+		    result = result & ~(NIS_READ_ACC << 8);
+		  if (w)
+		    result = result & ~(NIS_READ_ACC);
+		  break;
+		case 'm':
+		  if (n)
+		    result = result & ~(NIS_MODIFY_ACC << 24);
+		  if (o)
+		    result = result & ~(NIS_MODIFY_ACC << 16);
+		  if (g)
+		    result = result & ~(NIS_MODIFY_ACC << 8);
+		  if (w)
+		    result = result & ~(NIS_MODIFY_ACC);
+		  break;
+		case 'c':
+		  if (n)
+		    result = result & ~(NIS_CREATE_ACC << 24);
+		  if (o)
+		    result = result & ~(NIS_CREATE_ACC << 16);
+		  if (g)
+		    result = result & ~(NIS_CREATE_ACC << 8);
+		  if (w)
+		    result = result & ~(NIS_CREATE_ACC);
+		  break;
+		case 'd':
+		  if (n)
+		    result = result & ~(NIS_DESTROY_ACC << 24);
+		  if (o)
+		    result = result & ~(NIS_DESTROY_ACC << 16);
+		  if (g)
+		    result = result & ~(NIS_DESTROY_ACC << 8);
+		  if (w)
+		    result = result & ~(NIS_DESTROY_ACC);
+		  break;
+		default:
+		  fprintf (stderr, "Parse error in \"%s\"\n", buf);
+		  return 0;
+		}
+	      cptr++;
+	    }
+	  break;
+	case '+':
+	  cptr++;		/* Remove "=" from beginning */
+	  while (*cptr != '\0' && *cptr != ',')
+	    {
+	      switch (*cptr)
+		{
+		case 'r':
+		  if (n)
+		    result = result | (NIS_READ_ACC << 24);
+		  if (o)
+		    result = result | (NIS_READ_ACC << 16);
+		  if (g)
+		    result = result | (NIS_READ_ACC << 8);
+		  if (w)
+		    result = result | (NIS_READ_ACC);
+		  break;
+		case 'm':
+		  if (n)
+		    result = result | (NIS_MODIFY_ACC << 24);
+		  if (o)
+		    result = result | (NIS_MODIFY_ACC << 16);
+		  if (g)
+		    result = result | (NIS_MODIFY_ACC << 8);
+		  if (w)
+		    result = result | (NIS_MODIFY_ACC);
+		  break;
+		case 'c':
+		  if (n)
+		    result = result | (NIS_CREATE_ACC << 24);
+		  if (o)
+		    result = result | (NIS_CREATE_ACC << 16);
+		  if (g)
+		    result = result | (NIS_CREATE_ACC << 8);
+		  if (w)
+		    result = result | (NIS_CREATE_ACC);
+		  break;
+		case 'd':
+		  if (n)
+		    result = result | (NIS_DESTROY_ACC << 24);
+		  if (o)
+		    result = result | (NIS_DESTROY_ACC << 16);
+		  if (g)
+		    result = result | (NIS_DESTROY_ACC << 8);
+		  if (w)
+		    result = result | (NIS_DESTROY_ACC);
+		  break;
+		default:
+		  fprintf (stderr, "Parse error in \"%s\"\n", buf);
+		  return 0;
+		}
+	      cptr++;
+	    }
+	  break;
+	case '=':
+	  cptr++;		/* Remove "=" from beginning */
+	  /* Clear */
+	  if (n)
+	    result = result & ~((NIS_READ_ACC + NIS_MODIFY_ACC +
+				 NIS_CREATE_ACC + NIS_DESTROY_ACC) << 24);
+
+	  if (o)
+	    result = result & ~((NIS_READ_ACC + NIS_MODIFY_ACC +
+				 NIS_CREATE_ACC + NIS_DESTROY_ACC) << 16);
+	  if (g)
+	    result = result & ~((NIS_READ_ACC + NIS_MODIFY_ACC +
+				 NIS_CREATE_ACC + NIS_DESTROY_ACC) << 8);
+	  if (w)
+	    result = result & ~(NIS_READ_ACC + NIS_MODIFY_ACC +
+				NIS_CREATE_ACC + NIS_DESTROY_ACC);
+	  while (*cptr != '\0' && *cptr != ',')
+	    {
+	      switch (*cptr)
+		{
+		case 'r':
+		  if (n)
+		    result = result | (NIS_READ_ACC << 24);
+		  if (o)
+		    result = result | (NIS_READ_ACC << 16);
+		  if (g)
+		    result = result | (NIS_READ_ACC << 8);
+		  if (w)
+		    result = result | (NIS_READ_ACC);
+		  break;
+		case 'm':
+		  if (n)
+		    result = result | (NIS_MODIFY_ACC << 24);
+		  if (o)
+		    result = result | (NIS_MODIFY_ACC << 16);
+		  if (g)
+		    result = result | (NIS_MODIFY_ACC << 8);
+		  if (w)
+		    result = result | (NIS_MODIFY_ACC);
+		  break;
+		case 'c':
+		  if (n)
+		    result = result | (NIS_CREATE_ACC << 24);
+		  if (o)
+		    result = result | (NIS_CREATE_ACC << 16);
+		  if (g)
+		    result = result | (NIS_CREATE_ACC << 8);
+		  if (w)
+		    result = result | (NIS_CREATE_ACC);
+		  break;
+		case 'd':
+		  if (n)
+		    result = result | (NIS_DESTROY_ACC << 24);
+		  if (o)
+		    result = result | (NIS_DESTROY_ACC << 16);
+		  if (g)
+		    result = result | (NIS_DESTROY_ACC << 8);
+		  if (w)
+		    result = result | (NIS_DESTROY_ACC);
+		  break;
+		default:
+		  fprintf (stderr, "Parse error in \"%s\"\n", buf);
+		  return 0;
+		}
+	      cptr++;
+	    }
+	  break;
+	default:
+	  fprintf (stderr, "Parse error in \"%s\"\n", buf);
+	  return 0;
+	}
+      cptr++;
+    }
+
+  return 0;
+}
+
+nis_name
+__nis_default_owner (char *defaults)
+{
+  static char default_owner[NIS_MAXNAMELEN];
+  char *cptr, *dptr;
+
+  strcpy (default_owner, nis_local_principal ());
+
+  if (defaults != NULL)
+    {
+      dptr = strstr (defaults, "owner=");
+      if (dptr != NULL)
+	strcpy (default_owner, searchowner (defaults));
+    }
+  else
+    {
+      cptr = getenv ("NIS_DEFAULTS");
+      if (cptr != NULL)
+	{
+	  dptr = strstr (cptr, "owner=");
+	  if (dptr != NULL)
+	    strcpy (default_owner, searchowner (cptr));
+	}
+    }
+
+  return default_owner;
+}
+
+nis_name
+__nis_default_group (char *defaults)
+{
+  static char default_group[NIS_MAXNAMELEN];
+  char *cptr, *dptr;
+
+  strcpy (default_group, nis_local_group ());
+
+  if (defaults != NULL)
+    {
+      dptr = strstr (defaults, "group=");
+      if (dptr != NULL)
+	strcpy (default_group, searchgroup (defaults));
+    }
+  else
+    {
+      cptr = getenv ("NIS_DEFAULTS");
+      if (cptr != NULL)
+	{
+	  dptr = strstr (cptr, "group=");
+	  if (dptr != NULL)
+	    strcpy (default_group, searchgroup (cptr));
+	}
+    }
+
+  return default_group;
+}
+
+u_long
+__nis_default_ttl (char *defaults)
+{
+  char *cptr, *dptr;
+
+  if (defaults != NULL)
+    {
+      dptr = strstr (defaults, "ttl=");
+      if (dptr != NULL)
+	return searchttl (defaults);
+    }
+
+  cptr = getenv ("NIS_DEFAULTS");
+  if (cptr == NULL)
+    return DEFAULT_TTL;
+
+  dptr = strstr (cptr, "ttl=");
+  if (dptr == NULL)
+    return DEFAULT_TTL;
+
+  return searchttl (cptr);
+}
+
+/* Default access rights are ----rmcdr---r---, but we could change
+   this with the NIS_DEFAULTS variable. */
+u_long
+__nis_default_access (char *param, u_long defaults)
+{
+  u_long result;
+  char *cptr;
+
+  if (defaults == 0)
+    result = 0 | OWNER_DEFAULT | GROUP_DEFAULT | WORLD_DEFAULT;
+  else
+    result = defaults;
+
+  if (param != NULL && strstr (param, "access=") != NULL)
+    result = searchaccess (param, result);
+  else
+    {
+      cptr = getenv ("NIS_DEFAULTS");
+      if (cptr != NULL && strstr (cptr, "access=") != NULL)
+	result = searchaccess (getenv ("NIS_DEFAULTS"), result);
+    }
+
+  return result;
+}
diff --git a/nis/nis_destroygroup.c b/nis/nis_destroygroup.c
new file mode 100644
index 0000000000..524e0776ac
--- /dev/null
+++ b/nis/nis_destroygroup.c
@@ -0,0 +1,52 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+nis_error
+nis_destroygroup (const_nis_name group)
+{
+  if (group != NULL && strlen (group) > 0)
+    {
+      char buf[strlen (group) + 50];
+      char leafbuf[strlen (group) + 3];
+      char domainbuf[strlen (group) + 3];
+      nis_error status;
+      nis_result *res;
+      char *cp, *cp2;
+
+      cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1));
+      cp = stpcpy (cp, ".groups_dir");
+      cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1);
+      if (cp2 != NULL && strlen (cp2) > 0)
+	{
+	  cp = stpcpy (cp, ".");
+	  strcpy (cp, cp2);
+	}
+      res = nis_remove (buf, NULL);
+      status = res->status;
+      nis_freeresult (res);
+      return status;
+    }
+  else
+    return NIS_FAIL;
+
+}
diff --git a/nis/nis_domain_of.c b/nis/nis_domain_of.c
new file mode 100644
index 0000000000..f0cfe316e6
--- /dev/null
+++ b/nis/nis_domain_of.c
@@ -0,0 +1,29 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+nis_name
+nis_domain_of (const_nis_name name)
+{
+  static char result[NIS_MAXNAMELEN + 1];
+
+  return nis_domain_of_r (name, result, NIS_MAXNAMELEN);
+}
diff --git a/nis/nis_domain_of_r.c b/nis/nis_domain_of_r.c
new file mode 100644
index 0000000000..3435233aef
--- /dev/null
+++ b/nis/nis_domain_of_r.c
@@ -0,0 +1,58 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <string.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+nis_name
+nis_domain_of_r (const_nis_name name, char *buffer, size_t buflen)
+{
+  char *cptr;
+  size_t cptr_len;
+
+  if (buffer == NULL)
+    {
+      errno = ERANGE;
+      return NULL;
+    }
+
+  buffer[0] = '\0';
+
+  cptr = strchr (name, '.');
+
+  if (cptr == NULL)
+    return buffer;
+
+  ++cptr;
+  cptr_len = strlen (cptr);
+
+  if (cptr_len == 0)
+    strcpy (buffer, ".");
+  else if (cptr_len >= buflen)
+    {
+      errno = ERANGE;
+      return NULL;
+    }
+  else
+    memcpy (buffer, cptr, cptr_len + 1);
+
+  return buffer;
+}
diff --git a/nis/nis_getservlist.c b/nis/nis_getservlist.c
new file mode 100644
index 0000000000..0c9fbfb60d
--- /dev/null
+++ b/nis/nis_getservlist.c
@@ -0,0 +1,115 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+#include "nis_intern.h"
+
+nis_server **
+nis_getservlist (const_nis_name dir)
+{
+  nis_result *res;
+  nis_server **serv;
+
+  res = nis_lookup (dir, FOLLOW_LINKS);
+
+  if (res->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS)
+    {
+      unsigned long i;
+      nis_server *server;
+
+      serv = malloc (sizeof (nis_server *) *
+		     (res->objects.objects_val->DI_data.do_servers.do_servers_len + 1));
+      if (serv == NULL)
+	return NULL;
+      for (i = 0; i < res->objects.objects_val->DI_data.do_servers.do_servers_len; ++i)
+	{
+	  server =
+	    &res->objects.objects_val->DI_data.do_servers.do_servers_val[i];
+	  if (server->name != NULL)
+            serv[i]->name = strdup (server->name);
+          else
+            serv[i]->name = NULL;
+
+          serv[i]->ep.ep_len = server->ep.ep_len;
+          if (serv[i]->ep.ep_len > 0)
+            {
+              unsigned long j;
+
+              serv[i]->ep.ep_val =
+		malloc (server->ep.ep_len * sizeof (endpoint));
+              for (j = 0; j < serv[i]->ep.ep_len; ++j)
+                {
+                  if (server->ep.ep_val[j].uaddr)
+                    serv[i]->ep.ep_val[j].uaddr =
+		      strdup (server->ep.ep_val[j].uaddr);
+                  else
+                    serv[i]->ep.ep_val[j].uaddr = NULL;
+                  if (server->ep.ep_val[j].family)
+		    serv[i]->ep.ep_val[j].family =
+		      strdup (server->ep.ep_val[j].family);
+                  else
+                    serv[i]->ep.ep_val[j].family = NULL;
+                  if (server->ep.ep_val[j].proto)
+		    serv[i]->ep.ep_val[j].proto =
+		      strdup (server->ep.ep_val[j].proto);
+                  else
+		    serv[i]->ep.ep_val[j].proto = NULL;
+                }
+            }
+          else
+	    serv[i]->ep.ep_val = NULL;
+          serv[i]->key_type = server->key_type;
+          serv[i]->pkey.n_len = server->pkey.n_len;
+          if (server->pkey.n_len > 0)
+            {
+              serv[i]->pkey.n_bytes =
+                malloc (server->pkey.n_len);
+              if (serv[i]->pkey.n_bytes == NULL)
+                return NULL;
+              memcpy (serv[i]->pkey.n_bytes, server->pkey.n_bytes,
+                      server->pkey.n_len);
+            }
+          else
+            serv[i]->pkey.n_bytes = NULL;
+        }
+    }
+  else
+    {
+      serv = malloc (sizeof (nis_server *));
+      if (serv != NULL)
+	serv[0] = NULL;
+    }
+  return serv;
+}
+
+void
+nis_freeservlist (nis_server **serv)
+{
+  int i;
+
+  if (serv == NULL)
+    return;
+
+  i = 0;
+  while (serv[i] != NULL)
+    nis_free_servers (serv[i], 1);
+  free (serv);
+}
diff --git a/nis/nis_intern.c b/nis/nis_intern.c
index 91522a6312..7bfa263070 100644
--- a/nis/nis_intern.c
+++ b/nis/nis_intern.c
@@ -143,27 +143,3 @@ __nis_expandname (const char *name)
 
   return getnames;
 }
-
-fd_result *
-__nis_finddirectoy (const_nis_name name)
-{
-  fd_args args;
-  nis_error status;
-  fd_result *res;
-
-  args.dir_name = (char *) name;
-  args.requester = nis_local_principal ();
-
-  res = calloc (1, sizeof (fd_result));
-  if (res == NULL)
-    return NULL;
-
-  if ((status = __do_niscall (NULL, 0, NIS_FINDDIRECTORY,
-			      (xdrproc_t) xdr_fd_args,
-			      (caddr_t) &args,
-			      (xdrproc_t) xdr_fd_result,
-			      (caddr_t) res, 0)) != RPC_SUCCESS)
-    res->status = status;
-
-  return res;
-}
diff --git a/nis/nis_ismember.c b/nis/nis_ismember.c
new file mode 100644
index 0000000000..f0d087ca51
--- /dev/null
+++ b/nis/nis_ismember.c
@@ -0,0 +1,142 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+/* internal_nis_ismember ()
+   return codes: -1 principal is in -group
+                  0 principal isn't in any group
+		  1 pirncipal is in group */
+static int
+internal_ismember (const_nis_name principal, const_nis_name group)
+{
+  if (group != NULL && strlen (group) > 0)
+    {
+      char buf[strlen (group) + 50];
+      char leafbuf[strlen (group) + 2];
+      char domainbuf[strlen (group) + 2];
+      nis_result *res;
+      char *cp, *cp2;
+      u_int i;
+
+      cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1));
+      cp = stpcpy (cp, ".groups_dir");
+      cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1);
+      if (cp2 != NULL && strlen (cp2) > 0)
+        {
+          cp = stpcpy (cp, ".");
+          strcpy (cp, cp2);
+	}
+      res = nis_lookup (buf, EXPAND_NAME|FOLLOW_LINKS);
+      if (res->status != NIS_SUCCESS && res->status != NIS_S_SUCCESS)
+        return 0;
+
+      if ((res->objects.objects_len != 1) ||
+          (res->objects.objects_val[0].zo_data.zo_type != GROUP_OBJ))
+        return 0;
+
+      /* We search twice in the list, at first, if we have the name
+	 with a "-", then if without. "-member" has priority */
+      for (i = 0;
+           i < res->objects.objects_val[0].GR_data.gr_members.gr_members_len;
+           ++i)
+	{
+	  cp =res->objects.objects_val[0].GR_data.gr_members.gr_members_val[i];
+	  if (cp[0] == '-')
+	    {
+	      if (strcmp (&cp[1], principal) == 0)
+		return -1;
+	      if (cp[1] == '@')
+		switch (internal_ismember (principal, &cp[2]))
+		  {
+		  case -1:
+		    return -1;
+		  case 1:
+		    return -1;
+		  default:
+		    break;
+		  }
+	      else
+		if (cp[1] == '*')
+		  {
+		    char buf1[strlen (principal) + 2];
+		    char buf2[strlen (cp) + 2];
+
+		    strcpy (buf1, nis_domain_of (principal));
+		    strcpy (buf2, nis_domain_of (cp));
+		    if (strcmp (buf1, buf2) == 0)
+		      return -1;
+		  }
+	    }
+	}
+      for (i = 0;
+	   i < res->objects.objects_val[0].GR_data.gr_members.gr_members_len;
+           ++i)
+	{
+	  cp =res->objects.objects_val[0].GR_data.gr_members.gr_members_val[i];
+	  if (cp[0] != '-')
+	    {
+	      if (strcmp (cp, principal) == 0)
+		return 1;
+	      if (cp[0] == '@')
+		switch (internal_ismember (principal, &cp[1]))
+		  {
+		  case -1:
+		    return -1;
+		  case 1:
+		    return 1;
+		  default:
+		    break;
+		  }
+	      else
+		if (cp[0] == '*')
+		  {
+		    char buf1[strlen (principal) + 2];
+		    char buf2[strlen (cp) + 2];
+
+		    strcpy (buf1, nis_domain_of (principal));
+		    strcpy (buf2, nis_domain_of (cp));
+		    if (strcmp (buf1, buf2) == 0)
+		      return 1;
+		  }
+	    }
+	}
+    }
+
+  return 0;
+}
+
+bool_t
+nis_ismember (const_nis_name principal, const_nis_name group)
+{
+  if (group != NULL && strlen (group) > 0)
+    {
+      int status;
+
+      status = internal_ismember (principal, group);
+      if (status == 1)
+	return TRUE;
+      else
+	return FALSE;
+    }
+  else
+    return FALSE;
+}
diff --git a/nis/nis_lookup.c b/nis/nis_lookup.c
new file mode 100644
index 0000000000..9173437bfa
--- /dev/null
+++ b/nis/nis_lookup.c
@@ -0,0 +1,157 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <string.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+#include "nis_intern.h"
+
+nis_result *
+nis_lookup (const_nis_name name, const u_long flags)
+{
+  nis_result *res;
+  struct ns_request req;
+  nis_name *names;
+  nis_error status;
+  int is_link = 1;	 /* We should go at least once in the while loop */
+  int count_links = 0;	 /* We will follow only 16 links in the deep */
+  int i;
+
+  res = calloc (1, sizeof (nis_result));
+
+  if (flags & EXPAND_NAME)
+    {
+      names = __nis_expandname (name);
+      if (names == NULL)
+	{
+	  res->status = NIS_NAMEUNREACHABLE;
+	  return res;
+	}
+
+      i = 0;
+      while (names[i] != NULL && (i == 0 || res->status > 1))
+	{
+	  req.ns_name = names[i];
+
+	  while (is_link)
+	    {
+	      req.ns_object.ns_object_len = 0;
+	      req.ns_object.ns_object_val = NULL;
+	      memset (res, '\0', sizeof (nis_result));
+
+	      if ((status = __do_niscall (NULL, 0, NIS_LOOKUP,
+					  (xdrproc_t) xdr_ns_request,
+					  (caddr_t) & req,
+					  (xdrproc_t) xdr_nis_result,
+				      (caddr_t) res, flags)) != RPC_SUCCESS)
+		{
+		  res->status = status;
+		  nis_freenames (names);
+		  return res;
+		}
+
+	      if ((res->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS)
+		  && (res->objects.objects_len > 0 &&
+		      res->objects.objects_val->zo_data.zo_type == LINK_OBJ))
+		is_link = 1;
+	      else
+		is_link = 0;
+
+	      if (is_link)
+		{
+		  if ((flags & FOLLOW_LINKS) == FOLLOW_LINKS)
+		    {
+		      if (count_links == 16)
+			{
+			  res->status = NIS_LINKNAMEERROR;
+			  return res;
+			}
+		      else
+			++count_links;
+
+		      req.ns_name = res->objects.objects_val->LI_data.li_name;
+		    }
+		  else
+		    {
+		      res->status = NIS_NOTSEARCHABLE;
+		      return res;
+		    }
+		}
+	    }
+
+	  ++i;
+	  if (res->status == NIS_NOT_ME)
+	    res->status = NIS_NOSUCHNAME;
+	}
+
+      nis_freenames (names);
+    }
+  else
+    {
+      req.ns_name = (char *)name;
+
+      while (is_link)
+	{
+	  req.ns_object.ns_object_len = 0;
+	  req.ns_object.ns_object_val = NULL;
+	  memset (res, '\0', sizeof (nis_result));
+
+	  if ((status = __do_niscall (NULL, 0, NIS_LOOKUP,
+				      (xdrproc_t) xdr_ns_request,
+				      (caddr_t) &req,
+				      (xdrproc_t) xdr_nis_result,
+				      (caddr_t) res, flags)) != RPC_SUCCESS)
+	    {
+	      res->status = status;
+	      return res;
+	    }
+
+	  if ((res->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS) &&
+	      (res->objects.objects_len > 0 &&
+	       res->objects.objects_val->zo_data.zo_type == LINK_OBJ))
+	    is_link = 1;
+	  else
+	    is_link = 0;
+
+	  if (is_link)
+	    {
+	      if ((flags & FOLLOW_LINKS) == FOLLOW_LINKS)
+		{
+		  if (count_links == 16)
+		    {
+		      res->status = NIS_LINKNAMEERROR;
+		      return res;
+		    }
+		  else
+		    ++count_links;
+
+		  req.ns_name = res->objects.objects_val->LI_data.li_name;
+		}
+	      else
+		{
+		  res->status = NIS_NOTSEARCHABLE;
+		  return res;
+		}
+	    }
+	}
+    }
+
+  return res;
+}
diff --git a/nis/nis_mkdir.c b/nis/nis_mkdir.c
new file mode 100644
index 0000000000..a781c041ba
--- /dev/null
+++ b/nis/nis_mkdir.c
@@ -0,0 +1,46 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA. */
+
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+#include "nis_intern.h"
+
+nis_error
+nis_mkdir (const_nis_name dir, const nis_server *server)
+{
+  nis_error res;
+
+  if (server == NULL)
+    {
+      if (__do_niscall (NULL, 0, NIS_MKDIR, (xdrproc_t) xdr_nis_name,
+			(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
+			(caddr_t) &res, 0) != RPC_SUCCESS)
+	return NIS_RPCERROR;
+    }
+  else
+    {
+      if (__do_niscall (server, 1, NIS_MKDIR,
+			(xdrproc_t) xdr_nis_name,
+			(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
+			(caddr_t) &res, 0) != RPC_SUCCESS)
+	return NIS_RPCERROR;
+    }
+
+  return res;
+}
diff --git a/nis/nis_modify.c b/nis/nis_modify.c
new file mode 100644
index 0000000000..9c371c03bc
--- /dev/null
+++ b/nis/nis_modify.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+#include "nis_intern.h"
+
+nis_result *
+nis_modify (const_nis_name name, const nis_object *obj)
+{
+  nis_result *res;
+  nis_error status;
+  struct ns_request req;
+
+  res = calloc (1, sizeof (nis_result));
+
+  req.ns_name = (char *)name;
+
+  req.ns_object.ns_object_len = 1;
+  req.ns_object.ns_object_val = nis_clone_object (obj, NULL);
+
+  if ((status = __do_niscall (NULL, 0, NIS_MODIFY, (xdrproc_t) xdr_ns_request,
+			      (caddr_t) & req, (xdrproc_t) xdr_nis_result,
+			      (caddr_t) res, MASTER_ONLY)) != RPC_SUCCESS)
+    res->status = status;
+
+  nis_destroy_object (req.ns_object.ns_object_val);
+
+  return res;
+}
diff --git a/nis/nis_ping.c b/nis/nis_ping.c
new file mode 100644
index 0000000000..0aa56ed37e
--- /dev/null
+++ b/nis/nis_ping.c
@@ -0,0 +1,63 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA. */
+
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+#include "nis_intern.h"
+
+void
+nis_ping (const_nis_name dirname, u_long utime, const nis_object *dirobj)
+{
+  nis_result *res = NULL;
+  nis_object *obj;
+  ping_args args;
+  u_int i;
+
+  if (dirname == NULL && dirobj == NULL)
+    abort ();
+
+  if (dirobj == NULL)
+    {
+      res = nis_lookup (dirname, EXPAND_NAME + FOLLOW_LINKS);
+      if (res->status != NIS_SUCCESS && res->status != NIS_S_SUCCESS)
+	return;
+      obj = res->objects.objects_val;
+    }
+  else
+    obj = (nis_object *)dirobj;
+
+  /* Check if obj is really a diryectory object */
+  if (obj->zo_data.zo_type != DIRECTORY_OBJ)
+    abort ();
+
+  if (dirname == NULL)
+    args.dir = obj->DI_data.do_name;
+  else
+    args.dir = (char *)dirname;
+  args.stamp = utime;
+
+  for (i = 0; i < obj->DI_data.do_servers.do_servers_len; ++i)
+    __do_niscall (&obj->DI_data.do_servers.do_servers_val[i], 1,
+		  NIS_PING, (xdrproc_t) xdr_ping_args,
+		  (caddr_t) &args, (xdrproc_t) xdr_void,
+		  (caddr_t) NULL, 0);
+
+  if (res)
+    nis_freeresult (res);
+}
diff --git a/nis/nis_print_group_entry.c b/nis/nis_print_group_entry.c
new file mode 100644
index 0000000000..e7c866cbe2
--- /dev/null
+++ b/nis/nis_print_group_entry.c
@@ -0,0 +1,59 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+void
+nis_print_group_entry (const_nis_name group)
+{
+  if (group != NULL && strlen (group) > 0)
+    {
+      char buf[strlen (group) + 50];
+      char leafbuf[strlen (group) + 3];
+      char domainbuf[strlen (group) + 3];
+      nis_result *res;
+      char *cp, *cp2;
+      u_int i;
+
+      cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1));
+      cp = stpcpy (cp, ".groups_dir");
+      cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1);
+      if (cp2 != NULL && strlen (cp2) > 0)
+	{
+	  cp = stpcpy (cp, ".");
+	  strcpy (cp, cp2);
+	}
+      res = nis_lookup (buf, FOLLOW_LINKS|EXPAND_NAME);
+
+      if (res->status != NIS_SUCCESS && res->status != NIS_S_SUCCESS)
+	return;
+
+      if ((res->objects.objects_len != 1) ||
+          (res->objects.objects_val[0].zo_data.zo_type != GROUP_OBJ))
+	return;
+
+      for (i = 0;
+	   i < res->objects.objects_val[0].GR_data.gr_members.gr_members_len;
+	   ++i)
+	fprintf (stdout, "  %s\n",
+		 res->objects.objects_val[0].GR_data.gr_members.gr_members_val[i]);
+    }
+}
diff --git a/nis/nis_remove.c b/nis/nis_remove.c
new file mode 100644
index 0000000000..0415dca731
--- /dev/null
+++ b/nis/nis_remove.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+#include "nis_intern.h"
+
+nis_result *
+nis_remove (const_nis_name name, const nis_object *obj)
+{
+  nis_result *res;
+  nis_error status;
+  struct ns_request req;
+
+  res = calloc (1, sizeof (nis_result));
+
+  req.ns_name = (char *)name;
+
+  if (obj != NULL)
+    {
+      req.ns_object.ns_object_len = 1;
+      req.ns_object.ns_object_val = nis_clone_object (obj, NULL);
+    }
+  else
+    {
+      req.ns_object.ns_object_len = 0;
+      req.ns_object.ns_object_val = NULL;
+    }
+
+  if ((status = __do_niscall (NULL, 0, NIS_REMOVE, (xdrproc_t) xdr_ns_request,
+			      (caddr_t) & req, (xdrproc_t) xdr_nis_result,
+			      (caddr_t) res, MASTER_ONLY)) != RPC_SUCCESS)
+    res->status = status;
+
+  nis_destroy_object (req.ns_object.ns_object_val);
+
+  return res;
+}
diff --git a/nis/nis_removemember.c b/nis/nis_removemember.c
new file mode 100644
index 0000000000..473438ba5c
--- /dev/null
+++ b/nis/nis_removemember.c
@@ -0,0 +1,80 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+nis_error
+nis_removemember (const_nis_name member, const_nis_name group)
+{
+  if (group != NULL && strlen (group) > 0)
+    {
+      char buf[strlen (group) + 50];
+      char leafbuf[strlen (group) + 2];
+      char domainbuf[strlen (group) + 2];
+      nis_name *newmem;
+      nis_result *res, *res2;
+      nis_error status;
+      char *cp, *cp2;
+      u_int i, j;
+
+      cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1));
+      cp = stpcpy (cp, ".groups_dir");
+      cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1);
+      if (cp2 != NULL && strlen (cp2) > 0)
+        {
+          cp = stpcpy (cp, ".");
+          strcpy (cp, cp2);
+        }
+      res = nis_lookup (buf, FOLLOW_LINKS|EXPAND_NAME);
+      if (res->status != NIS_SUCCESS)
+        {
+          status = res->status;
+          nis_freeresult (res);
+          return status;
+        }
+      if ((res->objects.objects_len != 1) ||
+          (res->objects.objects_val[0].zo_data.zo_type != GROUP_OBJ))
+        return NIS_INVALIDOBJ;
+
+      newmem = malloc (res->objects.objects_val[0].GR_data.gr_members.gr_members_len);
+
+      j = 0;
+      for (i = 0; i < res->objects.objects_val[0].GR_data.gr_members.gr_members_len - 1; ++i)
+	{
+	  if (strcmp (res->objects.objects_val[0].GR_data.gr_members.gr_members_val[j], member) != 0)
+	    {
+	      newmem[j] = res->objects.objects_val[0].GR_data.gr_members.gr_members_val[i];
+	      ++j;
+	    }
+	}
+      --res->objects.objects_val[0].GR_data.gr_members.gr_members_len;
+      free (res->objects.objects_val[0].GR_data.gr_members.gr_members_val);
+      res->objects.objects_val[0].GR_data.gr_members.gr_members_val = newmem;
+      res2 = nis_modify (buf, res->objects.objects_val);
+      status = res2->status;
+      nis_freeresult (res);
+      nis_freeresult (res2);
+
+      return status;
+    }
+  else
+    return NIS_FAIL;
+}
diff --git a/nis/nis_rmdir.c b/nis/nis_rmdir.c
new file mode 100644
index 0000000000..5b6f1d181b
--- /dev/null
+++ b/nis/nis_rmdir.c
@@ -0,0 +1,46 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA. */
+
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+#include "nis_intern.h"
+
+nis_error
+nis_rmdir (const_nis_name dir, const nis_server *server)
+{
+  nis_error res;
+
+  if (server == NULL)
+    {
+      if (__do_niscall (NULL, 0, NIS_RMDIR, (xdrproc_t) xdr_nis_name,
+			(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
+			(caddr_t) &res, 0) != RPC_SUCCESS)
+	return NIS_RPCERROR;
+    }
+  else
+    {
+      if (__do_niscall (server, 1, NIS_RMDIR,
+			(xdrproc_t) xdr_nis_name,
+			(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
+			(caddr_t) &res, 0) != RPC_SUCCESS)
+	return NIS_RPCERROR;
+    }
+
+  return res;
+}
diff --git a/nis/nis_server.c b/nis/nis_server.c
index 431fbe7f2a..393f6c6eb4 100644
--- a/nis/nis_server.c
+++ b/nis/nis_server.c
@@ -17,93 +17,104 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA. */
 
+#include <string.h>
 #include <rpcsvc/nis.h>
 #include <rpcsvc/nislib.h>
 #include "nis_intern.h"
 
 nis_error
-nis_mkdir (const_nis_name dir, const nis_server *server)
+nis_servstate (const nis_server *serv, const nis_tag *tags,
+	       const int numtags, nis_tag **result)
 {
-  nis_error res;
+  nis_taglist taglist;
+  nis_taglist tagres;
+
+  tagres.tags.tags_len = 0;
+  tagres.tags.tags_val = NULL;
+  *result = NULL;
+  taglist.tags.tags_len = numtags;
+  taglist.tags.tags_val = (nis_tag *)tags;
 
-  if (server == NULL)
+  if (serv == NULL)
     {
-      int result;
-      if ((result = __do_niscall (NULL, 0, NIS_MKDIR, (xdrproc_t) xdr_nis_name,
-				  (caddr_t) &dir, (xdrproc_t) xdr_nis_error,
-				  (caddr_t) &res, 0)) != RPC_SUCCESS)
-	{
-	  fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
-	  return NIS_RPCERROR;
-	}
+      if (__do_niscall (NULL, 0, NIS_SERVSTATE, (xdrproc_t) xdr_nis_taglist,
+			(caddr_t) &taglist, (xdrproc_t) xdr_nis_taglist,
+			(caddr_t) &tagres, 0) != RPC_SUCCESS)
+	return NIS_RPCERROR;
     }
   else
     {
-      int result;
-      if ((result = __do_niscall (server, 1, NIS_MKDIR,
-				  (xdrproc_t) xdr_nis_name,
-				  (caddr_t) &dir, (xdrproc_t) xdr_nis_error,
-				  (caddr_t) &res, 0)) != RPC_SUCCESS)
+      if (__do_niscall (serv, 1, NIS_SERVSTATE, (xdrproc_t) xdr_nis_taglist,
+			(caddr_t) &taglist, (xdrproc_t) xdr_nis_taglist,
+			(caddr_t) &tagres, 0) != RPC_SUCCESS)
+	return NIS_RPCERROR;
+    }
+  if (tagres.tags.tags_len > 0)
+    {
+      u_long i;
+
+      result = malloc (sizeof (nis_tag *) * tagres.tags.tags_len);
+      if (result == NULL)
+	return NIS_NOMEMORY;
+      for (i = 0; i < tagres.tags.tags_len; ++i)
 	{
-	  fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
-	  return NIS_RPCERROR;
+	  result[i] = malloc (sizeof (nis_tag));
+	  if (result[i] == NULL)
+	    return NIS_NOMEMORY;
+	  result[i]->tag_val = strdup (tagres.tags.tags_val[i].tag_val);
+	  result[i]->tag_type = tagres.tags.tags_val[i].tag_type;
 	}
     }
 
-  return res;
+  return NIS_SUCCESS;
 }
 
 nis_error
-nis_rmdir (const_nis_name dir, const nis_server *server)
+nis_stats (const nis_server *serv, const nis_tag *tags,
+	   const int numtags, nis_tag **result)
 {
-  nis_error res;
+  nis_taglist taglist;
+  nis_taglist tagres;
 
-  if (server == NULL)
+  tagres.tags.tags_len = 0;
+  tagres.tags.tags_val = NULL;
+  *result = NULL;
+  taglist.tags.tags_len = numtags;
+  taglist.tags.tags_val = (nis_tag *)tags;
+
+  if (serv == NULL)
     {
-      int result;
-      if ((result = __do_niscall (NULL, 0, NIS_RMDIR, (xdrproc_t) xdr_nis_name,
-				  (caddr_t) &dir, (xdrproc_t) xdr_nis_error,
-				  (caddr_t) &res, 0)) != RPC_SUCCESS)
-	{
-	  fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
-	  return NIS_RPCERROR;
-	}
+      if (__do_niscall (NULL, 0, NIS_STATUS, (xdrproc_t) xdr_nis_taglist,
+			(caddr_t) &taglist, (xdrproc_t) xdr_nis_taglist,
+			(caddr_t) &tagres, 0) != RPC_SUCCESS)
+	return NIS_RPCERROR;
     }
   else
     {
-      int result;
-      if ((result = __do_niscall (server, 1, NIS_RMDIR,
-				  (xdrproc_t) xdr_nis_name,
-				  (caddr_t) &dir, (xdrproc_t) xdr_nis_error,
-				  (caddr_t) &res, 0)) != RPC_SUCCESS)
+      if (__do_niscall (serv, 1, NIS_STATUS, (xdrproc_t) xdr_nis_taglist,
+			(caddr_t) &taglist, (xdrproc_t) xdr_nis_taglist,
+			(caddr_t) &tagres, 0) != RPC_SUCCESS)
+	return NIS_RPCERROR;
+    }
+  if (tagres.tags.tags_len > 0)
+    {
+      u_long i;
+
+      result = malloc (sizeof (nis_tag *) * tagres.tags.tags_len);
+      if (result == NULL)
+	return NIS_NOMEMORY;
+      for (i = 0; i < tagres.tags.tags_len; ++i)
 	{
-	  fprintf (stderr, _("__do_niscall: Error #%d\n"), result);
-	  return NIS_RPCERROR;
+	  result[i] = malloc (sizeof (nis_tag));
+	  if (result[i] == NULL)
+	    return NIS_NOMEMORY;
+	  result[i]->tag_val = strdup (tagres.tags.tags_val[i].tag_val);
+	  result[i]->tag_type = tagres.tags.tags_val[i].tag_type;
 	}
     }
 
-  return res;
-}
-
-nis_error
-nis_servstate (const nis_server *serv, const nis_tag *tags,
-	       const int numtags, nis_tag **result)
-{
-  *result = NULL;
-  return NIS_FAIL;
-}
-stub_warning (nis_servstate)
-
-nis_error
-nis_stats (const nis_server *serv, const nis_tag *tags,
-	   const int numtags, nis_tag **result)
-{
-  result = malloc (sizeof (nis_tag *));
-  if (result != NULL)
-    result[0] = NULL;
-  return NIS_FAIL;
+  return NIS_SUCCESS;
 }
-stub_warning (nis_stats);
 
 void
 nis_freetags (nis_tag *tags, const int numtags)
@@ -114,30 +125,3 @@ nis_freetags (nis_tag *tags, const int numtags)
     free (tags->tag_val);
   free (tags);
 }
-
-nis_server **
-nis_getservlist (const_nis_name dir)
-{
-  nis_server **serv;
-
-  serv = malloc (sizeof (nis_server *));
-  if (serv != NULL)
-    serv[0] = NULL;
-
-  return serv;
-}
-stub_warning (nis_getservlist);
-
-void
-nis_freeservlist (nis_server **serv)
-{
-  int i;
-
-  if (serv == NULL)
-    return;
-
-  i = 0;
-  while (serv[i] != NULL)
-    nis_free_servers (serv[i], 1);
-  free (serv);
-}
diff --git a/nis/nis_subr.c b/nis/nis_subr.c
index 479e11d175..780c27f7b5 100644
--- a/nis/nis_subr.c
+++ b/nis/nis_subr.c
@@ -46,8 +46,16 @@ nis_leaf_of_r (const_nis_name name, char *buffer, size_t buflen)
       return NULL;
     }
 
-  if (i > 1)
-    strncpy (buffer, name, i - 1);
+  if (i > 0)
+    {
+      if ((size_t)i >= buflen)
+	{
+	  errno = ERANGE;
+	  return NULL;
+	}
+      strncpy (buffer, name, i);
+      buffer[i] = 0;
+    }
 
   return buffer;
 }
@@ -89,38 +97,6 @@ nis_name_of_r (const_nis_name name, char *buffer, size_t buflen)
   return buffer;
 }
 
-nis_name
-nis_domain_of (const_nis_name name)
-{
-  static char result[NIS_MAXNAMELEN + 1];
-
-  return nis_domain_of_r (name, result, NIS_MAXNAMELEN);
-}
-
-nis_name
-nis_domain_of_r (const_nis_name name, char *buffer, size_t buflen)
-{
-  char *cptr;
-  size_t cptr_len;
-
-  cptr = strchr (name, '.');	/* XXX What happens if the NIS name
-				   does not contain a `.'?  */
-  ++cptr;
-  cptr_len = strlen (cptr);
-
-  if (cptr_len == 0)
-    strcpy (buffer, ".");
-  else if (cptr_len >= buflen)
-    {
-      errno = ERANGE;
-      return NULL;
-    }
-  else
-    memcpy (buffer, cptr, cptr_len + 1);
-
-  return buffer;
-}
-
 static int
 count_dots (const_nis_name str)
 {
diff --git a/nis/nis_verifygroup.c b/nis/nis_verifygroup.c
new file mode 100644
index 0000000000..e57f16589a
--- /dev/null
+++ b/nis/nis_verifygroup.c
@@ -0,0 +1,51 @@
+/* Copyright (c) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA. */
+
+#include <string.h>
+#include <rpcsvc/nis.h>
+#include <rpcsvc/nislib.h>
+
+nis_error
+nis_verifygroup (const_nis_name group)
+{
+  if (group != NULL && strlen (group) > 0)
+    {
+      char buf[strlen (group) + 50];
+      char leafbuf[strlen (group) + 2];
+      char domainbuf[strlen (group) + 2];
+      nis_result *res;
+      nis_error status;
+      char *cp, *cp2;
+
+      cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1));
+      cp = stpcpy (cp, ".groups_dir");
+      cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1);
+      if (cp2 != NULL && strlen (cp2) > 0)
+	{
+	  cp = stpcpy (cp, ".");
+	  strcpy (cp, cp2);
+	}
+      res = nis_lookup (buf, 0);
+      status = res->status;
+      nis_freeresult (res);
+      return status;
+    }
+  else
+    return NIS_FAIL;
+}
diff --git a/nis/rpcsvc/nislib.h b/nis/rpcsvc/nislib.h
index fa3ee4f65d..cbd8fbde51 100644
--- a/nis/rpcsvc/nislib.h
+++ b/nis/rpcsvc/nislib.h
@@ -29,58 +29,58 @@ typedef const char *const_nis_name;
 /* nis_names: These functions are used to locate and manipulate all NIS+
  * objects except the NIS+ entry objects.
  *
- * nis_lookup (name, flags) resolves a NIS+ name and returns a copy of 
+ * nis_lookup (name, flags) resolves a NIS+ name and returns a copy of
  *                          that object  from a NIS+ server.
  *    const nis_name name: name of the object to be resolved
- *    u_long flags: logically ORing zero or more flags (FOLLOW_LINKS, 
- *                  HARD_LOOKUP, [NO_CACHE], MASTER_ONLY, EXPAND_NAME) 
- *   
+ *    u_long flags: logically ORing zero or more flags (FOLLOW_LINKS,
+ *                  HARD_LOOKUP, [NO_CACHE], MASTER_ONLY, EXPAND_NAME)
+ *
  * nis_add (name, obj) adds objects to the NIS+ namespace.
  *    const nis_name name: fully qualified NIS+ name.
- *    const nis_object *obj: object members zo_name and zo_domain will be 
+ *    const nis_object *obj: object members zo_name and zo_domain will be
  *                           constructed from name.
  *
  * nis_remove (name, obj) removes objects from the NIS+ namespace.
  *    const nis_name name: fully qualified NIS+ name.
- *    const nis_object *obj: if not NULL, it is assumed to point to a copy 
- *                           of the object being removed. In this case, if 
+ *    const nis_object *obj: if not NULL, it is assumed to point to a copy
+ *                           of the object being removed. In this case, if
  *                           the object on the server does not have the same
  *                           object identifier as the  object  being  passed,
- *                           the operation will fail with the NIS_NOTSAMEOBJ 
+ *                           the operation will fail with the NIS_NOTSAMEOBJ
  *                           error.
  *
- * nis_modify (name, obj) can change specific attributes of an object 
+ * nis_modify (name, obj) can change specific attributes of an object
  *                        that already exists in the namespace.
  */
 extern nis_result *nis_lookup __P ((const_nis_name name, u_long flags));
 extern nis_result *nis_add __P ((const_nis_name name, const nis_object *obj));
 extern nis_result *nis_remove __P ((const_nis_name name,
 				    const nis_object *obj));
-extern nis_result *nis_modify __P ((const_nis_name name, 
+extern nis_result *nis_modify __P ((const_nis_name name,
 				    const nis_object *obj));
 
 /* nis_tables: These functions are used to search and modify NIS+ tables.
  *
- * nis_list (table_name, flags, callback(table_name, obj, userdata), userdata) 
+ * nis_list (table_name, flags, callback(table_name, obj, userdata), userdata)
  *           search a table in the NIS+ namespace.
  *    const nis_name table_name: indexed name ([xx=yy],table.dir)
  *    u_long flags: logically ORing one or more flags (FOLLOW_LINKS,
  *                  [FOLLOW_PATH], HARD_LOOKUP, [ALL_RESULTS], [NO_CACHE],
  *                  MASTER_ONLY, EXPAND_NAME, RETURN_RESULT)
- *    callback(): callback is an optional pointer to a function that will 
- *                process the ENTRY type objects that are returned from the 
+ *    callback(): callback is an optional pointer to a function that will
+ *                process the ENTRY type objects that are returned from the
  *                search. If this pointer is NULL, then all entries that match
  *                the search criteria are returned in the nis_result structure,
- *                otherwise  this  function  will  be  called once for each 
+ *                otherwise  this  function  will  be  called once for each
  *                entry returned.
- *    void *userdata: passed to callback function along with the returned 
+ *    void *userdata: passed to callback function along with the returned
  *                    entry object.
  *
  * nis_add_entry (table_name, obj, flags) will add the NIS+ object to the
  *                                        NIS+ table_name.
  *    const nis_name table_name
  *    const nis_object *obj
- *    u_long flags: 0, ADD_OVERWRITE, RETURN_RESULT 
+ *    u_long flags: 0, ADD_OVERWRITE, RETURN_RESULT
  *
  * nis_modify_entry (name, obj, flags) modifies an object identified by name.
  *    const nis_name name: object identifier
@@ -95,15 +95,15 @@ extern nis_result *nis_modify __P ((const_nis_name name,
  *    const nis_object *obj: if obj is non-null, it is presumed to point to
  *                           a cached copy of the entry. When the removal is
  *                           attempted, and the object that would be removed
- *                           is not the same as the cached object pointed to 
- *                           by object then the operation will fail with an 
+ *                           is not the same as the cached object pointed to
+ *                           by object then the operation will fail with an
  *                           NIS_NOTSAMEOBJ error
  *    u_long flags: 0, REM_MULTIPLE
  *
  * nis_first_entry (table_name) fetches entries from a table one at a time.
  *    const nis_name table_name
  *
- * nis_next_entry (table_name, cookie) retrieves the "next" entry from a 
+ * nis_next_entry (table_name, cookie) retrieves the "next" entry from a
  *                                     table specified by table_name.
  *    const nis_name table_name:
  *    const netobj *cookie: The value of cookie from the nis_result structure
@@ -117,25 +117,25 @@ extern nis_result *nis_list __P ((const_nis_name name, u_long flags,
 extern nis_result *nis_add_entry __P ((const_nis_name table_name,
 				       const nis_object *obj, u_long flags));
 extern nis_result *nis_modify_entry __P ((const_nis_name name,
-					  const nis_object *obj, 
+					  const nis_object *obj,
 					  u_long flags));
 extern nis_result *nis_remove_entry __P ((const_nis_name table_name,
 					  const nis_object *obj,
 					  u_long flags));
 extern nis_result *nis_first_entry __P ((const_nis_name table_name));
-extern nis_result *nis_next_entry __P ((const_nis_name table_name, 
+extern nis_result *nis_next_entry __P ((const_nis_name table_name,
 					const netobj *cookie));
 /*
 ** nis_server
 */
-extern nis_error nis_mkdir __P ((const_nis_name dirname, 
+extern nis_error nis_mkdir __P ((const_nis_name dirname,
 				 const nis_server *machine));
-extern nis_error nis_rmdir __P ((const_nis_name dirname, 
+extern nis_error nis_rmdir __P ((const_nis_name dirname,
 				 const nis_server *machine));
-extern nis_error nis_servstate __P ((const nis_server *machine, 
-				     const nis_tag *tags, int numtags, 
+extern nis_error nis_servstate __P ((const nis_server *machine,
+				     const nis_tag *tags, int numtags,
 				     nis_tag **result));
-extern nis_error nis_stats __P ((const nis_server *machine, 
+extern nis_error nis_stats __P ((const nis_server *machine,
 				 const nis_tag *tags, int numtags,
 				 nis_tag **result));
 extern void nis_freetags __P ((nis_tag *tags, int numtags));
@@ -146,7 +146,7 @@ extern void nis_freeservlist __P ((nis_server **machines));
 ** nis_subr
 */
 extern nis_name nis_leaf_of __P ((const_nis_name name));
-extern nis_name nis_leaf_of_r __P ((const_nis_name name, char *buffer, 
+extern nis_name nis_leaf_of_r __P ((const_nis_name name, char *buffer,
 				    size_t buflen));
 extern nis_name nis_name_of __P ((const_nis_name name));
 extern nis_name nis_name_of_r __P ((const_nis_name name, char *buffer,
@@ -157,7 +157,7 @@ extern nis_name nis_domain_of_r __P ((const_nis_name name, char *buffer,
 extern nis_name *nis_getnames __P ((const_nis_name name));
 extern void nis_freenames __P ((nis_name *namelist));
 extern name_pos nis_dir_cmp __P ((const_nis_name n1, const_nis_name n2));
-extern nis_object *nis_clone_object __P ((const nis_object *src, 
+extern nis_object *nis_clone_object __P ((const nis_object *src,
 					  nis_object *dest));
 extern void nis_destroy_object __P ((nis_object *obj));
 extern void nis_print_object __P ((const nis_object *obj));
@@ -182,11 +182,11 @@ extern char *nis_sperror_r __P ((const nis_error status, const char *label,
 /*
 ** nis_groups
 */
-extern bool_t nis_ismember __P ((const_nis_name principal, 
+extern bool_t nis_ismember __P ((const_nis_name principal,
 				 const_nis_name group));
-extern nis_error nis_addmember __P ((const_nis_name member, 
+extern nis_error nis_addmember __P ((const_nis_name member,
 				     const_nis_name group));
-extern nis_error nis_removemember __P ((const_nis_name member, 
+extern nis_error nis_removemember __P ((const_nis_name member,
 					const_nis_name group));
 extern nis_error nis_creategroup __P ((const_nis_name group, u_long flags));
 extern nis_error nis_destroygroup __P ((const_nis_name group));
@@ -224,20 +224,18 @@ extern bool_t nis_write_obj __P ((const char *file, const nis_object *obj));
 */
 extern directory_obj *nis_clone_directory __P ((const directory_obj *src,
 						directory_obj *dest));
-extern group_obj *nis_clone_group __P ((const group_obj *src, 
+extern group_obj *nis_clone_group __P ((const group_obj *src,
 					group_obj *dest));
-extern table_obj *nis_clone_table __P ((const table_obj *src, 
+extern table_obj *nis_clone_table __P ((const table_obj *src,
 					table_obj *dest));
-extern entry_obj *nis_clone_entry __P ((const entry_obj *src, 
+extern entry_obj *nis_clone_entry __P ((const entry_obj *src,
 					entry_obj *dest));
 extern link_obj *nis_clone_link __P ((const link_obj *src, link_obj *dest));
 extern objdata *nis_clone_objdata __P ((const objdata *src, objdata *dest));
-extern nis_result *nis_clone_result __P ((const nis_result *src, 
+extern nis_result *nis_clone_result __P ((const nis_result *src,
 					  nis_result *dest));
 
-/*
-** nis_free - nis_freeresult
-*/
+/* nis_free - nis_freeresult */
 extern void nis_freeresult __P ((nis_result *result));
 /* (XXX THE FOLLOWING ARE INTERNAL FUNCTIONS, SHOULD NOT BE USED !!) */
 extern void nis_free_attr __P ((nis_attr *attr));
@@ -251,12 +249,15 @@ extern void nis_free_entry __P ((entry_obj *enobj));
 extern void nis_free_link __P ((link_obj *lnkobj));
 extern void nis_free_object __P ((nis_object *obj));
 
-/* This is the SUN definition, but I don't know for what we need
-   the directory_obj parameter */
-/* extern fd_result *nis_finddirectory __P ((directory_obj *, nis_name)); */
-extern fd_result *__nis_finddirectory __P ((const_nis_name name));
-extern int __start_clock(int);
-extern u_long __stop_clock(int);
+/* (XXX INTERNAL FUNCTIONS, SHOULD NOT BE USED !!) */
+extern nis_name __nis_default_owner __P ((char *));
+extern nis_name __nis_default_group __P ((char *));
+extern u_long __nis_default_ttl __P ((char *));
+extern u_long __nis_default_access __P ((char *, u_long));
+extern fd_result *__nis_finddirectory __P ((directory_obj *, nis_name));
+extern log_result *__nis_dumplog __P ((nis_server *,nis_name, u_long));
+extern log_result *__nis_dump __P ((nis_server *, nis_name,
+				    int (*)(nis_name, nis_object *, void *)));
 
 __END_DECLS