summaryrefslogtreecommitdiffstats
path: root/gl
diff options
context:
space:
mode:
Diffstat (limited to 'gl')
-rw-r--r--gl/Makefile.am50
-rw-r--r--gl/idpriv-droptemp.c204
-rw-r--r--gl/idpriv.h116
-rw-r--r--gl/m4/gnulib-cache.m44
-rw-r--r--gl/m4/gnulib-comp.m426
-rw-r--r--gl/m4/idpriv.m414
-rw-r--r--gl/m4/strcase.m445
-rw-r--r--gl/m4/strings_h.m452
-rw-r--r--gl/strcasecmp.c62
-rw-r--r--gl/strings.in.h122
-rw-r--r--gl/strncasecmp.c62
11 files changed, 753 insertions, 4 deletions
diff --git a/gl/Makefile.am b/gl/Makefile.am
index c2e8e5a..54abb4c 100644
--- a/gl/Makefile.am
+++ b/gl/Makefile.am
@@ -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=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files base64 crypto/sha1 dirname environ floorf fsusage getaddrinfo gethostname getloadavg getopt-gnu gettext mountlist regex setenv strsep timegm unsetenv vasprintf vsnprintf 24# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files base64 crypto/sha1 dirname environ floorf fsusage getaddrinfo gethostname getloadavg getopt-gnu gettext idpriv-droptemp mountlist regex setenv strcase strsep timegm unsetenv vasprintf vsnprintf
25 25
26AUTOMAKE_OPTIONS = 1.9.6 gnits subdir-objects 26AUTOMAKE_OPTIONS = 1.9.6 gnits subdir-objects
27 27
@@ -402,6 +402,14 @@ EXTRA_DIST += $(top_srcdir)/build-aux/config.rpath
402 402
403## end gnulib module havelib 403## end gnulib module havelib
404 404
405## begin gnulib module idpriv-droptemp
406
407libgnu_a_SOURCES += idpriv-droptemp.c
408
409EXTRA_DIST += idpriv.h
410
411## end gnulib module idpriv-droptemp
412
405## begin gnulib module inet_ntop 413## begin gnulib module inet_ntop
406 414
407 415
@@ -1536,6 +1544,15 @@ EXTRA_DIST += stdlib.in.h
1536 1544
1537## end gnulib module stdlib 1545## end gnulib module stdlib
1538 1546
1547## begin gnulib module strcase
1548
1549
1550EXTRA_DIST += strcasecmp.c strncasecmp.c
1551
1552EXTRA_libgnu_a_SOURCES += strcasecmp.c strncasecmp.c
1553
1554## end gnulib module strcase
1555
1539## begin gnulib module streq 1556## begin gnulib module streq
1540 1557
1541 1558
@@ -1661,6 +1678,37 @@ EXTRA_DIST += string.in.h
1661 1678
1662## end gnulib module string 1679## end gnulib module string
1663 1680
1681## begin gnulib module strings
1682
1683BUILT_SOURCES += strings.h
1684
1685# We need the following in order to create <strings.h> when the system
1686# doesn't have one that works with the given compiler.
1687strings.h: strings.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H)
1688 $(AM_V_GEN)rm -f $@-t $@ && \
1689 { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
1690 sed -e 's|@''GUARD_PREFIX''@|GL|g' \
1691 -e 's|@''HAVE_STRINGS_H''@|$(HAVE_STRINGS_H)|g' \
1692 -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
1693 -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
1694 -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
1695 -e 's|@''NEXT_STRINGS_H''@|$(NEXT_STRINGS_H)|g' \
1696 -e 's|@''GNULIB_FFS''@|$(GNULIB_FFS)|g' \
1697 -e 's|@''HAVE_FFS''@|$(HAVE_FFS)|g' \
1698 -e 's|@''HAVE_STRCASECMP''@|$(HAVE_STRCASECMP)|g' \
1699 -e 's|@''HAVE_DECL_STRNCASECMP''@|$(HAVE_DECL_STRNCASECMP)|g' \
1700 -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
1701 -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
1702 -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
1703 < $(srcdir)/strings.in.h; \
1704 } > $@-t && \
1705 mv $@-t $@
1706MOSTLYCLEANFILES += strings.h strings.h-t
1707
1708EXTRA_DIST += strings.in.h
1709
1710## end gnulib module strings
1711
1664## begin gnulib module strndup 1712## begin gnulib module strndup
1665 1713
1666 1714
diff --git a/gl/idpriv-droptemp.c b/gl/idpriv-droptemp.c
new file mode 100644
index 0000000..13d1064
--- /dev/null
+++ b/gl/idpriv-droptemp.c
@@ -0,0 +1,204 @@
1/* Dropping uid/gid privileges of the current process temporarily.
2 Copyright (C) 2009-2013 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#include <config.h>
18
19#include "idpriv.h"
20
21#include <errno.h>
22#include <stdlib.h>
23#include <sys/types.h>
24#include <unistd.h>
25
26/* The privileged uid and gid that the process had earlier. */
27#if HAVE_GETUID
28static int saved_uid = -1;
29#endif
30#if HAVE_GETGID
31static int saved_gid = -1;
32#endif
33
34int
35idpriv_temp_drop (void)
36{
37#if HAVE_GETEUID && HAVE_GETEGID && (HAVE_SETRESUID || HAVE_SETREUID) && (HAVE_SETRESGID || HAVE_SETREGID)
38 int uid = getuid ();
39 int gid = getgid ();
40
41 /* Find out about the privileged uid and gid at the first call. */
42 if (saved_uid == -1)
43 saved_uid = geteuid ();
44 if (saved_gid == -1)
45 saved_gid = getegid ();
46
47 /* Drop the gid privilege first, because in some cases the gid privilege
48 cannot be dropped after the uid privilege has been dropped. */
49
50 /* This is for executables that have the setgid bit set. */
51# if HAVE_SETRESGID /* glibc, FreeBSD, OpenBSD, HP-UX */
52 if (setresgid (-1, gid, saved_gid) < 0)
53 return -1;
54# else /* Mac OS X, NetBSD, AIX, IRIX, Solaris >= 2.5, OSF/1, Cygwin */
55 if (setregid (-1, gid) < 0)
56 return -1;
57# endif
58
59 /* This is for executables that have the setuid bit set. */
60# if HAVE_SETRESUID /* glibc, FreeBSD, OpenBSD, HP-UX */
61 /* See <http://www.usenix.org/events/sec02/full_papers/chen/chen.pdf>
62 figure 14. */
63 if (setresuid (-1, uid, saved_uid) < 0)
64 return -1;
65# else /* Mac OS X, NetBSD, AIX, IRIX, Solaris >= 2.5, OSF/1, Cygwin */
66 if (setreuid (-1, uid) < 0)
67 return -1;
68# endif
69
70 /* Verify that the privileges have really been dropped.
71 This verification is here for security reasons. Doesn't matter if it
72 takes a couple of system calls.
73 When the verification fails, it indicates that we need to use different
74 API in the code above. Therefore 'abort ()', not 'return -1'. */
75# if HAVE_GETRESUID /* glibc, FreeBSD, OpenBSD, HP-UX */
76 {
77 uid_t real;
78 uid_t effective;
79 uid_t saved;
80 if (getresuid (&real, &effective, &saved) < 0
81 || real != uid
82 || effective != uid
83 || saved != saved_uid)
84 abort ();
85 }
86# else
87# if HAVE_GETEUID
88 if (geteuid () != uid)
89 abort ();
90# endif
91 if (getuid () != uid)
92 abort ();
93# endif
94# if HAVE_GETRESGID /* glibc, FreeBSD, OpenBSD, HP-UX */
95 {
96 uid_t real;
97 uid_t effective;
98 uid_t saved;
99 if (getresgid (&real, &effective, &saved) < 0
100 || real != gid
101 || effective != gid
102 || saved != saved_gid)
103 abort ();
104 }
105# else
106# if HAVE_GETEGID
107 if (getegid () != gid)
108 abort ();
109# endif
110 if (getgid () != gid)
111 abort ();
112# endif
113
114 return 0;
115#else
116 errno = ENOSYS;
117 return -1;
118#endif
119}
120
121int
122idpriv_temp_restore (void)
123{
124#if HAVE_GETEUID && HAVE_GETEGID && (HAVE_SETRESUID || HAVE_SETREUID) && (HAVE_SETRESGID || HAVE_SETREGID)
125 int uid = getuid ();
126 int gid = getgid ();
127
128 if (saved_uid == -1 || saved_gid == -1)
129 /* Caller error: idpriv_temp_drop was never invoked. */
130 abort ();
131
132 /* Acquire the gid privilege last, because in some cases the gid privilege
133 cannot be acquired before the uid privilege has been acquired. */
134
135 /* This is for executables that have the setuid bit set. */
136# if HAVE_SETRESUID /* glibc, FreeBSD, OpenBSD, HP-UX */
137 /* See <http://www.usenix.org/events/sec02/full_papers/chen/chen.pdf>
138 figure 14. */
139 if (setresuid (-1, saved_uid, -1) < 0)
140 return -1;
141# else /* Mac OS X, NetBSD, AIX, IRIX, Solaris >= 2.5, OSF/1, Cygwin */
142 if (setreuid (-1, saved_uid) < 0)
143 return -1;
144# endif
145
146 /* This is for executables that have the setgid bit set. */
147# if HAVE_SETRESGID /* glibc, FreeBSD, OpenBSD, HP-UX */
148 if (setresgid (-1, saved_gid, -1) < 0)
149 return -1;
150# else /* Mac OS X, NetBSD, AIX, IRIX, Solaris >= 2.5, OSF/1, Cygwin */
151 if (setregid (-1, saved_gid) < 0)
152 return -1;
153# endif
154
155 /* Verify that the privileges have really been acquired.
156 This verification is here for security reasons. Doesn't matter if it
157 takes a couple of system calls.
158 When the verification fails, it indicates that we need to use different
159 API in the code above. Therefore 'abort ()', not 'return -1'. */
160# if HAVE_GETRESUID /* glibc, FreeBSD, OpenBSD, HP-UX */
161 {
162 uid_t real;
163 uid_t effective;
164 uid_t saved;
165 if (getresuid (&real, &effective, &saved) < 0
166 || real != uid
167 || effective != saved_uid
168 || saved != saved_uid)
169 abort ();
170 }
171# else
172# if HAVE_GETEUID
173 if (geteuid () != saved_uid)
174 abort ();
175# endif
176 if (getuid () != uid)
177 abort ();
178# endif
179# if HAVE_GETRESGID /* glibc, FreeBSD, OpenBSD, HP-UX */
180 {
181 uid_t real;
182 uid_t effective;
183 uid_t saved;
184 if (getresgid (&real, &effective, &saved) < 0
185 || real != gid
186 || effective != saved_gid
187 || saved != saved_gid)
188 abort ();
189 }
190# else
191# if HAVE_GETEGID
192 if (getegid () != saved_gid)
193 abort ();
194# endif
195 if (getgid () != gid)
196 abort ();
197# endif
198
199 return 0;
200#else
201 errno = ENOSYS;
202 return -1;
203#endif
204}
diff --git a/gl/idpriv.h b/gl/idpriv.h
new file mode 100644
index 0000000..f454a2c
--- /dev/null
+++ b/gl/idpriv.h
@@ -0,0 +1,116 @@
1/* Dropping uid/gid privileges of the current process.
2 Copyright (C) 2009-2013 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#ifndef _IDPRIV_H
18#define _IDPRIV_H
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
24/* This module allows programs which are installed with setuid or setgid bit
25 (and which therefore initially run with an effective user id or group id
26 different from the one of the current user) to drop their uid or gid
27 privilege, either permanently or temporarily.
28
29 It is absolutely necessary to minimize the amount of code that is running
30 with escalated privileges (e.g. with effective uid = root). The reason is
31 that any bug or exploit in a part of a program that is running with
32 escalated privileges is a security vulnerability that - upon discovery -
33 puts the users in danger and requires immediate fixing. Then consider that
34 there's a bug every 10 or 20 lines of code on average...
35
36 For programs that temporarily drop privileges but have the ability to
37 restore them later, there are additionally the dangers that
38 - Any bug in the non-privileged part of the program may be used to
39 create invalid data structures that will trigger security
40 vulnerabilities in the privileged part of the program.
41 - Code execution exploits in the non-privileged part of the program may
42 be used to invoke the function that restores high privileges and then
43 execute additional arbitrary code.
44
45 1) The usual, and reasonably safe, way to minimize the amount of code
46 running with privileges is to create a separate executable, with setuid
47 or setgid bit, that contains only code for the tasks that require
48 privileges (and,of course, strict checking of the arguments, so that the
49 program cannot be abused). The main program is installed without setuid
50 or setgid bit.
51
52 2) A less safe way is to do some privileged tasks at the beginning of the
53 program's run, and drop privileges permanently as soon as possible.
54
55 Note: There may still be security issues if the privileged task puts
56 sensitive data into the process memory or opens communication channels
57 to restricted facilities.
58
59 3) The most unsafe way is to drop privileges temporarily for most of the
60 main program but to re-enable them for the duration of privileged tasks.
61
62 As explained above, this approach has uncontrollable dangers for
63 security.
64
65 This approach is normally not usable in multithreaded programs, because
66 you cannot know what kind of system calls the other threads could be
67 doing during the time the privileges are enabled.
68
69 With approach 1, you don't need gnulib modules.
70 With approach 2, you need the gnulib module 'idpriv-drop'.
71 With approach 3, you need the gnulib module 'idpriv-droptemp'. But really,
72 you should better stay away from this approach.
73 */
74
75/* For more in-depth discussion of these topics, see the papers/articles
76 * Hao Chen, David Wagner, Drew Dean: Setuid Demystified
77 <http://www.usenix.org/events/sec02/full_papers/chen/chen.pdf>
78 * Dan Tsafrir, Dilma da Silva, David Wagner: The Murky Issue of Changing
79 Process Identity: Revising "Setuid Demystified"
80 <http://www.eecs.berkeley.edu/~daw/papers/setuid-login08b.pdf>
81 <http://code.google.com/p/change-process-identity/>
82 * Dhruv Mohindra: Observe correct revocation order while relinquishing
83 privileges
84 <https://www.securecoding.cert.org/confluence/display/seccode/POS36-C.+Observe+correct+revocation+order+while+relinquishing+privileges>
85 */
86
87
88/* For approach 2. */
89
90/* Drop the uid and gid privileges of the current process.
91 Return 0 if successful, or -1 with errno set upon failure. The recommended
92 handling of failure is to terminate the process. */
93extern int idpriv_drop (void);
94
95
96/* For approach 3. */
97
98/* Drop the uid and gid privileges of the current process in a way that allows
99 them to be restored later.
100 Return 0 if successful, or -1 with errno set upon failure. The recommended
101 handling of failure is to terminate the process. */
102extern int idpriv_temp_drop (void);
103
104/* Restore the uid and gid privileges of the current process.
105 Return 0 if successful, or -1 with errno set upon failure. The recommended
106 handling of failure is to not perform the actions that require the escalated
107 privileges. */
108extern int idpriv_temp_restore (void);
109
110
111#ifdef __cplusplus
112}
113#endif
114
115
116#endif /* _IDPRIV_H */
diff --git a/gl/m4/gnulib-cache.m4 b/gl/m4/gnulib-cache.m4
index 2ed3509..d6fca2a 100644
--- a/gl/m4/gnulib-cache.m4
+++ b/gl/m4/gnulib-cache.m4
@@ -27,7 +27,7 @@
27 27
28 28
29# Specification in the form of a command-line invocation: 29# Specification in the form of a command-line invocation:
30# gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files base64 crypto/sha1 dirname environ floorf fsusage getaddrinfo gethostname getloadavg getopt-gnu gettext mountlist regex setenv strsep timegm unsetenv vasprintf vsnprintf 30# gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --no-conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files base64 crypto/sha1 dirname environ floorf fsusage getaddrinfo gethostname getloadavg getopt-gnu gettext idpriv-droptemp mountlist regex setenv strcase strsep timegm unsetenv vasprintf vsnprintf
31 31
32# Specification in the form of a few gnulib-tool.m4 macro invocations: 32# Specification in the form of a few gnulib-tool.m4 macro invocations:
33gl_LOCAL_DIR([]) 33gl_LOCAL_DIR([])
@@ -43,9 +43,11 @@ gl_MODULES([
43 getloadavg 43 getloadavg
44 getopt-gnu 44 getopt-gnu
45 gettext 45 gettext
46 idpriv-droptemp
46 mountlist 47 mountlist
47 regex 48 regex
48 setenv 49 setenv
50 strcase
49 strsep 51 strsep
50 timegm 52 timegm
51 unsetenv 53 unsetenv
diff --git a/gl/m4/gnulib-comp.m4 b/gl/m4/gnulib-comp.m4
index f23f769..67a8156 100644
--- a/gl/m4/gnulib-comp.m4
+++ b/gl/m4/gnulib-comp.m4
@@ -28,7 +28,7 @@
28# other built files. 28# other built files.
29 29
30 30
31# This macro should be invoked from ./configure.in, in the section 31# This macro should be invoked from ./configure.ac, in the section
32# "Checks for programs", right after AC_PROG_CC, and certainly before 32# "Checks for programs", right after AC_PROG_CC, and certainly before
33# any checks for libraries, header files, types and library functions. 33# any checks for libraries, header files, types and library functions.
34AC_DEFUN([gl_EARLY], 34AC_DEFUN([gl_EARLY],
@@ -70,6 +70,7 @@ AC_DEFUN([gl_EARLY],
70 # Code from module gettext-h: 70 # Code from module gettext-h:
71 # Code from module havelib: 71 # Code from module havelib:
72 # Code from module hostent: 72 # Code from module hostent:
73 # Code from module idpriv-droptemp:
73 # Code from module include_next: 74 # Code from module include_next:
74 # Code from module inet_ntop: 75 # Code from module inet_ntop:
75 # Code from module intprops: 76 # Code from module intprops:
@@ -119,10 +120,12 @@ AC_DEFUN([gl_EARLY],
119 # Code from module stdint: 120 # Code from module stdint:
120 # Code from module stdio: 121 # Code from module stdio:
121 # Code from module stdlib: 122 # Code from module stdlib:
123 # Code from module strcase:
122 # Code from module streq: 124 # Code from module streq:
123 # Code from module strerror: 125 # Code from module strerror:
124 # Code from module strerror-override: 126 # Code from module strerror-override:
125 # Code from module string: 127 # Code from module string:
128 # Code from module strings:
126 # Code from module strndup: 129 # Code from module strndup:
127 # Code from module strnlen: 130 # Code from module strnlen:
128 # Code from module strsep: 131 # Code from module strsep:
@@ -151,7 +154,7 @@ AC_DEFUN([gl_EARLY],
151 # Code from module xstrndup: 154 # Code from module xstrndup:
152]) 155])
153 156
154# This macro should be invoked from ./configure.in, in the section 157# This macro should be invoked from ./configure.ac, in the section
155# "Check for header files, types and library functions". 158# "Check for header files, types and library functions".
156AC_DEFUN([gl_INIT], 159AC_DEFUN([gl_INIT],
157[ 160[
@@ -256,6 +259,7 @@ AC_DEFUN([gl_INIT],
256 AC_SUBST([LIBINTL]) 259 AC_SUBST([LIBINTL])
257 AC_SUBST([LTLIBINTL]) 260 AC_SUBST([LTLIBINTL])
258 gl_HOSTENT 261 gl_HOSTENT
262 gl_IDPRIV
259 gl_FUNC_INET_NTOP 263 gl_FUNC_INET_NTOP
260 if test $HAVE_INET_NTOP = 0 || test $REPLACE_INET_NTOP = 1; then 264 if test $HAVE_INET_NTOP = 0 || test $REPLACE_INET_NTOP = 1; then
261 AC_LIBOBJ([inet_ntop]) 265 AC_LIBOBJ([inet_ntop])
@@ -377,6 +381,15 @@ AC_DEFUN([gl_INIT],
377 gl_STDINT_H 381 gl_STDINT_H
378 gl_STDIO_H 382 gl_STDIO_H
379 gl_STDLIB_H 383 gl_STDLIB_H
384 gl_STRCASE
385 if test $HAVE_STRCASECMP = 0; then
386 AC_LIBOBJ([strcasecmp])
387 gl_PREREQ_STRCASECMP
388 fi
389 if test $HAVE_STRNCASECMP = 0; then
390 AC_LIBOBJ([strncasecmp])
391 gl_PREREQ_STRNCASECMP
392 fi
380 gl_FUNC_STRERROR 393 gl_FUNC_STRERROR
381 if test $REPLACE_STRERROR = 1; then 394 if test $REPLACE_STRERROR = 1; then
382 AC_LIBOBJ([strerror]) 395 AC_LIBOBJ([strerror])
@@ -390,6 +403,7 @@ AC_DEFUN([gl_INIT],
390 gl_PREREQ_SYS_H_WINSOCK2 403 gl_PREREQ_SYS_H_WINSOCK2
391 fi 404 fi
392 gl_HEADER_STRING_H 405 gl_HEADER_STRING_H
406 gl_HEADER_STRINGS_H
393 gl_FUNC_STRNDUP 407 gl_FUNC_STRNDUP
394 if test $HAVE_STRNDUP = 0 || test $REPLACE_STRNDUP = 1; then 408 if test $HAVE_STRNDUP = 0 || test $REPLACE_STRNDUP = 1; then
395 AC_LIBOBJ([strndup]) 409 AC_LIBOBJ([strndup])
@@ -646,6 +660,8 @@ AC_DEFUN([gl_FILE_LIST], [
646 lib/glthread/lock.c 660 lib/glthread/lock.c
647 lib/glthread/lock.h 661 lib/glthread/lock.h
648 lib/glthread/threadlib.c 662 lib/glthread/threadlib.c
663 lib/idpriv-droptemp.c
664 lib/idpriv.h
649 lib/inet_ntop.c 665 lib/inet_ntop.c
650 lib/intprops.h 666 lib/intprops.h
651 lib/itold.c 667 lib/itold.c
@@ -706,12 +722,15 @@ AC_DEFUN([gl_FILE_LIST], [
706 lib/stdio.in.h 722 lib/stdio.in.h
707 lib/stdlib.in.h 723 lib/stdlib.in.h
708 lib/str-two-way.h 724 lib/str-two-way.h
725 lib/strcasecmp.c
709 lib/streq.h 726 lib/streq.h
710 lib/strerror-override.c 727 lib/strerror-override.c
711 lib/strerror-override.h 728 lib/strerror-override.h
712 lib/strerror.c 729 lib/strerror.c
713 lib/string.in.h 730 lib/string.in.h
731 lib/strings.in.h
714 lib/stripslash.c 732 lib/stripslash.c
733 lib/strncasecmp.c
715 lib/strndup.c 734 lib/strndup.c
716 lib/strnlen.c 735 lib/strnlen.c
717 lib/strsep.c 736 lib/strsep.c
@@ -775,6 +794,7 @@ AC_DEFUN([gl_FILE_LIST], [
775 m4/gnulib-common.m4 794 m4/gnulib-common.m4
776 m4/hostent.m4 795 m4/hostent.m4
777 m4/iconv.m4 796 m4/iconv.m4
797 m4/idpriv.m4
778 m4/include_next.m4 798 m4/include_next.m4
779 m4/inet_ntop.m4 799 m4/inet_ntop.m4
780 m4/intdiv0.m4 800 m4/intdiv0.m4
@@ -845,8 +865,10 @@ AC_DEFUN([gl_FILE_LIST], [
845 m4/stdint_h.m4 865 m4/stdint_h.m4
846 m4/stdio_h.m4 866 m4/stdio_h.m4
847 m4/stdlib_h.m4 867 m4/stdlib_h.m4
868 m4/strcase.m4
848 m4/strerror.m4 869 m4/strerror.m4
849 m4/string_h.m4 870 m4/string_h.m4
871 m4/strings_h.m4
850 m4/strndup.m4 872 m4/strndup.m4
851 m4/strnlen.m4 873 m4/strnlen.m4
852 m4/strsep.m4 874 m4/strsep.m4
diff --git a/gl/m4/idpriv.m4 b/gl/m4/idpriv.m4
new file mode 100644
index 0000000..167f523
--- /dev/null
+++ b/gl/m4/idpriv.m4
@@ -0,0 +1,14 @@
1# idpriv.m4 serial 1
2dnl Copyright (C) 2009-2013 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it,
5dnl with or without modifications, as long as this notice is preserved.
6
7AC_DEFUN([gl_IDPRIV],
8[
9 dnl Persuade glibc <unistd.h> to declare {get,set}res{uid,gid}.
10 AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
11
12 AC_CHECK_FUNCS_ONCE([getuid geteuid getresuid getgid getegid getresgid])
13 AC_CHECK_FUNCS_ONCE([setresuid setreuid seteuid setresgid setregid setegid])
14])
diff --git a/gl/m4/strcase.m4 b/gl/m4/strcase.m4
new file mode 100644
index 0000000..22bf57c
--- /dev/null
+++ b/gl/m4/strcase.m4
@@ -0,0 +1,45 @@
1# strcase.m4 serial 11
2dnl Copyright (C) 2002, 2005-2013 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it,
5dnl with or without modifications, as long as this notice is preserved.
6
7AC_DEFUN([gl_STRCASE],
8[
9 gl_FUNC_STRCASECMP
10 gl_FUNC_STRNCASECMP
11])
12
13AC_DEFUN([gl_FUNC_STRCASECMP],
14[
15 AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS])
16 AC_CHECK_FUNCS([strcasecmp])
17 if test $ac_cv_func_strcasecmp = no; then
18 HAVE_STRCASECMP=0
19 fi
20])
21
22AC_DEFUN([gl_FUNC_STRNCASECMP],
23[
24 AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS])
25 AC_CHECK_FUNCS([strncasecmp])
26 if test $ac_cv_func_strncasecmp = yes; then
27 HAVE_STRNCASECMP=1
28 else
29 HAVE_STRNCASECMP=0
30 fi
31 AC_CHECK_DECLS([strncasecmp])
32 if test $ac_cv_have_decl_strncasecmp = no; then
33 HAVE_DECL_STRNCASECMP=0
34 fi
35])
36
37# Prerequisites of lib/strcasecmp.c.
38AC_DEFUN([gl_PREREQ_STRCASECMP], [
39 :
40])
41
42# Prerequisites of lib/strncasecmp.c.
43AC_DEFUN([gl_PREREQ_STRNCASECMP], [
44 :
45])
diff --git a/gl/m4/strings_h.m4 b/gl/m4/strings_h.m4
new file mode 100644
index 0000000..76ef242
--- /dev/null
+++ b/gl/m4/strings_h.m4
@@ -0,0 +1,52 @@
1# Configure a replacement for <strings.h>.
2# serial 6
3
4# Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc.
5# This file is free software; the Free Software Foundation
6# gives unlimited permission to copy and/or distribute it,
7# with or without modifications, as long as this notice is preserved.
8
9AC_DEFUN([gl_HEADER_STRINGS_H],
10[
11 dnl Use AC_REQUIRE here, so that the default behavior below is expanded
12 dnl once only, before all statements that occur in other macros.
13 AC_REQUIRE([gl_HEADER_STRINGS_H_BODY])
14])
15
16AC_DEFUN([gl_HEADER_STRINGS_H_BODY],
17[
18 AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS])
19
20 gl_CHECK_NEXT_HEADERS([strings.h])
21 if test $ac_cv_header_strings_h = yes; then
22 HAVE_STRINGS_H=1
23 else
24 HAVE_STRINGS_H=0
25 fi
26 AC_SUBST([HAVE_STRINGS_H])
27
28 dnl Check for declarations of anything we want to poison if the
29 dnl corresponding gnulib module is not in use.
30 gl_WARN_ON_USE_PREPARE([[
31 /* Minix 3.1.8 has a bug: <sys/types.h> must be included before
32 <strings.h>. */
33 #include <sys/types.h>
34 #include <strings.h>
35 ]], [ffs strcasecmp strncasecmp])
36])
37
38AC_DEFUN([gl_STRINGS_MODULE_INDICATOR],
39[
40 dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
41 AC_REQUIRE([gl_HEADER_STRINGS_H_DEFAULTS])
42 gl_MODULE_INDICATOR_SET_VARIABLE([$1])
43])
44
45AC_DEFUN([gl_HEADER_STRINGS_H_DEFAULTS],
46[
47 GNULIB_FFS=0; AC_SUBST([GNULIB_FFS])
48 dnl Assume proper GNU behavior unless another module says otherwise.
49 HAVE_FFS=1; AC_SUBST([HAVE_FFS])
50 HAVE_STRCASECMP=1; AC_SUBST([HAVE_STRCASECMP])
51 HAVE_DECL_STRNCASECMP=1; AC_SUBST([HAVE_DECL_STRNCASECMP])
52])
diff --git a/gl/strcasecmp.c b/gl/strcasecmp.c
new file mode 100644
index 0000000..0f0a742
--- /dev/null
+++ b/gl/strcasecmp.c
@@ -0,0 +1,62 @@
1/* Case-insensitive string comparison function.
2 Copyright (C) 1998-1999, 2005-2007, 2009-2013 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, or (at your option)
7 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#include <config.h>
18
19/* Specification. */
20#include <string.h>
21
22#include <ctype.h>
23#include <limits.h>
24
25#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
26
27/* Compare strings S1 and S2, ignoring case, returning less than, equal to or
28 greater than zero if S1 is lexicographically less than, equal to or greater
29 than S2.
30 Note: This function does not work with multibyte strings! */
31
32int
33strcasecmp (const char *s1, const char *s2)
34{
35 const unsigned char *p1 = (const unsigned char *) s1;
36 const unsigned char *p2 = (const unsigned char *) s2;
37 unsigned char c1, c2;
38
39 if (p1 == p2)
40 return 0;
41
42 do
43 {
44 c1 = TOLOWER (*p1);
45 c2 = TOLOWER (*p2);
46
47 if (c1 == '\0')
48 break;
49
50 ++p1;
51 ++p2;
52 }
53 while (c1 == c2);
54
55 if (UCHAR_MAX <= INT_MAX)
56 return c1 - c2;
57 else
58 /* On machines where 'char' and 'int' are types of the same size, the
59 difference of two 'unsigned char' values - including the sign bit -
60 doesn't fit in an 'int'. */
61 return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
62}
diff --git a/gl/strings.in.h b/gl/strings.in.h
new file mode 100644
index 0000000..4469f86
--- /dev/null
+++ b/gl/strings.in.h
@@ -0,0 +1,122 @@
1/* A substitute <strings.h>.
2
3 Copyright (C) 2007-2013 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, or (at your option)
8 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 _@GUARD_PREFIX@_STRINGS_H
19
20#if __GNUC__ >= 3
21@PRAGMA_SYSTEM_HEADER@
22#endif
23@PRAGMA_COLUMNS@
24
25/* Minix 3.1.8 has a bug: <sys/types.h> must be included before <strings.h>.
26 But avoid namespace pollution on glibc systems. */
27#if defined __minix && !defined __GLIBC__
28# include <sys/types.h>
29#endif
30
31/* The include_next requires a split double-inclusion guard. */
32#if @HAVE_STRINGS_H@
33# @INCLUDE_NEXT@ @NEXT_STRINGS_H@
34#endif
35
36#ifndef _@GUARD_PREFIX@_STRINGS_H
37#define _@GUARD_PREFIX@_STRINGS_H
38
39#if ! @HAVE_DECL_STRNCASECMP@
40/* Get size_t. */
41# include <stddef.h>
42#endif
43
44
45/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
46
47/* The definition of _GL_ARG_NONNULL is copied here. */
48
49/* The definition of _GL_WARN_ON_USE is copied here. */
50
51#ifdef __cplusplus
52extern "C" {
53#endif
54
55
56 /* Find the index of the least-significant set bit. */
57#if @GNULIB_FFS@
58# if !@HAVE_FFS@
59_GL_FUNCDECL_SYS (ffs, int, (int i));
60# endif
61_GL_CXXALIAS_SYS (ffs, int, (int i));
62_GL_CXXALIASWARN (ffs);
63#elif defined GNULIB_POSIXCHECK
64# undef ffs
65# if HAVE_RAW_DECL_FFS
66_GL_WARN_ON_USE (ffs, "ffs is not portable - use the ffs module");
67# endif
68#endif
69
70/* Compare strings S1 and S2, ignoring case, returning less than, equal to or
71 greater than zero if S1 is lexicographically less than, equal to or greater
72 than S2.
73 Note: This function does not work in multibyte locales. */
74#if ! @HAVE_STRCASECMP@
75extern int strcasecmp (char const *s1, char const *s2)
76 _GL_ARG_NONNULL ((1, 2));
77#endif
78#if defined GNULIB_POSIXCHECK
79/* strcasecmp() does not work with multibyte strings:
80 POSIX says that it operates on "strings", and "string" in POSIX is defined
81 as a sequence of bytes, not of characters. */
82# undef strcasecmp
83# if HAVE_RAW_DECL_STRCASECMP
84_GL_WARN_ON_USE (strcasecmp, "strcasecmp cannot work correctly on character "
85 "strings in multibyte locales - "
86 "use mbscasecmp if you care about "
87 "internationalization, or use c_strcasecmp , "
88 "gnulib module c-strcase) if you want a locale "
89 "independent function");
90# endif
91#endif
92
93/* Compare no more than N bytes of strings S1 and S2, ignoring case,
94 returning less than, equal to or greater than zero if S1 is
95 lexicographically less than, equal to or greater than S2.
96 Note: This function cannot work correctly in multibyte locales. */
97#if ! @HAVE_DECL_STRNCASECMP@
98extern int strncasecmp (char const *s1, char const *s2, size_t n)
99 _GL_ARG_NONNULL ((1, 2));
100#endif
101#if defined GNULIB_POSIXCHECK
102/* strncasecmp() does not work with multibyte strings:
103 POSIX says that it operates on "strings", and "string" in POSIX is defined
104 as a sequence of bytes, not of characters. */
105# undef strncasecmp
106# if HAVE_RAW_DECL_STRNCASECMP
107_GL_WARN_ON_USE (strncasecmp, "strncasecmp cannot work correctly on character "
108 "strings in multibyte locales - "
109 "use mbsncasecmp or mbspcasecmp if you care about "
110 "internationalization, or use c_strncasecmp , "
111 "gnulib module c-strcase) if you want a locale "
112 "independent function");
113# endif
114#endif
115
116
117#ifdef __cplusplus
118}
119#endif
120
121#endif /* _@GUARD_PREFIX@_STRING_H */
122#endif /* _@GUARD_PREFIX@_STRING_H */
diff --git a/gl/strncasecmp.c b/gl/strncasecmp.c
new file mode 100644
index 0000000..35840bc
--- /dev/null
+++ b/gl/strncasecmp.c
@@ -0,0 +1,62 @@
1/* strncasecmp.c -- case insensitive string comparator
2 Copyright (C) 1998-1999, 2005-2007, 2009-2013 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, or (at your option)
7 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#include <config.h>
18
19/* Specification. */
20#include <string.h>
21
22#include <ctype.h>
23#include <limits.h>
24
25#define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch))
26
27/* Compare no more than N bytes of strings S1 and S2, ignoring case,
28 returning less than, equal to or greater than zero if S1 is
29 lexicographically less than, equal to or greater than S2.
30 Note: This function cannot work correctly in multibyte locales. */
31
32int
33strncasecmp (const char *s1, const char *s2, size_t n)
34{
35 register const unsigned char *p1 = (const unsigned char *) s1;
36 register const unsigned char *p2 = (const unsigned char *) s2;
37 unsigned char c1, c2;
38
39 if (p1 == p2 || n == 0)
40 return 0;
41
42 do
43 {
44 c1 = TOLOWER (*p1);
45 c2 = TOLOWER (*p2);
46
47 if (--n == 0 || c1 == '\0')
48 break;
49
50 ++p1;
51 ++p2;
52 }
53 while (c1 == c2);
54
55 if (UCHAR_MAX <= INT_MAX)
56 return c1 - c2;
57 else
58 /* On machines where 'char' and 'int' are types of the same size, the
59 difference of two 'unsigned char' values - including the sign bit -
60 doesn't fit in an 'int'. */
61 return (c1 > c2 ? 1 : c1 < c2 ? -1 : 0);
62}