Annotation of embedtools/src/wdog.c, revision 1.1.2.8
1.1.2.1 misho 1: /*************************************************************************
2: * (C) 2010 AITNET - Sofia/Bulgaria - <office@aitbg.com>
3: * by Michael Pounov <misho@aitbg.com>
4: *
5: * $Author: misho $
1.1.2.8 ! misho 6: * $Id: wdog.c,v 1.1.2.7 2010/10/18 12:18:21 misho Exp $
1.1.2.1 misho 7: *
8: *************************************************************************/
9: #include "global.h"
10:
11:
1.1.2.8 ! misho 12: int Verbose, Kill, Log;
1.1.2.1 misho 13: extern char compiled[], compiledby[], compilehost[];
14:
15:
16: static void
17: Usage()
18: {
19:
20: printf( "WatchDog tool for risk process managment\n"
21: "=== %s === %s@%s ===\n\n"
22: " Syntax: wdog [options] [exec_file]\n\n"
23: "\t-v\t\tVerbose ...\n"
1.1.2.2 misho 24: "\t-c <dir>\tBefore execute chroot to dir [default=/]\n"
1.1.2.3 misho 25: "\t-u <user>\tBefore execute change user\n"
1.1.2.6 misho 26: "\t-P\t\tInfinit loop, bypass penalty timeout\n"
1.1.2.8 ! misho 27: "\t-S\t\tDisable send log events to syslog\n"
1.1.2.1 misho 28: "\n", compiled, compiledby, compilehost);
29: }
30:
1.1.2.2 misho 31: static void
32: sigHand(int sig)
33: {
34: int stat;
35:
36: switch (sig) {
37: case SIGTERM:
38: Kill++;
39: break;
40: case SIGCHLD:
41: while (waitpid(-1, &stat, WNOHANG) > 0);
42: break;
43: }
44: }
45:
1.1.2.8 ! misho 46: static void
! 47: logmsg(int prio, const char *fmt, ...)
! 48: {
! 49: va_list lst;
! 50:
! 51: va_start(lst, fmt);
! 52: if (!Log)
! 53: vsyslog(prio, fmt, lst);
! 54: else
! 55: vprintf(fmt, lst);
! 56: va_end(lst);
! 57: }
! 58:
1.1.2.1 misho 59:
60: int
61: main(int argc, char **argv)
62: {
1.1.2.7 misho 63: char ch, bypass = 0, szChroot[MAXPATHLEN] = DEFAULT_CHROOT;
1.1.2.3 misho 64: int status = 0, ret = 1;
1.1.2.2 misho 65: struct sigaction sa;
1.1.2.3 misho 66: struct passwd *pass = NULL;
1.1.2.5 misho 67: u_int penalty = 1;
1.1.2.7 misho 68: uid_t uid = getuid();
1.1.2.2 misho 69:
1.1.2.8 ! misho 70: while ((ch = getopt(argc, argv, "vhSPc:u:")) != -1)
1.1.2.2 misho 71: switch (ch) {
72: case 'v':
73: Verbose++;
74: break;
1.1.2.6 misho 75: case 'P':
76: bypass = 1;
77: break;
1.1.2.8 ! misho 78: case 'S':
! 79: Log = 1;
! 80: break;
1.1.2.2 misho 81: case 'c':
1.1.2.3 misho 82: if (uid) {
83: printf("Error:: can`t chroot, please run as root!\n");
84: goto end;
85: }
1.1.2.2 misho 86: if (access(optarg, R_OK)) {
87: printf("Error:: can`t chroot to %s #%d - %s\n", optarg,
88: errno, strerror(errno));
89: goto end;
90: } else
91: strlcpy(szChroot, optarg, MAXPATHLEN);
1.1.2.3 misho 92: status |= 1;
93: break;
94: case 'u':
95: if (uid) {
96: printf("Error:: can`t setuid, please run as root!\n");
97: goto end;
98: }
99: pass = getpwnam(optarg);
100: if (!pass) {
101: printf("Error:: can`t find user %s\n", optarg);
102: goto end;
103: } else
104: uid = pass->pw_uid;
105: endpwent();
106: status |= 2;
1.1.2.2 misho 107: break;
108: case 'h':
109: default:
110: Usage();
111: goto end;
112: }
113: argc -= optind;
114: argv += optind;
115: if (!argc || !argv || !*argv) {
116: Usage();
117: goto end;
1.1.2.8 ! misho 118: }
! 119:
! 120: if (!Log)
! 121: openlog("wdog", LOG_PID, LOG_USER);
! 122:
! 123: VERB(2) logmsg(LOG_NOTICE, "Info:: Chroot=%s Run=%s\n", szChroot, *argv);
1.1.2.2 misho 124:
125: memset(&sa, 0, sizeof sa);
126: sa.sa_handler = sigHand;
127: sigemptyset(&sa.sa_mask);
128: sigaction(SIGTERM, &sa, NULL);
129: sigaction(SIGCHLD, &sa, NULL);
130: sa.sa_handler = SIG_IGN;
131: sigaction(SIGHUP, &sa, NULL);
132: sigaction(SIGINT, &sa, NULL);
133: sigaction(SIGQUIT, &sa, NULL);
134: sigaction(SIGPIPE, &sa, NULL);
135: sigaction(SIGTSTP, &sa, NULL);
136: sigaction(SIGSTOP, &sa, NULL);
1.1.2.8 ! misho 137: VERB(5) logmsg(LOG_NOTICE, "Info:: Catched signals ...\n");
1.1.2.2 misho 138:
1.1.2.3 misho 139: if (status & 1 && (ret = chroot(szChroot)) == -1) {
1.1.2.2 misho 140: printf("Error:: error in chroot to %s #%d - %s\n", szChroot, errno, strerror(errno));
141: ret = 3;
142: goto end;
143: } else
1.1.2.8 ! misho 144: VERB(1) logmsg(LOG_NOTICE, "Info:: chrooted to %s\n", szChroot);
1.1.2.2 misho 145:
1.1.2.3 misho 146: if (status & 2 && setuid(uid) == -1) {
147: printf("Error:: error in setuid to %u #%d - %s\n", uid, errno, strerror(errno));
148: ret = 4;
149: goto end;
150: } else
1.1.2.8 ! misho 151: VERB(1) logmsg(LOG_NOTICE, "Info:: setuid to %u\n", uid);
1.1.2.3 misho 152:
1.1.2.4 misho 153: status ^= status;
1.1.2.5 misho 154: while (!Kill && penalty) {
1.1.2.2 misho 155: switch ((ret = fork())) {
156: case -1:
1.1.2.8 ! misho 157: logmsg(LOG_ERR, "Error:: error in fork #%d - %s\n", errno, strerror(errno));
1.1.2.3 misho 158: ret = 5;
1.1.2.2 misho 159: goto end;
160: case 0:
1.1.2.8 ! misho 161: VERB(3) logmsg(LOG_NOTICE, "Info:: I`m child of shadows ...\n");
1.1.2.4 misho 162: if (execvp(*argv, argv) == -1) {
1.1.2.8 ! misho 163: logmsg(LOG_ERR, "Error:: error in exec %s #%d - %s\n",
1.1.2.4 misho 164: *argv, errno, strerror(errno));
165: ret = 6;
166: goto end;
167: }
1.1.2.5 misho 168: /* never reached !!! */
1.1.2.2 misho 169: break;
170: default:
1.1.2.4 misho 171: wait(&status);
172: kill(ret, SIGTERM);
173: ret = status;
1.1.2.2 misho 174: }
1.1.2.5 misho 175: /* penalty timeout retry */
176: usleep(penalty);
1.1.2.6 misho 177: if (!bypass) {
178: penalty <<= 1;
1.1.2.8 ! misho 179: VERB(2) logmsg(LOG_NOTICE, "Info:: penalty timeout %u microseconds\n", penalty);
1.1.2.6 misho 180: }
1.1.2.5 misho 181: }
182: if (!penalty)
183: ret = 9;
1.1.2.2 misho 184: end:
1.1.2.8 ! misho 185: if (!Log)
! 186: closelog();
1.1.2.2 misho 187: return ret;
1.1.2.1 misho 188: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>