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

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.6 ! misho       6:  * $Id: wdog.c,v 1.1.2.5 2010/10/18 11:13:50 misho Exp $
1.1.2.1   misho       7:  *
                      8:  *************************************************************************/
                      9: #include "global.h"
                     10: 
                     11: 
1.1.2.2   misho      12: int Verbose, Kill;
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.1   misho      27:                "\n", compiled, compiledby, compilehost);
                     28: }
                     29: 
1.1.2.2   misho      30: static void
                     31: sigHand(int sig)
                     32: {
                     33:        int stat;
                     34: 
                     35:        switch (sig) {
                     36:                case SIGTERM:
                     37:                        Kill++;
                     38:                        break;
                     39:                case SIGCHLD:
                     40:                        while (waitpid(-1, &stat, WNOHANG) > 0);
                     41:                        break;
                     42:        }
                     43: }
                     44: 
1.1.2.1   misho      45: 
                     46: int
                     47: main(int argc, char **argv)
                     48: {
1.1.2.6 ! misho      49:        char ch, bypass = 0, szChroot[MAXPATHLEN] = "/";
1.1.2.3   misho      50:        int status = 0, ret = 1;
1.1.2.2   misho      51:        struct sigaction sa;
1.1.2.3   misho      52:        struct passwd *pass = NULL;
                     53:        uid_t uid = getuid();
1.1.2.5   misho      54:        u_int penalty = 1;
1.1.2.2   misho      55: 
1.1.2.6 ! misho      56:        while ((ch = getopt(argc, argv, "vhPc:u:")) != -1)
1.1.2.2   misho      57:                switch (ch) {
                     58:                        case 'v':
                     59:                                Verbose++;
                     60:                                break;
1.1.2.6 ! misho      61:                        case 'P':
        !            62:                                bypass = 1;
        !            63:                                break;
1.1.2.2   misho      64:                        case 'c':
1.1.2.3   misho      65:                                if (uid) {
                     66:                                        printf("Error:: can`t chroot, please run as root!\n");
                     67:                                        goto end;
                     68:                                }
1.1.2.2   misho      69:                                if (access(optarg, R_OK)) {
                     70:                                        printf("Error:: can`t chroot to %s #%d - %s\n", optarg, 
                     71:                                                        errno, strerror(errno));
                     72:                                        goto end;
                     73:                                } else
                     74:                                        strlcpy(szChroot, optarg, MAXPATHLEN);
1.1.2.3   misho      75:                                status |= 1;
                     76:                                break;
                     77:                        case 'u':
                     78:                                if (uid) {
                     79:                                        printf("Error:: can`t setuid, please run as root!\n");
                     80:                                        goto end;
                     81:                                }
                     82:                                pass = getpwnam(optarg);
                     83:                                if (!pass) {
                     84:                                        printf("Error:: can`t find user %s\n", optarg);
                     85:                                        goto end;
                     86:                                } else
                     87:                                        uid = pass->pw_uid;
                     88:                                endpwent();
                     89:                                status |= 2;
1.1.2.2   misho      90:                                break;
                     91:                        case 'h':
                     92:                        default:
                     93:                                Usage();
                     94:                                goto end;
                     95:                }
                     96:        argc -= optind;
                     97:        argv += optind;
                     98:        if (!argc || !argv || !*argv) {
                     99:                Usage();
                    100:                goto end;
                    101:        } else
1.1.2.4   misho     102:                VERB(2) printf("Info:: Chroot=%s Run=%s\n", szChroot, *argv);
1.1.2.2   misho     103: 
                    104:        memset(&sa, 0, sizeof sa);
                    105:        sa.sa_handler = sigHand;
                    106:        sigemptyset(&sa.sa_mask);
                    107:        sigaction(SIGTERM, &sa, NULL);
                    108:        sigaction(SIGCHLD, &sa, NULL);
                    109:        sa.sa_handler = SIG_IGN;
                    110:        sigaction(SIGHUP, &sa, NULL);
                    111:        sigaction(SIGINT, &sa, NULL);
                    112:        sigaction(SIGQUIT, &sa, NULL);
                    113:        sigaction(SIGPIPE, &sa, NULL);
                    114:        sigaction(SIGTSTP, &sa, NULL);
                    115:        sigaction(SIGSTOP, &sa, NULL);
                    116:        VERB(5) printf("Info:: Catched signals ...\n");
                    117: 
1.1.2.3   misho     118:        if (status & 1 && (ret = chroot(szChroot)) == -1) {
1.1.2.2   misho     119:                printf("Error:: error in chroot to %s #%d - %s\n", szChroot, errno, strerror(errno));
                    120:                ret = 3;
                    121:                goto end;
                    122:        } else
                    123:                VERB(1) printf("Info:: chrooted to %s\n", szChroot);
                    124: 
1.1.2.3   misho     125:        if (status & 2 && setuid(uid) == -1) {
                    126:                printf("Error:: error in setuid to %u #%d - %s\n", uid, errno, strerror(errno));
                    127:                ret = 4;
                    128:                goto end;
                    129:        } else
                    130:                VERB(1) printf("Info:: setuid to %u\n", uid);
                    131: 
1.1.2.4   misho     132:        status ^= status;
1.1.2.5   misho     133:        while (!Kill && penalty) {
1.1.2.2   misho     134:                switch ((ret = fork())) {
                    135:                        case -1:
                    136:                                printf("Error:: error in fork #%d - %s\n", errno, strerror(errno));
1.1.2.3   misho     137:                                ret = 5;
1.1.2.2   misho     138:                                goto end;
                    139:                        case 0:
1.1.2.4   misho     140:                                VERB(3) printf("Info:: I`m child of shadows ...\n");
                    141:                                if (execvp(*argv, argv) == -1) {
                    142:                                        printf("Error:: error in exec %s #%d - %s\n", 
                    143:                                                        *argv, errno, strerror(errno));
                    144:                                        ret = 6;
                    145:                                        goto end;
                    146:                                }
1.1.2.5   misho     147:                                /* never reached !!! */
1.1.2.2   misho     148:                                break;
                    149:                        default:
1.1.2.4   misho     150:                                wait(&status);
                    151:                                kill(ret, SIGTERM);
                    152:                                ret = status;
1.1.2.2   misho     153:                }
1.1.2.5   misho     154:                /* penalty timeout retry */
                    155:                usleep(penalty);
1.1.2.6 ! misho     156:                if (!bypass) {
        !           157:                        penalty <<= 1;
        !           158:                        VERB(2) printf("Info:: penalty timeout %u microseconds\n", penalty);
        !           159:                }
1.1.2.5   misho     160:        }
                    161:        if (!penalty)
                    162:                ret = 9;
1.1.2.2   misho     163: end:
                    164:        return ret;
1.1.2.1   misho     165: }

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