about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--NEWS6
-rw-r--r--nis/Makefile2
-rw-r--r--nis/nss_nis/nis-publickey.c234
-rw-r--r--nis/nss_nisplus/nisplus-publickey.c411
-rw-r--r--nss/Makefile3
-rw-r--r--nss/nss_files/files-key.c113
6 files changed, 9 insertions, 760 deletions
diff --git a/NEWS b/NEWS
index 03e82d8adc..d7282b4ad5 100644
--- a/NEWS
+++ b/NEWS
@@ -104,6 +104,12 @@ Deprecated and removed features, and other changes affecting compatibility:
   or contents might be overwritten on subsequent calls in the same thread or
   if the thread is terminated.  It makes strerror MT-safe.
 
+* The "files", "nis" and "nisplus" NSS modules no longer supports the
+  "key" database (used for secure RPC).  The contents of the
+  /etc/publickey file will be ignored, regardless of the settings in
+  /etc/nsswitch.conf.  (This method of storing RPC keys only supported
+  the obsolete and insecure AUTH_DES flavor of secure RPC.)
+
 Changes to build and runtime requirements:
 
 * powerpc64le requires GCC 7.4 or newer.  This is required for supporting
diff --git a/nis/Makefile b/nis/Makefile
index 6ce2199459..9ad5e1db7a 100644
--- a/nis/Makefile
+++ b/nis/Makefile
@@ -36,7 +36,7 @@ headers			:= $(wildcard rpcsvc/*.[hx])
 # These are the databases available for the nis (and perhaps later nisplus)
 # service.  This must be a superset of the services in nss.
 databases		= proto service hosts network grp pwd rpc ethers \
-			  spwd netgrp alias publickey
+			  spwd netgrp alias
 
 # Specify rules for the nss_* modules.
 services		:= nis nisplus
diff --git a/nis/nss_nis/nis-publickey.c b/nis/nss_nis/nis-publickey.c
deleted file mode 100644
index adbc04bf2d..0000000000
--- a/nis/nss_nis/nis-publickey.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#include <nss.h>
-#include <ctype.h>
-#include <errno.h>
-#include <string.h>
-#include <syslog.h>
-#include <rpc/rpc.h>
-#include <rpcsvc/yp.h>
-#include <rpcsvc/ypclnt.h>
-#include <rpc/key_prot.h>
-#include <rpc/des_crypt.h>
-
-#include "nss-nis.h"
-
-/* If we haven't found the entry, we give a SUCCESS and an empty key back.
-   Solaris docu says: sizeof (pkey) == HEXKEYBYTES + 1.
-*/
-enum nss_status
-_nss_nis_getpublickey (const char *netname, char *pkey, int *errnop)
-{
-  pkey[0] = 0;
-
-  if (netname == NULL)
-    {
-      *errnop = EINVAL;
-      return NSS_STATUS_UNAVAIL;
-    }
-
-  char *domain = strchr (netname, '@');
-  if (domain == NULL)
-    {
-      *errnop = EINVAL;
-      return NSS_STATUS_UNAVAIL;
-    }
-  ++domain;
-
-  char *result;
-  int len;
-  int yperr = yp_match (domain, "publickey.byname", netname, strlen (netname),
-			&result, &len);
-
-  if (__glibc_unlikely (yperr != YPERR_SUCCESS))
-    {
-      enum nss_status retval = yperr2nss (yperr);
-
-      if (retval == NSS_STATUS_TRYAGAIN)
-	*errnop = errno;
-      return retval;
-    }
-
-  if (result != NULL)
-    {
-      char *p = strchr (result, ':');
-      if (p != NULL)
-	*p = 0;
-      strncpy (pkey, result, HEXKEYBYTES + 1);
-      pkey[HEXKEYBYTES] = '\0';
-      free (result);
-    }
-  return NSS_STATUS_SUCCESS;
-}
-
-enum nss_status
-_nss_nis_getsecretkey (const char *netname, char *skey, char *passwd,
-		       int *errnop)
-{
-  skey[0] = 0;
-
-  if (netname == NULL || passwd == NULL)
-    {
-      *errnop = EINVAL;
-      return NSS_STATUS_UNAVAIL;
-    }
-
-  char *domain = strchr (netname, '@');
-  if (domain == NULL)
-    {
-      *errnop = EINVAL;
-      return NSS_STATUS_UNAVAIL;
-    }
-  ++domain;
-
-  char *result;
-  int len;
-  int yperr = yp_match (domain, "publickey.byname", netname, strlen (netname),
-			&result, &len);
-
-  if (__glibc_unlikely (yperr != YPERR_SUCCESS))
-    {
-      enum nss_status retval = yperr2nss (yperr);
-
-      if (retval == NSS_STATUS_TRYAGAIN)
-	*errnop = errno;
-      return retval;
-    }
-
-  if (result != NULL)
-    {
-      char *p = strchr (result, ':');
-      if (p != NULL)
-	{
-	  char buf[2 * (HEXKEYBYTES + 1)];
-
-	  ++p;
-	  strncpy (buf, p, 2 * (HEXKEYBYTES + 1));
-	  buf[2 * HEXKEYBYTES + 1] = '\0';
-	  if (xdecrypt (buf, passwd)
-	      && memcmp (buf, &(buf[HEXKEYBYTES]), KEYCHECKSUMSIZE) == 0)
-	    {
-	      buf[HEXKEYBYTES] = '\0';
-	      strcpy (skey, buf);
-	    }
-	}
-
-      free (result);
-    }
-  return NSS_STATUS_SUCCESS;
-}
-
-/* Parse uid and group information from the passed string.
-   The format of the string passed is uid:gid,grp,grp, ...  */
-static enum nss_status
-parse_netid_str (const char *s, uid_t *uidp, gid_t *gidp, int *gidlenp,
-		 gid_t *gidlist)
-{
-  char *p, *ep;
-  int gidlen;
-
-  if (!s || !isdigit (*s))
-    {
-      syslog (LOG_ERR, "netname2user: expecting uid '%s'", s);
-      return NSS_STATUS_NOTFOUND;	/* XXX need a better error */
-    }
-
-  /* Fetch the uid */
-  *uidp = strtoul (s, NULL, 10);
-
-  if (*uidp == 0)
-    {
-      syslog (LOG_ERR, "netname2user: should not have uid 0");
-      return NSS_STATUS_NOTFOUND;
-    }
-
-  /* Now get the group list */
-  p = strchr (s, ':');
-  if (!p)
-    {
-      syslog (LOG_ERR, "netname2user: missing group id list in '%s'", s);
-      return NSS_STATUS_NOTFOUND;
-    }
-  ++p;				/* skip ':' */
-  if (!p || (!isdigit (*p)))
-    {
-      syslog (LOG_ERR, "netname2user: missing group id list in '%s'.", p);
-      return NSS_STATUS_NOTFOUND;
-    }
-
-  *gidp = strtoul (p, &ep, 10);
-
-  gidlen = 0;
-
-  /* After strtoul() ep should point to the first invalid character.
-     This is the marker "," we search for the next value.  */
-  while (ep != NULL && *ep == ',')
-    {
-      ep++;
-      p = ep;
-      gidlist[gidlen++] = strtoul (p, &ep, 10);
-    }
-
-  *gidlenp = gidlen;
-
-  return NSS_STATUS_SUCCESS;
-}
-
-
-enum nss_status
-_nss_nis_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
-		       gid_t *gidp, int *gidlenp, gid_t *gidlist, int *errnop)
-{
-  char *domain = strchr (netname, '@');
-  if (domain == NULL)
-    {
-      *errnop = EINVAL;
-      return NSS_STATUS_UNAVAIL;
-    }
-
-  /* Point past the '@' character */
-  ++domain;
-  char *lookup = NULL;
-  int len;
-  int yperr = yp_match (domain, "netid.byname", netname, strlen (netname),
-			&lookup, &len);
-  switch (yperr)
-    {
-    case YPERR_SUCCESS:
-      break;			/* the successful case */
-    case YPERR_DOMAIN:
-    case YPERR_KEY:
-      return NSS_STATUS_NOTFOUND;
-    case YPERR_MAP:
-    default:
-      return NSS_STATUS_UNAVAIL;
-    }
-
-  if (lookup == NULL)
-    return NSS_STATUS_NOTFOUND;
-
-
-  lookup[len] = '\0';
-
-  enum nss_status err = parse_netid_str (lookup, uidp, gidp, gidlenp, gidlist);
-
-  free (lookup);
-
-  return err;
-}
diff --git a/nis/nss_nisplus/nisplus-publickey.c b/nis/nss_nisplus/nisplus-publickey.c
deleted file mode 100644
index ebbb3dafb2..0000000000
--- a/nis/nss_nisplus/nisplus-publickey.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/* Copyright (c) 1997-2020 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#include <nss.h>
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <libintl.h>
-#include <syslog.h>
-#include <rpc/rpc.h>
-#include <rpcsvc/nis.h>
-#include <rpc/key_prot.h>
-extern int xdecrypt (char *, char *);
-
-#include <nss-nisplus.h>
-
-/* If we haven't found the entry, we give a SUCCESS and an empty key back. */
-enum nss_status
-_nss_nisplus_getpublickey (const char *netname, char *pkey, int *errnop)
-{
-  nis_result *res;
-  enum nss_status retval;
-  char buf[NIS_MAXNAMELEN + 2];
-  size_t slen;
-  char *domain, *cptr;
-  int len;
-
-  pkey[0] = 0;
-
-  if (netname == NULL)
-    {
-      *errnop = EINVAL;
-      return NSS_STATUS_UNAVAIL;
-    }
-
-  domain = strchr (netname, '@');
-  if (!domain)
-    return NSS_STATUS_UNAVAIL;
-  domain++;
-
-  slen = snprintf (buf, NIS_MAXNAMELEN,
-		   "[auth_name=%s,auth_type=DES],cred.org_dir.%s",
-		   netname, domain);
-
-  if (slen >= NIS_MAXNAMELEN)
-    {
-      *errnop = EINVAL;
-      return NSS_STATUS_UNAVAIL;
-    }
-
-  if (buf[slen - 1] != '.')
-    {
-      buf[slen++] = '.';
-      buf[slen] = '\0';
-    }
-
-  res = nis_list (buf, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
-		  NULL, NULL);
-
-  if (res == NULL)
-    {
-      *errnop = ENOMEM;
-      return NSS_STATUS_TRYAGAIN;
-    }
-  retval = niserr2nss (res->status);
-
-  if (retval != NSS_STATUS_SUCCESS)
-    {
-      if (retval == NSS_STATUS_TRYAGAIN)
-	*errnop = errno;
-      if (res->status == NIS_NOTFOUND)
-	retval = NSS_STATUS_SUCCESS;
-      nis_freeresult (res);
-      return retval;
-    }
-
-  if (NIS_RES_NUMOBJ (res) > 1)
-    {
-      /*
-       * More than one principal with same uid?
-       * something wrong with cred table. Should be unique
-       * Warn user and continue.
-       */
-      syslog (LOG_ERR, _("DES entry for netname %s not unique\n"), netname);
-      nis_freeresult (res);
-      return NSS_STATUS_SUCCESS;
-    }
-
-  len = ENTRY_LEN (NIS_RES_OBJECT (res), 3);
-  memcpy (pkey, ENTRY_VAL (NIS_RES_OBJECT (res),3), len);
-  pkey[len] = 0;
-  cptr = strchr (pkey, ':');
-  if (cptr)
-    cptr[0] = '\0';
-  nis_freeresult (res);
-
-  return NSS_STATUS_SUCCESS;
-}
-
-
-enum nss_status
-_nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd,
-			   int *errnop)
-{
-  nis_result *res;
-  enum nss_status retval;
-  char buf[NIS_MAXNAMELEN + 2];
-  size_t slen;
-  char *domain, *cptr;
-  int len;
-
-  skey[0] = 0;
-
-  if (netname == NULL)
-    {
-      *errnop = EINVAL;
-      return NSS_STATUS_UNAVAIL;
-    }
-
-  domain = strchr (netname, '@');
-  if (!domain)
-    return NSS_STATUS_UNAVAIL;
-  domain++;
-
-  slen = snprintf (buf, NIS_MAXNAMELEN,
-		   "[auth_name=%s,auth_type=DES],cred.org_dir.%s",
-		   netname, domain);
-
-  if (slen >= NIS_MAXNAMELEN)
-    {
-      *errnop = EINVAL;
-      return NSS_STATUS_UNAVAIL;
-    }
-
-  if (buf[slen - 1] != '.')
-    {
-      buf[slen++] = '.';
-      buf[slen] = '\0';
-    }
-
-  res = nis_list (buf, USE_DGRAM | NO_AUTHINFO | FOLLOW_LINKS | FOLLOW_PATH,
-		  NULL, NULL);
-
-  if (res == NULL)
-    {
-      *errnop = ENOMEM;
-      return NSS_STATUS_TRYAGAIN;
-    }
-  retval = niserr2nss (res->status);
-
-  if (retval != NSS_STATUS_SUCCESS)
-    {
-      if (retval == NSS_STATUS_TRYAGAIN)
-	*errnop = errno;
-      nis_freeresult (res);
-      return retval;
-    }
-
-  if (NIS_RES_NUMOBJ (res) > 1)
-    {
-      /*
-       * More than one principal with same uid?
-       * something wrong with cred table. Should be unique
-       * Warn user and continue.
-       */
-      syslog (LOG_ERR, _("DES entry for netname %s not unique\n"), netname);
-      nis_freeresult (res);
-      return NSS_STATUS_SUCCESS;
-    }
-
-  len = ENTRY_LEN (NIS_RES_OBJECT (res), 4);
-  memcpy (buf, ENTRY_VAL (NIS_RES_OBJECT (res), 4), len);
-  buf[len] = '\0';
-  cptr = strchr (buf, ':');
-  if (cptr)
-    cptr[0] = '\0';
-  nis_freeresult (res);
-
-  if (!xdecrypt (buf, passwd))
-    return NSS_STATUS_SUCCESS;
-
-  if (memcmp (buf, &(buf[HEXKEYBYTES]), KEYCHECKSUMSIZE) != 0)
-    return NSS_STATUS_SUCCESS;
-
-  buf[HEXKEYBYTES] = 0;
-  strcpy (skey, buf);
-
-  return NSS_STATUS_SUCCESS;
-}
-
-
-/* Parse information from the passed string.
-   The format of the string passed is gid,grp,grp, ...  */
-static enum nss_status
-parse_grp_str (const char *s, gid_t *gidp, int *gidlenp, gid_t *gidlist,
-	       int *errnop)
-{
-  char *ep;
-  int gidlen;
-
-  if (!s || (!isdigit (*s)))
-    {
-      syslog (LOG_ERR, _("netname2user: missing group id list in `%s'"), s);
-      return NSS_STATUS_NOTFOUND;
-    }
-
-  *gidp = strtoul (s, &ep, 10);
-
-  gidlen = 0;
-
-  /* After strtoul() ep should point to the marker ',', which means
-     here starts a new value.
-
-     The Sun man pages show that GIDLIST should contain at least NGRPS
-     elements.  Limiting the number written by this value is the best
-     we can do.  */
-  while (ep != NULL && *ep == ',' && gidlen < NGRPS)
-    {
-      ep++;
-      s = ep;
-      gidlist[gidlen++] = strtoul (s, &ep, 10);
-    }
-  *gidlenp = gidlen;
-
-  return NSS_STATUS_SUCCESS;
-}
-
-enum nss_status
-_nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
-		       gid_t *gidp, int *gidlenp, gid_t *gidlist, int *errnop)
-{
-  char *domain;
-  nis_result *res;
-  char sname[NIS_MAXNAMELEN + 2]; /*  search criteria + table name */
-  size_t slen;
-  char principal[NIS_MAXNAMELEN + 1];
-  int len;
-
-  /* 1.  Get home domain of user. */
-  domain = strchr (netname, '@');
-  if (! domain)
-    return NSS_STATUS_UNAVAIL;
-
-  ++domain;  /* skip '@' */
-
-  /* 2.  Get user's nisplus principal name.  */
-  slen = snprintf (sname, NIS_MAXNAMELEN,
-		   "[auth_name=%s,auth_type=DES],cred.org_dir.%s",
-		   netname, domain);
-
-  if (slen >= NIS_MAXNAMELEN)
-    {
-      *errnop = EINVAL;
-      return NSS_STATUS_UNAVAIL;
-    }
-
-  if (sname[slen - 1] != '.')
-    {
-      sname[slen++] = '.';
-      sname[slen] = '\0';
-    }
-
-  /* must use authenticated call here */
-  /* XXX but we cant, for now. XXX */
-  res = nis_list (sname, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
-		  NULL, NULL);
-  if (res == NULL)
-    {
-      *errnop = ENOMEM;
-      return NSS_STATUS_TRYAGAIN;
-    }
-  switch (res->status)
-    {
-    case NIS_SUCCESS:
-    case NIS_S_SUCCESS:
-      break;   /* go and do something useful */
-    case NIS_NOTFOUND:
-    case NIS_PARTIAL:
-    case NIS_NOSUCHNAME:
-    case NIS_NOSUCHTABLE:
-      nis_freeresult (res);
-      return NSS_STATUS_NOTFOUND;
-    case NIS_S_NOTFOUND:
-    case NIS_TRYAGAIN:
-      syslog (LOG_ERR, _("netname2user: (nis+ lookup): %s\n"),
-	      nis_sperrno (res->status));
-      nis_freeresult (res);
-      *errnop = errno;
-      return NSS_STATUS_TRYAGAIN;
-    default:
-      syslog (LOG_ERR, _("netname2user: (nis+ lookup): %s\n"),
-	      nis_sperrno (res->status));
-      nis_freeresult (res);
-      return NSS_STATUS_UNAVAIL;
-    }
-
-  if (NIS_RES_NUMOBJ (res) > 1)
-    /*
-     * A netname belonging to more than one principal?
-     * Something wrong with cred table. should be unique.
-     * Warn user and continue.
-     */
-    syslog (LOG_ALERT,
-	    _("netname2user: DES entry for %s in directory %s not unique"),
-	    netname, domain);
-
-  len = ENTRY_LEN (NIS_RES_OBJECT (res), 0);
-  strncpy (principal, ENTRY_VAL (NIS_RES_OBJECT (res), 0), len);
-  principal[len] = '\0';
-  nis_freeresult (res);
-
-  if (principal[0] == '\0')
-    return NSS_STATUS_UNAVAIL;
-
-  /*
-   * 3.  Use principal name to look up uid/gid information in
-   *     LOCAL entry in **local** cred table.
-   */
-  domain = nis_local_directory ();
-  if (strlen (principal) + strlen (domain) + 45 > (size_t) NIS_MAXNAMELEN)
-    {
-      syslog (LOG_ERR, _("netname2user: principal name `%s' too long"),
-	      principal);
-      return NSS_STATUS_UNAVAIL;
-    }
-
-  slen = snprintf (sname, sizeof  (sname),
-		   "[cname=%s,auth_type=LOCAL],cred.org_dir.%s",
-		   principal, domain);
-
-  if (sname[slen - 1] != '.')
-    {
-      sname[slen++] = '.';
-      sname[slen] = '\0';
-    }
-
-  /* must use authenticated call here */
-  /* XXX but we cant, for now. XXX */
-  res = nis_list (sname, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
-		  NULL, NULL);
-  if (res == NULL)
-    {
-      *errnop = ENOMEM;
-      return NSS_STATUS_TRYAGAIN;
-    }
-  switch(res->status)
-    {
-    case NIS_NOTFOUND:
-    case NIS_PARTIAL:
-    case NIS_NOSUCHNAME:
-    case NIS_NOSUCHTABLE:
-      nis_freeresult (res);
-      return NSS_STATUS_NOTFOUND;
-    case NIS_S_NOTFOUND:
-    case NIS_TRYAGAIN:
-      syslog (LOG_ERR, _("netname2user: (nis+ lookup): %s\n"),
-	      nis_sperrno (res->status));
-      nis_freeresult (res);
-      *errnop = errno;
-      return NSS_STATUS_TRYAGAIN;
-    case NIS_SUCCESS:
-    case NIS_S_SUCCESS:
-      break;   /* go and do something useful */
-    default:
-      syslog (LOG_ERR, _("netname2user: (nis+ lookup): %s\n"),
-	      nis_sperrno (res->status));
-      nis_freeresult (res);
-      return NSS_STATUS_UNAVAIL;
-    }
-
-  if (NIS_RES_NUMOBJ (res) > 1)
-    /*
-     * A principal can have more than one LOCAL entry?
-     * Something wrong with cred table.
-     * Warn user and continue.
-     */
-    syslog (LOG_ALERT,
-	    _("netname2user: LOCAL entry for %s in directory %s not unique"),
-	    netname, domain);
-  /* Fetch the uid */
-  *uidp = strtoul (ENTRY_VAL (NIS_RES_OBJECT (res), 2), NULL, 10);
-
-  if (*uidp == 0)
-    {
-      syslog (LOG_ERR, _("netname2user: should not have uid 0"));
-      nis_freeresult (res);
-      return NSS_STATUS_NOTFOUND;
-    }
-
-  parse_grp_str (ENTRY_VAL (NIS_RES_OBJECT (res), 3),
-		 gidp, gidlenp, gidlist, errnop);
-
-  nis_freeresult (res);
-  return NSS_STATUS_SUCCESS;
-}
diff --git a/nss/Makefile b/nss/Makefile
index 97bab5bb75..cbb70167a9 100644
--- a/nss/Makefile
+++ b/nss/Makefile
@@ -93,7 +93,8 @@ subdir-dirs = $(services:%=nss_%)
 vpath %.c $(subdir-dirs) ../locale/programs ../intl
 
 
-libnss_files-routines	:= $(addprefix files-,$(databases)) \
+libnss_files-routines	:= $(addprefix files-, \
+			     $(filter-out key, $(databases))) \
 			   files-initgroups files-init
 
 libnss_db-dbs		:= $(addprefix db-,\
diff --git a/nss/nss_files/files-key.c b/nss/nss_files/files-key.c
deleted file mode 100644
index cf0a7d9ad9..0000000000
--- a/nss/nss_files/files-key.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* Public key file parser in nss_files module.
-   Copyright (C) 1996-2020 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <https://www.gnu.org/licenses/>.  */
-
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <netdb.h>
-#include <rpc/key_prot.h>
-#include <rpc/des_crypt.h>
-#include "nsswitch.h"
-
-NSS_DECLARE_MODULE_FUNCTIONS (files)
-
-#define DATAFILE "/etc/publickey"
-
-
-static enum nss_status
-search (const char *netname, char *result, int *errnop, int secret)
-{
-  FILE *stream = fopen (DATAFILE, "rce");
-  if (stream == NULL)
-    return errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
-
-  for (;;)
-    {
-      char buffer[HEXKEYBYTES * 2 + KEYCHECKSUMSIZE + MAXNETNAMELEN + 17];
-      char *p;
-      char *save_ptr;
-
-      buffer[sizeof (buffer) - 1] = '\xff';
-      p = fgets_unlocked (buffer, sizeof (buffer), stream);
-      if (p == NULL)
-	{
-	  /* End of file or read error.  */
-	  *errnop = errno;
-	  fclose (stream);
-	  return NSS_STATUS_NOTFOUND;
-	}
-      else if (buffer[sizeof (buffer) - 1] != '\xff')
-	{
-	  /* Invalid line in file?  Skip remainder of line.  */
-	  if (buffer[sizeof (buffer) - 2] != '\0')
-	    while (getc_unlocked (stream) != '\n')
-	      continue;
-	  continue;
-	}
-
-      /* Parse line.  */
-      p = __strtok_r (buffer, "# \t:\n", &save_ptr);
-      if (p == NULL) /* Skip empty and comment lines.  */
-	continue;
-      if (strcmp (p, netname) != 0)
-	continue;
-
-      /* A hit!  Find the field we want and return.  */
-      p = __strtok_r (NULL, ":\n", &save_ptr);
-      if (p == NULL)  /* malformed line? */
-	continue;
-      if (secret)
-	p = __strtok_r (NULL, ":\n", &save_ptr);
-      if (p == NULL)  /* malformed line? */
-	continue;
-      fclose (stream);
-      strcpy (result, p);
-      return NSS_STATUS_SUCCESS;
-    }
-}
-
-enum nss_status
-_nss_files_getpublickey (const char *netname, char *pkey, int *errnop)
-{
-  return search (netname, pkey, errnop, 0);
-}
-
-enum nss_status
-_nss_files_getsecretkey (const char *netname, char *skey, char *passwd,
-			 int *errnop)
-{
-  enum nss_status status;
-  char buf[HEXKEYBYTES + KEYCHECKSUMSIZE + 16];
-
-  skey[0] = 0;
-
-  status = search (netname, buf, errnop, 1);
-  if (status != NSS_STATUS_SUCCESS)
-    return status;
-
-  if (!xdecrypt (buf, passwd))
-    return NSS_STATUS_SUCCESS;
-
-  if (memcmp (buf, &(buf[HEXKEYBYTES]), KEYCHECKSUMSIZE) != 0)
-    return NSS_STATUS_SUCCESS;
-
-  buf[HEXKEYBYTES] = 0;
-  strcpy (skey, buf);
-
-  return NSS_STATUS_SUCCESS;
-}