From 6f3ffa2ea88c6537a5fe1f5c76c5a93bde7416a8 Mon Sep 17 00:00:00 2001 From: Sune Foldager Date: Mon, 7 Jul 2008 22:15:59 +0200 Subject: [PATCH] Bug fixes and new features. - Made the CHECK_GID feature optional (by compile-time configuration). - The supplementary group access list is now set, if the target user has a pwent. - Target users can be required to have a pwent (by compile-time configuration). - Child exit statuses are now correctly propagated to the parent. - Updated the README. - Bumped version number to 0.5. --- README | 5 +++++ execwrap.c | 35 ++++++++++++++++++++++++++++------- execwrap_config.h | 8 +++++++- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/README b/README index 7aeab77..8d3e1b1 100644 --- a/README +++ b/README @@ -70,6 +70,11 @@ DEFAULT_UID The default (numeric) UID to become, if no UID is given vi DEFAULT_GID The same as DEFAULT_UID, but for the GID. The same reasons and restrictions apply. +REQUIRE_PWENT If set, target users are reuired to have passwd-entries. These are + used to set the supplementary group access list. Defaults to 0. + +ALLOW_CHECKGID If set, enabled the CHECK_GID feature, q.v. Defaults to 1. + The following configuration parameters shouldn't normally be changed. In case you have a clash with some other ENV arguments to the target program, they can be changed, however. diff --git a/execwrap.c b/execwrap.c index 8fb5dfa..0c059dd 100644 --- a/execwrap.c +++ b/execwrap.c @@ -2,7 +2,7 @@ Superuser-exec wrapper for HTTP serves and other needs (made especially for lighttpd). Allows programs to be run with configurable uid/gid. -Version 0.4 (2006-06-09) +Version 0.5 (2008-07-07) For documentation on how to configure the wrapper, see the README. Command line option -v displays version, while -V displays compile-time configuration. @@ -12,6 +12,11 @@ Brief version history: Vers Date Changes ----------------------------------------------------------------------------------------- +0.5 2008-07-07 Added proper handling of the supplementary group access list. Fixed a + bug with passing on return values from the child process. Added + compile-time configuration options to disable the CHECK_GID feature and + to require the target user to have a pwent (in /etc/passwd). + Thanks to stbuehler, hoffie and _lotek from #lighttpd for help. 0.4 2006-06-09 Added a BSD license. 0.3 2005-09-27 Changed the wrapper to stay resident and propagate SIGTERM to the target. Not doing so will prevent the server from managing the target. @@ -26,7 +31,7 @@ Vers Date Changes License: -Copyright (c) 2006, Sune Foldager +Copyright (c) 2008, Sune Foldager All rights reserved. Redistribution and use in source and binary forms, with or without modification, are @@ -76,6 +81,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define RC_WRONG_GROUP 22 #define RC_EXEC 23 #define RC_BAD_OPTION 24 +#define RC_CHILD_ABNORMAL_EXIT 25 +#define RC_MISSING_PWENT 26 + /* User configuration. */ #include "execwrap_config.h" @@ -95,7 +103,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endif /* Useful macro and other stuff. */ -#define VERSION_STRING "ExecWrap v0.3 by Sune Foldager." +#define VERSION_STRING "ExecWrap v0.5 Copyright (c) 2008, Sune Foldager." #define STRLEN(a) (sizeof(a)-1) /* Shortcuts. */ @@ -111,8 +119,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include #include +#include /* The global child PID and previous SIGTERM handler. */ @@ -155,6 +165,9 @@ int main(int argc, char* argv[], char* envp[]) printf("TARGET_PATH_PREFIX : %s\n", TARGET_PATH_PREFIX); printf("DEFAULT_UID : %d\n", DEFAULT_UID); printf("DEFAULT_GID : %d\n", DEFAULT_GID); + puts(""); + printf("REQUIRE_PWENT : %d\n", REQUIRE_PWENT); + printf("ALLOW_CHECKGID : %d\n", ALLOW_CHECKGID); return 0; } @@ -198,10 +211,12 @@ int main(int argc, char* argv[], char* envp[]) } /* Check GID instead of UID. */ + #if ALLOW_CHECKGID if(!strncmp(ENV_CHECK_GID, s, ENV_CHECK_GID_LEN)) { check_gid = 1; } + #endif /* Use non-resident wrapping style. */ if(!strncmp(ENV_NON_RESIDENT, s, ENV_NON_RESIDENT_LEN)) @@ -214,6 +229,12 @@ int main(int argc, char* argv[], char* envp[]) /* See if we got all we need. */ if(!target) return RC_MISSING_CONFIG; + /* Fetch user information from passwd. */ + struct passwd *pwent = getpwuid(uid); + #if REQUIRE_PWENT + if(!pwent) return RC_MISSING_PWENT; + #endif + /* Install the SIGTERM handler. */ if(!non_resident) { @@ -225,7 +246,8 @@ int main(int argc, char* argv[], char* envp[]) if(non_resident || !(pid = fork())) { - /* We're in the child. Drop privileges. */ + /* We're in the child. Drop privileges and set the group list. */ + if(pwent && initgroups(pwent->pw_name, gid)) return RC_SETGID; if(setgid(gid)) return RC_SETGID; if(setuid(uid)) return RC_SETUID; @@ -262,7 +284,6 @@ int main(int argc, char* argv[], char* envp[]) /* Here we're in the parent. Wait for the child to be done, and return. */ int status; wait(&status); - return status; - + if(WIFEXITED(status)) return WEXITSTATUS(status); + return RC_CHILD_ABNORMAL_EXIT; } - diff --git a/execwrap_config.h b/execwrap_config.h index 4682165..a0eb7e5 100644 --- a/execwrap_config.h +++ b/execwrap_config.h @@ -9,7 +9,7 @@ See the README for documentation. /* Our parent must have this UID, or we will abort. */ -#define PARENT_UID 104 +#define PARENT_UID 106 /* Minimum UID we can switch to. */ #define TARGET_MIN_UID 1000 @@ -26,3 +26,9 @@ See the README for documentation. /* Default GID to switch to, if none given. */ #define DEFAULT_GID 65534 + +/* Require users to have pwents (i.e. entries in /etc/passwd or similar)? */ +#define REQUIRE_PWENT 0 + +/* Allow use of the CHECK_GID mode? */ +#define ALLOW_CHECKGID 1