|
|
1.1 ! root 1: static char Copyright[] = "$Copyright: (c) 1985, INETCO Systems, Ltd.$"; ! 2: static char Release[] = "$Release: INETCO COHERENT V8.0$"; ! 3: static char Date[] = "$Date: 91/04/19 12:26:17 $"; ! 4: ! 5: /* $Header: /newbits/usr/lib/RCS/atrun.c,v 1.1 91/04/19 12:26:17 bin Exp $ ! 6: * ! 7: * The information contained herein is a trade secret of Mark Williams ! 8: * Company, and is confidential information. It is provided under a ! 9: * license agreement, and may be copied or disclosed only under the ! 10: * terms of that agreement. Any reproduction or disclosure of this ! 11: * material without the express written authorization of Mark Williams ! 12: * Company or persuant to the license agreement is unlawful. ! 13: * ! 14: * Coherent Version 2.3.38 ! 15: * Copyright (c) 1982, 1983, 1984. ! 16: * An unpublished work by Mark Williams Company, Chicago. ! 17: * All rights reserved. ! 18: */ ! 19: ! 20: /* ! 21: * Atrun is the daemon which is regularly invoked by cron inorder ! 22: * to run scripts saved by at. It runs the files by changeing its ! 23: * uid and gid to the owner and then running a shell on them. ! 24: * In order to have the ability to set its uid and group id, it ! 25: * must be set uid to root. ! 26: * Since anyone can write into the at spooling directory, for a ! 27: * script to be run, it must have the set uid, set gid and owner ! 28: * execute bits set. ! 29: * ! 30: * $Log: /newbits/usr/lib/RCS/atrun.c,v $ ! 31: * Revision 1.1 91/04/19 12:26:17 bin ! 32: * Initial revision ! 33: * ! 34: * Revision 1.1 89/04/03 13:02:41 src ! 35: * Initial revision ! 36: * ! 37: * 85/02/11 Allan Cornish eliminated stdio functions. ! 38: */ ! 39: ! 40: #include <stdio.h> ! 41: #include <sys/types.h> ! 42: #include <ctype.h> ! 43: #include <sys/dir.h> ! 44: #include <time.h> ! 45: #include <setjmp.h> ! 46: #include <sys/stat.h> ! 47: ! 48: ! 49: #define MODE 06100 /* set uid, set gid, owner exec */ ! 50: #define TRUE (0 == 0) ! 51: #define FALSE (0 != 0) ! 52: #define STDIN 0 /* standard input file descriptor */ ! 53: #define STDOUT 1 /* standard output file descriptor */ ! 54: #define STDERR 2 /* standard error file descriptor */ ! 55: #define RW 2 /* open code for read and write */ ! 56: ! 57: ! 58: struct tm *now; /* current time */ ! 59: char atdir[] = "/usr/spool/at"; ! 60: jmp_buf cerror; /* where to go if file is strange */ ! 61: int atfd; /* stream for file atdir */ ! 62: ! 63: ! 64: main() ! 65: { ! 66: register struct direct *dp; ! 67: register int n; ! 68: time_t ct; ! 69: time_t time(); ! 70: static char dbuf[BUFSIZ]; ! 71: ! 72: if (chdir(atdir) < 0) ! 73: exit(1); ! 74: ! 75: time(&ct); ! 76: now = localtime(&ct); ! 77: if ((atfd = open(".", 0)) < 0) ! 78: exit(1); ! 79: ! 80: while ((n = read( atfd, dbuf, sizeof dbuf)) > 0) { ! 81: ! 82: dp = (struct direct *) &dbuf[n]; ! 83: ! 84: while (--dp >= dbuf) ! 85: if (dp->d_ino) ! 86: check(dp); ! 87: } ! 88: return (0); ! 89: } ! 90: ! 91: ! 92: /* ! 93: * Check checks to see if the file with directory entry `dent' ! 94: * should be executed. ! 95: */ ! 96: check(dent) ! 97: register struct direct *dent; ! 98: { ! 99: struct tm dot; ! 100: ! 101: if (dent->d_ino == 0 || setjmp(cerror)) ! 102: return; ! 103: gettime(&dot, dent->d_name); ! 104: if (cmptime(&dot, now) <= 0) ! 105: docmd(dent->d_name); ! 106: } ! 107: ! 108: ! 109: /* ! 110: * Gettime fills in certain fields in the struct tm `time' according to ! 111: * the file name `name'. The file name is assumed to be of the form ! 112: * yymmddhhmm.xx where ! 113: * yy is the last two digits of the year ! 114: * mm is the month number (1 - 12) ! 115: * dd is the day of the month (1 - 31) ! 116: * hh is the hour ! 117: * mm is the minute ! 118: * Only the corresponding fields of `time' are filled in. ! 119: */ ! 120: gettime(time, name) ! 121: register struct tm *time; ! 122: register char *name; ! 123: { ! 124: time->tm_year = cnum2(name); ! 125: name += 2; ! 126: ! 127: /* ! 128: * This kludge will fail in 2070. ! 129: */ ! 130: if (time->tm_year < 70) ! 131: time->tm_year += 100; ! 132: ! 133: time->tm_mon = cnum2(name) - 1; ! 134: name += 2; ! 135: time->tm_mday = cnum2(name); ! 136: name += 2; ! 137: time->tm_hour = cnum2(name); ! 138: name += 2; ! 139: time->tm_min = cnum2(name); ! 140: if (name[2] != '.') ! 141: longjmp(cerror, TRUE); ! 142: } ! 143: ! 144: ! 145: /* ! 146: * Cnum2 converts the first two characters of the string `str' ! 147: * to a number. ! 148: */ ! 149: cnum2(str) ! 150: register char *str; ! 151: { ! 152: register int res, ! 153: i; ! 154: ! 155: for (res=0, i=2; --i >= 0; ++str) { ! 156: if (!isascii(*str) || !isdigit(*str)) ! 157: longjmp(cerror, TRUE); ! 158: res *= 10; ! 159: res += *str - '0'; ! 160: } ! 161: return (res); ! 162: } ! 163: ! 164: ! 165: /* ! 166: * Cmptime compares the two struct tm's `a' and `b'. It returns ! 167: * a number which compares to zero in the same way that `a' compares ! 168: * to `b'. ! 169: */ ! 170: cmptime(a, b) ! 171: register struct tm *a, ! 172: *b; ! 173: { ! 174: register int res; ! 175: ! 176: if ((res = a->tm_year - b->tm_year) != 0) ! 177: return (res); ! 178: if ((res = a->tm_mon - b->tm_mon) != 0) ! 179: return (res); ! 180: if ((res = a->tm_mday - b->tm_mday) != 0) ! 181: return (res); ! 182: if ((res = a->tm_hour - b->tm_hour) != 0) ! 183: return (res); ! 184: return (a->tm_min - b->tm_min); ! 185: } ! 186: ! 187: ! 188: /* ! 189: * Docmd executes the shell command file `file'. This entails ! 190: * forking of a child which changes its user and group id and ! 191: * then calls the shell. ! 192: */ ! 193: docmd(file) ! 194: char *file; ! 195: { ! 196: register int fd; ! 197: char cbuf[DIRSIZ + 2]; ! 198: struct stat sbuf; ! 199: ! 200: if (fork() != 0) ! 201: return; ! 202: close(atfd); ! 203: strncpy(cbuf, file, DIRSIZ+1); ! 204: if (stat(cbuf, &sbuf) != 0) ! 205: exit(1); ! 206: if ((MODE & ~sbuf.st_mode) != 0) ! 207: exit(1); ! 208: if (setgid(sbuf.st_gid) != 0) ! 209: exit(1); ! 210: if (setuid(sbuf.st_uid) != 0) ! 211: exit(1); ! 212: if ((fd = open("/dev/null", RW)) == EOF) ! 213: exit(1); ! 214: dup2(fd, STDIN); ! 215: dup2(fd, STDOUT); ! 216: dup2(fd, STDERR); ! 217: close(fd); ! 218: strcat(cbuf, "&"); ! 219: execle("/bin/sh", "sh", "-c", cbuf, NULL, NULL); ! 220: exit(1); ! 221: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.