/*************************************************************************
* (C) 2010 AITNET - Sofia/Bulgaria - <office@aitbg.com>
* by Michael Pounov <misho@aitbg.com>
*
* $Author: misho $
* $Id: wdog.c,v 1.1.2.3 2010/10/18 08:47:31 misho Exp $
*
*************************************************************************/
#include "global.h"
int Verbose, Kill;
extern char compiled[], compiledby[], compilehost[];
static void
Usage()
{
printf( "WatchDog tool for risk process managment\n"
"=== %s === %s@%s ===\n\n"
" Syntax: wdog [options] [exec_file]\n\n"
"\t-v\t\tVerbose ...\n"
"\t-c <dir>\tBefore execute chroot to dir [default=/]\n"
"\t-u <user>\tBefore execute change user\n"
"\n", compiled, compiledby, compilehost);
}
static void
sigHand(int sig)
{
int stat;
switch (sig) {
case SIGTERM:
Kill++;
break;
case SIGCHLD:
while (waitpid(-1, &stat, WNOHANG) > 0);
break;
}
}
int
main(int argc, char **argv)
{
char ch, szRun[MAXPATHLEN], szChroot[MAXPATHLEN] = "/";
int status = 0, ret = 1;
struct sigaction sa;
struct passwd *pass = NULL;
uid_t uid = getuid();
while ((ch = getopt(argc, argv, "vhc:u:")) != -1)
switch (ch) {
case 'v':
Verbose++;
break;
case 'c':
if (uid) {
printf("Error:: can`t chroot, please run as root!\n");
goto end;
}
if (access(optarg, R_OK)) {
printf("Error:: can`t chroot to %s #%d - %s\n", optarg,
errno, strerror(errno));
goto end;
} else
strlcpy(szChroot, optarg, MAXPATHLEN);
status |= 1;
break;
case 'u':
if (uid) {
printf("Error:: can`t setuid, please run as root!\n");
goto end;
}
pass = getpwnam(optarg);
if (!pass) {
printf("Error:: can`t find user %s\n", optarg);
goto end;
} else
uid = pass->pw_uid;
endpwent();
status |= 2;
break;
case 'h':
default:
Usage();
goto end;
}
argc -= optind;
argv += optind;
if (!argc || !argv || !*argv) {
Usage();
goto end;
} else
strlcpy(szRun, *argv, MAXPATHLEN);
VERB(2) printf("Info:: Chroot=%s Run=%s\n", szChroot, szRun);
memset(&sa, 0, sizeof sa);
sa.sa_handler = sigHand;
sigemptyset(&sa.sa_mask);
sigaction(SIGTERM, &sa, NULL);
sigaction(SIGCHLD, &sa, NULL);
sa.sa_handler = SIG_IGN;
sigaction(SIGHUP, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
sigaction(SIGQUIT, &sa, NULL);
sigaction(SIGPIPE, &sa, NULL);
sigaction(SIGTSTP, &sa, NULL);
sigaction(SIGSTOP, &sa, NULL);
VERB(5) printf("Info:: Catched signals ...\n");
if (status & 1 && (ret = chroot(szChroot)) == -1) {
printf("Error:: error in chroot to %s #%d - %s\n", szChroot, errno, strerror(errno));
ret = 3;
goto end;
} else
VERB(1) printf("Info:: chrooted to %s\n", szChroot);
if (status & 2 && setuid(uid) == -1) {
printf("Error:: error in setuid to %u #%d - %s\n", uid, errno, strerror(errno));
ret = 4;
goto end;
} else
VERB(1) printf("Info:: setuid to %u\n", uid);
// while (!Kill)
switch ((ret = fork())) {
case -1:
printf("Error:: error in fork #%d - %s\n", errno, strerror(errno));
ret = 5;
goto end;
case 0:
break;
default:
waitpid(ret, &status, 0);
}
ret = 0;
end:
return ret;
}
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>