|
|
b9ba6d |
2011-11-07 Andreas Schwab <schwab@redhat.com>
|
|
|
b9ba6d |
|
|
|
b9ba6d |
* nss/nss_files/files-initgroups.c (_nss_files_initgroups_dyn):
|
|
|
b9ba6d |
Fix size of allocated buffer.
|
|
|
b9ba6d |
|
|
|
b9ba6d |
2011-05-10 Ulrich Drepper <drepper@gmail.com>
|
|
|
b9ba6d |
|
|
|
b9ba6d |
[BZ #11257]
|
|
|
b9ba6d |
* grp/initgroups.c (internal_getgrouplist): When we found the service
|
|
|
b9ba6d |
list through the initgroups entry in nsswitch.conf do not always
|
|
|
b9ba6d |
continue on a successful lookup. Don't always use the
|
|
|
b9ba6d |
__nss_group_data-ase value if it is set.
|
|
|
b9ba6d |
* nss/nsswitch.conf (initgroups): Change action for successful db
|
|
|
b9ba6d |
lookup to continue for compatibility.
|
|
|
b9ba6d |
|
|
|
b9ba6d |
2011-05-06 Ulrich Drepper <drepper@gmail.com>
|
|
|
b9ba6d |
|
|
|
b9ba6d |
* nss/nss_files/files-initgroups.c (_nss_files_initgroups_dyn): Return
|
|
|
b9ba6d |
NSS_STATUS_NOTFOUND if no record was found.
|
|
|
b9ba6d |
|
|
|
b9ba6d |
2011-04-29 Ulrich Drepper <drepper@gmail.com>
|
|
|
b9ba6d |
|
|
|
b9ba6d |
* grp/initgroups.c (internal_getgrouplist): Prefer initgroups setting
|
|
|
b9ba6d |
to groups setting in database lookup.
|
|
|
b9ba6d |
* nss/nsswitch.conf: Add initgroups entry.
|
|
|
b9ba6d |
|
|
|
b9ba6d |
2011-04-21 Ulrich Drepper <drepper@gmail.com>
|
|
|
b9ba6d |
|
|
|
b9ba6d |
* nss/nss_files/files-initgroups.c (_nss_files_initgroups_dyn): Fix
|
|
|
b9ba6d |
problem in reallocation in last patch.
|
|
|
b9ba6d |
|
|
|
b9ba6d |
2011-04-19 Ulrich Drepper <drepper@gmail.com>
|
|
|
b9ba6d |
|
|
|
b9ba6d |
* nss/nss_files/files-initgroups.c: New file.
|
|
|
b9ba6d |
* nss/Makefile (libnss_files-routines): Add files-initgroups.
|
|
|
b9ba6d |
* nss/Versions (libnss_files) [GLIBC_PRIVATE]: Export
|
|
|
b9ba6d |
_nss_files_initgroups_dyn.
|
|
|
b9ba6d |
|
|
|
b9ba6d |
2011-01-13 Ulrich Drepper <drepper@gmail.com>
|
|
|
b9ba6d |
|
|
|
b9ba6d |
[BZ #10484]
|
|
|
b9ba6d |
* nss/nss_files/files-hosts.c (HOST_DB_LOOKUP): Handle overflows of
|
|
|
b9ba6d |
temporary buffer used to handle multi lookups locally.
|
|
|
b9ba6d |
* include/alloca.h: Add libc_hidden_proto for __libc_alloca_cutoff.
|
|
|
b9ba6d |
|
|
|
b9ba6d |
2011-01-13 Ulrich Drepper <drepper@gmail.com>
|
|
|
b9ba6d |
|
|
|
b9ba6d |
[BZ #10484]
|
|
|
b9ba6d |
* Versions [libc] (GLIBC_PRIVATE): Export __libc_alloca_cutoff.
|
|
|
b9ba6d |
* alloca_cutoff.c: Add libc_hidden_def.
|
|
|
b9ba6d |
|
|
|
b9ba6d |
Index: glibc-2.12-2-gc4ccff1/grp/initgroups.c
|
|
|
b9ba6d |
===================================================================
|
|
|
b9ba6d |
--- glibc-2.12-2-gc4ccff1.orig/grp/initgroups.c
|
|
|
b9ba6d |
+++ glibc-2.12-2-gc4ccff1/grp/initgroups.c
|
|
|
b9ba6d |
@@ -43,6 +43,8 @@ extern int __nss_group_lookup (service_u
|
|
|
b9ba6d |
extern void *__nss_lookup_function (service_user *ni, const char *fct_name);
|
|
|
b9ba6d |
|
|
|
b9ba6d |
extern service_user *__nss_group_database attribute_hidden;
|
|
|
b9ba6d |
+static service_user *initgroups_database;
|
|
|
b9ba6d |
+static bool use_initgroups_entry;
|
|
|
b9ba6d |
|
|
|
b9ba6d |
|
|
|
b9ba6d |
#include "compat-initgroups.c"
|
|
|
b9ba6d |
@@ -67,32 +69,41 @@ internal_getgrouplist (const char *user,
|
|
|
b9ba6d |
}
|
|
|
b9ba6d |
#endif
|
|
|
b9ba6d |
|
|
|
b9ba6d |
- service_user *nip = NULL;
|
|
|
b9ba6d |
- initgroups_dyn_function fct;
|
|
|
b9ba6d |
enum nss_status status = NSS_STATUS_UNAVAIL;
|
|
|
b9ba6d |
- int no_more;
|
|
|
b9ba6d |
- /* Start is one, because we have the first group as parameter. */
|
|
|
b9ba6d |
- long int start = 1;
|
|
|
b9ba6d |
+ int no_more = 0;
|
|
|
b9ba6d |
|
|
|
b9ba6d |
/* Never store more than the starting *SIZE number of elements. */
|
|
|
b9ba6d |
assert (*size > 0);
|
|
|
b9ba6d |
(*groupsp)[0] = group;
|
|
|
b9ba6d |
+ /* Start is one, because we have the first group as parameter. */
|
|
|
b9ba6d |
+ long int start = 1;
|
|
|
b9ba6d |
|
|
|
b9ba6d |
- if (__nss_group_database != NULL)
|
|
|
b9ba6d |
+ if (initgroups_database == NULL)
|
|
|
b9ba6d |
{
|
|
|
b9ba6d |
- no_more = 0;
|
|
|
b9ba6d |
- nip = __nss_group_database;
|
|
|
b9ba6d |
+ no_more = __nss_database_lookup ("initgroups", NULL, "",
|
|
|
b9ba6d |
+ &initgroups_database);
|
|
|
b9ba6d |
+ if (no_more == 0 && initgroups_database == NULL)
|
|
|
b9ba6d |
+ {
|
|
|
b9ba6d |
+ if (__nss_group_database == NULL)
|
|
|
b9ba6d |
+ no_more = __nss_database_lookup ("group", NULL, "compat files",
|
|
|
b9ba6d |
+ &__nss_group_database);
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ initgroups_database = __nss_group_database;
|
|
|
b9ba6d |
+ }
|
|
|
b9ba6d |
+ else if (initgroups_database != NULL)
|
|
|
b9ba6d |
+ {
|
|
|
b9ba6d |
+ assert (no_more == 0);
|
|
|
b9ba6d |
+ use_initgroups_entry = true;
|
|
|
b9ba6d |
+ }
|
|
|
b9ba6d |
}
|
|
|
b9ba6d |
- else
|
|
|
b9ba6d |
- no_more = __nss_database_lookup ("group", NULL,
|
|
|
b9ba6d |
- "compat [NOTFOUND=return] files", &nip;;
|
|
|
b9ba6d |
|
|
|
b9ba6d |
+ service_user *nip = initgroups_database;
|
|
|
b9ba6d |
while (! no_more)
|
|
|
b9ba6d |
{
|
|
|
b9ba6d |
long int prev_start = start;
|
|
|
b9ba6d |
|
|
|
b9ba6d |
- fct = __nss_lookup_function (nip, "initgroups_dyn");
|
|
|
b9ba6d |
-
|
|
|
b9ba6d |
+ initgroups_dyn_function fct = __nss_lookup_function (nip,
|
|
|
b9ba6d |
+ "initgroups_dyn");
|
|
|
b9ba6d |
if (fct == NULL)
|
|
|
b9ba6d |
status = compat_call (nip, user, group, &start, size, groupsp,
|
|
|
b9ba6d |
limit, &errno);
|
|
|
b9ba6d |
@@ -119,7 +130,13 @@ internal_getgrouplist (const char *user,
|
|
|
b9ba6d |
if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN)
|
|
|
b9ba6d |
__libc_fatal ("illegal status in internal_getgrouplist");
|
|
|
b9ba6d |
|
|
|
b9ba6d |
- if (status != NSS_STATUS_SUCCESS
|
|
|
b9ba6d |
+ /* For compatibility reason we will continue to look for more
|
|
|
b9ba6d |
+ entries using the next service even though data has already
|
|
|
b9ba6d |
+ been found if the nsswitch.conf file contained only a 'groups'
|
|
|
b9ba6d |
+ line and no 'initgroups' line. If the latter is available
|
|
|
b9ba6d |
+ we always respect the status. This means that the default
|
|
|
b9ba6d |
+ for successful lookups is to return. */
|
|
|
b9ba6d |
+ if ((use_initgroups_entry || status != NSS_STATUS_SUCCESS)
|
|
|
b9ba6d |
&& nss_next_action (nip, status) == NSS_ACTION_RETURN)
|
|
|
b9ba6d |
break;
|
|
|
b9ba6d |
|
|
|
b9ba6d |
Index: glibc-2.12-2-gc4ccff1/include/alloca.h
|
|
|
b9ba6d |
===================================================================
|
|
|
b9ba6d |
--- glibc-2.12-2-gc4ccff1.orig/include/alloca.h
|
|
|
b9ba6d |
+++ glibc-2.12-2-gc4ccff1/include/alloca.h
|
|
|
b9ba6d |
@@ -14,6 +14,7 @@ extern void *__alloca (size_t __size);
|
|
|
b9ba6d |
|
|
|
b9ba6d |
extern int __libc_use_alloca (size_t size) __attribute__ ((const));
|
|
|
b9ba6d |
extern int __libc_alloca_cutoff (size_t size) __attribute__ ((const));
|
|
|
b9ba6d |
+libc_hidden_proto (__libc_alloca_cutoff)
|
|
|
b9ba6d |
|
|
|
b9ba6d |
#define __MAX_ALLOCA_CUTOFF 65536
|
|
|
b9ba6d |
|
|
|
b9ba6d |
Index: glibc-2.12-2-gc4ccff1/nptl/Versions
|
|
|
b9ba6d |
===================================================================
|
|
|
b9ba6d |
--- glibc-2.12-2-gc4ccff1.orig/nptl/Versions
|
|
|
b9ba6d |
+++ glibc-2.12-2-gc4ccff1/nptl/Versions
|
|
|
b9ba6d |
@@ -27,6 +27,7 @@ libc {
|
|
|
b9ba6d |
pthread_cond_broadcast; pthread_cond_timedwait;
|
|
|
b9ba6d |
}
|
|
|
b9ba6d |
GLIBC_PRIVATE {
|
|
|
b9ba6d |
+ __libc_alloca_cutoff;
|
|
|
b9ba6d |
# Internal libc interface to libpthread
|
|
|
b9ba6d |
__libc_dl_error_tsd;
|
|
|
b9ba6d |
}
|
|
|
b9ba6d |
Index: glibc-2.12-2-gc4ccff1/nptl/alloca_cutoff.c
|
|
|
b9ba6d |
===================================================================
|
|
|
b9ba6d |
--- glibc-2.12-2-gc4ccff1.orig/nptl/alloca_cutoff.c
|
|
|
b9ba6d |
+++ glibc-2.12-2-gc4ccff1/nptl/alloca_cutoff.c
|
|
|
b9ba6d |
@@ -34,3 +34,4 @@ __libc_alloca_cutoff (size_t size)
|
|
|
b9ba6d |
assume the maximum available stack space. */
|
|
|
b9ba6d |
?: __MAX_ALLOCA_CUTOFF * 4));
|
|
|
b9ba6d |
}
|
|
|
b9ba6d |
+libc_hidden_def (__libc_alloca_cutoff)
|
|
|
b9ba6d |
Index: glibc-2.12-2-gc4ccff1/nss/Makefile
|
|
|
b9ba6d |
===================================================================
|
|
|
b9ba6d |
--- glibc-2.12-2-gc4ccff1.orig/nss/Makefile
|
|
|
b9ba6d |
+++ glibc-2.12-2-gc4ccff1/nss/Makefile
|
|
|
b9ba6d |
@@ -63,7 +63,7 @@ vpath %.c $(subdir-dirs)
|
|
|
b9ba6d |
|
|
|
b9ba6d |
|
|
|
b9ba6d |
libnss_files-routines := $(addprefix files-,$(databases)) \
|
|
|
b9ba6d |
- files-have_o_cloexec
|
|
|
b9ba6d |
+ files-initgroups files-have_o_cloexec
|
|
|
b9ba6d |
distribute += files-XXX.c files-parse.c
|
|
|
b9ba6d |
|
|
|
b9ba6d |
|
|
|
b9ba6d |
Index: glibc-2.12-2-gc4ccff1/nss/Versions
|
|
|
b9ba6d |
===================================================================
|
|
|
b9ba6d |
--- glibc-2.12-2-gc4ccff1.orig/nss/Versions
|
|
|
b9ba6d |
+++ glibc-2.12-2-gc4ccff1/nss/Versions
|
|
|
b9ba6d |
@@ -95,5 +95,7 @@ libnss_files {
|
|
|
b9ba6d |
_nss_netgroup_parseline;
|
|
|
b9ba6d |
_nss_files_getpublickey;
|
|
|
b9ba6d |
_nss_files_getsecretkey;
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ _nss_files_initgroups_dyn;
|
|
|
b9ba6d |
}
|
|
|
b9ba6d |
}
|
|
|
b9ba6d |
Index: glibc-2.12-2-gc4ccff1/nss/nss_files/files-hosts.c
|
|
|
b9ba6d |
===================================================================
|
|
|
b9ba6d |
--- glibc-2.12-2-gc4ccff1.orig/nss/nss_files/files-hosts.c
|
|
|
b9ba6d |
+++ glibc-2.12-2-gc4ccff1/nss/nss_files/files-hosts.c
|
|
|
b9ba6d |
@@ -129,19 +129,22 @@ _nss_files_get##name##_r (proto,
|
|
|
b9ba6d |
&& _res_hconf.flags & HCONF_FLAG_MULTI) \
|
|
|
b9ba6d |
{ \
|
|
|
b9ba6d |
/* We have to get all host entries from the file. */ \
|
|
|
b9ba6d |
- const size_t tmp_buflen = MIN (buflen, 4096); \
|
|
|
b9ba6d |
- char tmp_buffer[tmp_buflen] \
|
|
|
b9ba6d |
+ size_t tmp_buflen = MIN (buflen, 4096); \
|
|
|
b9ba6d |
+ char tmp_buffer_stack[tmp_buflen] \
|
|
|
b9ba6d |
__attribute__ ((__aligned__ (__alignof__ (struct hostent_data))));\
|
|
|
b9ba6d |
+ char *tmp_buffer = tmp_buffer_stack; \
|
|
|
b9ba6d |
struct hostent tmp_result_buf; \
|
|
|
b9ba6d |
int naddrs = 1; \
|
|
|
b9ba6d |
int naliases = 0; \
|
|
|
b9ba6d |
char *bufferend; \
|
|
|
b9ba6d |
+ bool tmp_buffer_malloced = false; \
|
|
|
b9ba6d |
\
|
|
|
b9ba6d |
while (result->h_aliases[naliases] != NULL) \
|
|
|
b9ba6d |
++naliases; \
|
|
|
b9ba6d |
\
|
|
|
b9ba6d |
bufferend = (char *) &result->h_aliases[naliases + 1]; \
|
|
|
b9ba6d |
\
|
|
|
b9ba6d |
+ again: \
|
|
|
b9ba6d |
while ((status = internal_getent (&tmp_result_buf, tmp_buffer, \
|
|
|
b9ba6d |
tmp_buflen, errnop H_ERRNO_ARG \
|
|
|
b9ba6d |
EXTRA_ARGS_VALUE)) \
|
|
|
b9ba6d |
@@ -182,7 +185,7 @@ _nss_files_get##name##_r (proto,
|
|
|
b9ba6d |
} \
|
|
|
b9ba6d |
/* If the real name is different add it also to the \
|
|
|
b9ba6d |
aliases. This means that there is a duplication \
|
|
|
b9ba6d |
- in the alias list but this is really the users \
|
|
|
b9ba6d |
+ in the alias list but this is really the user's \
|
|
|
b9ba6d |
problem. */ \
|
|
|
b9ba6d |
if (strcmp (old_result->h_name, \
|
|
|
b9ba6d |
tmp_result_buf.h_name) != 0) \
|
|
|
b9ba6d |
@@ -204,7 +207,7 @@ _nss_files_get##name##_r (proto,
|
|
|
b9ba6d |
*errnop = ERANGE; \
|
|
|
b9ba6d |
*herrnop = NETDB_INTERNAL; \
|
|
|
b9ba6d |
status = NSS_STATUS_TRYAGAIN; \
|
|
|
b9ba6d |
- break; \
|
|
|
b9ba6d |
+ goto out; \
|
|
|
b9ba6d |
} \
|
|
|
b9ba6d |
\
|
|
|
b9ba6d |
new_h_addr_list = \
|
|
|
b9ba6d |
@@ -268,8 +271,54 @@ _nss_files_get##name##_r (proto,
|
|
|
b9ba6d |
} \
|
|
|
b9ba6d |
} \
|
|
|
b9ba6d |
\
|
|
|
b9ba6d |
- if (status != NSS_STATUS_TRYAGAIN) \
|
|
|
b9ba6d |
+ if (status == NSS_STATUS_TRYAGAIN) \
|
|
|
b9ba6d |
+ { \
|
|
|
b9ba6d |
+ size_t newsize = 2 * tmp_buflen; \
|
|
|
b9ba6d |
+ if (tmp_buffer_malloced) \
|
|
|
b9ba6d |
+ { \
|
|
|
b9ba6d |
+ char *newp = realloc (tmp_buffer, newsize); \
|
|
|
b9ba6d |
+ if (newp != NULL) \
|
|
|
b9ba6d |
+ { \
|
|
|
b9ba6d |
+ assert ((((uintptr_t) newp) \
|
|
|
b9ba6d |
+ & (__alignof__ (struct hostent_data) - 1)) \
|
|
|
b9ba6d |
+ == 0); \
|
|
|
b9ba6d |
+ tmp_buffer = newp; \
|
|
|
b9ba6d |
+ tmp_buflen = newsize; \
|
|
|
b9ba6d |
+ goto again; \
|
|
|
b9ba6d |
+ } \
|
|
|
b9ba6d |
+ } \
|
|
|
b9ba6d |
+ else if (!__libc_use_alloca (buflen + newsize)) \
|
|
|
b9ba6d |
+ { \
|
|
|
b9ba6d |
+ tmp_buffer = malloc (newsize); \
|
|
|
b9ba6d |
+ if (tmp_buffer != NULL) \
|
|
|
b9ba6d |
+ { \
|
|
|
b9ba6d |
+ assert ((((uintptr_t) tmp_buffer) \
|
|
|
b9ba6d |
+ & (__alignof__ (struct hostent_data) - 1)) \
|
|
|
b9ba6d |
+ == 0); \
|
|
|
b9ba6d |
+ tmp_buffer_malloced = true; \
|
|
|
b9ba6d |
+ tmp_buflen = newsize; \
|
|
|
b9ba6d |
+ goto again; \
|
|
|
b9ba6d |
+ } \
|
|
|
b9ba6d |
+ } \
|
|
|
b9ba6d |
+ else \
|
|
|
b9ba6d |
+ { \
|
|
|
b9ba6d |
+ tmp_buffer \
|
|
|
b9ba6d |
+ = extend_alloca (tmp_buffer, tmp_buflen, \
|
|
|
b9ba6d |
+ newsize \
|
|
|
b9ba6d |
+ + __alignof__ (struct hostent_data)); \
|
|
|
b9ba6d |
+ tmp_buffer = (char *) (((uintptr_t) tmp_buffer \
|
|
|
b9ba6d |
+ + __alignof__ (struct hostent_data) \
|
|
|
b9ba6d |
+ - 1) \
|
|
|
b9ba6d |
+ & ~(__alignof__ (struct hostent_data)\
|
|
|
b9ba6d |
+ - 1)); \
|
|
|
b9ba6d |
+ goto again; \
|
|
|
b9ba6d |
+ } \
|
|
|
b9ba6d |
+ } \
|
|
|
b9ba6d |
+ else \
|
|
|
b9ba6d |
status = NSS_STATUS_SUCCESS; \
|
|
|
b9ba6d |
+ out: \
|
|
|
b9ba6d |
+ if (tmp_buffer_malloced) \
|
|
|
b9ba6d |
+ free (tmp_buffer); \
|
|
|
b9ba6d |
} \
|
|
|
b9ba6d |
\
|
|
|
b9ba6d |
\
|
|
|
b9ba6d |
Index: glibc-2.12-2-gc4ccff1/nss/nss_files/files-initgroups.c
|
|
|
b9ba6d |
===================================================================
|
|
|
b9ba6d |
--- /dev/null
|
|
|
b9ba6d |
+++ glibc-2.12-2-gc4ccff1/nss/nss_files/files-initgroups.c
|
|
|
b9ba6d |
@@ -0,0 +1,137 @@
|
|
|
b9ba6d |
+/* Initgroups handling in nss_files module.
|
|
|
b9ba6d |
+ Copyright (C) 2011 Free Software Foundation, Inc.
|
|
|
b9ba6d |
+ This file is part of the GNU C Library.
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ The GNU C Library is free software; you can redistribute it and/or
|
|
|
b9ba6d |
+ modify it under the terms of the GNU Lesser General Public
|
|
|
b9ba6d |
+ License as published by the Free Software Foundation; either
|
|
|
b9ba6d |
+ version 2.1 of the License, or (at your option) any later version.
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
|
b9ba6d |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
b9ba6d |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
b9ba6d |
+ Lesser General Public License for more details.
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ You should have received a copy of the GNU Lesser General Public
|
|
|
b9ba6d |
+ License along with the GNU C Library; if not, write to the Free
|
|
|
b9ba6d |
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|
|
b9ba6d |
+ 02111-1307 USA. */
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+#include <alloca.h>
|
|
|
b9ba6d |
+#include <errno.h>
|
|
|
b9ba6d |
+#include <grp.h>
|
|
|
b9ba6d |
+#include <nss.h>
|
|
|
b9ba6d |
+#include <stdio_ext.h>
|
|
|
b9ba6d |
+#include <string.h>
|
|
|
b9ba6d |
+#include <sys/param.h>
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+enum nss_status
|
|
|
b9ba6d |
+_nss_files_initgroups_dyn (const char *user, gid_t group, long int *start,
|
|
|
b9ba6d |
+ long int *size, gid_t **groupsp, long int limit,
|
|
|
b9ba6d |
+ int *errnop)
|
|
|
b9ba6d |
+{
|
|
|
b9ba6d |
+ FILE *stream = fopen ("/etc/group", "re");
|
|
|
b9ba6d |
+ if (stream == NULL)
|
|
|
b9ba6d |
+ {
|
|
|
b9ba6d |
+ *errnop = errno;
|
|
|
b9ba6d |
+ return *errnop == ENOMEM ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
|
|
|
b9ba6d |
+ }
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ /* No other thread using this stream. */
|
|
|
b9ba6d |
+ __fsetlocking (stream, FSETLOCKING_BYCALLER);
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ char *line = NULL;
|
|
|
b9ba6d |
+ size_t linelen = 0;
|
|
|
b9ba6d |
+ enum nss_status status = NSS_STATUS_SUCCESS;
|
|
|
b9ba6d |
+ bool any = false;
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ size_t buflen = 1024;
|
|
|
b9ba6d |
+ void *buffer = alloca (buflen);
|
|
|
b9ba6d |
+ bool buffer_use_malloc = false;
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ gid_t *groups = *groupsp;
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ /* We have to iterate over the entire file. */
|
|
|
b9ba6d |
+ while (!feof_unlocked (stream))
|
|
|
b9ba6d |
+ {
|
|
|
b9ba6d |
+ ssize_t n = getline (&line, &linelen, stream);
|
|
|
b9ba6d |
+ if (n < 0)
|
|
|
b9ba6d |
+ {
|
|
|
b9ba6d |
+ if (! feof_unlocked (stream))
|
|
|
b9ba6d |
+ status = ((*errnop = errno) == ENOMEM
|
|
|
b9ba6d |
+ ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL);
|
|
|
b9ba6d |
+ break;
|
|
|
b9ba6d |
+ }
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ struct group grp;
|
|
|
b9ba6d |
+ int res;
|
|
|
b9ba6d |
+ while ((res = _nss_files_parse_grent (line, &grp, buffer, buflen,
|
|
|
b9ba6d |
+ errnop)) == -1)
|
|
|
b9ba6d |
+ {
|
|
|
b9ba6d |
+ size_t newbuflen = 2 * buflen;
|
|
|
b9ba6d |
+ if (buffer_use_malloc || ! __libc_use_alloca (buflen + newbuflen))
|
|
|
b9ba6d |
+ {
|
|
|
b9ba6d |
+ void *newbuf = realloc (buffer_use_malloc ? buffer : NULL,
|
|
|
b9ba6d |
+ newbuflen);
|
|
|
b9ba6d |
+ if (newbuf == NULL)
|
|
|
b9ba6d |
+ {
|
|
|
b9ba6d |
+ *errnop = ENOMEM;
|
|
|
b9ba6d |
+ status = NSS_STATUS_TRYAGAIN;
|
|
|
b9ba6d |
+ goto out;
|
|
|
b9ba6d |
+ }
|
|
|
b9ba6d |
+ buffer = newbuf;
|
|
|
b9ba6d |
+ buflen = newbuflen;
|
|
|
b9ba6d |
+ buffer_use_malloc = true;
|
|
|
b9ba6d |
+ }
|
|
|
b9ba6d |
+ else
|
|
|
b9ba6d |
+ buffer = extend_alloca (buffer, buflen, newbuflen);
|
|
|
b9ba6d |
+ }
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ if (res > 0 && grp.gr_gid != group)
|
|
|
b9ba6d |
+ for (char **m = grp.gr_mem; *m != NULL; ++m)
|
|
|
b9ba6d |
+ if (strcmp (*m, user) == 0)
|
|
|
b9ba6d |
+ {
|
|
|
b9ba6d |
+ /* Matches user. Insert this group. */
|
|
|
b9ba6d |
+ if (*start == *size)
|
|
|
b9ba6d |
+ {
|
|
|
b9ba6d |
+ /* Need a bigger buffer. */
|
|
|
b9ba6d |
+ if (limit > 0 && *size == limit)
|
|
|
b9ba6d |
+ /* We reached the maximum. */
|
|
|
b9ba6d |
+ goto out;
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ long int newsize;
|
|
|
b9ba6d |
+ if (limit <= 0)
|
|
|
b9ba6d |
+ newsize = 2 * *size;
|
|
|
b9ba6d |
+ else
|
|
|
b9ba6d |
+ newsize = MIN (limit, 2 * *size);
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ gid_t *newgroups = realloc (groups,
|
|
|
b9ba6d |
+ newsize * sizeof (*groups));
|
|
|
b9ba6d |
+ if (newgroups == NULL)
|
|
|
b9ba6d |
+ {
|
|
|
b9ba6d |
+ *errnop = ENOMEM;
|
|
|
b9ba6d |
+ status = NSS_STATUS_TRYAGAIN;
|
|
|
b9ba6d |
+ goto out;
|
|
|
b9ba6d |
+ }
|
|
|
b9ba6d |
+ *groupsp = groups = newgroups;
|
|
|
b9ba6d |
+ *size = newsize;
|
|
|
b9ba6d |
+ }
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ groups[*start] = grp.gr_gid;
|
|
|
b9ba6d |
+ *start += 1;
|
|
|
b9ba6d |
+ any = true;
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ break;
|
|
|
b9ba6d |
+ }
|
|
|
b9ba6d |
+ }
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ out:
|
|
|
b9ba6d |
+ /* Free memory. */
|
|
|
b9ba6d |
+ if (buffer_use_malloc)
|
|
|
b9ba6d |
+ free (buffer);
|
|
|
b9ba6d |
+ free (line);
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ fclose (stream);
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ return status == NSS_STATUS_SUCCESS && !any ? NSS_STATUS_NOTFOUND : status;
|
|
|
b9ba6d |
+}
|
|
|
b9ba6d |
Index: glibc-2.12-2-gc4ccff1/nss/nsswitch.conf
|
|
|
b9ba6d |
===================================================================
|
|
|
b9ba6d |
--- glibc-2.12-2-gc4ccff1.orig/nss/nsswitch.conf
|
|
|
b9ba6d |
+++ glibc-2.12-2-gc4ccff1/nss/nsswitch.conf
|
|
|
b9ba6d |
@@ -5,6 +5,7 @@
|
|
|
b9ba6d |
|
|
|
b9ba6d |
passwd: db files
|
|
|
b9ba6d |
group: db files
|
|
|
b9ba6d |
+initgroups: db [SUCCESS=continue] files
|
|
|
b9ba6d |
shadow: db files
|
|
|
b9ba6d |
gshadow: files
|
|
|
b9ba6d |
|