[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[commits] r10204 - in /fsf/trunk/libc: ./ localedata/ localedata/locales/ nis/ nis/nss_nis/ posix/



Author: eglibc
Date: Thu Apr  8 00:03:37 2010
New Revision: 10204

Log:
Import glibc-mainline for 2010-04-08

Added:
    fsf/trunk/libc/posix/bug-getopt1.c
    fsf/trunk/libc/posix/bug-getopt2.c
    fsf/trunk/libc/posix/bug-getopt3.c
    fsf/trunk/libc/posix/bug-getopt4.c
    fsf/trunk/libc/posix/bug-getopt5.c
Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/NEWS
    fsf/trunk/libc/localedata/ChangeLog
    fsf/trunk/libc/localedata/locales/sq_AL
    fsf/trunk/libc/nis/libnsl.h
    fsf/trunk/libc/nis/nss
    fsf/trunk/libc/nis/nss-default.c
    fsf/trunk/libc/nis/nss_nis/nis-pwd.c
    fsf/trunk/libc/nis/nss_nis/nis-spwd.c
    fsf/trunk/libc/posix/Makefile
    fsf/trunk/libc/posix/getopt.c

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Thu Apr  8 00:03:37 2010
@@ -1,3 +1,49 @@
+2010-04-07  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	* posix/bug-getopt1.c: New file.
+	* posix/bug-getopt2.c: New file.
+	* posix/bug-getopt3.c: New file.
+	* posix/bug-getopt4.c: New file.
+	* posix/bug-getopt5.c: New file.
+
+2009-12-01  Eric Blake  <ebb9@xxxxxxx>
+
+	[BZ #11039]
+	* posix/getopt.c (_getopt_internal_r): Skip optional - or + before
+	checking lead byte of optstring for :.
+
+	[BZ #11040]
+	* posix/getopt.c (_getopt_internal_r): Reject '-;' as short
+	option, since it conflicts with "W;" optstring extension.
+
+2009-12-02  Eric Blake  <ebb9@xxxxxxx>
+
+	[BZ #11041]
+	* posix/getopt.c (_getopt_internal_r): Handle '-Wfoo' identically
+	to '--foo', with optional argument or non-ambiguous prefix.
+
+2010-04-07  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	[BZ #11134]
+	* nis/libnsl.h (NSS_FLAG_ADJUNCT_AS_SHADOW): Define.
+	* nis/nss: Document new ADJUNCT_AS_SHADOW variable.
+	* nis/nss-default.c: Handle ADJUNCT_AS_SHADOW variable.
+	* nis/nss_nis/nis-pwd.c (internal_nis_endpwent): Minor cleanups.
+	(internal_nis_getpwent_r): Don't fill in password from adjunct table
+	if NSS_FLAG_ADJUNCT_AS_SHADOW is set.
+	(_nss_nis_getpwnam_r): Likewise.
+	(_nss_nis_getpwuid_r): Likewise.
+	* nis/nss_nis/nis-spwd.c (ent_adjunct_used): New global variable.
+	(_nss_nis_setspent): Also reset ent_adjunct_used.
+	(internal_nis_getspent_r): If new_start is set and shadow.byname table
+	does not exist and NSS_FLAG_ADJUNCT_AS_SHADOW is set, try to get
+	passwd.adjunct.byname table.  If new_start is not set get next entry
+	from the initially used table.  Synthesize shadow.byname table if
+	necessary by adding two empty fields.
+	(_nss_nis_getspnam_r): If shadow.byname table does not exist and
+	NSS_FLAG_ADJUNCT_AS_SHADOW is set, try to get passwd.adjunct.byname
+	table and synthesize shadow.byname table.
+
 2010-04-06  H.J. Lu  <hongjiu.lu@xxxxxxxxx>
 
 	* Makerules (libc-abis): Add $(..) to libc-abis.

Modified: fsf/trunk/libc/NEWS
==============================================================================
--- fsf/trunk/libc/NEWS (original)
+++ fsf/trunk/libc/NEWS Thu Apr  8 00:03:37 2010
@@ -1,5 +1,5 @@
-GNU C Library NEWS -- history of user-visible changes.  2009-12-8
-Copyright (C) 1992-2008, 2009 Free Software Foundation, Inc.
+GNU C Library NEWS -- history of user-visible changes.  2010-4-7
+Copyright (C) 1992-2009, 2010 Free Software Foundation, Inc.
 See the end for copying conditions.
 
 Please send GNU C library bug reports via <http://sources.redhat.com/bugzilla/>
@@ -8,6 +8,12 @@
 Version 2.12
 
 * New Linux interface: recvmmsg
+
+* New NIS mode selector ADJUNCT_AS_SHADOW.  The passwd.adjunct.byname table
+  will not be used to fill in password fields in the passwd.byname replies.
+  Instead it is used to synthesize the shadow.byname table, should it be
+  missing.  This is a useful mode in some installations involving Solaris.
+  Implemented by Ulrich Drepper.
 
 
 Version 2.11

Modified: fsf/trunk/libc/localedata/ChangeLog
==============================================================================
--- fsf/trunk/libc/localedata/ChangeLog (original)
+++ fsf/trunk/libc/localedata/ChangeLog Thu Apr  8 00:03:37 2010
@@ -1,3 +1,9 @@
+2010-04-07  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	[BZ #11471]
+	* locales/sq_AL: Fix Mr. Mrs. Ms. and Miss.
+	Patch by Agron Selimaj <linuxmaster@xxxxxxxxxxx>.
+
 2010-04-05  Ulrich Drepper  <drepper@xxxxxxxxxx>
 
 	[BZ #11007]

Modified: fsf/trunk/libc/localedata/locales/sq_AL
==============================================================================
--- fsf/trunk/libc/localedata/locales/sq_AL (original)
+++ fsf/trunk/libc/localedata/locales/sq_AL Thu Apr  8 00:03:37 2010
@@ -228,41 +228,41 @@
 %
 % Abbreviated weekday names (%a)
 abday       "<U0044><U0069><U0065><U0020>";"<U0048><U00EB><U006E><U0020>";/
-            "<U004D><U0061><U0072><U0020>";"<U004D><U00EB><U0072><U0020>";/
-            "<U0045><U006E><U006A><U0020>";"<U0050><U0072><U0065><U0020>";/
-            "<U0053><U0068><U0074><U0020>"
+	    "<U004D><U0061><U0072><U0020>";"<U004D><U00EB><U0072><U0020>";/
+	    "<U0045><U006E><U006A><U0020>";"<U0050><U0072><U0065><U0020>";/
+	    "<U0053><U0068><U0074><U0020>"
 %
 % Full weekday names (%A)
 day         "<U0065><U0020><U0064><U0069><U0065><U006C><U0020>";/
-            "<U0065><U0020><U0068><U00EB><U006E><U00EB><U0020>";/
-            "<U0065><U0020><U006D><U0061><U0072><U0074><U00EB><U0020>";/
-            "<U0065><U0020><U006D><U00EB><U0072><U006B><U0075><U0072>/
+	    "<U0065><U0020><U0068><U00EB><U006E><U00EB><U0020>";/
+	    "<U0065><U0020><U006D><U0061><U0072><U0074><U00EB><U0020>";/
+	    "<U0065><U0020><U006D><U00EB><U0072><U006B><U0075><U0072>/
 <U00EB><U0020>";/
-            "<U0065><U0020><U0065><U006E><U006A><U0074><U0065><U0020>";/
-            "<U0065><U0020><U0070><U0072><U0065><U006D><U0074><U0065><U0020>";/
-            "<U0065><U0020><U0073><U0068><U0074><U0075><U006E><U00EB><U0020>"
+	    "<U0065><U0020><U0065><U006E><U006A><U0074><U0065><U0020>";/
+	    "<U0065><U0020><U0070><U0072><U0065><U006D><U0074><U0065><U0020>";/
+	    "<U0065><U0020><U0073><U0068><U0074><U0075><U006E><U00EB><U0020>"
 %
 % Abbreviated month names (%b)
 abmon       "<U004A><U0061><U006E>";"<U0053><U0068><U006B>";/
-            "<U004D><U0061><U0072>";"<U0050><U0072><U0069>";/
-            "<U004D><U0061><U006A>";"<U0051><U0065><U0072>";/
-            "<U004B><U006F><U0072>";"<U0047><U0073><U0068>";/
-            "<U0053><U0068><U0074>";"<U0054><U0065><U0074>";/
-            "<U004E><U00EB><U006E>";"<U0044><U0068><U006A>"
+	    "<U004D><U0061><U0072>";"<U0050><U0072><U0069>";/
+	    "<U004D><U0061><U006A>";"<U0051><U0065><U0072>";/
+	    "<U004B><U006F><U0072>";"<U0047><U0073><U0068>";/
+	    "<U0053><U0068><U0074>";"<U0054><U0065><U0074>";/
+	    "<U004E><U00EB><U006E>";"<U0044><U0068><U006A>"
 %
 % Full month names (%B)
 mon         "<U006A><U0061><U006E><U0061><U0072>";/
-            "<U0073><U0068><U006B><U0075><U0072><U0074>";/
-            "<U006D><U0061><U0072><U0073>";/
-            "<U0070><U0072><U0069><U006C><U006C>";/
-            "<U006D><U0061><U006A>";/
-            "<U0071><U0065><U0072><U0073><U0068><U006F><U0072>";/
-            "<U006B><U006F><U0072><U0072><U0069><U006B>";/
-            "<U0067><U0075><U0073><U0068><U0074>";/
-            "<U0073><U0068><U0074><U0061><U0074><U006F><U0072>";/
-            "<U0074><U0065><U0074><U006F><U0072>";/
-            "<U006E><U00EB><U006E><U0074><U006F><U0072>";/
-            "<U0064><U0068><U006A><U0065><U0074><U006F><U0072>"
+	    "<U0073><U0068><U006B><U0075><U0072><U0074>";/
+	    "<U006D><U0061><U0072><U0073>";/
+	    "<U0070><U0072><U0069><U006C><U006C>";/
+	    "<U006D><U0061><U006A>";/
+	    "<U0071><U0065><U0072><U0073><U0068><U006F><U0072>";/
+	    "<U006B><U006F><U0072><U0072><U0069><U006B>";/
+	    "<U0067><U0075><U0073><U0068><U0074>";/
+	    "<U0073><U0068><U0074><U0061><U0074><U006F><U0072>";/
+	    "<U0074><U0065><U0074><U006F><U0072>";/
+	    "<U006E><U00EB><U006E><U0074><U006F><U0072>";/
+	    "<U0064><U0068><U006A><U0065><U0074><U006F><U0072>"
 %
 % Equivalent of AM PM
 am_pm       "<U0050><U0044>";"<U004D><U0044>"
@@ -315,10 +315,10 @@
 name_fmt    "<U0025><U0070><U0025><U0074><U0025><U0066><U0025><U0074>/
 <U0025><U0067>"
 name_gen    ""
-name_mr     "<U004D><U0072><U002E>"
-name_mrs    "<U004D><U0072><U0073><U002E>"
-name_miss   "<U004D><U0069><U0073><U0073><U002E>"
-name_ms     "<U004D><U0073><U002E>"
+name_mr     "<U005A><U002E>"
+name_mrs    "<U005A><U006E><U006A><U002E>"
+name_miss   "<U005A><U0073><U0068><U002E>"
+name_ms     "<U005A><U006E><U006A><U002E>"
 
 END LC_NAME
 

Modified: fsf/trunk/libc/nis/libnsl.h
==============================================================================
--- fsf/trunk/libc/nis/libnsl.h (original)
+++ fsf/trunk/libc/nis/libnsl.h Thu Apr  8 00:03:37 2010
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006, 2010 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
@@ -21,6 +21,7 @@
 #define NSS_FLAG_NETID_AUTHORITATIVE	1
 #define NSS_FLAG_SERVICES_AUTHORITATIVE	2
 #define NSS_FLAG_SETENT_BATCH_READ	4
+#define NSS_FLAG_ADJUNCT_AS_SHADOW	8
 
 
 /* Get current set of default flags.  */

Modified: fsf/trunk/libc/nis/nss
==============================================================================
--- fsf/trunk/libc/nis/nss (original)
+++ fsf/trunk/libc/nis/nss Thu Apr  8 00:03:37 2010
@@ -1,7 +1,7 @@
 # /etc/default/nss
 # This file can theoretically contain a bunch of customization variables
 # for Name Service Switch in the GNU C library.  For now there are only
-# three variables:
+# four variables:
 #
 # NETID_AUTHORITATIVE
 #   If set to TRUE, the initgroups() function will accept the information
@@ -26,3 +26,12 @@
 #  might result into a network communication with the server to get
 #  the next entry.
 #SETENT_BATCH_READ=TRUE
+#
+# ADJUNCT_AS_SHADOW
+#  If set to TRUE, the passwd routines in the NIS NSS module will not
+#  use the passwd.adjunct.byname tables to fill in the password data
+#  in the passwd structure.  This is a security problem if the NIS
+#  server cannot be trusted to send the passwd.adjuct table only to
+#  privileged clients.  Instead the passwd.adjunct.byname table is
+#  used to synthesize the shadow.byname table if it does not exist.
+#ADJUNCT_AS_SHADOW=TRUE

Modified: fsf/trunk/libc/nis/nss-default.c
==============================================================================
--- fsf/trunk/libc/nis/nss-default.c (original)
+++ fsf/trunk/libc/nis/nss-default.c Thu Apr  8 00:03:37 2010
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 2001, 2004, 2006, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 1996,2001,2004,2006,2007,2010 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
@@ -47,7 +47,8 @@
 #define STRNLEN(s) s, sizeof (s) - 1
     { STRNLEN ("NETID_AUTHORITATIVE"), NSS_FLAG_NETID_AUTHORITATIVE },
     { STRNLEN ("SERVICES_AUTHORITATIVE"), NSS_FLAG_SERVICES_AUTHORITATIVE },
-    { STRNLEN ("SETENT_BATCH_READ"), NSS_FLAG_SETENT_BATCH_READ }
+    { STRNLEN ("SETENT_BATCH_READ"), NSS_FLAG_SETENT_BATCH_READ },
+    { STRNLEN ("ADJUNCT_AS_SHADOW"), NSS_FLAG_ADJUNCT_AS_SHADOW },
   };
 #define nvars (sizeof (vars) / sizeof (vars[0]))
 

Modified: fsf/trunk/libc/nis/nss_nis/nis-pwd.c
==============================================================================
--- fsf/trunk/libc/nis/nss_nis/nis-pwd.c (original)
+++ fsf/trunk/libc/nis/nss_nis/nis-pwd.c Thu Apr  8 00:03:37 2010
@@ -1,4 +1,5 @@
-/* Copyright (C) 1996-1998,2001-2003,2006,2009 Free Software Foundation, Inc.
+/* Copyright (C) 1996-1998,2001-2003,2006,2009,2010
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@xxxxxxxxxxxxxxxxxxx>, 1996.
 
@@ -39,7 +40,7 @@
 /* Protect global state against multiple changers */
 __libc_lock_define_initialized (static, lock)
 
-static bool_t new_start = 1;
+static bool new_start = true;
 static char *oldkey;
 static int oldkeylen;
 static intern_t intern;
@@ -108,13 +109,10 @@
 static void
 internal_nis_endpwent (void)
 {
-  new_start = 1;
-  if (oldkey != NULL)
-    {
-      free (oldkey);
-      oldkey = NULL;
-      oldkeylen = 0;
-    }
+  new_start = true;
+  free (oldkey);
+  oldkey = NULL;
+  oldkeylen = 0;
 
   struct response_t *curr = intern.start;
 
@@ -264,18 +262,21 @@
 	}
 
       /* Check for adjunct style secret passwords.  They can be
-	 recognized by a password starting with "##".  */
+	 recognized by a password starting with "##".  We do not use
+	 it if the passwd.adjunct.byname table is supposed to be used
+	 as a shadow.byname replacement.  */
       char *p = strchr (result, ':');
       size_t namelen;
       char *result2;
       int len2;
-      if (p != NULL	/* This better should be true in all cases.  */
+      if ((_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW) == 0
+	  && p != NULL	/* This better should be true in all cases.  */
 	  && p[1] == '#' && p[2] == '#'
 	  && (namelen = p - result,
 	      yp_match (domain, "passwd.adjunct.byname", result, namelen,
 			&result2, &len2)) == YPERR_SUCCESS)
 	{
-	  /* We found a passwd.adjunct entry.  Merge encrypted
+	  /* We found a passwd.adjunct.byname entry.  Merge encrypted
 	     password therein into original result.  */
 	  char *encrypted = strchr (result2, ':');
 	  char *endp;
@@ -325,7 +326,7 @@
 	}
 
       while (isspace (*p))
-        ++p;
+	++p;
       if (!batch_read)
 	free (result);
 
@@ -346,7 +347,7 @@
 	  free (oldkey);
 	  oldkey = outkey;
 	  oldkeylen = keylen;
-	  new_start = 0;
+	  new_start = false;
 	}
     }
   while (parse_res < 1);
@@ -399,16 +400,19 @@
     }
 
   /* Check for adjunct style secret passwords.  They can be recognized
-     by a password starting with "##".  */
+     by a password starting with "##". We do not use it if the
+     passwd.adjunct.byname table is supposed to be used as a shadow.byname
+     replacement.  */
   char *result2;
   int len2;
   char *p = strchr (result, ':');
-  if (p != NULL	/* This better should be true in all cases.  */
+  if ((_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW) == 0
+      && p != NULL	/* This better should be true in all cases.  */
       && p[1] == '#' && p[2] == '#'
       && yp_match (domain, "passwd.adjunct.byname", name, namelen,
 		   &result2, &len2) == YPERR_SUCCESS)
     {
-      /* We found a passwd.adjunct entry.  Merge encrypted password
+      /* We found a passwd.adjunct.byname entry.  Merge encrypted password
 	 therein into original result.  */
       char *encrypted = strchr (result2, ':');
       char *endp;
@@ -465,7 +469,7 @@
   if (__builtin_expect (parse_res < 1, 0))
     {
       if (parse_res == -1)
-        return NSS_STATUS_TRYAGAIN;
+	return NSS_STATUS_TRYAGAIN;
       else
 	return NSS_STATUS_NOTFOUND;
     }
@@ -498,18 +502,21 @@
     }
 
   /* Check for adjunct style secret passwords.  They can be recognized
-     by a password starting with "##".  */
+     by a password starting with "##".  We do not use it if the
+     passwd.adjunct.byname table is supposed to be used as a shadow.byname
+     replacement.  */
   char *result2;
   int len2;
   size_t namelen;
   char *p = strchr (result, ':');
-  if (p != NULL	/* This better should be true in all cases.  */
+  if ((_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW) == 0
+      && p != NULL	/* This better should be true in all cases.  */
       && p[1] == '#' && p[2] == '#'
       && (namelen = p - result,
 	  yp_match (domain, "passwd.adjunct.byname", result, namelen,
 		    &result2, &len2)) == YPERR_SUCCESS)
     {
-      /* We found a passwd.adjunct entry.  Merge encrypted password
+      /* We found a passwd.adjunct.byname entry.  Merge encrypted password
 	 therein into original result.  */
       char *encrypted = strchr (result2, ':');
       char *endp;
@@ -567,7 +574,7 @@
   if (__builtin_expect (parse_res < 1, 0))
     {
       if (parse_res == -1)
-        return NSS_STATUS_TRYAGAIN;
+	return NSS_STATUS_TRYAGAIN;
      else
        return NSS_STATUS_NOTFOUND;
     }

Modified: fsf/trunk/libc/nis/nss_nis/nis-spwd.c
==============================================================================
--- fsf/trunk/libc/nis/nss_nis/nis-spwd.c (original)
+++ fsf/trunk/libc/nis/nss_nis/nis-spwd.c Thu Apr  8 00:03:37 2010
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-1998,2001,2002,2003,2006 Free Software Foundation, Inc.
+/* Copyright (C) 1996-1998,2001-2003,2006,2010 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Thorsten Kukuk <kukuk@xxxxxxxxxxxxxxxxxxx>, 1996.
 
@@ -31,6 +31,7 @@
 #include <rpcsvc/ypclnt.h>
 
 #include "nss-nis.h"
+#include <libnsl.h>
 
 /* Get the declaration of the parser function.  */
 #define ENTNAME spent
@@ -41,7 +42,8 @@
 /* Protect global state against multiple changers */
 __libc_lock_define_initialized (static, lock)
 
-static bool_t new_start = 1;
+static bool new_start = true;
+static bool ent_adjunct_used;
 static char *oldkey;
 static int oldkeylen;
 
@@ -50,7 +52,8 @@
 {
   __libc_lock_lock (lock);
 
-  new_start = 1;
+  new_start = true;
+  ent_adjunct_used = false;
   free (oldkey);
   oldkey = NULL;
   oldkeylen = 0;
@@ -83,32 +86,50 @@
       int yperr;
 
       if (new_start)
-        yperr = yp_first (domain, "shadow.byname", &outkey, &keylen, &result,
-			  &len);
+	{
+	  yperr = yp_first (domain, "shadow.byname", &outkey, &keylen, &result,
+			    &len);
+	  if (__builtin_expect (yperr == YPERR_MAP, 0)
+	      && (_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW))
+	    {
+	      free (result);
+	      yperr = yp_first (domain, "passwd.adjunct.byname", &outkey,
+				&keylen, &result, &len);
+	      ent_adjunct_used = true;
+	    }
+	}
       else
-        yperr = yp_next (domain, "shadow.byname", oldkey, oldkeylen, &outkey,
-			 &keylen, &result, &len);
+	yperr = yp_next (domain, (ent_adjunct_used
+				  ? "passwd.adjunct.byname" : "shadow.byname"),
+			 oldkey, oldkeylen, &outkey, &keylen, &result, &len);
 
       if (__builtin_expect (yperr != YPERR_SUCCESS, 0))
-        {
+	{
 	  enum nss_status retval = yperr2nss (yperr);
 
 	  if (retval == NSS_STATUS_TRYAGAIN)
 	    *errnop = errno;
-          return retval;
-        }
-
-      if (__builtin_expect ((size_t) (len + 1) > buflen, 0))
-        {
-          free (result);
+	  return retval;
+	}
+
+      if (__builtin_expect ((size_t) (len + (ent_adjunct_used ? 3 : 1))
+			    > buflen, 0))
+	{
+	  free (result);
 	  *errnop = ERANGE;
-          return NSS_STATUS_TRYAGAIN;
-        }
+	  return NSS_STATUS_TRYAGAIN;
+	}
 
       char *p = strncpy (buffer, result, len);
-      buffer[len] = '\0';
+      if (ent_adjunct_used)
+	/* This is an ugly trick.  The format of passwd.adjunct.byname almost
+	   matches the shadow.byname format except that the last two fields
+	   are missing.  Synthesize them by marking them empty.  */
+	strcpy (&buffer[len], "::");
+      else
+	buffer[len] = '\0';
       while (isspace (*p))
-        ++p;
+	++p;
       free (result);
 
       parse_res = _nss_files_parse_spent (p, sp, (void *) buffer, buflen,
@@ -123,7 +144,7 @@
       free (oldkey);
       oldkey = outkey;
       oldkeylen = keylen;
-      new_start = 0;
+      new_start = false;
     }
   while (!parse_res);
 
@@ -154,15 +175,25 @@
       *errnop = EINVAL;
       return NSS_STATUS_UNAVAIL;
     }
+  const size_t name_len = strlen (name);
 
   char *domain;
   if (__builtin_expect (yp_get_default_domain (&domain), 0))
     return NSS_STATUS_UNAVAIL;
 
+  bool adjunct_used = false;
   char *result;
   int len;
-  int yperr = yp_match (domain, "shadow.byname", name, strlen (name), &result,
+  int yperr = yp_match (domain, "shadow.byname", name, name_len, &result,
 			&len);
+  if (__builtin_expect (yperr == YPERR_MAP, 0)
+      && (_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW))
+    {
+      free (result);
+      yperr = yp_match (domain, "passwd.adjunct.byname", name, name_len,
+			&result, &len);
+      adjunct_used = true;
+    }
 
   if (__builtin_expect (yperr != YPERR_SUCCESS, 0))
     {
@@ -173,7 +204,7 @@
       return retval;
     }
 
-  if (__builtin_expect ((size_t) (len + 1) > buflen, 0))
+  if (__builtin_expect ((size_t) (len + (adjunct_used ? 3 : 1)) > buflen, 0))
     {
       free (result);
       *errnop = ERANGE;
@@ -181,7 +212,13 @@
     }
 
   char *p = strncpy (buffer, result, len);
-  buffer[len] = '\0';
+  if (__builtin_expect (adjunct_used, false))
+    /* This is an ugly trick.  The format of passwd.adjunct.byname almost
+       matches the shadow.byname format except that the last two fields
+       are missing.  Synthesize them by marking them empty.  */
+    strcpy (&buffer[len], "::");
+  else
+    buffer[len] = '\0';
   while (isspace (*p))
     ++p;
   free (result);

Modified: fsf/trunk/libc/posix/Makefile
==============================================================================
--- fsf/trunk/libc/posix/Makefile (original)
+++ fsf/trunk/libc/posix/Makefile Thu Apr  8 00:03:37 2010
@@ -92,7 +92,9 @@
 		   tst-execve1 tst-execve2 tst-execle1 tst-execle2 \
 		   tst-execvp3 tst-execvp4 tst-rfc3484 tst-rfc3484-2 \
 		   tst-rfc3484-3 \
-		   tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset
+		   tst-getaddrinfo3 tst-fnmatch2 tst-cpucount tst-cpuset \
+		   bug-getopt1 bug-getopt2 bug-getopt3 bug-getopt4 \
+		   bug-getopt5
 xtests		:= bug-ga2
 ifeq (yes,$(build-shared))
 test-srcs	:= globtest

Added: fsf/trunk/libc/posix/bug-getopt1.c
==============================================================================
--- fsf/trunk/libc/posix/bug-getopt1.c (added)
+++ fsf/trunk/libc/posix/bug-getopt1.c Thu Apr  8 00:03:37 2010
@@ -1,0 +1,73 @@
+/* BZ 11039 */
+#include <unistd.h>
+#include <stdio.h>
+
+static int
+one_test (const char *fmt, int argc, char *argv[], int expected[argc - 1])
+{
+  optind = 1;
+
+  int res = 0;
+  for (int i = 0; i < argc - 1; ++i)
+    {
+      rewind (stderr);
+      if (ftruncate (fileno (stderr), 0) != 0)
+	{
+	  puts ("cannot truncate file");
+	  return 1;
+	}
+
+      int c = getopt (argc, argv, fmt);
+      if (c != expected[i])
+	{
+	  printf ("format '%s' test %d failed: expected '%c', got '%c'\n",
+		  fmt, i, expected[i], c);
+	  res = 1;
+	}
+      if (ftell (stderr) != 0)
+	{
+	  printf ("format '%s' test %d failed: printed to stderr\n",
+		  fmt, i);
+	  res = 1;
+	}
+    }
+
+  return res;
+}
+
+
+static int
+do_test (void)
+{
+  char *fname = tmpnam (NULL);
+  if (fname == NULL)
+    {
+      puts ("cannot generate name for temporary file");
+      return 1;
+    }
+
+  if (freopen (fname, "w+", stderr) == NULL)
+    {
+      puts ("cannot redirect stderr");
+      return 1;
+    }
+
+  remove (fname);
+
+  int ret = one_test ("+:a:b", 2,
+		      (char *[2]) { (char *) "bug-getopt1", (char *) "-a" },
+		      (int [1]) { ':' });
+
+  ret |= one_test ("+:a:b", 3,
+		   (char *[3]) { (char *) "bug-getopt1", (char *) "-b",
+				 (char *) "-a" },
+		   (int [2]) { 'b', ':' });
+
+  if (ret == 0)
+    puts ("all OK");
+
+  return ret;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"

Added: fsf/trunk/libc/posix/bug-getopt2.c
==============================================================================
--- fsf/trunk/libc/posix/bug-getopt2.c (added)
+++ fsf/trunk/libc/posix/bug-getopt2.c Thu Apr  8 00:03:37 2010
@@ -1,0 +1,72 @@
+/* BZ 11039 */
+#include <unistd.h>
+#include <stdio.h>
+
+static int
+one_test (const char *fmt, int argc, char *argv[], int expected[argc - 1])
+{
+  int res = 0;
+  for (int i = 0; i < argc - 1; ++i)
+    {
+      rewind (stderr);
+      if (ftruncate (fileno (stderr), 0) != 0)
+	{
+	  puts ("cannot truncate file");
+	  return 1;
+	}
+
+      int c = getopt (argc, argv, fmt);
+      if (c != expected[i])
+	{
+	  printf ("format '%s' test %d failed: expected '%c', got '%c'\n",
+		  fmt, i, expected[i], c);
+	  res = 1;
+	}
+      if (ftell (stderr) == 0)
+	{
+	  printf ("format '%s' test %d failed: not printed to stderr\n",
+		  fmt, i);
+	  res = 1;
+	}
+    }
+
+  return res;
+}
+
+
+static int
+do_test (void)
+{
+  char *fname = tmpnam (NULL);
+  if (fname == NULL)
+    {
+      puts ("cannot generate name for temporary file");
+      return 1;
+    }
+
+  if (freopen (fname, "w+", stderr) == NULL)
+    {
+      puts ("cannot redirect stderr");
+      return 1;
+    }
+
+  remove (fname);
+
+  optind = 0;
+  int ret = one_test ("+a", 2,
+		      (char *[2]) { (char *) "bug-getopt2", (char *) "-+" },
+		      (int [1]) { '?' });
+
+  optind = 1;
+  ret |= one_test ("+a", 2,
+		   (char *[2]) { (char *) "bug-getopt2", (char *) "-+" },
+		   (int [1]) { '?' });
+
+  if (ret == 0)
+    puts ("all OK");
+
+  return ret;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"

Added: fsf/trunk/libc/posix/bug-getopt3.c
==============================================================================
--- fsf/trunk/libc/posix/bug-getopt3.c (added)
+++ fsf/trunk/libc/posix/bug-getopt3.c Thu Apr  8 00:03:37 2010
@@ -1,0 +1,81 @@
+/* BZ 11040 */
+#include <getopt.h>
+#include <unistd.h>
+#include <stdio.h>
+
+static const struct option opts[] =
+  {
+    { "alpha",	no_argument,       NULL, 'a' },
+    { "beta",	required_argument, NULL, 'b' },
+    { NULL,	0,                 NULL, 0 }
+  };
+
+static int
+one_test (const char *fmt, int argc, char *argv[], int n, int expected[n],
+	  int out[n])
+{
+  optind = 1;
+
+  int res = 0;
+  for (int i = 0; i < n; ++i)
+    {
+      rewind (stderr);
+      if (ftruncate (fileno (stderr), 0) != 0)
+	{
+	  puts ("cannot truncate file");
+	  return 1;
+	}
+
+      int c = getopt_long (argc, argv, fmt, opts, NULL);
+      if (c != expected[i])
+	{
+	  printf ("format '%s' test %d failed: expected '%c', got '%c'\n",
+		  fmt, i, expected[i], c);
+	  res = 1;
+	}
+      if ((ftell (stderr) != 0) != out[i])
+	{
+	  printf ("format '%s' test %d failed: %sprinted to stderr\n",
+		  fmt, i, out[i] ? "not " : "");
+	  res = 1;
+	}
+    }
+
+  return res;
+}
+
+
+static int
+do_test (void)
+{
+  char *fname = tmpnam (NULL);
+  if (fname == NULL)
+    {
+      puts ("cannot generate name for temporary file");
+      return 1;
+    }
+
+  if (freopen (fname, "w+", stderr) == NULL)
+    {
+      puts ("cannot redirect stderr");
+      return 1;
+    }
+
+  remove (fname);
+
+  int ret = one_test ("ab:W;", 2,
+		      (char *[2]) { (char *) "bug-getopt3", (char *) "-a;" },
+		      2, (int [2]) { 'a', '?' }, (int [2]) { 0, 1 });
+
+  ret |= one_test ("ab:W;", 2,
+		   (char *[2]) { (char *) "bug-getopt3", (char *) "-a:" }, 2,
+		   (int [2]) { 'a', '?' }, (int [2]) { 0, 1 });
+
+  if (ret == 0)
+    puts ("all OK");
+
+  return ret;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"

Added: fsf/trunk/libc/posix/bug-getopt4.c
==============================================================================
--- fsf/trunk/libc/posix/bug-getopt4.c (added)
+++ fsf/trunk/libc/posix/bug-getopt4.c Thu Apr  8 00:03:37 2010
@@ -1,0 +1,86 @@
+/* BZ 11041 */
+#include <getopt.h>
+#include <unistd.h>
+#include <stdio.h>
+
+static const struct option opts[] =
+  {
+    { "alpha",    optional_argument, NULL, 'a' },
+    { NULL,       0,                 NULL, 0 }
+  };
+
+static int
+one_test (const char *fmt, int argc, char *argv[], int n, int expected[n])
+{
+  optind = 1;
+
+  int res = 0;
+  for (int i = 0; i < n; ++i)
+    {
+      rewind (stderr);
+      if (ftruncate (fileno (stderr), 0) != 0)
+	{
+	  puts ("cannot truncate file");
+	  return 1;
+	}
+
+      int c = getopt_long (argc, argv, fmt, opts, NULL);
+      if (c != expected[i])
+	{
+	  printf ("format '%s' test %d failed: expected '%c', got '%c'\n",
+		  fmt, i, expected[i], c);
+	  res = 1;
+	}
+      else if (optarg != NULL)
+	{
+	  printf ("format '%s' test %d failed: optarg is \"%s\", not NULL\n",
+		  fmt, i, optarg);
+	  res = 1;
+	}
+      if (ftell (stderr) != 0)
+	{
+	  printf ("format '%s' test %d failed: printed to stderr\n",
+		  fmt, i);
+	  res = 1;
+	}
+    }
+
+  return res;
+}
+
+
+static int
+do_test (void)
+{
+  char *fname = tmpnam (NULL);
+  if (fname == NULL)
+    {
+      puts ("cannot generate name for temporary file");
+      return 1;
+    }
+
+  if (freopen (fname, "w+", stderr) == NULL)
+    {
+      puts ("cannot redirect stderr");
+      return 1;
+    }
+
+  remove (fname);
+
+  int ret = one_test ("W;", 2,
+		      (char *[2]) { (char *) "bug-getopt4", (char *) "--a" },
+		      1, (int [1]) { 'a' });
+
+  ret |= one_test ("W;", 3,
+		   (char *[3]) { (char *) "bug-getopt4", (char *) "-W",
+				 (char *) "a" },
+		   1, (int [1]) { 'a' });
+
+  if (ret == 0)
+    puts ("all OK");
+
+  return ret;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"

Added: fsf/trunk/libc/posix/bug-getopt5.c
==============================================================================
--- fsf/trunk/libc/posix/bug-getopt5.c (added)
+++ fsf/trunk/libc/posix/bug-getopt5.c Thu Apr  8 00:03:37 2010
@@ -1,0 +1,81 @@
+/* BZ 11041 */
+#include <getopt.h>
+#include <unistd.h>
+#include <stdio.h>
+
+static const struct option opts[] =
+  {
+    { "a1",    no_argument, NULL, 'a' },
+    { "a2",    no_argument, NULL, 'a' },
+    { NULL,    0,           NULL, 0 }
+  };
+
+static int
+one_test (const char *fmt, int argc, char *argv[], int n, int expected[n])
+{
+  optind = 1;
+
+  int res = 0;
+  for (int i = 0; i < n; ++i)
+    {
+      rewind (stderr);
+      if (ftruncate (fileno (stderr), 0) != 0)
+	{
+	  puts ("cannot truncate file");
+	  return 1;
+	}
+
+      int c = getopt_long (argc, argv, fmt, opts, NULL);
+      if (c != expected[i])
+	{
+	  printf ("format '%s' test %d failed: expected '%c', got '%c'\n",
+		  fmt, i, expected[i], c);
+	  res = 1;
+	}
+      if (ftell (stderr) != 0)
+	{
+	  printf ("format '%s' test %d failed: printed to stderr\n",
+		  fmt, i);
+	  res = 1;
+	}
+    }
+
+  return res;
+}
+
+
+static int
+do_test (void)
+{
+  char *fname = tmpnam (NULL);
+  if (fname == NULL)
+    {
+      puts ("cannot generate name for temporary file");
+      return 1;
+    }
+
+  if (freopen (fname, "w+", stderr) == NULL)
+    {
+      puts ("cannot redirect stderr");
+      return 1;
+    }
+
+  remove (fname);
+
+  int ret = one_test (":W;", 2,
+		      (char *[2]) { (char *) "bug-getopt5", (char *) "--a" },
+		      1, (int [1]) { 'a' });
+
+  ret |= one_test (":W;", 3,
+		   (char *[3]) { (char *) "bug-getopt5", (char *) "-W",
+				 (char *) "a" },
+		   1, (int [1]) { 'a' });
+
+  if (ret == 0)
+    puts ("all OK");
+
+  return ret;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"

Modified: fsf/trunk/libc/posix/getopt.c
==============================================================================
--- fsf/trunk/libc/posix/getopt.c (original)
+++ fsf/trunk/libc/posix/getopt.c Thu Apr  8 00:03:37 2010
@@ -395,8 +395,6 @@
 		    int long_only, struct _getopt_data *d, int posixly_correct)
 {
   int print_errors = d->opterr;
-  if (optstring[0] == ':')
-    print_errors = 0;
 
   if (argc < 1)
     return -1;
@@ -411,6 +409,10 @@
 				      posixly_correct);
       d->__initialized = 1;
     }
+  else if (optstring[0] == '-' || optstring[0] == '+')
+    optstring++;
+  if (optstring[0] == ':')
+    print_errors = 0;
 
   /* Test whether ARGV[optind] points to a non-option argument.
      Either it does not have option syntax, or there is an environment flag
@@ -789,7 +791,7 @@
     if (*d->__nextchar == '\0')
       ++d->optind;
 
-    if (temp == NULL || c == ':')
+    if (temp == NULL || c == ':' || c == ';')
       {
 	if (print_errors)
 	  {
@@ -911,7 +913,10 @@
 		  pfound = p;
 		  indfound = option_index;
 		}
-	      else
+	      else if (long_only
+		       || pfound->has_arg != p->has_arg
+		       || pfound->flag != p->flag
+		       || pfound->val != p->val)
 		/* Second or later nonexact match found.  */
 		ambig = 1;
 	    }
@@ -1028,6 +1033,8 @@
 		    return optstring[0] == ':' ? ':' : '?';
 		  }
 	      }
+	    else
+	      d->optarg = NULL;
 	    d->__nextchar += strlen (d->__nextchar);
 	    if (longind != NULL)
 	      *longind = option_index;