summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2004-10-05 11:23:19 +0000
committerJakub Jelinek <jakub@redhat.com>2004-10-05 11:23:19 +0000
commit09c3bcb4adf312661293d6e41a52a572f6db8241 (patch)
treed9185beca616a817aee1c07223e2dac0bff91657
parentfd63f7c6ce353ccfdbba58a37e8ef5465fcedfe4 (diff)
Fix s390{,x} build. grouplist fixes from Ulrich.
-rw-r--r--ChangeLog3
-rw-r--r--grp/compat-initgroups.c61
-rw-r--r--grp/initgroups.c19
-rw-r--r--nscd/initgrcache.c16
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h1
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h1
6 files changed, 75 insertions, 26 deletions
diff --git a/ChangeLog b/ChangeLog
index 8f3248f773..ea4be8811c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
2004-10-05 Jakub Jelinek <jakub@redhat.com>
+ * sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h: Include dl-sysdep.h.
+ * sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h: Likewise.
+
* sysdeps/unix/sysv/linux/i386/sysconf.c: Include hp-timing.h.
(__sysconf): Return -1 for _SC_CPUTIME or _SC_THREAD_CPUTIME if
!HP_TIMING_AVAIL.
diff --git a/grp/compat-initgroups.c b/grp/compat-initgroups.c
index 585c4aecbb..efd875a689 100644
--- a/grp/compat-initgroups.c
+++ b/grp/compat-initgroups.c
@@ -58,31 +58,42 @@ compat_call (service_user *nip, const char *user, gid_t group, long int *start,
for (m = grpbuf.gr_mem; *m != NULL; ++m)
if (strcmp (*m, user) == 0)
{
- /* Matches user. Insert this group. */
- if (__builtin_expect (*start == *size, 0))
- {
- /* Need a bigger buffer. */
- gid_t *newgroups;
- long int newsize;
-
- if (limit > 0 && *size == limit)
- /* We reached the maximum. */
- goto done;
-
- if (limit <= 0)
- newsize = 2 * *size;
- else
- newsize = MIN (limit, 2 * *size);
-
- newgroups = realloc (groups, newsize * sizeof (*groups));
- if (newgroups == NULL)
- goto done;
- *groupsp = groups = newgroups;
- *size = newsize;
- }
-
- groups[*start] = grpbuf.gr_gid;
- *start += 1;
+ /* Check whether the group is already on the list. */
+ long int cnt;
+ for (cnt = 0; cnt < *start; ++cnt)
+ if (groups[cnt] == grpbuf.gr_gid)
+ break;
+
+ if (cnt == *start)
+ {
+ /* Matches user and not yet on the list. Insert
+ this group. */
+ if (__builtin_expect (*start == *size, 0))
+ {
+ /* Need a bigger buffer. */
+ gid_t *newgroups;
+ long int newsize;
+
+ if (limit > 0 && *size == limit)
+ /* We reached the maximum. */
+ goto done;
+
+ if (limit <= 0)
+ newsize = 2 * *size;
+ else
+ newsize = MIN (limit, 2 * *size);
+
+ newgroups = realloc (groups,
+ newsize * sizeof (*groups));
+ if (newgroups == NULL)
+ goto done;
+ *groupsp = groups = newgroups;
+ *size = newsize;
+ }
+
+ groups[*start] = grpbuf.gr_gid;
+ *start += 1;
+ }
break;
}
diff --git a/grp/initgroups.c b/grp/initgroups.c
index 9e79273f3e..f86f5c63f4 100644
--- a/grp/initgroups.c
+++ b/grp/initgroups.c
@@ -73,7 +73,7 @@ internal_getgrouplist (const char *user, gid_t group, long int *size,
/* Start is one, because we have the first group as parameter. */
long int start = 1;
- *groupsp[0] = group;
+ (*groupsp)[0] = group;
if (__nss_group_database != NULL)
{
@@ -86,6 +86,8 @@ internal_getgrouplist (const char *user, gid_t group, long int *size,
while (! no_more)
{
+ long int prev_start = start;
+
fct = __nss_lookup_function (nip, "initgroups_dyn");
if (fct == NULL)
@@ -100,6 +102,21 @@ internal_getgrouplist (const char *user, gid_t group, long int *size,
status = DL_CALL_FCT (fct, (user, group, &start, size, groupsp,
limit, &errno));
+ /* Remove duplicates. */
+ long int cnt = prev_start;
+ while (cnt < start)
+ {
+ long int inner;
+ for (inner = 0; inner < prev_start; ++inner)
+ if ((*groupsp)[inner] == (*groups)[cnt])
+ break;
+
+ if (inner < prev_start)
+ ++cnt;
+ else
+ (*groupsp)[cnt] = (*groupsp)[--start];
+ }
+
/* This is really only for debugging. */
if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN)
__libc_fatal ("illegal status in internal_getgrouplist");
diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
index 124b4bae62..9ba7b89bdf 100644
--- a/nscd/initgrcache.c
+++ b/nscd/initgrcache.c
@@ -117,6 +117,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
/* Nothing added yet. */
while (! no_more)
{
+ long int prev_start = start;
enum nss_status status;
initgroups_dyn_function fct;
fct = __nss_lookup_function (nip, "initgroups_dyn");
@@ -133,6 +134,21 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
status = DL_CALL_FCT (fct, (key, -1, &start, &size, &groups,
limit, &errno));
+ /* Remove duplicates. */
+ long int cnt = prev_start;
+ while (cnt < start)
+ {
+ long int inner;
+ for (inner = 0; inner < prev_start; ++inner)
+ if ((*groupsp)[inner] == (*groups)[cnt])
+ break;
+
+ if (inner < prev_start)
+ ++cnt;
+ else
+ (*groupsp)[cnt] = (*groupsp)[--start];
+ }
+
if (status != NSS_STATUS_TRYAGAIN)
all_tryagain = false;
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h b/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h
index ad3cde6a66..43b1b951d5 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h
@@ -22,6 +22,7 @@
#include <sysdeps/s390/s390-32/sysdep.h>
#include <sysdeps/unix/sysdep.h>
+#include <dl-sysdep.h> /* For RTLD_PRIVATE_ERRNO. */
/* For Linux we can use the system call table in the header file
/usr/include/asm/unistd.h
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h
index 45e701e7a4..154bc06803 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h
@@ -23,6 +23,7 @@
#include <sysdeps/s390/s390-64/sysdep.h>
#include <sysdeps/unix/sysdep.h>
+#include <dl-sysdep.h> /* For RTLD_PRIVATE_ERRNO. */
/* For Linux we can use the system call table in the header file
/usr/include/asm/unistd.h