Annotation of embedtools/src/wdog.c, revision 1.2

1.2     ! misho       1: /*************************************************************************
        !             2:  * (C) 2010 AITNET - Sofia/Bulgaria - <office@aitbg.com>
        !             3:  *  by Michael Pounov <misho@aitbg.com>
        !             4:  *
        !             5:  * $Author: misho $
        !             6:  * $Id: wdog.c,v 1.1.2.8 2010/10/18 15:06:10 misho Exp $
        !             7:  *
        !             8:  *************************************************************************/
        !             9: #include "global.h"
        !            10: 
        !            11: 
        !            12: int Verbose, Kill, Log;
        !            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"
        !            24:                "\t-c <dir>\tBefore execute chroot to dir [default=/]\n"
        !            25:                "\t-u <user>\tBefore execute change user\n"
        !            26:                "\t-P\t\tInfinit loop, bypass penalty timeout\n"
        !            27:                "\t-S\t\tDisable send log events to syslog\n"
        !            28:                "\n", compiled, compiledby, compilehost);
        !            29: }
        !            30: 
        !            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: 
        !            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: 
        !            59: 
        !            60: int
        !            61: main(int argc, char **argv)
        !            62: {
        !            63:        char ch, bypass = 0, szChroot[MAXPATHLEN] = DEFAULT_CHROOT;
        !            64:        int status = 0, ret = 1;
        !            65:        struct sigaction sa;
        !            66:        struct passwd *pass = NULL;
        !            67:        u_int penalty = 1;
        !            68:        uid_t uid = getuid();
        !            69: 
        !            70:        while ((ch = getopt(argc, argv, "vhSPc:u:")) != -1)
        !            71:                switch (ch) {
        !            72:                        case 'v':
        !            73:                                Verbose++;
        !            74:                                break;
        !            75:                        case 'P':
        !            76:                                bypass = 1;
        !            77:                                break;
        !            78:                        case 'S':
        !            79:                                Log = 1;
        !            80:                                break;
        !            81:                        case 'c':
        !            82:                                if (uid) {
        !            83:                                        printf("Error:: can`t chroot, please run as root!\n");
        !            84:                                        goto end;
        !            85:                                }
        !            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);
        !            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;
        !           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;
        !           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);
        !           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);
        !           137:        VERB(5) logmsg(LOG_NOTICE, "Info:: Catched signals ...\n");
        !           138: 
        !           139:        if (status & 1 && (ret = chroot(szChroot)) == -1) {
        !           140:                printf("Error:: error in chroot to %s #%d - %s\n", szChroot, errno, strerror(errno));
        !           141:                ret = 3;
        !           142:                goto end;
        !           143:        } else
        !           144:                VERB(1) logmsg(LOG_NOTICE, "Info:: chrooted to %s\n", szChroot);
        !           145: 
        !           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
        !           151:                VERB(1) logmsg(LOG_NOTICE, "Info:: setuid to %u\n", uid);
        !           152: 
        !           153:        status ^= status;
        !           154:        while (!Kill && penalty) {
        !           155:                switch ((ret = fork())) {
        !           156:                        case -1:
        !           157:                                logmsg(LOG_ERR, "Error:: error in fork #%d - %s\n", errno, strerror(errno));
        !           158:                                ret = 5;
        !           159:                                goto end;
        !           160:                        case 0:
        !           161:                                VERB(3) logmsg(LOG_NOTICE, "Info:: I`m child of shadows ...\n");
        !           162:                                if (execvp(*argv, argv) == -1) {
        !           163:                                        logmsg(LOG_ERR, "Error:: error in exec %s #%d - %s\n", 
        !           164:                                                        *argv, errno, strerror(errno));
        !           165:                                        ret = 6;
        !           166:                                        goto end;
        !           167:                                }
        !           168:                                /* never reached !!! */
        !           169:                                break;
        !           170:                        default:
        !           171:                                wait(&status);
        !           172:                                kill(ret, SIGTERM);
        !           173:                                ret = status;
        !           174:                }
        !           175:                /* penalty timeout retry */
        !           176:                usleep(penalty);
        !           177:                if (!bypass) {
        !           178:                        penalty <<= 1;
        !           179:                        VERB(2) logmsg(LOG_NOTICE, "Info:: penalty timeout %u microseconds\n", penalty);
        !           180:                }
        !           181:        }
        !           182:        if (!penalty)
        !           183:                ret = 9;
        !           184: end:
        !           185:        if (!Log)
        !           186:                closelog();
        !           187:        return ret;
        !           188: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>