From 88b0d668394c22a1097b0cb80347d839abbf804d Mon Sep 17 00:00:00 2001 From: Riccardo Murri Date: Tue, 30 May 2017 16:20:48 +0200 Subject: [PATCH 01/15] Add Makefile target for debug compilation --- Makefile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index bda7689..1e128e8 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -CFLAGS ?= -Wall -Werror -g +CFLAGS ?= -Wall -Werror LDFLAGS ?= PROG := su-exec @@ -13,5 +13,8 @@ $(PROG): $(SRCS) $(PROG)-static: $(SRCS) $(CC) $(CFLAGS) -o $@ $^ -static $(LDFLAGS) +$(PROG)-debug: $(SRCS) + $(CC) -g $(CFLAGS) -o $@ $^ $(LDFLAGS) + clean: - rm -f $(PROG) $(PROG)-static + rm -f $(PROG) $(PROG)-static $(PROG)-debug From f4d37b2f1cf50b9aa1cc2f2650bfae758dfe85b0 Mon Sep 17 00:00:00 2001 From: Riccardo Murri Date: Tue, 30 May 2017 16:22:35 +0200 Subject: [PATCH 02/15] Strip non-debug binaries. This brings down `su-exec` to 11kB and `su-exec-static` to 853kB on my Ubuntu 16.04 x86_64. --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 1e128e8..0eead54 100644 --- a/Makefile +++ b/Makefile @@ -9,9 +9,11 @@ all: $(PROG) $(PROG): $(SRCS) $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + strip $@ $(PROG)-static: $(SRCS) $(CC) $(CFLAGS) -o $@ $^ -static $(LDFLAGS) + strip $@ $(PROG)-debug: $(SRCS) $(CC) -g $(CFLAGS) -o $@ $^ $(LDFLAGS) From cc18e89d7338c798f5447a1119355bf67ba14bed Mon Sep 17 00:00:00 2001 From: Andrew Ball Date: Tue, 30 May 2017 13:48:36 -0500 Subject: [PATCH 03/15] Add functionality for "make install" with dynamic linking to libc. Static linking to GNU libc is not really allowed, and I am using GNU libc for my purposes (running Java on CentOS and Fedora). Being able to do "make install" makes packaging su-exec as an RPM easier. --- Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Makefile b/Makefile index bda7689..75919ea 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,9 @@ LDFLAGS ?= PROG := su-exec SRCS := $(PROG).c +PREFIX := /usr/local +INSTALL_DIR := $(PREFIX)/bin + all: $(PROG) $(PROG): $(SRCS) @@ -13,5 +16,8 @@ $(PROG): $(SRCS) $(PROG)-static: $(SRCS) $(CC) $(CFLAGS) -o $@ $^ -static $(LDFLAGS) +install: + install -m 0755 $(PROG) $(INSTALL_DIR) + clean: rm -f $(PROG) $(PROG)-static From 5a4e10b56fe8d1f9820f3aab5636ed1f94d9f4e6 Mon Sep 17 00:00:00 2001 From: Riccardo Murri Date: Wed, 31 May 2017 13:38:06 +0200 Subject: [PATCH 04/15] git ignore also the `-static` and `-debug` variants of exe file --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index ac47793..94e08f0 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,5 @@ *.dSYM/ su-exec +su-exec-static +su-exec-debug From 41cda4e5a30adaf5b56d6143d53ead11439980d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20L=C3=B8vdal?= Date: Sat, 14 Oct 2017 13:19:16 +0200 Subject: [PATCH 05/15] Add support for DESTDIR install prefix --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5698707..2532c7f 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ $(PROG)-debug: $(SRCS) $(CC) -g $(CFLAGS) -o $@ $^ $(LDFLAGS) install: - install -m 0755 $(PROG) $(INSTALL_DIR) + install -m 0755 $(PROG) $(DESTDIR)$(INSTALL_DIR) clean: rm -f $(PROG) $(PROG)-static $(PROG)-debug From 4912a85c95b0d471256947117d52cca28846d827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20L=C3=B8vdal?= Date: Sat, 14 Oct 2017 13:47:21 +0200 Subject: [PATCH 06/15] Make sure install dir exists --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 2532c7f..bf4f3d7 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,7 @@ $(PROG)-debug: $(SRCS) $(CC) -g $(CFLAGS) -o $@ $^ $(LDFLAGS) install: + install -d 0755 $(DESTDIR)$(INSTALL_DIR) install -m 0755 $(PROG) $(DESTDIR)$(INSTALL_DIR) clean: From 4176c2cf71b7313ba947f0434f91d776caeaee14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20L=C3=B8vdal?= Date: Sat, 14 Oct 2017 21:22:16 +0200 Subject: [PATCH 07/15] Add man page http://www.linuxjournal.com/article/1158 used as reference. --- Makefile | 3 +++ su-exec.1 | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 su-exec.1 diff --git a/Makefile b/Makefile index bf4f3d7..b70490a 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ SRCS := $(PROG).c PREFIX := /usr/local INSTALL_DIR := $(PREFIX)/bin +MAN_DIR := $(PREFIX)/share/man/man8 all: $(PROG) @@ -24,6 +25,8 @@ $(PROG)-debug: $(SRCS) install: install -d 0755 $(DESTDIR)$(INSTALL_DIR) install -m 0755 $(PROG) $(DESTDIR)$(INSTALL_DIR) + install -d 0755 $(DESTDIR)$(MAN_DIR) + install -m 0644 su-exec.1 $(DESTDIR)$(MAN_DIR) clean: rm -f $(PROG) $(PROG)-static $(PROG)-debug diff --git a/su-exec.1 b/su-exec.1 new file mode 100644 index 0000000..47e809b --- /dev/null +++ b/su-exec.1 @@ -0,0 +1,59 @@ +.TH SU-EXEC 8 "14 Oct 2017" + +.SH NAME +su-exec \- change user id and group id before executing a program + +.SH SYNOPSIS +\fBsu-exec\fP \fIuser-spec\fP \fIcommand\fP [ \fIarguments...\fP ] + +.SH DESCRIPTION +\fBsu-exec\fP executes a program with modified privileges. The program +will be exceuted directly and not run as a child, like su and sudo does, +which avoids TTY and signal issues. + +Notice that su-exec depends on being run by the root user, non-root +users do not have permission to change uid/gid. + +.SH OPTIONS +.TP +\fIuser-spec\fP +is either a user name (e.g. \fBnobody\fP) or user name and group name +separated with colon (e.g. \fBnobody:ftp\fP). Numeric uid/gid values +can be used instead of names. + +.TP +\fIcommand\fP +is the program to execute. Can be either absolute or relative path. + +.SH EXAMPLES + +.TP +Execute httpd as user \fIapache\fP and gid value 1000 with the two specified arguments: + +$ \fBsu-exec apache:1000 /usr/sbin/httpd -f /opt/www/httpd.conf\fP + +.SH ENVIRONMENT VARIABLES + +.TP +\fBHOME\fP +Is updated to the value matching the user entry in \fC/etc/passwd\fP. + +.TP +\fBPATH\fP +Is used for searching for the program to execute. + +Since su-exec is not running as a suid binary, the dynamic linker or +libc will not strip or ignore variables like LD_LIBRARY_PATH etc. + +.SH EXIT STATUS +.TP +\fB1\fP +If \fbsu-exec\fR fails to change priveledges or execute the program it +will return \fB1\fP. In the successfull case the exit value will be +whatever the executed program returns. + +.SH "SEE ALSO" +su(1), runuser(8), sudo(8), gosu(1) + +.SH BUGS +\fBUSER\fP and \fBLOGNAME\fP environmental variables are not updated. From d50ad68002797177532056da048a59075ddc286b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20L=C3=B8vdal?= Date: Sun, 15 Oct 2017 00:51:30 +0200 Subject: [PATCH 08/15] Add option for license printing Addresses https://github.com/ncopa/su-exec/issues/7 --- .gitignore | 1 + Makefile | 19 ++++++++++++------- su-exec.1 | 10 ++++++++++ su-exec.c | 14 ++++++++++++++ 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 94e08f0..bbf718a 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ su-exec su-exec-static su-exec-debug +license.inc diff --git a/Makefile b/Makefile index b70490a..d53af98 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ LDFLAGS ?= PROG := su-exec SRCS := $(PROG).c +INCS := license.inc PREFIX := /usr/local INSTALL_DIR := $(PREFIX)/bin @@ -11,16 +12,19 @@ MAN_DIR := $(PREFIX)/share/man/man8 all: $(PROG) -$(PROG): $(SRCS) - $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) +license.inc: LICENSE + xxd -i $^ > $@ + +$(PROG): $(SRCS) $(INCS) + $(CC) $(CFLAGS) -o $@ $(SRCS) $(LDFLAGS) strip $@ -$(PROG)-static: $(SRCS) - $(CC) $(CFLAGS) -o $@ $^ -static $(LDFLAGS) +$(PROG)-static: $(SRCS) $(INCS) + $(CC) $(CFLAGS) -o $@ $(SRCS) -static $(LDFLAGS) strip $@ -$(PROG)-debug: $(SRCS) - $(CC) -g $(CFLAGS) -o $@ $^ $(LDFLAGS) +$(PROG)-debug: $(SRCS) $(INCS) + $(CC) -g $(CFLAGS) -o $@ $(SRCS) $(LDFLAGS) install: install -d 0755 $(DESTDIR)$(INSTALL_DIR) @@ -29,4 +33,5 @@ install: install -m 0644 su-exec.1 $(DESTDIR)$(MAN_DIR) clean: - rm -f $(PROG) $(PROG)-static $(PROG)-debug + rm -f $(PROG) $(PROG)-static $(PROG)-debug $(INCS) + diff --git a/su-exec.1 b/su-exec.1 index 47e809b..67cf2be 100644 --- a/su-exec.1 +++ b/su-exec.1 @@ -6,6 +6,8 @@ su-exec \- change user id and group id before executing a program .SH SYNOPSIS \fBsu-exec\fP \fIuser-spec\fP \fIcommand\fP [ \fIarguments...\fP ] +\fBsu-exec\fP \fI-l\fP + .SH DESCRIPTION \fBsu-exec\fP executes a program with modified privileges. The program will be exceuted directly and not run as a child, like su and sudo does, @@ -25,6 +27,10 @@ can be used instead of names. \fIcommand\fP is the program to execute. Can be either absolute or relative path. +.TP +\fI-l\fP +Print license information and exits. + .SH EXAMPLES .TP @@ -46,6 +52,10 @@ Since su-exec is not running as a suid binary, the dynamic linker or libc will not strip or ignore variables like LD_LIBRARY_PATH etc. .SH EXIT STATUS +.TP +\fB0\fP +When printing license information. + .TP \fB1\fP If \fbsu-exec\fR fails to change priveledges or execute the program it diff --git a/su-exec.c b/su-exec.c index 176bbf2..a3c2655 100644 --- a/su-exec.c +++ b/su-exec.c @@ -11,14 +11,24 @@ #include #include + static char *argv0; static void usage(int exitcode) { printf("Usage: %s user-spec command [args]\n", argv0); + printf("Usage: %s -l\n\tShows license.\n", argv0); exit(exitcode); } +#include "license.inc" +static void print_license() +{ + unsigned int i; + for (i=0; i Date: Sat, 14 Oct 2017 22:27:54 +0200 Subject: [PATCH 09/15] Ignore vim swap files --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index bbf718a..016e97d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Vim swap files +.*.swp + # Object files *.o *.ko From 62cc5b0d7c4fc71965670e63a320d07022008fc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20L=C3=B8vdal?= Date: Sun, 15 Oct 2017 00:19:27 +0200 Subject: [PATCH 10/15] Use exit code 1 in case of too few arguments --- su-exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/su-exec.c b/su-exec.c index a3c2655..40962b8 100644 --- a/su-exec.c +++ b/su-exec.c @@ -43,7 +43,7 @@ int main(int argc, char *argv[]) return 0; } if (argc < 3) - usage(0); + usage(1); user = argv[1]; group = strchr(user, ':'); From 161380c565ff480c86f1770d04ac1d7b4530cdf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20L=C3=B8vdal?= Date: Sun, 15 Oct 2017 01:02:07 +0200 Subject: [PATCH 11/15] Use EXIT_SUCCESS + EXIT_FAILURE --- su-exec.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/su-exec.c b/su-exec.c index 40962b8..fa1bbe3 100644 --- a/su-exec.c +++ b/su-exec.c @@ -40,10 +40,10 @@ int main(int argc, char *argv[]) argv0 = argv[0]; if (argc == 2 && strcmp(argv[1], "-l") == 0) { print_license(); - return 0; + return EXIT_SUCCESS; } if (argc < 3) - usage(1); + usage(EXIT_FAILURE); user = argv[1]; group = strchr(user, ':'); @@ -88,7 +88,7 @@ int main(int argc, char *argv[]) if (pw == NULL) { if (setgroups(1, &gid) < 0) - err(1, "setgroups(%i)", gid); + err(EXIT_FAILURE, "setgroups(%i)", gid); } else { int ngroups = 0; gid_t *glist = NULL; @@ -98,24 +98,24 @@ int main(int argc, char *argv[]) if (r >= 0) { if (setgroups(ngroups, glist) < 0) - err(1, "setgroups"); + err(EXIT_FAILURE, "setgroups"); break; } glist = realloc(glist, ngroups * sizeof(gid_t)); if (glist == NULL) - err(1, "malloc"); + err(EXIT_FAILURE, "malloc"); } } if (setgid(gid) < 0) - err(1, "setgid(%i)", gid); + err(EXIT_FAILURE, "setgid(%i)", gid); if (setuid(uid) < 0) - err(1, "setuid(%i)", uid); + err(EXIT_FAILURE, "setuid(%i)", uid); execvp(cmdargv[0], cmdargv); - err(1, "%s", cmdargv[0]); + err(EXIT_FAILURE, "%s", cmdargv[0]); - return 1; + return EXIT_FAILURE; } From 898b79af4cd0839c22528a4f01b1fa35ee1ae5fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20L=C3=B8vdal?= Date: Sun, 15 Oct 2017 14:04:07 +0200 Subject: [PATCH 12/15] Print an extra, descriptive warning for EPERM The far most likely cause for EPERM is that people try to run su-exec as a non-root user, so help them understand this is not possible. --- su-exec.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/su-exec.c b/su-exec.c index fa1bbe3..955ff5d 100644 --- a/su-exec.c +++ b/su-exec.c @@ -29,6 +29,26 @@ static void print_license() putchar(LICENSE[i]); } +#ifdef linux +#define WARNING_setgroups " (on Linux you need CAP_SETGID)" +#define WARNING_setgid " (on Linux you need CAP_SETGID)" +#define WARNING_setuid " (on Linux you need CAP_SETUID)" +#else +#define WARNING_setgroups "" +#define WARNING_setgid "" +#define WARNING_setuid "" +#endif + +static void print_eperm_warning(const char *extra_warn) +{ + int saved_errno; + if (errno != EPERM) + return; + saved_errno = errno; + fprintf(stderr, "Insufficient privilege, %s needs to run as root%s.\n", argv0, extra_warn); + errno = saved_errno; +} + int main(int argc, char *argv[]) { char *user, *group, **cmdargv; @@ -87,8 +107,10 @@ int main(int argc, char *argv[]) } if (pw == NULL) { - if (setgroups(1, &gid) < 0) + if (setgroups(1, &gid) < 0) { + print_eperm_warning(WARNING_setgroups); err(EXIT_FAILURE, "setgroups(%i)", gid); + } } else { int ngroups = 0; gid_t *glist = NULL; @@ -97,8 +119,10 @@ int main(int argc, char *argv[]) int r = getgrouplist(pw->pw_name, gid, glist, &ngroups); if (r >= 0) { - if (setgroups(ngroups, glist) < 0) + if (setgroups(ngroups, glist) < 0) { + print_eperm_warning(WARNING_setgroups); err(EXIT_FAILURE, "setgroups"); + } break; } @@ -108,11 +132,15 @@ int main(int argc, char *argv[]) } } - if (setgid(gid) < 0) + if (setgid(gid) < 0) { + print_eperm_warning(WARNING_setgid); err(EXIT_FAILURE, "setgid(%i)", gid); + } - if (setuid(uid) < 0) + if (setuid(uid) < 0) { + print_eperm_warning(WARNING_setuid); err(EXIT_FAILURE, "setuid(%i)", uid); + } execvp(cmdargv[0], cmdargv); err(EXIT_FAILURE, "%s", cmdargv[0]); From 93149d3f1b0827fabebed05290eec6f9a3f87f50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20L=C3=B8vdal?= Date: Sun, 15 Oct 2017 21:16:23 +0200 Subject: [PATCH 13/15] Refactor conditional expression into if..else --- su-exec.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/su-exec.c b/su-exec.c index 955ff5d..e31bb07 100644 --- a/su-exec.c +++ b/su-exec.c @@ -87,7 +87,11 @@ int main(int argc, char *argv[]) gid = pw->pw_gid; } - setenv("HOME", pw != NULL ? pw->pw_dir : "/", 1); + if (pw != NULL) { + setenv("HOME", pw->pw_dir, 1); + } else { + setenv("HOME", "/", 1); + } if (group && group[0] != '\0') { /* group was specified, ignore grouplist for setgroups later */ From a23053adcd125442eb4326d560563990e1bc3b26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20L=C3=B8vdal?= Date: Sun, 15 Oct 2017 23:21:47 +0200 Subject: [PATCH 14/15] Add static_assert.h headerfile --- Makefile | 2 +- include/static_assert.h | 106 ++++++++++++ include/static_assert_counter.h | 279 ++++++++++++++++++++++++++++++++ 3 files changed, 386 insertions(+), 1 deletion(-) create mode 100644 include/static_assert.h create mode 100644 include/static_assert_counter.h diff --git a/Makefile b/Makefile index d53af98..61a3647 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -CFLAGS ?= -Wall -Werror +CFLAGS ?= -Wall -Werror -Iinclude LDFLAGS ?= PROG := su-exec diff --git a/include/static_assert.h b/include/static_assert.h new file mode 100644 index 0000000..160f368 --- /dev/null +++ b/include/static_assert.h @@ -0,0 +1,106 @@ +/* + * Copied from https://github.com/wc-duck/dbgtools/blob/master/include/dbgtools/static_assert.h + */ +/* + dbgtools - platform independent wrapping of "nice to have" debug functions. + + version 0.1, october, 2013 + + https://github.com/wc-duck/dbgtools + + Copyright (C) 2013- Fredrik Kihlander + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Fredrik Kihlander + */ + +#ifndef DBGTOOLS_STATIC_ASSERT_INCLUDED +#define DBGTOOLS_STATIC_ASSERT_INCLUDED + +/** + * Compile-time check that condition is true, if false a compile-time error will be generated. + * This macro tries to use a built in variant of static assert to generate as good errors as possible but fall back to a generic implementation + * if that is not available. + * + * @note msg will be ignored and an "as good as possible" message will get displayed instead if compiler has no built in support for static assert. + * + * @note macro do unfortunately not work within structs in its c-implementation =/ + * @note on compilers that do not support __COUNTER__ static_assert_counter.h will be used to generate a counter. This however forces the user to include + * static_assert.h in each file where it is used ( as should be done anyways ). + * + * @example STATIC_ASSERT( sizeof( int ) == 4, "size of int is not 4!" ); + */ +#define STATIC_ASSERT(cond, msg) +#undef STATIC_ASSERT + +// ... clang ... +#if defined( __clang__ ) +# if defined( __cplusplus ) && __has_feature(cxx_static_assert) +# define STATIC_ASSERT( cond, msg ) static_assert( cond, msg ) +# elif __has_feature(c_static_assert) +# define STATIC_ASSERT( cond, msg ) _Static_assert( cond, msg ) +# endif + +// ... msvc ... +#elif defined( _MSC_VER ) && ( defined(_MSC_VER) && (_MSC_VER >= 1600) ) +# define STATIC_ASSERT( cond, msg ) static_assert( cond, msg ) + +// ... gcc ... +#elif defined( __cplusplus ) +# if __cplusplus >= 201103L || ( defined(_MSC_VER) && (_MSC_VER >= 1600) ) +# define STATIC_ASSERT( cond, msg ) static_assert( cond, msg ) +# endif +#elif defined( __STDC__ ) +# if defined( __STDC_VERSION__ ) +# if __STDC_VERSION__ >= 201112L +# define STATIC_ASSERT( cond, msg ) _Static_assert( cond, msg ) +# else +# define STATIC_ASSERT( cond, msg ) _Static_assert( cond, msg ) +# endif +# endif +#endif + +/* if we couldn't detect a builtin static assert, lets define one! */ +#ifndef STATIC_ASSERT +# if defined( __COUNTER__ ) +# define DBGTOOLS_STATIC_ASSERT_MACRO_TOKENS_DO(line) DBGTOOLS_STATIC_ASSERT_MACRO_TOKENS_DO1(__COUNTER__,line) +# else +# define DBGTOOLS_STATIC_ASSERT_MACRO_TOKENS_DO(line) DBGTOOLS_STATIC_ASSERT_MACRO_TOKENS_DO1(DBG_TOOLS_STATIC_ASSERT_COUNTER,line) +# endif +# define DBGTOOLS_STATIC_ASSERT_MACRO_TOKENS_DO1(count,line) DBGTOOLS_STATIC_ASSERT_MACRO_TOKENS_DO2(count,line) +# define DBGTOOLS_STATIC_ASSERT_MACRO_TOKENS_DO2(count,line) static_assert_##count##_at_line_##line +# +# if defined( _MSC_VER ) +# if defined( __cplusplus ) + template struct DBG_TOOLS_STATIC_ASSERT_IMPL; + template<> struct DBG_TOOLS_STATIC_ASSERT_IMPL {}; +# define STATIC_ASSERT( cond, msg ) struct DBGTOOLS_STATIC_ASSERT_MACRO_TOKENS_DO( __LINE__ ) { DBG_TOOLS_STATIC_ASSERT_IMPL<(cond)> a; } +# else +# define STATIC_ASSERT( cond, msg ) enum { DBGTOOLS_STATIC_ASSERT_MACRO_TOKENS_DO( __LINE__ ) = 1 / (!!(cond)) } +# endif +# else +# define STATIC_ASSERT( cond, msg ) typedef char DBGTOOLS_STATIC_ASSERT_MACRO_TOKENS_DO( __LINE__ )[ (cond) ? 1 : -1 ] __attribute__ ((unused)) +# endif +#endif + +#endif + +// This inclusion is outside the ifdef on purpose. +#if !defined( __COUNTER__ ) +# include "static_assert_counter.h" +#endif diff --git a/include/static_assert_counter.h b/include/static_assert_counter.h new file mode 100644 index 0000000..358093b --- /dev/null +++ b/include/static_assert_counter.h @@ -0,0 +1,279 @@ +/* + * Copied from https://github.com/wc-duck/dbgtools/blob/master/include/dbgtools/static_assert_counter.h + */ +/* + dbgtools - platform independent wrapping of "nice to have" debug functions. + + version 0.1, october, 2013 + + https://github.com/wc-duck/dbgtools + + Copyright (C) 2013- Fredrik Kihlander + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Fredrik Kihlander +*/ + +/** + * Auto-generated header implementing a counter that increases by each include of the file. + * + * This header will define the macro DBG_TOOLS_STATIC_ASSERT_COUNTER to be increased for each inclusion of the file. + * + * It has been generated with 3 amount of digits resulting in the counter wrapping around after + * 10000 inclusions. + * + * Usage: + * + * #include "this_header.h" + * int a = DBG_TOOLS_STATIC_ASSERT_COUNTER; // 0 + * #include "this_header.h" + * int b = DBG_TOOLS_STATIC_ASSERT_COUNTER; // 1 + * #include "this_header.h" + * int c = DBG_TOOLS_STATIC_ASSERT_COUNTER; // 2 + * #include "this_header.h" + * int d = DBG_TOOLS_STATIC_ASSERT_COUNTER; // 3 + */ + +#ifndef DBG_TOOLS_STATIC_ASSERT_COUNTER +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_0 0 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_1 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_2 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_3 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_0 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_0 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_0 +#endif // DBG_TOOLS_STATIC_ASSERT_COUNTER + +#if !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_0 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_0 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_0 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_0 0 +#elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_1 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_1 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_0 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_0 1 +#elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_2 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_2 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_0 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_0 2 +#elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_3 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_3 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_0 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_0 3 +#elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_4 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_4 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_0 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_0 4 +#elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_5 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_5 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_0 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_0 5 +#elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_6 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_6 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_0 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_0 6 +#elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_7 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_7 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_0 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_0 7 +#elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_8 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_8 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_0 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_0 8 +#elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_9 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_9 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_0 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_0 9 +#else +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_1 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_2 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_3 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_4 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_5 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_6 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_7 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_8 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D0_9 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_0 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_0 0 +# if !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_0 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_0 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_1 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_1 0 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_1 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_1 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_1 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_1 1 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_2 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_2 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_1 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_1 2 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_3 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_3 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_1 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_1 3 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_4 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_4 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_1 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_1 4 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_5 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_5 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_1 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_1 5 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_6 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_6 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_1 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_1 6 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_7 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_7 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_1 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_1 7 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_8 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_8 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_1 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_1 8 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_9 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_9 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_1 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_1 9 +# else +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_1 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_2 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_3 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_4 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_5 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_6 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_7 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_8 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D1_9 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_1 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_1 0 +# if !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_0 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_0 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_2 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_2 0 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_1 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_1 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_2 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_2 1 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_2 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_2 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_2 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_2 2 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_3 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_3 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_2 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_2 3 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_4 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_4 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_2 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_2 4 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_5 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_5 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_2 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_2 5 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_6 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_6 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_2 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_2 6 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_7 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_7 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_2 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_2 7 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_8 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_8 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_2 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_2 8 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_9 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_9 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_2 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_2 9 +# else +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_1 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_2 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_3 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_4 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_5 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_6 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_7 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_8 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D2_9 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_2 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_2 0 +# if !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_0 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_0 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_3 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_3 0 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_1 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_1 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_3 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_3 1 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_2 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_2 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_3 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_3 2 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_3 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_3 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_3 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_3 3 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_4 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_4 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_3 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_3 4 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_5 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_5 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_3 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_3 5 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_6 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_6 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_3 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_3 6 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_7 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_7 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_3 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_3 7 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_8 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_8 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_3 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_3 8 +# elif !defined( DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_9 ) +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_9 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_3 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_3 9 +# else +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_1 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_2 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_3 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_4 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_5 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_6 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_7 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_8 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_D3_9 +# undef DBG_TOOLS_STATIC_ASSERT_COUNTER_3 +# define DBG_TOOLS_STATIC_ASSERT_COUNTER_3 0 +# endif +# endif +# endif +#endif + +#define DBG_TOOLS_STATIC_ASSERT_COUNTER_JOIN_DIGITS_MACRO_(digit0,digit1,digit2,digit3) digit0##digit1##digit2##digit3 +#define DBG_TOOLS_STATIC_ASSERT_COUNTER_JOIN_DIGITS_MACRO(digit0,digit1,digit2,digit3) DBG_TOOLS_STATIC_ASSERT_COUNTER_JOIN_DIGITS_MACRO_(digit0,digit1,digit2,digit3) +#undef DBG_TOOLS_STATIC_ASSERT_COUNTER +#define DBG_TOOLS_STATIC_ASSERT_COUNTER DBG_TOOLS_STATIC_ASSERT_COUNTER_JOIN_DIGITS_MACRO(DBG_TOOLS_STATIC_ASSERT_COUNTER_3,DBG_TOOLS_STATIC_ASSERT_COUNTER_2,DBG_TOOLS_STATIC_ASSERT_COUNTER_1,DBG_TOOLS_STATIC_ASSERT_COUNTER_0) + From 5b3191db9345e96bebfc0fc70483e5fbb1094629 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20L=C3=B8vdal?= Date: Sun, 15 Oct 2017 23:31:49 +0200 Subject: [PATCH 15/15] Update USER and LOGNAME environment variables as well --- su-exec.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/su-exec.c b/su-exec.c index e31bb07..435b3ae 100644 --- a/su-exec.c +++ b/su-exec.c @@ -11,6 +11,12 @@ #include #include +#include "static_assert.h" + +STATIC_ASSERT( sizeof(uid_t) <= 4, "The size of uid_t is too big, the source must be updated" ); +#define UID_T_STRING_SIZE 11 /* Worst case: "4294967295\0" */ +#define UID_T_FMT "%lu" +#define UID_T_FMT_CAST (unsigned long) static char *argv0; @@ -89,8 +95,14 @@ int main(int argc, char *argv[]) if (pw != NULL) { setenv("HOME", pw->pw_dir, 1); + setenv("USER", pw->pw_name, 1); + setenv("LOGNAME", pw->pw_name, 1); } else { + char tmp[UID_T_STRING_SIZE]; + sprintf(tmp, UID_T_FMT, UID_T_FMT_CAST uid); setenv("HOME", "/", 1); + setenv("USER", tmp, 1); + setenv("LOGNAME", tmp, 1); } if (group && group[0] != '\0') {