File:  [ELWIX - Embedded LightWeight unIX -] / embedtools / src / wdog.c
Revision 1.1.2.3: download - view: text, annotated - select for diffs - revision graph
Mon Oct 18 08:47:31 2010 UTC (13 years, 7 months ago) by misho
Branches: tools1_0
added set uid

/*************************************************************************
 * (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>