summaryrefslogtreecommitdiff
path: root/grp
diff options
context:
space:
mode:
Diffstat (limited to 'grp')
-rw-r--r--grp/Makefile25
-rw-r--r--grp/Versions3
-rw-r--r--grp/fgetgrent.c2
-rw-r--r--grp/fgetgrent_r.c2
-rw-r--r--grp/getgrent.c2
-rw-r--r--grp/getgrent_r.c2
-rw-r--r--grp/getgrgid.c2
-rw-r--r--grp/getgrgid_r.c5
-rw-r--r--grp/getgrnam.c2
-rw-r--r--grp/getgrnam_r.c6
-rw-r--r--grp/grp-merge.c200
-rw-r--r--grp/grp-merge.h35
-rw-r--r--grp/grp.h5
-rw-r--r--grp/initgroups.c17
-rw-r--r--grp/putgrent.c2
-rw-r--r--grp/setgroups.c2
-rw-r--r--grp/tst-putgrent.c2
-rw-r--r--grp/tst_fgetgrent.c12
-rw-r--r--grp/tst_fgetgrent.sh2
19 files changed, 290 insertions, 38 deletions
diff --git a/grp/Makefile b/grp/Makefile
index 4f1809cea5..d72fee5f6b 100644
--- a/grp/Makefile
+++ b/grp/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-2016 Free Software Foundation, Inc.
+# Copyright (C) 1991-2018 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
@@ -26,7 +26,8 @@ headers := grp.h
routines := fgetgrent initgroups setgroups \
getgrent getgrgid getgrnam putgrent \
- getgrent_r getgrgid_r getgrnam_r fgetgrent_r
+ getgrent_r getgrgid_r getgrnam_r fgetgrent_r \
+ grp-merge
tests := testgrp tst-putgrent
@@ -42,15 +43,15 @@ include ../Rules
ifeq ($(have-thread-library),yes)
-CFLAGS-getgrgid_r.c = -fexceptions
-CFLAGS-getgrnam_r.c = -fexceptions
-CFLAGS-getgrent_r.c = -fexceptions
-CFLAGS-getgrent.c = -fexceptions
-CFLAGS-fgetgrent.c = -fexceptions
-CFLAGS-fgetgrent_r.c = -fexceptions $(libio-mtsafe)
-CFLAGS-putgrent.c = -fexceptions $(libio-mtsafe)
-CFLAGS-initgroups.c = -fexceptions
-CFLAGS-getgrgid.c = -fexceptions
+CFLAGS-getgrgid_r.c += -fexceptions
+CFLAGS-getgrnam_r.c += -fexceptions
+CFLAGS-getgrent_r.c += -fexceptions
+CFLAGS-getgrent.c += -fexceptions
+CFLAGS-fgetgrent.c += -fexceptions
+CFLAGS-fgetgrent_r.c += -fexceptions $(libio-mtsafe)
+CFLAGS-putgrent.c += -fexceptions $(libio-mtsafe)
+CFLAGS-initgroups.c += -fexceptions
+CFLAGS-getgrgid.c += -fexceptions
endif
@@ -58,7 +59,7 @@ ifeq ($(run-built-tests),yes)
# tst_fgetgrent currently only works with shared libraries
ifeq (yes,$(build-shared))
$(objpfx)tst_fgetgrent.out: tst_fgetgrent.sh $(objpfx)tst_fgetgrent
- $(SHELL) $< $(common-objpfx) '$(test-program-prefix)'; \
+ $(SHELL) $< $(common-objpfx) '$(test-program-prefix)' > $@; \
$(evaluate-test)
endif
diff --git a/grp/Versions b/grp/Versions
index e01360da42..096caa47c5 100644
--- a/grp/Versions
+++ b/grp/Versions
@@ -28,4 +28,7 @@ libc {
# g*
getgrouplist;
}
+ GLIBC_PRIVATE {
+ __merge_grp; __copy_grp;
+ }
}
diff --git a/grp/fgetgrent.c b/grp/fgetgrent.c
index 2447083b1a..80f96fbba2 100644
--- a/grp/fgetgrent.c
+++ b/grp/fgetgrent.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/grp/fgetgrent_r.c b/grp/fgetgrent_r.c
index b5b6c1e3bf..6793fa1ca6 100644
--- a/grp/fgetgrent_r.c
+++ b/grp/fgetgrent_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/grp/getgrent.c b/grp/getgrent.c
index e8977d0881..de950484bd 100644
--- a/grp/getgrent.c
+++ b/grp/getgrent.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
diff --git a/grp/getgrent_r.c b/grp/getgrent_r.c
index 6623070e26..52a844eedd 100644
--- a/grp/getgrent_r.c
+++ b/grp/getgrent_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
diff --git a/grp/getgrgid.c b/grp/getgrgid.c
index cd7a2ac2fa..9d86919ec6 100644
--- a/grp/getgrgid.c
+++ b/grp/getgrgid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
diff --git a/grp/getgrgid_r.c b/grp/getgrgid_r.c
index 9da834ac98..f212738e83 100644
--- a/grp/getgrgid_r.c
+++ b/grp/getgrgid_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -18,6 +18,7 @@
#include <grp.h>
+#include <grp-merge.h>
#define LOOKUP_TYPE struct group
#define FUNCTION_NAME getgrgid
@@ -25,5 +26,7 @@
#define ADD_PARAMS gid_t gid
#define ADD_VARIABLES gid
#define BUFLEN NSS_BUFLEN_GROUP
+#define DEEPCOPY_FN __copy_grp
+#define MERGE_FN __merge_grp
#include <nss/getXXbyYY_r.c>
diff --git a/grp/getgrnam.c b/grp/getgrnam.c
index 03a2534dba..eaab12c4b4 100644
--- a/grp/getgrnam.c
+++ b/grp/getgrnam.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
diff --git a/grp/getgrnam_r.c b/grp/getgrnam_r.c
index 80960825c0..f54b63ce94 100644
--- a/grp/getgrnam_r.c
+++ b/grp/getgrnam_r.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -18,6 +18,7 @@
#include <grp.h>
+#include <grp-merge.h>
#define LOOKUP_TYPE struct group
#define FUNCTION_NAME getgrnam
@@ -25,4 +26,7 @@
#define ADD_PARAMS const char *name
#define ADD_VARIABLES name
+#define DEEPCOPY_FN __copy_grp
+#define MERGE_FN __merge_grp
+
#include <nss/getXXbyYY_r.c>
diff --git a/grp/grp-merge.c b/grp/grp-merge.c
new file mode 100644
index 0000000000..24898b05d0
--- /dev/null
+++ b/grp/grp-merge.c
@@ -0,0 +1,200 @@
+/* Group merging implementation.
+ Copyright (C) 2016-2018 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
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <grp.h>
+#include <grp-merge.h>
+
+#define BUFCHECK(size) \
+ ({ \
+ do \
+ { \
+ if (c + (size) > buflen) \
+ { \
+ free (members); \
+ return ERANGE; \
+ } \
+ } \
+ while (0); \
+ })
+
+int
+__copy_grp (const struct group srcgrp, const size_t buflen,
+ struct group *destgrp, char *destbuf, char **endptr)
+{
+ size_t i;
+ size_t c = 0;
+ size_t len;
+ size_t memcount;
+ char **members = NULL;
+
+ /* Copy the GID. */
+ destgrp->gr_gid = srcgrp.gr_gid;
+
+ /* Copy the name. */
+ len = strlen (srcgrp.gr_name) + 1;
+ BUFCHECK (len);
+ memcpy (&destbuf[c], srcgrp.gr_name, len);
+ destgrp->gr_name = &destbuf[c];
+ c += len;
+
+ /* Copy the password. */
+ len = strlen (srcgrp.gr_passwd) + 1;
+ BUFCHECK (len);
+ memcpy (&destbuf[c], srcgrp.gr_passwd, len);
+ destgrp->gr_passwd = &destbuf[c];
+ c += len;
+
+ /* Count all of the members. */
+ for (memcount = 0; srcgrp.gr_mem[memcount]; memcount++)
+ ;
+
+ /* Allocate a temporary holding area for the pointers to the member
+ contents, including space for a NULL-terminator. */
+ members = malloc (sizeof (char *) * (memcount + 1));
+ if (members == NULL)
+ return ENOMEM;
+
+ /* Copy all of the group members to destbuf and add a pointer to each of
+ them into the 'members' array. */
+ for (i = 0; srcgrp.gr_mem[i]; i++)
+ {
+ len = strlen (srcgrp.gr_mem[i]) + 1;
+ BUFCHECK (len);
+ memcpy (&destbuf[c], srcgrp.gr_mem[i], len);
+ members[i] = &destbuf[c];
+ c += len;
+ }
+ members[i] = NULL;
+
+ /* Align for pointers. We can't simply align C because we need to
+ align destbuf[c]. */
+ if ((((uintptr_t)destbuf + c) & (__alignof__(char **) - 1)) != 0)
+ {
+ uintptr_t mis_align = ((uintptr_t)destbuf + c) & (__alignof__(char **) - 1);
+ c += __alignof__(char **) - mis_align;
+ }
+
+ /* Copy the pointers from the members array into the buffer and assign them
+ to the gr_mem member of destgrp. */
+ destgrp->gr_mem = (char **) &destbuf[c];
+ len = sizeof (char *) * (memcount + 1);
+ BUFCHECK (len);
+ memcpy (&destbuf[c], members, len);
+ c += len;
+ free (members);
+ members = NULL;
+
+ /* Save the count of members at the end. */
+ BUFCHECK (sizeof (size_t));
+ memcpy (&destbuf[c], &memcount, sizeof (size_t));
+ c += sizeof (size_t);
+
+ if (endptr)
+ *endptr = destbuf + c;
+ return 0;
+}
+libc_hidden_def (__copy_grp)
+
+/* Check that the name, GID and passwd fields match, then
+ copy in the gr_mem array. */
+int
+__merge_grp (struct group *savedgrp, char *savedbuf, char *savedend,
+ size_t buflen, struct group *mergegrp, char *mergebuf)
+{
+ size_t c, i, len;
+ size_t savedmemcount;
+ size_t memcount;
+ size_t membersize;
+ char **members = NULL;
+
+ /* We only support merging members of groups with identical names and
+ GID values. If we hit this case, we need to overwrite the current
+ buffer with the saved one (which is functionally equivalent to
+ treating the new lookup as NSS_STATUS_NOTFOUND). */
+ if (mergegrp->gr_gid != savedgrp->gr_gid
+ || strcmp (mergegrp->gr_name, savedgrp->gr_name))
+ return __copy_grp (*savedgrp, buflen, mergegrp, mergebuf, NULL);
+
+ /* Get the count of group members from the last sizeof (size_t) bytes in the
+ mergegrp buffer. */
+ savedmemcount = *(size_t *) (savedend - sizeof (size_t));
+
+ /* Get the count of new members to add. */
+ for (memcount = 0; mergegrp->gr_mem[memcount]; memcount++)
+ ;
+
+ /* Create a temporary array to hold the pointers to the member values from
+ both the saved and merge groups. */
+ membersize = savedmemcount + memcount + 1;
+ members = malloc (sizeof (char *) * membersize);
+ if (members == NULL)
+ return ENOMEM;
+
+ /* Copy in the existing member pointers from the saved group
+ Note: this is not NULL-terminated yet. */
+ memcpy (members, savedgrp->gr_mem, sizeof (char *) * savedmemcount);
+
+ /* Back up into the savedbuf until we get back to the NULL-terminator of the
+ group member list. (This means walking back savedmemcount + 1 (char *) pointers
+ and the member count value.
+ The value of c is going to be the used length of the buffer backed up by
+ the member count and further backed up by the size of the pointers. */
+ c = savedend - savedbuf
+ - sizeof (size_t)
+ - sizeof (char *) * (savedmemcount + 1);
+
+ /* Add all the new group members, overwriting the old NULL-terminator while
+ adding the new pointers to the temporary array. */
+ for (i = 0; mergegrp->gr_mem[i]; i++)
+ {
+ len = strlen (mergegrp->gr_mem[i]) + 1;
+ BUFCHECK (len);
+ memcpy (&savedbuf[c], mergegrp->gr_mem[i], len);
+ members[savedmemcount + i] = &savedbuf[c];
+ c += len;
+ }
+ /* Add the NULL-terminator. */
+ members[savedmemcount + memcount] = NULL;
+
+ /* Align for pointers. We can't simply align C because we need to
+ align savedbuf[c]. */
+ if ((((uintptr_t)savedbuf + c) & (__alignof__(char **) - 1)) != 0)
+ {
+ uintptr_t mis_align = ((uintptr_t)savedbuf + c) & (__alignof__(char **) - 1);
+ c += __alignof__(char **) - mis_align;
+ }
+
+ /* Copy the member array back into the buffer after the member list and free
+ the member array. */
+ savedgrp->gr_mem = (char **) &savedbuf[c];
+ len = sizeof (char *) * membersize;
+ BUFCHECK (len);
+ memcpy (&savedbuf[c], members, len);
+ c += len;
+
+ free (members);
+ members = NULL;
+
+ /* Finally, copy the results back into mergebuf, since that's the buffer
+ that we were provided by the caller. */
+ return __copy_grp (*savedgrp, buflen, mergegrp, mergebuf, NULL);
+}
+libc_hidden_def (__merge_grp)
diff --git a/grp/grp-merge.h b/grp/grp-merge.h
new file mode 100644
index 0000000000..1539c6f6d1
--- /dev/null
+++ b/grp/grp-merge.h
@@ -0,0 +1,35 @@
+/* Group merging implementation.
+ Copyright (C) 2016-2018 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
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _GRP_MERGE_H
+#define _GRP_MERGE_H 1
+
+#include <grp.h>
+
+/* Duplicate a grp struct (and its members). When no longer needed, the
+ calling function must free(newbuf). */
+int
+__copy_grp (const struct group srcgrp, const size_t buflen,
+ struct group *destgrp, char *destbuf, char **endptr);
+
+/* Merge the member lists of two grp structs together. */
+int
+__merge_grp (struct group *savedgrp, char *savedbuf, char *savedend,
+ size_t buflen, struct group *mergegrp, char *mergebuf);
+
+#endif /* _GRP_MERGE_H */
diff --git a/grp/grp.h b/grp/grp.h
index e904ee2145..432a147ebe 100644
--- a/grp/grp.h
+++ b/grp/grp.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
@@ -49,8 +49,7 @@ struct group
#ifdef __USE_MISC
-# define __need_FILE
-# include <stdio.h>
+# include <bits/types/FILE.h>
#endif
diff --git a/grp/initgroups.c b/grp/initgroups.c
index 3242aee04e..f056fbf5aa 100644
--- a/grp/initgroups.c
+++ b/grp/initgroups.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1989, 1991-2018 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
@@ -26,23 +26,22 @@
#include <sys/types.h>
#include <nsswitch.h>
#include <scratch_buffer.h>
+#include <config.h>
#include "../nscd/nscd-client.h"
#include "../nscd/nscd_proto.h"
+#ifdef LINK_OBSOLETE_NSL
+# define DEFAULT_CONFIG "compat [NOTFOUND=return] files"
+#else
+# define DEFAULT_CONFIG "files"
+#endif
/* Type of the lookup function. */
typedef enum nss_status (*initgroups_dyn_function) (const char *, gid_t,
long int *, long int *,
gid_t **, long int, int *);
-/* The lookup function for the first entry of this service. */
-extern int __nss_group_lookup (service_user **nip, const char *name,
- void **fctp);
-extern void *__nss_lookup_function (service_user *ni, const char *fct_name);
-
-extern service_user *__nss_group_database attribute_hidden;
-service_user *__nss_initgroups_database;
static bool use_initgroups_entry;
@@ -84,7 +83,7 @@ internal_getgrouplist (const char *user, gid_t group, long int *size,
&__nss_initgroups_database) < 0)
{
if (__nss_group_database == NULL)
- no_more = __nss_database_lookup ("group", NULL, "compat files",
+ no_more = __nss_database_lookup ("group", NULL, DEFAULT_CONFIG,
&__nss_group_database);
__nss_initgroups_database = __nss_group_database;
diff --git a/grp/putgrent.c b/grp/putgrent.c
index 4442b27311..810dc8d24c 100644
--- a/grp/putgrent.c
+++ b/grp/putgrent.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/grp/setgroups.c b/grp/setgroups.c
index 724d3ffe5f..0c57bef6af 100644
--- a/grp/setgroups.c
+++ b/grp/setgroups.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2018 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
diff --git a/grp/tst-putgrent.c b/grp/tst-putgrent.c
index 41cca95792..6a75a0e0d7 100644
--- a/grp/tst-putgrent.c
+++ b/grp/tst-putgrent.c
@@ -1,5 +1,5 @@
/* Test for processing of invalid group entries. [BZ #18724]
- Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ Copyright (C) 2015-2018 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
diff --git a/grp/tst_fgetgrent.c b/grp/tst_fgetgrent.c
index 66717ed591..d612445fed 100644
--- a/grp/tst_fgetgrent.c
+++ b/grp/tst_fgetgrent.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999-2016 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@arthur.rhein-neckar.de>, 1999.
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
+#include <unistd.h>
static int errors;
@@ -99,7 +100,14 @@ test_fgetgrent (const char *filename)
int
main (int argc, char *argv[])
{
- char *file = tmpnam (NULL);
+ char file[] = "/tmp/tst_fgetgrent.XXXXXX";
+ int fd = mkstemp (file);
+ if (fd == -1)
+ {
+ printf ("mkstemp failed: %m\n");
+ return 1;
+ }
+ close (fd);
int i = 0;
if (argc > 1)
diff --git a/grp/tst_fgetgrent.sh b/grp/tst_fgetgrent.sh
index 8dbf095ba9..d878293786 100644
--- a/grp/tst_fgetgrent.sh
+++ b/grp/tst_fgetgrent.sh
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright (C) 1999-2016 Free Software Foundation, Inc.
+# Copyright (C) 1999-2018 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# Contributed by Andreas Jaeger <aj@arthur.rhein-neckar.de>, 1999.