about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--nis/nis_error.c15
-rw-r--r--nis/nss_nisplus/nisplus-ethers.c88
-rw-r--r--nis/nss_nisplus/nisplus-netgrp.c7
-rw-r--r--nis/nss_nisplus/nisplus-publickey.c21
-rw-r--r--nis/nss_nisplus/nisplus-pwd.c15
-rw-r--r--nis/nss_nisplus/nisplus-spwd.c4
7 files changed, 68 insertions, 88 deletions
diff --git a/ChangeLog b/ChangeLog
index 4e8ee89335..4601a7a513 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 2005-12-03  Ulrich Drepper  <drepper@redhat.com>
 
+	* nis/nis_error.c (nis_sperror_r): Let snprintf determine whether
+	there is an overflow.
 	* nis/nss_nisplus/nisplus-service.c: Fix locking to use
 	_nss_create_tablename.  Avoid unnecessary copying, remove
 	unnecessary variables, general cleanup.
@@ -17,6 +19,10 @@
 	general cleanup.
 	* nis/nss_nisplus/nisplus-alias.c: Fix locking to use
 	_nss_create_tablename.  Avoid unnecessary copying, general cleanup.
+	* nis/nss_nisplus/nisplus-netgrp.c (_nss_nisplus_setnetgrent):
+	Rewrite to use snprintf.
+	* nis/nss_nisplus/nisplus-publickey.c (_nss_nisplus_netname2user):
+	Likewise.
 
 2005-12-02  Ulrich Drepper  <drepper@redhat.com>
 
diff --git a/nis/nis_error.c b/nis/nis_error.c
index 147f88ce15..7db885ef93 100644
--- a/nis/nis_error.c
+++ b/nis/nis_error.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 1997, 1998, 1999, 2004 Free Software Foundation, Inc.
+/* Copyright (c) 1997, 1998, 1999, 2004, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
 
@@ -102,26 +102,21 @@ char *
 nis_sperror_r (const nis_error status, const char *label,
 	       char *buffer, size_t buflen)
 {
-  const char *cptr;
-
-  cptr = nis_sperrno (status);
-
-  if ((strlen (cptr) + strlen (label) + 3) > buflen)
+  if (snprintf (buffer, buflen, "%s: %s", label, nis_sperrno (status))
+      >= buflen)
     {
       errno = ERANGE;
       return NULL;
     }
 
-    sprintf (buffer, "%s: %s", label, cptr);
-
-    return buffer;
+  return buffer;
 }
 libnsl_hidden_def (nis_sperror_r)
 
 char *
 nis_sperror (const nis_error status, const char *label)
 {
-  static char buffer[NIS_MAXNAMELEN +1];
+  static char buffer[NIS_MAXNAMELEN + 1];
 
   return nis_sperror_r (status, label, buffer, sizeof (buffer));
 }
diff --git a/nis/nss_nisplus/nisplus-ethers.c b/nis/nss_nisplus/nisplus-ethers.c
index 528ae88a0c..fcc550e743 100644
--- a/nis/nss_nisplus/nisplus-ethers.c
+++ b/nis/nss_nisplus/nisplus-ethers.c
@@ -156,8 +156,6 @@ static enum nss_status
 internal_nisplus_getetherent_r (struct etherent *ether, char *buffer,
 				size_t buflen, int *errnop)
 {
-  int parse_res;
-
   if (tablename_val == NULL)
     {
       enum nss_status status = _nss_create_tablename (errnop);
@@ -167,6 +165,7 @@ internal_nisplus_getetherent_r (struct etherent *ether, char *buffer,
     }
 
   /* Get the next entry until we found a correct one. */
+  int parse_res;
   do
     {
       nis_result *saved_result;
@@ -180,11 +179,8 @@ internal_nisplus_getetherent_r (struct etherent *ether, char *buffer,
 	}
       else
 	{
-	  nis_result *res2;
-
-	  res2 = nis_next_entry(tablename_val, &result->cookie);
 	  saved_result = result;
-	  result = res2;
+	  result = nis_next_entry (tablename_val, &result->cookie);
 	  if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
 	    {
 	      nis_freeresult (saved_result);
@@ -200,13 +196,12 @@ internal_nisplus_getetherent_r (struct etherent *ether, char *buffer,
 	  result = saved_result;
 	  return NSS_STATUS_TRYAGAIN;
 	}
-      else
-	{
-	  if (saved_result != NULL)
-	    nis_freeresult (saved_result);
-	}
 
-    } while (!parse_res);
+      if (saved_result != NULL)
+	nis_freeresult (saved_result);
+
+    }
+  while (!parse_res);
 
   return NSS_STATUS_SUCCESS;
 }
@@ -230,8 +225,6 @@ enum nss_status
 _nss_nisplus_gethostton_r (const char *name, struct etherent *eth,
 			   char *buffer, size_t buflen, int *errnop)
 {
-  int parse_res;
-
   if (tablename_val == NULL)
     {
       enum nss_status status = _nss_create_tablename (errnop);
@@ -245,49 +238,47 @@ _nss_nisplus_gethostton_r (const char *name, struct etherent *eth,
       *errnop = EINVAL;
       return NSS_STATUS_UNAVAIL;
     }
-  else
-    {
-      nis_result *result;
-      char buf[strlen (name) + 40 + tablename_len];
-      int olderr = errno;
 
-      sprintf (buf, "[name=%s],%s", name, tablename_val);
+  char buf[strlen (name) + 9 + tablename_len];
+  int olderr = errno;
 
-      result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
+  snprintf (buf, sizeof (buf), "[name=%s],%s", name, tablename_val);
 
-      if (result == NULL)
-	{
-	  *errnop = ENOMEM;
-	  return NSS_STATUS_TRYAGAIN;
-	}
-      if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
-	{
-	  enum nss_status status = niserr2nss (result->status);
-	  nis_freeresult (result);
-	  return status;
-	}
+  nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
 
-      parse_res = _nss_nisplus_parse_etherent (result, eth, buffer,
+  if (result == NULL)
+    {
+      *errnop = ENOMEM;
+      return NSS_STATUS_TRYAGAIN;
+    }
+
+  if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0))
+    {
+      enum nss_status status = niserr2nss (result->status);
+      nis_freeresult (result);
+      return status;
+    }
+
+  int parse_res = _nss_nisplus_parse_etherent (result, eth, buffer,
 					       buflen, errnop);
-      if (parse_res < 1)
-	{
-	  __set_errno (olderr);
+  if (__builtin_expect (parse_res < 1, 0))
+    {
+      __set_errno (olderr);
 
-	  if (parse_res == -1)
-	    {
-	      nis_freeresult (result);
-	      return NSS_STATUS_TRYAGAIN;
-	    }
-	  else
-	   return NSS_STATUS_NOTFOUND;
+      if (parse_res == -1)
+	{
+	  nis_freeresult (result);
+	  return NSS_STATUS_TRYAGAIN;
 	}
-      return NSS_STATUS_SUCCESS;
+      else
+	return NSS_STATUS_NOTFOUND;
     }
+
+  return NSS_STATUS_SUCCESS;
 }
 
 enum nss_status
-_nss_nisplus_getntohost_r (const struct ether_addr *addr,
-			   struct etherent *eth,
+_nss_nisplus_getntohost_r (const struct ether_addr *addr, struct etherent *eth,
 			   char *buffer, size_t buflen, int *errnop)
 {
   if (tablename_val == NULL)
@@ -308,7 +299,6 @@ _nss_nisplus_getntohost_r (const struct ether_addr *addr,
       return NSS_STATUS_UNAVAIL;
     }
 
-  int parse_res;
   char buf[26 + tablename_len];
 
   snprintf (buf, sizeof (buf),
@@ -334,8 +324,8 @@ _nss_nisplus_getntohost_r (const struct ether_addr *addr,
       return status;
     }
 
-  parse_res = _nss_nisplus_parse_etherent (result, eth, buffer,
-					   buflen, errnop);
+  int parse_res = _nss_nisplus_parse_etherent (result, eth, buffer,
+					       buflen, errnop);
   if (__builtin_expect (parse_res < 1, 0))
     {
       if (parse_res == -1)
diff --git a/nis/nss_nisplus/nisplus-netgrp.c b/nis/nss_nisplus/nisplus-netgrp.c
index 344d65f4c4..31a8cdf097 100644
--- a/nis/nss_nisplus/nisplus-netgrp.c
+++ b/nis/nss_nisplus/nisplus-netgrp.c
@@ -150,15 +150,14 @@ internal_endnetgrent (struct __netgrent *netgrp)
 enum nss_status
 _nss_nisplus_setnetgrent (const char *group, struct __netgrent *netgrp)
 {
-  enum nss_status status;
-  char buf[strlen (group) + 30];
+  char buf[strlen (group) + 25];
 
   if (group == NULL || group[0] == '\0')
     return NSS_STATUS_UNAVAIL;
 
-  status = NSS_STATUS_SUCCESS;
+  enum nss_status status = NSS_STATUS_SUCCESS;
 
-  sprintf (buf, "[name=%s],netgroup.org_dir", group);
+  snprintf (buf, sizeof (buf), "[name=%s],netgroup.org_dir", group);
 
   netgrp->data = (char *) nis_list (buf, EXPAND_NAME, NULL, NULL);
 
diff --git a/nis/nss_nisplus/nisplus-publickey.c b/nis/nss_nisplus/nisplus-publickey.c
index 58ae7012af..c24e898137 100644
--- a/nis/nss_nisplus/nisplus-publickey.c
+++ b/nis/nss_nisplus/nisplus-publickey.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 1997, 1999, 2001, 2003 Free Software Foundation, Inc.
+/* Copyright (c) 1997, 1999, 2001, 2003, 2005 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
 
@@ -37,7 +37,7 @@ _nss_nisplus_getpublickey (const char *netname, char *pkey, int *errnop)
 {
   nis_result *res;
   enum nss_status retval;
-  char buf[NIS_MAXNAMELEN+2];
+  char buf[NIS_MAXNAMELEN + 2];
   size_t slen;
   char *domain, *cptr;
   int len;
@@ -120,7 +120,7 @@ _nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd,
 {
   nis_result *res;
   enum nss_status retval;
-  char buf[NIS_MAXNAMELEN+2];
+  char buf[NIS_MAXNAMELEN + 2];
   size_t slen;
   char *domain, *cptr;
   int len;
@@ -154,7 +154,7 @@ _nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd,
       buf[slen] = '\0';
     }
 
-  res = nis_list (buf, USE_DGRAM+NO_AUTHINFO+FOLLOW_LINKS+FOLLOW_PATH,
+  res = nis_list (buf, USE_DGRAM | NO_AUTHINFO | FOLLOW_LINKS | FOLLOW_PATH,
 		  NULL, NULL);
 
   if (res == NULL)
@@ -242,9 +242,9 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
 {
   char *domain;
   nis_result *res;
-  char sname[NIS_MAXNAMELEN+2]; /*  search criteria + table name */
+  char sname[NIS_MAXNAMELEN + 2]; /*  search criteria + table name */
   size_t slen;
-  char principal[NIS_MAXNAMELEN+1];
+  char principal[NIS_MAXNAMELEN + 1];
   int len;
 
   /* 1.  Get home domain of user. */
@@ -255,10 +255,6 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
   ++domain;  /* skip '@' */
 
   /* 2.  Get user's nisplus principal name.  */
-  if ((strlen (netname) + strlen (domain)+45) >
-      (size_t) NIS_MAXNAMELEN)
-    return NSS_STATUS_UNAVAIL;
-
   slen = snprintf (sname, NIS_MAXNAMELEN,
 		   "[auth_name=%s,auth_type=DES],cred.org_dir.%s",
 		   netname, domain);
@@ -339,8 +335,9 @@ _nss_nisplus_netname2user (char netname[MAXNETNAMELEN + 1], uid_t *uidp,
       return NSS_STATUS_UNAVAIL;
     }
 
-  slen = sprintf (sname, "[cname=%s,auth_type=LOCAL],cred.org_dir.%s",
-		  principal, domain);
+  slen = snprintf (sname, sizeof  (sname),
+		   "[cname=%s,auth_type=LOCAL],cred.org_dir.%s",
+		   principal, domain);
 
   if (sname[slen - 1] != '.')
     {
diff --git a/nis/nss_nisplus/nisplus-pwd.c b/nis/nss_nisplus/nisplus-pwd.c
index a1c53f74a6..97679dd349 100644
--- a/nis/nss_nisplus/nisplus-pwd.c
+++ b/nis/nss_nisplus/nisplus-pwd.c
@@ -56,7 +56,12 @@ _nss_pwd_create_tablename (int *errnop)
 
       atomic_write_barrier ();
 
-      pwd_tablename_val = p;
+      if (atomic_compare_and_exchange_bool_acq (&pwd_tablename_val, p, NULL))
+	{
+	  /* Another thread already installed the value.  */
+	  free (p);
+	  pwd_tablename_len = strlen (pwd_tablename_val);
+	}
     }
 
   return NSS_STATUS_SUCCESS;
@@ -181,12 +186,8 @@ _nss_nisplus_getpwnam_r (const char *name, struct passwd *pw,
 
   if (pwd_tablename_val == NULL)
     {
-      __libc_lock_lock (lock);
-
       enum nss_status status = _nss_pwd_create_tablename (errnop);
 
-      __libc_lock_unlock (lock);
-
       if (status != NSS_STATUS_SUCCESS)
 	return status;
     }
@@ -248,12 +249,8 @@ _nss_nisplus_getpwuid_r (const uid_t uid, struct passwd *pw,
 {
   if (pwd_tablename_val == NULL)
     {
-      __libc_lock_lock (lock);
-
       enum nss_status status = _nss_pwd_create_tablename (errnop);
 
-      __libc_lock_unlock (lock);
-
       if (status != NSS_STATUS_SUCCESS)
 	return status;
     }
diff --git a/nis/nss_nisplus/nisplus-spwd.c b/nis/nss_nisplus/nisplus-spwd.c
index dd213c1ca9..8584300698 100644
--- a/nis/nss_nisplus/nisplus-spwd.c
+++ b/nis/nss_nisplus/nisplus-spwd.c
@@ -154,12 +154,8 @@ _nss_nisplus_getspnam_r (const char *name, struct spwd *sp,
 
   if (pwd_tablename_val == NULL)
     {
-      __libc_lock_lock (lock);
-
       enum nss_status status = _nss_pwd_create_tablename (errnop);
 
-      __libc_lock_unlock (lock);
-
       if (status != NSS_STATUS_SUCCESS)
 	return status;
     }