Compare commits

...

2 Commits

Author SHA1 Message Date
Stefan Bühler
7bc3242654 Use pam 2009-10-23 10:40:30 +02:00
Stefan Bühler
306bb5fcfc Debianize 2009-10-23 10:35:28 +02:00
12 changed files with 254 additions and 7 deletions

42
Makefile Normal file
View File

@ -0,0 +1,42 @@
path = $(subst :, ,$(PATH))
diet_path = $(foreach dir,$(path),$(wildcard $(dir)/diet))
ifeq ($(strip $(diet_path)),)
ifneq ($(wildcard /opt/diet/bin/diet),)
DIET=/opt/diet/bin/diet
else
DIET=
endif
else
DIET:=$(strip $(diet_path))
endif
# to build without diet libc support, use $ make DIET=
# see http://www.fefe.de/dietlibc/ for details about the diet libc
ifneq ($(DEBUG),)
CFLAGS+=-g
LDFLAGS+=-g
else
CFLAGS+=-O2 -fomit-frame-pointer
LDFLAGS+=-s
ifneq ($(DIET),)
DIET+=-Os
endif
endif
# CC:=$(DIET) $(CC)
.PHONY: all install clean
all: execwrap
execwrap: execwrap.o
$(CC) -o $@ $< -lpam
install: execwrap
install -d $(DESTDIR)/usr/sbin/ $(DESTDIR)/usr/share/man/man8/
install -s -m 755 execwrap $(DESTDIR)/usr/sbin/
install execwrap.8 $(DESTDIR)/usr/share/man/man8/
clean:
rm -f execwrap

2
README
View File

@ -110,7 +110,7 @@ ENV_DEBUG Controls the name of environment variable used to enable d
There is no Makefile right now, but compile is as simple as:
> gcc -W -Wall -O2 -o execwrap execwrap.c && strip execwrap
> gcc -W -Wall -O2 -o execwrap execwrap.c -lpam && strip execwrap
Or similar, depending on taste. You need something other than an ancient compiler to make
it work, preferably C99. To install, make sure the file is owned by the super user and has

5
debian/changelog vendored Normal file
View File

@ -0,0 +1,5 @@
execwrap (0.5-1) unstable; urgency=low
* Initial release
-- Stefan Bühler <stbuehler@web.de> Thu, 03 Jan 2008 14:42:27 +0100

1
debian/compat vendored Normal file
View File

@ -0,0 +1 @@
6

18
debian/control vendored Normal file
View File

@ -0,0 +1,18 @@
Source: execwrap
Section: net
Priority: extra
Maintainer: Stefan Bühler <stbuehler@web.de>
Build-Depends: cdbs, debhelper (>= 5), libpam-dev
Standards-Version: 3.8.0
Homepage: http://cyanite.org/projects/execwrap/
Vcs-Git: git://cyanite.org/execwrap
Package: execwrap
Architecture: any
Depends: ${shlibs:Depends}
Description: super-user exec wrapper for the lighttpd web-server
ExecWrap is a super-user exec wrapper for the lighttpd web-server, but it can
be used in any environment as long as arguments can be passed from the server
to its children via the environment.
.
ExecWrap is released under the BSD license.

36
debian/copyright vendored Normal file
View File

@ -0,0 +1,36 @@
This package was debianized by Stefan Bühler <stbuehler@web.de> on
Thu, 03 Jan 2008 14:42:27 +0100.
It was downloaded from http://cyanite.org/projects/execwrap/
Upstream Author:
Sune Foldager
Copyright:
<Copyright (C) 2008 Sune Foldager>
License:
Redistribution and use in source and binary forms, with or without
modification, are permitted under the terms of the BSD License.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
On Debian systems, the complete text of the BSD License can be
found in `/usr/share/common-licenses/BSD'.
The Debian packaging is (C) 2008, Stefan Bühler <stbuehler@web.de> and
is licensed under the GPL, see `/usr/share/common-licenses/GPL'.

1
debian/docs vendored Normal file
View File

@ -0,0 +1 @@
README

5
debian/execwrap.pam vendored Normal file
View File

@ -0,0 +1,5 @@
#%PAM-1.0
session required pam_limits.so
@include common-session

43
debian/postinst vendored Normal file
View File

@ -0,0 +1,43 @@
#!/bin/sh
# postinst script for execwrap
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postinst> `configure' <most-recently-configured-version>
# * <old-postinst> `abort-upgrade' <new version>
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
# <new-version>
# * <postinst> `abort-remove'
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
# <failed-install-package> <version> `removing'
# <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
configure)
chown root:www-data /usr/sbin/execwrap
chmod 4750 /usr/sbin/execwrap
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

8
debian/rules vendored Executable file
View File

@ -0,0 +1,8 @@
#!/usr/bin/make -f
include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/class/makefile.mk
DEB_MAKE_INSTALL_TARGET := install DESTDIR=$(CURDIR)/debian/execwrap/
DEB_MAKE_CHECK_TARGET :=
DEB_INSTALL_MANPAGES_execwrap-static := execwrap.8

View File

@ -1,4 +1,4 @@
/*
// /*
Superuser-exec wrapper for HTTP serves and other needs (made especially for lighttpd).
Allows programs to be run with configurable uid/gid.
@ -84,7 +84,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define RC_BAD_OPTION 24
#define RC_CHILD_ABNORMAL_EXIT 25
#define RC_MISSING_PWENT 26
#define RC_PAM_FAILED 27
/* User configuration. */
#include "execwrap_config.h"
@ -127,6 +127,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sys/types.h>
#include <grp.h>
#include <sys/types.h>
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#if USE_SYSLOG
# include <syslog.h>
@ -147,6 +151,83 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif /* USE_SYSLOG */
#define UNUSED(x) ((void)(x))
static int execwrap_conv(int num_msg, const struct pam_message **msg, struct pam_response **response, void *appdata_ptr) {
struct pam_response *pr;
const struct pam_message *pm;
int n;
UNUSED(appdata_ptr);
if ((*response = calloc(num_msg, sizeof(struct pam_response))) == NULL)
return(PAM_CONV_ERR);
for (pr = *response, pm = *msg, n = num_msg; n--; pr++, pm++) {
switch (pm->msg_style) {
case PAM_PROMPT_ECHO_ON:
case PAM_PROMPT_ECHO_OFF:
// No input available!
goto err;
case PAM_TEXT_INFO:
if (pm->msg)
puts(pm->msg);
break;
case PAM_ERROR_MSG:
if (pm->msg) {
fputs(pm->msg, stderr);
fputc('\n', stderr);
}
break;
default:
goto err;
}
}
return PAM_SUCCESS;
err:
free(*response);
*response = NULL;
return(PAM_CONV_ERR);
}
static pam_handle_t *pamh;
// return 0 on success
int setup_pam_session(const char *username) {
static struct pam_conv pam_conv;
int pam_status;
pam_conv.conv = execwrap_conv;
pam_status = pam_start("execwrap", username, &pam_conv, &pamh);
if (pam_status != PAM_SUCCESS) {
puts("unable to initialize PAM");
return 1;
}
(void) pam_set_item(pamh, PAM_USER, username);
(void) pam_set_item(pamh, PAM_RUSER, "www-data");
(void) pam_setcred(pamh, PAM_ESTABLISH_CRED);
if ((pam_status = pam_open_session(pamh, 0)) != PAM_SUCCESS) {
(void) pam_end(pamh, pam_status | PAM_DATA_SILENT);
pamh = NULL;
puts("unable to open PAM session");
return 2;
}
return 0;
}
void close_pam_session() {
(void) pam_close_session(pamh, 0);
if (pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT) != PAM_SUCCESS) {
puts("unable to close PAM session");
}
pamh = NULL;
}
/* The global child PID and previous SIGTERM handler. */
int pid;
void (*oldHandler)(int);
@ -296,6 +377,10 @@ int main(int argc, char* argv[], char* envp[])
if(oldHandler == SIG_ERR) return RC_SIGNAL_HANDLER;
}
/* setup pam session for limits */
if (setup_pam_session(pwent->pw_name)) return RC_PAM_FAILED;
if (non_resident) close_pam_session();
/* Fork off (or, if we are a non-resident wrapper, just carry on). */
if(non_resident || !(pid = fork()))
{
@ -363,6 +448,9 @@ 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);
close_pam_session();
if(WIFEXITED(status)) return WEXITSTATUS(status);
return RC_CHILD_ABNORMAL_EXIT;
}

View File

@ -9,16 +9,16 @@ See the README for documentation.
/* Our parent must have this UID, or we will abort. */
#define PARENT_UID 106
#define PARENT_UID 33
/* Minimum UID we can switch to. */
#define TARGET_MIN_UID 1000
#define TARGET_MIN_UID 10000
/* Minimum GID we can switch to. */
#define TARGET_MIN_GID 100
#define TARGET_MIN_GID 10000
/* Path prefix all targets must start with. */
#define TARGET_PATH_PREFIX "/var/www/light/"
#define TARGET_PATH_PREFIX "/srv/www/"
/* Default UID to switch to, if none given. */
#define DEFAULT_UID 65534