Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/planix-v0/sys/src/cmd/auth/warning.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <bio.h>
4
#include <auth.h>
5
#include "authcmdlib.h"
6
 
7
/* working directory */
8
Dir	*dirbuf;
9
long	ndirbuf = 0;
10
 
11
int debug;
12
 
13
long	readdirect(int);
14
void	douser(Fs*, char*);
15
void	dodir(Fs*);
16
int	mail(Fs*, char*, char*, long);
17
int	mailin(Fs*, char*, long, char*, char*);
18
void	complain(char*, ...);
19
long	readnumfile(char*);
20
void	writenumfile(char*, long);
21
 
22
void
23
usage(void)
24
{
25
	fprint(2, "usage: %s [-n] [-p]\n", argv0);
26
	exits("usage");
27
}
28
 
29
void
30
main(int argc, char **argv)
31
{
32
	int which;
33
 
34
	which = 0;
35
	ARGBEGIN{
36
	case 'p':
37
		which |= Plan9;
38
		break;
39
	case 'n':
40
		which |= Securenet;
41
		break;
42
	case 'd':
43
		debug++;
44
		break;
45
	default:
46
		usage();
47
	}ARGEND
48
	argv0 = "warning";
49
 
50
	if(!which)
51
		which |= Plan9 | Securenet;
52
	if(which & Plan9)
53
		dodir(&fs[Plan9]);
54
	if(which & Securenet)
55
		dodir(&fs[Securenet]);
56
}
57
 
58
void
59
dodir(Fs *f)
60
{
61
	int nfiles;
62
	int i, fd;
63
 
64
	if(chdir(f->keys) < 0){
65
		complain("can't chdir to %s: %r", f->keys);
66
		return;
67
	}
68
 	fd = open(".", OREAD);
69
	if(fd < 0){
70
		complain("can't open %s: %r\n", f->keys);
71
		return;
72
	}
73
	nfiles = dirreadall(fd, &dirbuf);
74
	close(fd);
75
	for(i = 0; i < nfiles; i++)
76
		douser(f, dirbuf[i].name);
77
}
78
 
79
/*
80
 *  check for expiration
81
 */
82
void
83
douser(Fs *f, char *user)
84
{
85
	int n, nwarn;
86
	char buf[128];
87
	long rcvrs, et, now;
88
	char *l;
89
 
90
	snprint(buf, sizeof buf, "%s/expire", user);
91
	et = readnumfile(buf);
92
	now = time(0);
93
 
94
	/* start warning 2 weeks ahead of time */
95
	if(et <= now || et > now+14*24*60*60)
96
		return;
97
 
98
	snprint(buf, sizeof buf, "%s/warnings", user);
99
	nwarn = readnumfile(buf);
100
	if(et <= now+14*24*60*60 && et > now+7*24*60*60){
101
		/* one warning 2 weeks before expiration */
102
		if(nwarn > 0)
103
			return;
104
		nwarn = 1;
105
	} else {
106
		/* one warning 1 week before expiration */
107
		if(nwarn > 1)
108
			return;
109
		nwarn = 2;
110
	}
111
 
112
	/*
113
	 *  if we can't open the who file, just mail to the user and hope
114
 	 *  for it makes it.
115
	 */
116
	if(f->b){
117
		if(Bseek(f->b, 0, 0) < 0){
118
			Bterm(f->b);
119
			f->b = 0;
120
		}
121
	}
122
	if(f->b == 0){
123
		f->b = Bopen(f->who, OREAD);
124
		if(f->b == 0){
125
			if(mail(f, user, user, et) > 0)
126
				writenumfile(buf, nwarn);
127
			return;
128
		}
129
	}
130
 
131
	/*
132
	 *  look for matches in the who file and mail to every address on
133
	 *  matching lines
134
	 */
135
	rcvrs = 0;
136
	while(l = Brdline(f->b, '\n')){
137
		n = strlen(user);
138
		if(strncmp(l, user, n) == 0 && (l[n] == ' ' || l[n] == '\t'))
139
			rcvrs += mailin(f, user, et, l, l+Blinelen(f->b));
140
	}
141
 
142
	/*
143
	 *  if no matches, try the user directly
144
	 */
145
	if(rcvrs == 0)
146
		rcvrs = mail(f, user, user, et);
147
	rcvrs += mail(f, "netkeys", user, et);
148
	if(rcvrs)
149
		writenumfile(buf, nwarn);
150
}
151
 
152
/*
153
 *  anything in <>'s is an address
154
 */
155
int
156
mailin(Fs *f, char *user, long et, char *l, char *e)
157
{
158
	int n;
159
	int rcvrs;
160
	char *p;
161
	char addr[256];
162
 
163
	p = 0;
164
	rcvrs = 0;
165
	while(l < e){
166
		switch(*l){
167
		case '<':
168
			p = l + 1;
169
			break;
170
		case '>':
171
			if(p == 0)
172
				break;
173
			n = l - p;
174
			if(n > 0 && n <= sizeof(addr) - 2){
175
				memmove(addr, p, n);
176
				addr[n] = 0;
177
				rcvrs += mail(f, addr, user, et);
178
			}
179
			p = 0;
180
			break;
181
		}
182
		l++;
183
	}
184
	return rcvrs;
185
}
186
 
187
/*
188
 *  send mail
189
 */
190
int
191
mail(Fs *f, char *rcvr, char *user, long et)
192
{
193
	int pid, i, fd;
194
	int pfd[2];
195
	char *ct, *p;
196
	Waitmsg *w;
197
	char buf[128];
198
 
199
	if(pipe(pfd) < 0){
200
		complain("out of pipes: %r");
201
		return 0;
202
	}
203
 
204
	switch(pid = fork()){
205
	case -1:
206
		complain("can't fork: %r");
207
		return 0;
208
	case 0:
209
		break;
210
	default:
211
		if(debug)
212
			fprint(2, "started %d\n", pid);
213
		close(pfd[0]);
214
		ct = ctime(et);
215
		p = strchr(ct, '\n');
216
		*p = '.';
217
		fprint(pfd[1], "User '%s's %s expires on %s\n", user, f->msg, ct);
218
		if(f != fs)
219
			fprint(pfd[1], "If you wish to renew contact your local administrator.\n");
220
		p = strrchr(f->keys, '/');
221
		if(p)
222
			p++;
223
		else
224
			p = f->keys;
225
		snprint(buf, sizeof buf, "/adm/warn.%s", p);
226
		fd = open(buf, OREAD);
227
		if(fd >= 0){
228
			while((i = read(fd, buf, sizeof(buf))) > 0)
229
				write(pfd[1], buf, i);
230
			close(fd);
231
		}
232
		close(pfd[1]);
233
 
234
		/* wait for warning to be mailed */
235
		for(;;){
236
			w = wait();
237
			if(w == nil)
238
				break;
239
			if(w->pid == pid){
240
				if(debug)
241
					fprint(2, "%d terminated: %s\n", pid, w->msg);
242
				if(w->msg[0] == 0){
243
					free(w);
244
					break;
245
				}else{
246
					free(w);
247
					return 0;
248
				}
249
			}else
250
				free(w);
251
		}
252
		return 1;
253
	}
254
 
255
	/* get out of the current namespace */
256
	newns("none", 0);
257
 
258
	dup(pfd[0], 0);
259
	close(pfd[0]);
260
	close(pfd[1]);
261
	putenv("upasname", "netkeys");
262
	if(debug){
263
		print("\nto %s\n", rcvr);
264
		execl("/bin/cat", "cat", nil);
265
	}
266
	execl("/bin/upas/send", "send", "-r", rcvr, nil);
267
 
268
	/* just in case */
269
	sysfatal("can't exec send: %r");
270
 
271
	return 0;		/* for compiler */
272
}
273
 
274
void
275
complain(char *fmt, ...)
276
{
277
	char buf[8192], *s;
278
	va_list arg;
279
 
280
	s = buf;
281
	s += snprint(s, sizeof buf, "%s: ", argv0);
282
	va_start(arg, fmt);
283
	s = vseprint(s, buf + sizeof(buf) / sizeof(*buf), fmt, arg);
284
	va_end(arg);
285
	*s++ = '\n';
286
	write(2, buf, s - buf);
287
}
288
 
289
long
290
readnumfile(char *file)
291
{
292
	int fd, n;
293
	char buf[64];
294
 
295
	fd = open(file, OREAD);
296
	if(fd < 0){
297
		complain("can't open %s: %r", file);
298
		return 0;
299
	}
300
	n = read(fd, buf, sizeof(buf)-1);
301
	close(fd);
302
	if(n < 0){
303
		complain("can't read %s: %r", file);
304
		return 0;
305
	}
306
	buf[n] = 0;
307
	return atol(buf);
308
}
309
 
310
void
311
writenumfile(char *file, long num)
312
{
313
	int fd;
314
 
315
	fd = open(file, OWRITE);
316
	if(fd < 0){
317
		complain("can't open %s: %r", file);
318
		return;
319
	}
320
	fprint(fd, "%ld", num);
321
	close(fd);
322
}