Use pam
This commit is contained in:
parent
306bb5fcfc
commit
7bc3242654
5
Makefile
5
Makefile
@ -25,11 +25,14 @@ DIET+=-Os
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CC:=$(DIET) $(CC)
|
# CC:=$(DIET) $(CC)
|
||||||
|
|
||||||
.PHONY: all install clean
|
.PHONY: all install clean
|
||||||
all: execwrap
|
all: execwrap
|
||||||
|
|
||||||
|
execwrap: execwrap.o
|
||||||
|
$(CC) -o $@ $< -lpam
|
||||||
|
|
||||||
install: execwrap
|
install: execwrap
|
||||||
install -d $(DESTDIR)/usr/sbin/ $(DESTDIR)/usr/share/man/man8/
|
install -d $(DESTDIR)/usr/sbin/ $(DESTDIR)/usr/share/man/man8/
|
||||||
install -s -m 755 execwrap $(DESTDIR)/usr/sbin/
|
install -s -m 755 execwrap $(DESTDIR)/usr/sbin/
|
||||||
|
2
README
2
README
@ -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:
|
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
|
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
|
it work, preferably C99. To install, make sure the file is owned by the super user and has
|
||||||
|
2
debian/control
vendored
2
debian/control
vendored
@ -2,7 +2,7 @@ Source: execwrap
|
|||||||
Section: net
|
Section: net
|
||||||
Priority: extra
|
Priority: extra
|
||||||
Maintainer: Stefan Bühler <stbuehler@web.de>
|
Maintainer: Stefan Bühler <stbuehler@web.de>
|
||||||
Build-Depends: cdbs, debhelper (>= 5)
|
Build-Depends: cdbs, debhelper (>= 5), libpam-dev
|
||||||
Standards-Version: 3.8.0
|
Standards-Version: 3.8.0
|
||||||
Homepage: http://cyanite.org/projects/execwrap/
|
Homepage: http://cyanite.org/projects/execwrap/
|
||||||
Vcs-Git: git://cyanite.org/execwrap
|
Vcs-Git: git://cyanite.org/execwrap
|
||||||
|
92
execwrap.c
92
execwrap.c
@ -1,4 +1,4 @@
|
|||||||
/*
|
// /*
|
||||||
|
|
||||||
Superuser-exec wrapper for HTTP serves and other needs (made especially for lighttpd).
|
Superuser-exec wrapper for HTTP serves and other needs (made especially for lighttpd).
|
||||||
Allows programs to be run with configurable uid/gid.
|
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_BAD_OPTION 24
|
||||||
#define RC_CHILD_ABNORMAL_EXIT 25
|
#define RC_CHILD_ABNORMAL_EXIT 25
|
||||||
#define RC_MISSING_PWENT 26
|
#define RC_MISSING_PWENT 26
|
||||||
|
#define RC_PAM_FAILED 27
|
||||||
|
|
||||||
/* User configuration. */
|
/* User configuration. */
|
||||||
#include "execwrap_config.h"
|
#include "execwrap_config.h"
|
||||||
@ -127,6 +127,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <security/pam_appl.h>
|
||||||
|
#include <security/pam_misc.h>
|
||||||
|
|
||||||
#if USE_SYSLOG
|
#if USE_SYSLOG
|
||||||
|
|
||||||
# include <syslog.h>
|
# include <syslog.h>
|
||||||
@ -147,6 +151,83 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#endif /* USE_SYSLOG */
|
#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. */
|
/* The global child PID and previous SIGTERM handler. */
|
||||||
int pid;
|
int pid;
|
||||||
void (*oldHandler)(int);
|
void (*oldHandler)(int);
|
||||||
@ -296,6 +377,10 @@ int main(int argc, char* argv[], char* envp[])
|
|||||||
if(oldHandler == SIG_ERR) return RC_SIGNAL_HANDLER;
|
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). */
|
/* Fork off (or, if we are a non-resident wrapper, just carry on). */
|
||||||
if(non_resident || !(pid = fork()))
|
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. */
|
/* Here we're in the parent. Wait for the child to be done, and return. */
|
||||||
int status;
|
int status;
|
||||||
wait(&status);
|
wait(&status);
|
||||||
|
|
||||||
|
close_pam_session();
|
||||||
|
|
||||||
if(WIFEXITED(status)) return WEXITSTATUS(status);
|
if(WIFEXITED(status)) return WEXITSTATUS(status);
|
||||||
return RC_CHILD_ABNORMAL_EXIT;
|
return RC_CHILD_ABNORMAL_EXIT;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user