|
|
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.