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>