diff options
Diffstat (limited to 'grp')
-rw-r--r-- | grp/Makefile | 25 | ||||
-rw-r--r-- | grp/Versions | 3 | ||||
-rw-r--r-- | grp/fgetgrent.c | 2 | ||||
-rw-r--r-- | grp/fgetgrent_r.c | 2 | ||||
-rw-r--r-- | grp/getgrent.c | 2 | ||||
-rw-r--r-- | grp/getgrent_r.c | 2 | ||||
-rw-r--r-- | grp/getgrgid.c | 2 | ||||
-rw-r--r-- | grp/getgrgid_r.c | 5 | ||||
-rw-r--r-- | grp/getgrnam.c | 2 | ||||
-rw-r--r-- | grp/getgrnam_r.c | 6 | ||||
-rw-r--r-- | grp/grp-merge.c | 200 | ||||
-rw-r--r-- | grp/grp-merge.h | 35 | ||||
-rw-r--r-- | grp/grp.h | 5 | ||||
-rw-r--r-- | grp/initgroups.c | 17 | ||||
-rw-r--r-- | grp/putgrent.c | 2 | ||||
-rw-r--r-- | grp/setgroups.c | 2 | ||||
-rw-r--r-- | grp/tst-putgrent.c | 2 | ||||
-rw-r--r-- | grp/tst_fgetgrent.c | 12 | ||||
-rw-r--r-- | grp/tst_fgetgrent.sh | 2 |
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 */ @@ -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. |