Make sure errno is always set correct.
authordrepper <drepper>
Sat, 18 Dec 1999 19:27:07 +0000 (19:27 +0000)
committerdrepper <drepper>
Sat, 18 Dec 1999 19:27:07 +0000 (19:27 +0000)
nis/nss_nis/nis-alias.c
nis/nss_nis/nis-ethers.c
nis/nss_nis/nis-grp.c
nis/nss_nis/nis-hosts.c
nis/nss_nis/nis-netgrp.c
nis/nss_nis/nis-publickey.c
nis/nss_nis/nis-service.c

index 64d0bf8..e6e2386 100644 (file)
@@ -278,7 +278,10 @@ _nss_nis_getaliasbyname_r (const char *name, struct aliasent *alias,
       if (parse_res == -1)
        return NSS_STATUS_TRYAGAIN;
       else
-       return NSS_STATUS_NOTFOUND;
+       {
+         *errnop = ENOENT;
+         return NSS_STATUS_NOTFOUND;
+       }
     }
 
   return NSS_STATUS_SUCCESS;
index c95f766..c1ea32a 100644 (file)
@@ -1,6 +1,6 @@
-/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
+   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 Library General Public License as
@@ -241,7 +241,10 @@ _nss_nis_gethostton_r (const char *name, struct ether *eth,
       if (parse_res == -1)
        return NSS_STATUS_TRYAGAIN;
       else
-       return NSS_STATUS_NOTFOUND;
+       {
+         *errnop = ENOENT;
+         return NSS_STATUS_NOTFOUND;
+       }
     }
   return NSS_STATUS_SUCCESS;
 }
index 6dca66e..62e6b47 100644 (file)
@@ -1,6 +1,6 @@
-/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
+   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 Library General Public License as
@@ -207,7 +207,7 @@ _nss_nis_getgrnam_r (const char *name, struct group *grp,
        return NSS_STATUS_TRYAGAIN;
       else
        {
-         *errnop = EAGAIN;
+         *errnop = ENOENT;
          return NSS_STATUS_NOTFOUND;
        }
     }
index 0ddc930..15aff25 100644 (file)
@@ -321,6 +321,7 @@ internal_gethostbyname2_r (const char *name, int af, struct hostent *host,
       else
        {
          *h_errnop = HOST_NOT_FOUND;
+         *errnop = ENOENT;
          return NSS_STATUS_NOTFOUND;
        }
     }
@@ -392,7 +393,10 @@ _nss_nis_gethostbyaddr_r (char *addr, size_t addrlen, int af,
          *errnop = errno;
        }
       if (retval == NSS_STATUS_NOTFOUND)
-       *h_errnop = HOST_NOT_FOUND;
+       {
+         *h_errnop = HOST_NOT_FOUND;
+         *errnop = ENOENT;
+       }
       return retval;
     }
 
index d170b56..0d3ed44 100644 (file)
@@ -1,6 +1,6 @@
-/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
+   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 Library General Public License as
@@ -117,7 +117,10 @@ _nss_nis_getnetgrent_r (struct __netgrent *result, char *buffer, size_t buflen,
   enum nss_status status;
 
   if (cursor == NULL)
-    return NSS_STATUS_NOTFOUND;
+    {
+      *errnop = ENOENT;
+      return NSS_STATUS_NOTFOUND;
+    }
 
   __libc_lock_lock (lock);
 
index 73afd44..821accf 100644 (file)
@@ -1,6 +1,6 @@
-/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
+   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 Library General Public License as
@@ -50,8 +50,11 @@ _nss_nis_getpublickey (const char *netname, char *pkey, int *errnop)
 
   domain = strchr (netname, '@');
   if (!domain)
-    return NSS_STATUS_UNAVAIL;
-  domain++;
+    {
+      *errnop = EINVAL;
+      return NSS_STATUS_UNAVAIL;
+    }
+  ++domain;
 
   retval = yperr2nss (yp_match (domain, "publickey.byname", netname,
                                strlen (netname), &result, &len));
@@ -95,8 +98,11 @@ _nss_nis_getsecretkey (const char *netname, char *skey, char *passwd,
 
   domain = strchr (netname, '@');
   if (!domain)
-    return NSS_STATUS_UNAVAIL;
-  domain++;
+    {
+      *errnop = EINVAL;
+      return NSS_STATUS_UNAVAIL;
+    }
+  ++domain;
 
   retval = yperr2nss (yp_match (domain, "publickey.byname", netname,
                                strlen (netname), &result, &len));
@@ -196,10 +202,13 @@ _nss_nis_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
 
   domain = strchr (netname, '@');
   if (!domain)
-    return NSS_STATUS_UNAVAIL;
+    {
+      *errnop = EINVAL;
+      return NSS_STATUS_UNAVAIL;
+    }
 
   /* Point past the '@' character */
-  domain++;
+  ++domain;
   lookup = NULL;
   yperr = yp_match (domain, "netid.byname", netname, strlen (netname),
                    &lookup, &len);
@@ -209,11 +218,13 @@ _nss_nis_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
       break;                   /* the successful case */
     case YPERR_DOMAIN:
     case YPERR_KEY:
+      *errnop = ENOENT;
       return NSS_STATUS_NOTFOUND;
     case YPERR_MAP:
     default:
       return NSS_STATUS_UNAVAIL;
     }
+
   if (lookup)
     {
       enum nss_status err;
@@ -224,7 +235,9 @@ _nss_nis_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
       return err;
     }
   else
-    return NSS_STATUS_NOTFOUND;
-
+    {
+      *errnop = ENOENT;
+      return NSS_STATUS_NOTFOUND;
+    }
   return NSS_STATUS_SUCCESS;
 }
index 103b1e4..cece55c 100644 (file)
@@ -172,7 +172,7 @@ internal_nis_getservent_r (struct servent *serv, char *buffer,
          return NSS_STATUS_NOTFOUND;
        }
       p = strncpy (buffer, data->next->val, buflen);
-           while (isspace (*p))
+      while (isspace (*p))
         ++p;
 
       parse_res = _nss_files_parse_servent (p, serv, pdata, buflen, errnop);
@@ -215,6 +215,63 @@ _nss_nis_getservbyname_r (const char *name, char *protocol,
       return NSS_STATUS_UNAVAIL;
     }
 
+  /* If the protocol is given, we could try if our NIS server knows
+     about services.byservicename map. If yes, we only need one query */
+  if (protocol != NULL)
+    {
+      char key[strlen (name) + strlen (protocol) + 2];
+      char *cp, *domain, *result;
+      size_t keylen, len;
+
+      /* If this fails, the other solution will also fail. */
+      if (yp_get_default_domain (&domain))
+       return NSS_STATUS_UNAVAIL;
+
+      /* key is: "name/protocol" */
+      cp = stpcpy (key, name);
+      *cp++ = '/';
+      stpcpy (cp, protocol);
+      keylen = strlen (key);
+      status = yperr2nss (yp_match (domain, "services.byservicename", key,
+                                   keylen, &result, &len));
+
+      /* If we found the key, it's ok and parse the result. If not,
+        fall through and parse the complete table. */
+      if (status == NSS_STATUS_SUCCESS)
+       {
+         struct parser_data *pdata = (void *) buffer;
+         int parse_res;
+         char *p;
+
+         if ((size_t) (len + 1) > buflen)
+           {
+             free (result);
+             *errnop = ERANGE;
+             return NSS_STATUS_TRYAGAIN;
+           }
+
+         p = strncpy (buffer, result, len);
+         buffer[len] = '\0';
+         while (isspace (*p))
+           ++p;
+         free (result);
+         parse_res = _nss_files_parse_servent (p, serv, pdata,
+                                               buflen, errnop);
+         if (parse_res < 0)
+           {
+             if (parse_res == -1)
+               return NSS_STATUS_TRYAGAIN;
+             else
+               {
+                 *errnop = ENOENT;
+                 return NSS_STATUS_NOTFOUND;
+               }
+           }
+         else
+           return NSS_STATUS_SUCCESS;
+       }
+    }
+
   status = internal_nis_setservent (&data);
   if (status != NSS_STATUS_SUCCESS)
     return status;
@@ -256,10 +313,57 @@ _nss_nis_getservbyport_r (int port, char *protocol, struct servent *serv,
   enum nss_status status;
   int found;
 
-  if (protocol == NULL)
+  /* If the protocol is given, we only need one query */
+  if (protocol != NULL)
     {
-      *errnop = EINVAL;
-      return NSS_STATUS_UNAVAIL;
+      char key[100 + strlen (protocol) + 2];
+      char *domain, *result;
+      size_t keylen, len;
+
+      /* If this fails, the other solution will also fail. */
+      if (yp_get_default_domain (&domain))
+       return NSS_STATUS_UNAVAIL;
+
+      /* key is: "port/protocol" */
+      keylen = snprintf (key, sizeof (key), "%d/%s", port, protocol);
+      status = yperr2nss (yp_match (domain, "services.byname", key,
+                                   keylen, &result, &len));
+
+      /* If we found the key, it's ok and parse the result. If not,
+        fall through and parse the complete table. */
+      if (status == NSS_STATUS_SUCCESS)
+       {
+         struct parser_data *pdata = (void *) buffer;
+         int parse_res;
+         char *p;
+
+         if ((size_t) (len + 1) > buflen)
+           {
+             free (result);
+             *errnop = ERANGE;
+             return NSS_STATUS_TRYAGAIN;
+           }
+
+         p = strncpy (buffer, result, len);
+         buffer[len] = '\0';
+         while (isspace (*p))
+           ++p;
+         free (result);
+         parse_res = _nss_files_parse_servent (p, serv, pdata,
+                                               buflen, errnop);
+         if (parse_res < 0)
+           {
+             if (parse_res == -1)
+               return NSS_STATUS_TRYAGAIN;
+             else
+               {
+                 *errnop = ENOENT;
+                 return NSS_STATUS_NOTFOUND;
+               }
+           }
+         else
+           return NSS_STATUS_SUCCESS;
+       }
     }
 
   status = internal_nis_setservent (&data);
@@ -270,7 +374,8 @@ _nss_nis_getservbyport_r (int port, char *protocol, struct servent *serv,
   while (!found &&
          ((status = internal_nis_getservent_r (serv, buffer, buflen, errnop,
                                               &data)) == NSS_STATUS_SUCCESS))
-    if (serv->s_port == port && strcmp (serv->s_proto, protocol) == 0)
+    if (serv->s_port == port &&
+       (protocol == NULL || strcmp (serv->s_proto, protocol) == 0))
       found = 1;
 
   internal_nis_endservent (&data);