aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPaul Eggert2012-11-13 20:55:41 -0800
committerPaul Eggert2012-11-13 20:55:41 -0800
commit73dcdb9f30cb94a3183db54d9b463370c3978d4d (patch)
tree216d47d5bc96bce2a4ca87a57967b0e1c3c151f2 /lib
parent9c3912d3d9aaa1e20e3f7168f5764695ad5e43fd (diff)
downloademacs-73dcdb9f30cb94a3183db54d9b463370c3978d4d.tar.gz
emacs-73dcdb9f30cb94a3183db54d9b463370c3978d4d.zip
Use faccessat, not access, when checking file permissions.
This fixes a bug that has been present in Emacs since its creation. It was reported by Chris Torek in 1983 even before GNU Emacs existed, which must set some sort of record. (Torek's bug report was against a predecessor of GNU Emacs, but GNU Emacs happened to have the same common flaw.) See Torek's Usenet posting "setuid/setgid programs & Emacs" Article-I.D.: sri-arpa.858 Posted: Fri Apr 8 14:18:56 1983. * .bzrignore: Add lib/fcntl.h. * configure.ac (euidaccess): Remove check; gnulib does this for us now. (gl_FCNTL_O_FLAGS): Define a dummy version. * lib/at-func.c, lib/euidaccess.c, lib/faccessat.c, lib/fcntl.in.h: * lib/getgroups.c, lib/group-member.c, lib/root-uid.h: * lib/xalloc-oversized.h, m4/euidaccess.m4, m4/faccessat.m4: * m4/fcntl_h.m4, m4/getgroups.m4, m4/group-member.m4: New files, from gnulib. * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. * admin/merge-gnulib (GNULIB_MODULES): Add faccessat. (GNULIB_TOOL_FLAGS): Avoid at-internal, fchdir, malloc-posix, openat-die, openat-h, save-cwd. Do not avoid fcntl-h. Omit gnulib's m4/fcntl-o.m4. * nt/inc/ms-w32.h (AT_FDCWD, AT_EACCESS): New symbols. (access): Remove. (faccessat): New macro. * src/Makefile.in (LIB_EACCESS): New macro. (LIBES): Use it. * src/callproc.c (init_callproc): * src/charset.c (init_charset): * src/fileio.c (check_existing, check_executable, check_writable) (Ffile_readable_p): * src/lread.c (openp, load_path_check): * src/process.c (allocate_pty): * src/xrdb.c (file_p): Use effective UID when checking permissions, not real UID. * src/callproc.c (init_callproc): * src/charset.c (init_charset): * src/lread.c (load_path_check, init_lread): Test whether directories are accessible, not merely whether they exist. * src/conf_post.h (GNULIB_SUPPORT_ONLY_AT_FDCWD): New macro. * src/fileio.c (check_existing, check_executable, check_writable) (Ffile_readable_p): Use symbolic names instead of integers for the flags, as they're portable now. (check_writable): New arg AMODE. All uses changed. Set errno on failure. (Ffile_readable_p): Use faccessat, not stat + open + close. (Ffile_writable_p): No need to call check_existing + check_writable. Just call check_writable and then look at errno. This saves a syscall. dir should never be nil; replace an unnecessary runtime check with an eassert. When checking the parent directory of a nonexistent file, check that the directory is searchable as well as writable, as we can't create files in unsearchable directories. (file_directory_p): New function, which uses 'stat' on most platforms but faccessat with D_OK (for efficiency) if WINDOWSNT. (Ffile_directory_p, Fset_file_times): Use it. (file_accessible_directory_p): New function, which uses a single syscall for efficiency. (Ffile_accessible_directory_p): Use it. * src/xrdb.c (file_p): Use file_directory_p. * src/lisp.h (file_directory_p, file_accessible_directory_p): New decls. * src/lread.c (openp): When opening a file, use fstat rather than stat, as that avoids a permissions race. When not opening a file, use file_directory_p rather than stat. (dir_warning): First arg is now a usage string, not a format. Use errno. All uses changed. * src/nsterm.m (ns_term_init): Remove unnecessary call to file-readable that merely introduced a race. * src/process.c, src/sysdep.c, src/term.c: All uses of '#ifdef O_NONBLOCK' changed to '#if O_NONBLOCK', to accommodate gnulib O_* style, and similarly for the other O_* flags. * src/w32.c (sys_faccessat): Rename from sys_access and switch to faccessat's API. All uses changed. * src/xrdb.c: Do not include <sys/stat.h>; no longer needed. (magic_db): Rename from magic_file_p. (magic_db, search_magic_path): Return an XrmDatabase rather than a char *, so that we don't have to test for file existence separately from opening the file for reading. This removes a race fixes a permission-checking problem, and simplifies the code. All uses changed. (file_p): Remove; no longer needed. Fixes: debbugs:12632
Diffstat (limited to 'lib')
-rw-r--r--lib/at-func.c146
-rw-r--r--lib/euidaccess.c221
-rw-r--r--lib/faccessat.c45
-rw-r--r--lib/fcntl.in.h355
-rw-r--r--lib/getgroups.c116
-rw-r--r--lib/gnulib.mk97
-rw-r--r--lib/group-member.c119
-rw-r--r--lib/root-uid.h30
-rw-r--r--lib/xalloc-oversized.h38
9 files changed, 1166 insertions, 1 deletions
diff --git a/lib/at-func.c b/lib/at-func.c
new file mode 100644
index 00000000000..481eea475a1
--- /dev/null
+++ b/lib/at-func.c
@@ -0,0 +1,146 @@
1/* Define at-style functions like fstatat, unlinkat, fchownat, etc.
2 Copyright (C) 2006, 2009-2012 Free Software Foundation, Inc.
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
16
17/* written by Jim Meyering */
18
19#include "dosname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */
20
21#ifdef GNULIB_SUPPORT_ONLY_AT_FDCWD
22# include <errno.h>
23# ifndef ENOTSUP
24# define ENOTSUP EINVAL
25# endif
26#else
27# include "openat.h"
28# include "openat-priv.h"
29# include "save-cwd.h"
30#endif
31
32#ifdef AT_FUNC_USE_F1_COND
33# define CALL_FUNC(F) \
34 (flag == AT_FUNC_USE_F1_COND \
35 ? AT_FUNC_F1 (F AT_FUNC_POST_FILE_ARGS) \
36 : AT_FUNC_F2 (F AT_FUNC_POST_FILE_ARGS))
37# define VALIDATE_FLAG(F) \
38 if (flag & ~AT_FUNC_USE_F1_COND) \
39 { \
40 errno = EINVAL; \
41 return FUNC_FAIL; \
42 }
43#else
44# define CALL_FUNC(F) (AT_FUNC_F1 (F AT_FUNC_POST_FILE_ARGS))
45# define VALIDATE_FLAG(F) /* empty */
46#endif
47
48#ifdef AT_FUNC_RESULT
49# define FUNC_RESULT AT_FUNC_RESULT
50#else
51# define FUNC_RESULT int
52#endif
53
54#ifdef AT_FUNC_FAIL
55# define FUNC_FAIL AT_FUNC_FAIL
56#else
57# define FUNC_FAIL -1
58#endif
59
60/* Call AT_FUNC_F1 to operate on FILE, which is in the directory
61 open on descriptor FD. If AT_FUNC_USE_F1_COND is defined to a value,
62 AT_FUNC_POST_FILE_PARAM_DECLS must include a parameter named flag;
63 call AT_FUNC_F2 if FLAG is 0 or fail if FLAG contains more bits than
64 AT_FUNC_USE_F1_COND. Return int and fail with -1 unless AT_FUNC_RESULT
65 or AT_FUNC_FAIL are defined. If possible, do it without changing the
66 working directory. Otherwise, resort to using save_cwd/fchdir,
67 then AT_FUNC_F?/restore_cwd. If either the save_cwd or the restore_cwd
68 fails, then give a diagnostic and exit nonzero. */
69FUNC_RESULT
70AT_FUNC_NAME (int fd, char const *file AT_FUNC_POST_FILE_PARAM_DECLS)
71{
72 VALIDATE_FLAG (flag);
73
74 if (fd == AT_FDCWD || IS_ABSOLUTE_FILE_NAME (file))
75 return CALL_FUNC (file);
76
77#ifdef GNULIB_SUPPORT_ONLY_AT_FDCWD
78 errno = ENOTSUP;
79 return FUNC_FAIL;
80#else
81 {
82 /* Be careful to choose names unlikely to conflict with
83 AT_FUNC_POST_FILE_PARAM_DECLS. */
84 struct saved_cwd saved_cwd;
85 int saved_errno;
86 FUNC_RESULT err;
87
88 {
89 char proc_buf[OPENAT_BUFFER_SIZE];
90 char *proc_file = openat_proc_name (proc_buf, fd, file);
91 if (proc_file)
92 {
93 FUNC_RESULT proc_result = CALL_FUNC (proc_file);
94 int proc_errno = errno;
95 if (proc_file != proc_buf)
96 free (proc_file);
97 /* If the syscall succeeds, or if it fails with an unexpected
98 errno value, then return right away. Otherwise, fall through
99 and resort to using save_cwd/restore_cwd. */
100 if (FUNC_FAIL != proc_result)
101 return proc_result;
102 if (! EXPECTED_ERRNO (proc_errno))
103 {
104 errno = proc_errno;
105 return proc_result;
106 }
107 }
108 }
109
110 if (save_cwd (&saved_cwd) != 0)
111 openat_save_fail (errno);
112 if (0 <= fd && fd == saved_cwd.desc)
113 {
114 /* If saving the working directory collides with the user's
115 requested fd, then the user's fd must have been closed to
116 begin with. */
117 free_cwd (&saved_cwd);
118 errno = EBADF;
119 return FUNC_FAIL;
120 }
121
122 if (fchdir (fd) != 0)
123 {
124 saved_errno = errno;
125 free_cwd (&saved_cwd);
126 errno = saved_errno;
127 return FUNC_FAIL;
128 }
129
130 err = CALL_FUNC (file);
131 saved_errno = (err == FUNC_FAIL ? errno : 0);
132
133 if (restore_cwd (&saved_cwd) != 0)
134 openat_restore_fail (errno);
135
136 free_cwd (&saved_cwd);
137
138 if (saved_errno)
139 errno = saved_errno;
140 return err;
141 }
142#endif
143}
144#undef CALL_FUNC
145#undef FUNC_RESULT
146#undef FUNC_FAIL
diff --git a/lib/euidaccess.c b/lib/euidaccess.c
new file mode 100644
index 00000000000..ca2ceca5d22
--- /dev/null
+++ b/lib/euidaccess.c
@@ -0,0 +1,221 @@
1/* euidaccess -- check if effective user id can access file
2
3 Copyright (C) 1990-1991, 1995, 1998, 2000, 2003-2006, 2008-2012 Free
4 Software Foundation, Inc.
5
6 This file is part of the GNU C Library.
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21/* Written by David MacKenzie and Torbjorn Granlund.
22 Adapted for GNU C library by Roland McGrath. */
23
24#ifndef _LIBC
25# include <config.h>
26#endif
27
28#include <fcntl.h>
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <unistd.h>
32
33#include "root-uid.h"
34
35#if HAVE_LIBGEN_H
36# include <libgen.h>
37#endif
38
39#include <errno.h>
40#ifndef __set_errno
41# define __set_errno(val) errno = (val)
42#endif
43
44#if defined EACCES && !defined EACCESS
45# define EACCESS EACCES
46#endif
47
48#ifndef F_OK
49# define F_OK 0
50# define X_OK 1
51# define W_OK 2
52# define R_OK 4
53#endif
54
55
56#ifdef _LIBC
57
58# define access __access
59# define getuid __getuid
60# define getgid __getgid
61# define geteuid __geteuid
62# define getegid __getegid
63# define group_member __group_member
64# define euidaccess __euidaccess
65# undef stat
66# define stat stat64
67
68#endif
69
70/* Return 0 if the user has permission of type MODE on FILE;
71 otherwise, return -1 and set 'errno'.
72 Like access, except that it uses the effective user and group
73 id's instead of the real ones, and it does not always check for read-only
74 file system, text busy, etc. */
75
76int
77euidaccess (const char *file, int mode)
78{
79#if HAVE_FACCESSAT /* glibc, AIX 7, Solaris 11, Cygwin 1.7 */
80 return faccessat (AT_FDCWD, file, mode, AT_EACCESS);
81#elif defined EFF_ONLY_OK /* IRIX, OSF/1, Interix */
82 return access (file, mode | EFF_ONLY_OK);
83#elif defined ACC_SELF /* AIX */
84 return accessx (file, mode, ACC_SELF);
85#elif HAVE_EACCESS /* FreeBSD */
86 return eaccess (file, mode);
87#else /* Mac OS X, NetBSD, OpenBSD, HP-UX, Solaris, Cygwin, mingw, BeOS */
88
89 uid_t uid = getuid ();
90 gid_t gid = getgid ();
91 uid_t euid = geteuid ();
92 gid_t egid = getegid ();
93 struct stat stats;
94
95# if HAVE_DECL_SETREGID && PREFER_NONREENTRANT_EUIDACCESS
96
97 /* Define PREFER_NONREENTRANT_EUIDACCESS if you prefer euidaccess to
98 return the correct result even if this would make it
99 nonreentrant. Define this only if your entire application is
100 safe even if the uid or gid might temporarily change. If your
101 application uses signal handlers or threads it is probably not
102 safe. */
103
104 if (mode == F_OK)
105 return stat (file, &stats);
106 else
107 {
108 int result;
109 int saved_errno;
110
111 if (uid != euid)
112 setreuid (euid, uid);
113 if (gid != egid)
114 setregid (egid, gid);
115
116 result = access (file, mode);
117 saved_errno = errno;
118
119 /* Restore them. */
120 if (uid != euid)
121 setreuid (uid, euid);
122 if (gid != egid)
123 setregid (gid, egid);
124
125 errno = saved_errno;
126 return result;
127 }
128
129# else
130
131 /* The following code assumes the traditional Unix model, and is not
132 correct on systems that have ACLs or the like. However, it's
133 better than nothing, and it is reentrant. */
134
135 unsigned int granted;
136 if (uid == euid && gid == egid)
137 /* If we are not set-uid or set-gid, access does the same. */
138 return access (file, mode);
139
140 if (stat (file, &stats) != 0)
141 return -1;
142
143 /* The super-user can read and write any file, and execute any file
144 that anyone can execute. */
145 if (euid == ROOT_UID
146 && ((mode & X_OK) == 0
147 || (stats.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
148 return 0;
149
150 /* Convert the mode to traditional form, clearing any bogus bits. */
151 if (R_OK == 4 && W_OK == 2 && X_OK == 1 && F_OK == 0)
152 mode &= 7;
153 else
154 mode = ((mode & R_OK ? 4 : 0)
155 + (mode & W_OK ? 2 : 0)
156 + (mode & X_OK ? 1 : 0));
157
158 if (mode == 0)
159 return 0; /* The file exists. */
160
161 /* Convert the file's permission bits to traditional form. */
162 if (S_IRUSR == (4 << 6) && S_IWUSR == (2 << 6) && S_IXUSR == (1 << 6)
163 && S_IRGRP == (4 << 3) && S_IWGRP == (2 << 3) && S_IXGRP == (1 << 3)
164 && S_IROTH == (4 << 0) && S_IWOTH == (2 << 0) && S_IXOTH == (1 << 0))
165 granted = stats.st_mode;
166 else
167 granted = ((stats.st_mode & S_IRUSR ? 4 << 6 : 0)
168 + (stats.st_mode & S_IWUSR ? 2 << 6 : 0)
169 + (stats.st_mode & S_IXUSR ? 1 << 6 : 0)
170 + (stats.st_mode & S_IRGRP ? 4 << 3 : 0)
171 + (stats.st_mode & S_IWGRP ? 2 << 3 : 0)
172 + (stats.st_mode & S_IXGRP ? 1 << 3 : 0)
173 + (stats.st_mode & S_IROTH ? 4 << 0 : 0)
174 + (stats.st_mode & S_IWOTH ? 2 << 0 : 0)
175 + (stats.st_mode & S_IXOTH ? 1 << 0 : 0));
176
177 if (euid == stats.st_uid)
178 granted >>= 6;
179 else if (egid == stats.st_gid || group_member (stats.st_gid))
180 granted >>= 3;
181
182 if ((mode & ~granted) == 0)
183 return 0;
184 __set_errno (EACCESS);
185 return -1;
186
187# endif
188#endif
189}
190#undef euidaccess
191#ifdef weak_alias
192weak_alias (__euidaccess, euidaccess)
193#endif
194
195#ifdef TEST
196# include <error.h>
197# include <stdio.h>
198# include <stdlib.h>
199
200char *program_name;
201
202int
203main (int argc, char **argv)
204{
205 char *file;
206 int mode;
207 int err;
208
209 program_name = argv[0];
210 if (argc < 3)
211 abort ();
212 file = argv[1];
213 mode = atoi (argv[2]);
214
215 err = euidaccess (file, mode);
216 printf ("%d\n", err);
217 if (err != 0)
218 error (0, errno, "%s", file);
219 exit (0);
220}
221#endif
diff --git a/lib/faccessat.c b/lib/faccessat.c
new file mode 100644
index 00000000000..d11a3efaad6
--- /dev/null
+++ b/lib/faccessat.c
@@ -0,0 +1,45 @@
1/* Check the access rights of a file relative to an open directory.
2 Copyright (C) 2009-2012 Free Software Foundation, Inc.
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
16
17/* written by Eric Blake */
18
19#include <config.h>
20
21#include <unistd.h>
22#include <fcntl.h>
23
24#ifndef HAVE_ACCESS
25/* Mingw lacks access, but it also lacks real vs. effective ids, so
26 the gnulib euidaccess module is good enough. */
27# undef access
28# define access euidaccess
29#endif
30
31/* Invoke access or euidaccess on file, FILE, using mode MODE, in the directory
32 open on descriptor FD. If possible, do it without changing the
33 working directory. Otherwise, resort to using save_cwd/fchdir, then
34 (access|euidaccess)/restore_cwd. If either the save_cwd or the
35 restore_cwd fails, then give a diagnostic and exit nonzero.
36 Note that this implementation only supports AT_EACCESS, although some
37 native versions also support AT_SYMLINK_NOFOLLOW. */
38
39#define AT_FUNC_NAME faccessat
40#define AT_FUNC_F1 euidaccess
41#define AT_FUNC_F2 access
42#define AT_FUNC_USE_F1_COND AT_EACCESS
43#define AT_FUNC_POST_FILE_PARAM_DECLS , int mode, int flag
44#define AT_FUNC_POST_FILE_ARGS , mode
45#include "at-func.c"
diff --git a/lib/fcntl.in.h b/lib/fcntl.in.h
new file mode 100644
index 00000000000..fb402ee1f0f
--- /dev/null
+++ b/lib/fcntl.in.h
@@ -0,0 +1,355 @@
1/* Like <fcntl.h>, but with non-working flags defined to 0.
2
3 Copyright (C) 2006-2012 Free Software Foundation, Inc.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18/* written by Paul Eggert */
19
20#if __GNUC__ >= 3
21@PRAGMA_SYSTEM_HEADER@
22#endif
23@PRAGMA_COLUMNS@
24
25#if defined __need_system_fcntl_h
26/* Special invocation convention. */
27
28/* Needed before <sys/stat.h>.
29 May also define off_t to a 64-bit type on native Windows. */
30#include <sys/types.h>
31/* On some systems other than glibc, <sys/stat.h> is a prerequisite of
32 <fcntl.h>. On glibc systems, we would like to avoid namespace pollution.
33 But on glibc systems, <fcntl.h> includes <sys/stat.h> inside an
34 extern "C" { ... } block, which leads to errors in C++ mode with the
35 overridden <sys/stat.h> from gnulib. These errors are known to be gone
36 with g++ version >= 4.3. */
37#if !(defined __GLIBC__ || defined __UCLIBC__) || (defined __cplusplus && defined GNULIB_NAMESPACE && !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
38# include <sys/stat.h>
39#endif
40#@INCLUDE_NEXT@ @NEXT_FCNTL_H@
41
42#else
43/* Normal invocation convention. */
44
45#ifndef _@GUARD_PREFIX@_FCNTL_H
46
47/* Needed before <sys/stat.h>.
48 May also define off_t to a 64-bit type on native Windows. */
49#include <sys/types.h>
50/* On some systems other than glibc, <sys/stat.h> is a prerequisite of
51 <fcntl.h>. On glibc systems, we would like to avoid namespace pollution.
52 But on glibc systems, <fcntl.h> includes <sys/stat.h> inside an
53 extern "C" { ... } block, which leads to errors in C++ mode with the
54 overridden <sys/stat.h> from gnulib. These errors are known to be gone
55 with g++ version >= 4.3. */
56#if !(defined __GLIBC__ || defined __UCLIBC__) || (defined __cplusplus && defined GNULIB_NAMESPACE && !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
57# include <sys/stat.h>
58#endif
59/* The include_next requires a split double-inclusion guard. */
60#@INCLUDE_NEXT@ @NEXT_FCNTL_H@
61
62#ifndef _@GUARD_PREFIX@_FCNTL_H
63#define _@GUARD_PREFIX@_FCNTL_H
64
65#ifndef __GLIBC__ /* Avoid namespace pollution on glibc systems. */
66# include <unistd.h>
67#endif
68
69/* Native Windows platforms declare open(), creat() in <io.h>. */
70#if (@GNULIB_OPEN@ || defined GNULIB_POSIXCHECK) \
71 && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
72# include <io.h>
73#endif
74
75
76/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
77
78/* The definition of _GL_ARG_NONNULL is copied here. */
79
80/* The definition of _GL_WARN_ON_USE is copied here. */
81
82
83/* Declare overridden functions. */
84
85#if @GNULIB_FCNTL@
86# if @REPLACE_FCNTL@
87# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
88# undef fcntl
89# define fcntl rpl_fcntl
90# endif
91_GL_FUNCDECL_RPL (fcntl, int, (int fd, int action, ...));
92_GL_CXXALIAS_RPL (fcntl, int, (int fd, int action, ...));
93# else
94# if !@HAVE_FCNTL@
95_GL_FUNCDECL_SYS (fcntl, int, (int fd, int action, ...));
96# endif
97_GL_CXXALIAS_SYS (fcntl, int, (int fd, int action, ...));
98# endif
99_GL_CXXALIASWARN (fcntl);
100#elif defined GNULIB_POSIXCHECK
101# undef fcntl
102# if HAVE_RAW_DECL_FCNTL
103_GL_WARN_ON_USE (fcntl, "fcntl is not always POSIX compliant - "
104 "use gnulib module fcntl for portability");
105# endif
106#endif
107
108#if @GNULIB_OPEN@
109# if @REPLACE_OPEN@
110# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
111# undef open
112# define open rpl_open
113# endif
114_GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
115 _GL_ARG_NONNULL ((1)));
116_GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
117# else
118_GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
119# endif
120/* On HP-UX 11, in C++ mode, open() is defined as an inline function with a
121 default argument. _GL_CXXALIASWARN does not work in this case. */
122# if !defined __hpux
123_GL_CXXALIASWARN (open);
124# endif
125#elif defined GNULIB_POSIXCHECK
126# undef open
127/* Assume open is always declared. */
128_GL_WARN_ON_USE (open, "open is not always POSIX compliant - "
129 "use gnulib module open for portability");
130#endif
131
132#if @GNULIB_OPENAT@
133# if @REPLACE_OPENAT@
134# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
135# undef openat
136# define openat rpl_openat
137# endif
138_GL_FUNCDECL_RPL (openat, int,
139 (int fd, char const *file, int flags, /* mode_t mode */ ...)
140 _GL_ARG_NONNULL ((2)));
141_GL_CXXALIAS_RPL (openat, int,
142 (int fd, char const *file, int flags, /* mode_t mode */ ...));
143# else
144# if !@HAVE_OPENAT@
145_GL_FUNCDECL_SYS (openat, int,
146 (int fd, char const *file, int flags, /* mode_t mode */ ...)
147 _GL_ARG_NONNULL ((2)));
148# endif
149_GL_CXXALIAS_SYS (openat, int,
150 (int fd, char const *file, int flags, /* mode_t mode */ ...));
151# endif
152_GL_CXXALIASWARN (openat);
153#elif defined GNULIB_POSIXCHECK
154# undef openat
155# if HAVE_RAW_DECL_OPENAT
156_GL_WARN_ON_USE (openat, "openat is not portable - "
157 "use gnulib module openat for portability");
158# endif
159#endif
160
161
162/* Fix up the FD_* macros, only known to be missing on mingw. */
163
164#ifndef FD_CLOEXEC
165# define FD_CLOEXEC 1
166#endif
167
168/* Fix up the supported F_* macros. Intentionally leave other F_*
169 macros undefined. Only known to be missing on mingw. */
170
171#ifndef F_DUPFD_CLOEXEC
172# define F_DUPFD_CLOEXEC 0x40000000
173/* Witness variable: 1 if gnulib defined F_DUPFD_CLOEXEC, 0 otherwise. */
174# define GNULIB_defined_F_DUPFD_CLOEXEC 1
175#else
176# define GNULIB_defined_F_DUPFD_CLOEXEC 0
177#endif
178
179#ifndef F_DUPFD
180# define F_DUPFD 1
181#endif
182
183#ifndef F_GETFD
184# define F_GETFD 2
185#endif
186
187/* Fix up the O_* macros. */
188
189#if !defined O_DIRECT && defined O_DIRECTIO
190/* Tru64 spells it 'O_DIRECTIO'. */
191# define O_DIRECT O_DIRECTIO
192#endif
193
194#if !defined O_CLOEXEC && defined O_NOINHERIT
195/* Mingw spells it 'O_NOINHERIT'. */
196# define O_CLOEXEC O_NOINHERIT
197#endif
198
199#ifndef O_CLOEXEC
200# define O_CLOEXEC 0
201#endif
202
203#ifndef O_DIRECT
204# define O_DIRECT 0
205#endif
206
207#ifndef O_DIRECTORY
208# define O_DIRECTORY 0
209#endif
210
211#ifndef O_DSYNC
212# define O_DSYNC 0
213#endif
214
215#ifndef O_EXEC
216# ifdef O_PATH
217# define O_EXEC O_PATH
218# else
219# define O_EXEC O_RDONLY /* This is often close enough in older systems. */
220# endif
221#endif
222
223#ifndef O_IGNORE_CTTY
224# define O_IGNORE_CTTY 0
225#endif
226
227#ifndef O_NDELAY
228# define O_NDELAY 0
229#endif
230
231#ifndef O_NOATIME
232# define O_NOATIME 0
233#endif
234
235#ifndef O_NONBLOCK
236# define O_NONBLOCK O_NDELAY
237#endif
238
239/* If the gnulib module 'nonblocking' is in use, guarantee a working non-zero
240 value of O_NONBLOCK. Otherwise, O_NONBLOCK is defined (above) to O_NDELAY
241 or to 0 as fallback. */
242#if @GNULIB_NONBLOCKING@
243# if O_NONBLOCK
244# define GNULIB_defined_O_NONBLOCK 0
245# else
246# define GNULIB_defined_O_NONBLOCK 1
247# undef O_NONBLOCK
248# define O_NONBLOCK 0x40000000
249# endif
250#endif
251
252#ifndef O_NOCTTY
253# define O_NOCTTY 0
254#endif
255
256#ifndef O_NOFOLLOW
257# define O_NOFOLLOW 0
258#endif
259
260#ifndef O_NOLINK
261# define O_NOLINK 0
262#endif
263
264#ifndef O_NOLINKS
265# define O_NOLINKS 0
266#endif
267
268#ifndef O_NOTRANS
269# define O_NOTRANS 0
270#endif
271
272#ifndef O_RSYNC
273# define O_RSYNC 0
274#endif
275
276#ifndef O_SEARCH
277# ifdef O_PATH
278# define O_SEARCH O_PATH
279# else
280# define O_SEARCH O_RDONLY /* This is often close enough in older systems. */
281# endif
282#endif
283
284#ifndef O_SYNC
285# define O_SYNC 0
286#endif
287
288#ifndef O_TTY_INIT
289# define O_TTY_INIT 0
290#endif
291
292#if ~O_ACCMODE & (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH)
293# undef O_ACCMODE
294# define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH)
295#endif
296
297/* For systems that distinguish between text and binary I/O.
298 O_BINARY is usually declared in fcntl.h */
299#if !defined O_BINARY && defined _O_BINARY
300 /* For MSC-compatible compilers. */
301# define O_BINARY _O_BINARY
302# define O_TEXT _O_TEXT
303#endif
304
305#if defined __BEOS__ || defined __HAIKU__
306 /* BeOS 5 and Haiku have O_BINARY and O_TEXT, but they have no effect. */
307# undef O_BINARY
308# undef O_TEXT
309#endif
310
311#ifndef O_BINARY
312# define O_BINARY 0
313# define O_TEXT 0
314#endif
315
316/* Fix up the AT_* macros. */
317
318/* Work around a bug in Solaris 9 and 10: AT_FDCWD is positive. Its
319 value exceeds INT_MAX, so its use as an int doesn't conform to the
320 C standard, and GCC and Sun C complain in some cases. If the bug
321 is present, undef AT_FDCWD here, so it can be redefined below. */
322#if 0 < AT_FDCWD && AT_FDCWD == 0xffd19553
323# undef AT_FDCWD
324#endif
325
326/* Use the same bit pattern as Solaris 9, but with the proper
327 signedness. The bit pattern is important, in case this actually is
328 Solaris with the above workaround. */
329#ifndef AT_FDCWD
330# define AT_FDCWD (-3041965)
331#endif
332
333/* Use the same values as Solaris 9. This shouldn't matter, but
334 there's no real reason to differ. */
335#ifndef AT_SYMLINK_NOFOLLOW
336# define AT_SYMLINK_NOFOLLOW 4096
337#endif
338
339#ifndef AT_REMOVEDIR
340# define AT_REMOVEDIR 1
341#endif
342
343/* Solaris 9 lacks these two, so just pick unique values. */
344#ifndef AT_SYMLINK_FOLLOW
345# define AT_SYMLINK_FOLLOW 2
346#endif
347
348#ifndef AT_EACCESS
349# define AT_EACCESS 4
350#endif
351
352
353#endif /* _@GUARD_PREFIX@_FCNTL_H */
354#endif /* _@GUARD_PREFIX@_FCNTL_H */
355#endif
diff --git a/lib/getgroups.c b/lib/getgroups.c
new file mode 100644
index 00000000000..f9d36236afe
--- /dev/null
+++ b/lib/getgroups.c
@@ -0,0 +1,116 @@
1/* provide consistent interface to getgroups for systems that don't allow N==0
2
3 Copyright (C) 1996, 1999, 2003, 2006-2012 Free Software Foundation, Inc.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18/* written by Jim Meyering */
19
20#include <config.h>
21
22#include <unistd.h>
23
24#include <errno.h>
25#include <stdlib.h>
26#include <stdint.h>
27
28#if !HAVE_GETGROUPS
29
30/* Provide a stub that fails with ENOSYS, since there is no group
31 information available on mingw. */
32int
33getgroups (int n _GL_UNUSED, GETGROUPS_T *groups _GL_UNUSED)
34{
35 errno = ENOSYS;
36 return -1;
37}
38
39#else /* HAVE_GETGROUPS */
40
41# undef getgroups
42# ifndef GETGROUPS_ZERO_BUG
43# define GETGROUPS_ZERO_BUG 0
44# endif
45
46/* On at least Ultrix 4.3 and NextStep 3.2, getgroups (0, NULL) always
47 fails. On other systems, it returns the number of supplemental
48 groups for the process. This function handles that special case
49 and lets the system-provided function handle all others. However,
50 it can fail with ENOMEM if memory is tight. It is unspecified
51 whether the effective group id is included in the list. */
52
53int
54rpl_getgroups (int n, gid_t *group)
55{
56 int n_groups;
57 GETGROUPS_T *gbuf;
58 int saved_errno;
59
60 if (n < 0)
61 {
62 errno = EINVAL;
63 return -1;
64 }
65
66 if (n != 0 || !GETGROUPS_ZERO_BUG)
67 {
68 int result;
69 if (sizeof *group == sizeof *gbuf)
70 return getgroups (n, (GETGROUPS_T *) group);
71
72 if (SIZE_MAX / sizeof *gbuf <= n)
73 {
74 errno = ENOMEM;
75 return -1;
76 }
77 gbuf = malloc (n * sizeof *gbuf);
78 if (!gbuf)
79 return -1;
80 result = getgroups (n, gbuf);
81 if (0 <= result)
82 {
83 n = result;
84 while (n--)
85 group[n] = gbuf[n];
86 }
87 saved_errno = errno;
88 free (gbuf);
89 errno == saved_errno;
90 return result;
91 }
92
93 n = 20;
94 while (1)
95 {
96 /* No need to worry about address arithmetic overflow here,
97 since the ancient systems that we're running on have low
98 limits on the number of secondary groups. */
99 gbuf = malloc (n * sizeof *gbuf);
100 if (!gbuf)
101 return -1;
102 n_groups = getgroups (n, gbuf);
103 if (n_groups == -1 ? errno != EINVAL : n_groups < n)
104 break;
105 free (gbuf);
106 n *= 2;
107 }
108
109 saved_errno = errno;
110 free (gbuf);
111 errno = saved_errno;
112
113 return n_groups;
114}
115
116#endif /* HAVE_GETGROUPS */
diff --git a/lib/gnulib.mk b/lib/gnulib.mk
index 324e5cb78fd..f74c46ae9c8 100644
--- a/lib/gnulib.mk
+++ b/lib/gnulib.mk
@@ -21,7 +21,7 @@
21# the same distribution terms as the rest of that program. 21# the same distribution terms as the rest of that program.
22# 22#
23# Generated by gnulib-tool. 23# Generated by gnulib-tool.
24# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=errno --avoid=fcntl --avoid=fcntl-h --avoid=fstat --avoid=msvc-inval --avoid=msvc-nothrow --avoid=raise --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings mktime pselect pthread_sigmask readlink socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub utimens warnings 24# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=at-internal --avoid=errno --avoid=fchdir --avoid=fcntl --avoid=fstat --avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=openat-die --avoid=openat-h --avoid=raise --avoid=save-cwd --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo faccessat filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings mktime pselect pthread_sigmask readlink socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub utimens warnings
25 25
26 26
27MOSTLYCLEANFILES += core *.stackdump 27MOSTLYCLEANFILES += core *.stackdump
@@ -158,6 +158,17 @@ EXTRA_libgnu_a_SOURCES += dup2.c
158 158
159## end gnulib module dup2 159## end gnulib module dup2
160 160
161## begin gnulib module euidaccess
162
163if gl_GNULIB_ENABLED_euidaccess
164
165endif
166EXTRA_DIST += euidaccess.c
167
168EXTRA_libgnu_a_SOURCES += euidaccess.c
169
170## end gnulib module euidaccess
171
161## begin gnulib module execinfo 172## begin gnulib module execinfo
162 173
163BUILT_SOURCES += $(EXECINFO_H) 174BUILT_SOURCES += $(EXECINFO_H)
@@ -183,6 +194,50 @@ EXTRA_libgnu_a_SOURCES += execinfo.c
183 194
184## end gnulib module execinfo 195## end gnulib module execinfo
185 196
197## begin gnulib module faccessat
198
199
200EXTRA_DIST += at-func.c faccessat.c
201
202EXTRA_libgnu_a_SOURCES += at-func.c faccessat.c
203
204## end gnulib module faccessat
205
206## begin gnulib module fcntl-h
207
208BUILT_SOURCES += fcntl.h
209
210# We need the following in order to create <fcntl.h> when the system
211# doesn't have one that works with the given compiler.
212fcntl.h: fcntl.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
213 $(AM_V_GEN)rm -f $@-t $@ && \
214 { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
215 sed -e 's|@''GUARD_PREFIX''@|GL|g' \
216 -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
217 -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
218 -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
219 -e 's|@''NEXT_FCNTL_H''@|$(NEXT_FCNTL_H)|g' \
220 -e 's/@''GNULIB_FCNTL''@/$(GNULIB_FCNTL)/g' \
221 -e 's/@''GNULIB_NONBLOCKING''@/$(GNULIB_NONBLOCKING)/g' \
222 -e 's/@''GNULIB_OPEN''@/$(GNULIB_OPEN)/g' \
223 -e 's/@''GNULIB_OPENAT''@/$(GNULIB_OPENAT)/g' \
224 -e 's|@''HAVE_FCNTL''@|$(HAVE_FCNTL)|g' \
225 -e 's|@''HAVE_OPENAT''@|$(HAVE_OPENAT)|g' \
226 -e 's|@''REPLACE_FCNTL''@|$(REPLACE_FCNTL)|g' \
227 -e 's|@''REPLACE_OPEN''@|$(REPLACE_OPEN)|g' \
228 -e 's|@''REPLACE_OPENAT''@|$(REPLACE_OPENAT)|g' \
229 -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
230 -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
231 -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
232 < $(srcdir)/fcntl.in.h; \
233 } > $@-t && \
234 mv $@-t $@
235MOSTLYCLEANFILES += fcntl.h fcntl.h-t
236
237EXTRA_DIST += fcntl.in.h
238
239## end gnulib module fcntl-h
240
186## begin gnulib module filemode 241## begin gnulib module filemode
187 242
188libgnu_a_SOURCES += filemode.c 243libgnu_a_SOURCES += filemode.c
@@ -200,6 +255,17 @@ EXTRA_libgnu_a_SOURCES += fpending.c
200 255
201## end gnulib module fpending 256## end gnulib module fpending
202 257
258## begin gnulib module getgroups
259
260if gl_GNULIB_ENABLED_getgroups
261
262endif
263EXTRA_DIST += getgroups.c
264
265EXTRA_libgnu_a_SOURCES += getgroups.c
266
267## end gnulib module getgroups
268
203## begin gnulib module getloadavg 269## begin gnulib module getloadavg
204 270
205 271
@@ -259,6 +325,17 @@ EXTRA_libgnu_a_SOURCES += gettimeofday.c
259 325
260## end gnulib module gettimeofday 326## end gnulib module gettimeofday
261 327
328## begin gnulib module group-member
329
330if gl_GNULIB_ENABLED_a9786850e999ae65a836a6041e8e5ed1
331
332endif
333EXTRA_DIST += group-member.c
334
335EXTRA_libgnu_a_SOURCES += group-member.c
336
337## end gnulib module group-member
338
262## begin gnulib module ignore-value 339## begin gnulib module ignore-value
263 340
264 341
@@ -371,6 +448,15 @@ EXTRA_libgnu_a_SOURCES += readlink.c
371 448
372## end gnulib module readlink 449## end gnulib module readlink
373 450
451## begin gnulib module root-uid
452
453if gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c
454
455endif
456EXTRA_DIST += root-uid.h
457
458## end gnulib module root-uid
459
374## begin gnulib module signal-h 460## begin gnulib module signal-h
375 461
376BUILT_SOURCES += signal.h 462BUILT_SOURCES += signal.h
@@ -1329,6 +1415,15 @@ EXTRA_DIST += verify.h
1329 1415
1330## end gnulib module verify 1416## end gnulib module verify
1331 1417
1418## begin gnulib module xalloc-oversized
1419
1420if gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec
1421
1422endif
1423EXTRA_DIST += xalloc-oversized.h
1424
1425## end gnulib module xalloc-oversized
1426
1332 1427
1333mostlyclean-local: mostlyclean-generic 1428mostlyclean-local: mostlyclean-generic
1334 @for dir in '' $(MOSTLYCLEANDIRS); do \ 1429 @for dir in '' $(MOSTLYCLEANDIRS); do \
diff --git a/lib/group-member.c b/lib/group-member.c
new file mode 100644
index 00000000000..5fcc7e01d0c
--- /dev/null
+++ b/lib/group-member.c
@@ -0,0 +1,119 @@
1/* group-member.c -- determine whether group id is in calling user's group list
2
3 Copyright (C) 1994, 1997-1998, 2003, 2005-2006, 2009-2012 Free Software
4 Foundation, Inc.
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19#include <config.h>
20
21/* Specification. */
22#include <unistd.h>
23
24#include <stdio.h>
25#include <sys/types.h>
26#include <stdlib.h>
27
28#include "xalloc-oversized.h"
29
30/* Most processes have no more than this many groups, and for these
31 processes we can avoid using malloc. */
32enum { GROUPBUF_SIZE = 100 };
33
34struct group_info
35 {
36 gid_t *group;
37 gid_t groupbuf[GROUPBUF_SIZE];
38 };
39
40static void
41free_group_info (struct group_info const *g)
42{
43 if (g->group != g->groupbuf)
44 free (g->group);
45}
46
47static int
48get_group_info (struct group_info *gi)
49{
50 int n_groups = getgroups (GROUPBUF_SIZE, gi->groupbuf);
51 gi->group = gi->groupbuf;
52
53 if (n_groups < 0)
54 {
55 int n_group_slots = getgroups (0, NULL);
56 if (0 <= n_group_slots
57 && ! xalloc_oversized (n_group_slots, sizeof *gi->group))
58 {
59 gi->group = malloc (n_group_slots * sizeof *gi->group);
60 if (gi->group)
61 n_groups = getgroups (n_group_slots, gi->group);
62 }
63 }
64
65 /* In case of error, the user loses. */
66 return n_groups;
67}
68
69/* Return non-zero if GID is one that we have in our groups list.
70 Note that the groups list is not guaranteed to contain the current
71 or effective group ID, so they should generally be checked
72 separately. */
73
74int
75group_member (gid_t gid)
76{
77 int i;
78 int found;
79 struct group_info gi;
80 int n_groups = get_group_info (&gi);
81
82 /* Search through the list looking for GID. */
83 found = 0;
84 for (i = 0; i < n_groups; i++)
85 {
86 if (gid == gi.group[i])
87 {
88 found = 1;
89 break;
90 }
91 }
92
93 free_group_info (&gi);
94
95 return found;
96}
97
98#ifdef TEST
99
100char *program_name;
101
102int
103main (int argc, char **argv)
104{
105 int i;
106
107 program_name = argv[0];
108
109 for (i = 1; i < argc; i++)
110 {
111 gid_t gid;
112
113 gid = atoi (argv[i]);
114 printf ("%d: %s\n", gid, group_member (gid) ? "yes" : "no");
115 }
116 exit (0);
117}
118
119#endif /* TEST */
diff --git a/lib/root-uid.h b/lib/root-uid.h
new file mode 100644
index 00000000000..2379773c291
--- /dev/null
+++ b/lib/root-uid.h
@@ -0,0 +1,30 @@
1/* The user ID that always has appropriate privileges in the POSIX sense.
2
3 Copyright 2012 Free Software Foundation, Inc.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 Written by Paul Eggert. */
19
20#ifndef ROOT_UID_H_
21#define ROOT_UID_H_
22
23/* The user ID that always has appropriate privileges in the POSIX sense. */
24#ifdef __TANDEM
25# define ROOT_UID 65535
26#else
27# define ROOT_UID 0
28#endif
29
30#endif
diff --git a/lib/xalloc-oversized.h b/lib/xalloc-oversized.h
new file mode 100644
index 00000000000..ad777d8dd79
--- /dev/null
+++ b/lib/xalloc-oversized.h
@@ -0,0 +1,38 @@
1/* xalloc-oversized.h -- memory allocation size checking
2
3 Copyright (C) 1990-2000, 2003-2004, 2006-2012 Free Software Foundation, Inc.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18#ifndef XALLOC_OVERSIZED_H_
19# define XALLOC_OVERSIZED_H_
20
21# include <stddef.h>
22
23/* Return 1 if an array of N objects, each of size S, cannot exist due
24 to size arithmetic overflow. S must be positive and N must be
25 nonnegative. This is a macro, not a function, so that it
26 works correctly even when SIZE_MAX < N.
27
28 By gnulib convention, SIZE_MAX represents overflow in size
29 calculations, so the conservative dividend to use here is
30 SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
31 However, malloc (SIZE_MAX) fails on all known hosts where
32 sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
33 exactly-SIZE_MAX allocations on such hosts; this avoids a test and
34 branch when S is known to be 1. */
35# define xalloc_oversized(n, s) \
36 ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
37
38#endif /* !XALLOC_OVERSIZED_H_ */