123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #include <auth.h>
- #include "authcmdlib.h"
- /* working directory */
- Dir *dirbuf;
- long ndirbuf = 0;
- int debug;
- long readdirect(int);
- void douser(Fs*, char*);
- void dodir(Fs*);
- int mail(Fs*, char*, char*, long);
- int mailin(Fs*, char*, long, char*, char*);
- void complain(char*, ...);
- long readnumfile(char*);
- void writenumfile(char*, long);
- void
- usage(void)
- {
- fprint(2, "usage: %s [-n] [-p]\n", argv0);
- exits("usage");
- }
- void
- main(int argc, char **argv)
- {
- int which;
- which = 0;
- ARGBEGIN{
- case 'p':
- which |= Plan9;
- break;
- case 'n':
- which |= Securenet;
- break;
- case 'd':
- debug++;
- break;
- default:
- usage();
- }ARGEND
- argv0 = "warning";
- if(!which)
- which |= Plan9 | Securenet;
- if(which & Plan9)
- dodir(&fs[Plan9]);
- if(which & Securenet)
- dodir(&fs[Securenet]);
- }
- void
- dodir(Fs *f)
- {
- int nfiles;
- int i, fd;
- if(chdir(f->keys) < 0){
- complain("can't chdir to %s: %r", f->keys);
- return;
- }
- fd = open(".", OREAD);
- if(fd < 0){
- complain("can't open %s: %r\n", f->keys);
- return;
- }
- nfiles = dirreadall(fd, &dirbuf);
- close(fd);
- for(i = 0; i < nfiles; i++)
- douser(f, dirbuf[i].name);
- }
- /*
- * check for expiration
- */
- void
- douser(Fs *f, char *user)
- {
- int n, nwarn;
- char buf[128];
- long rcvrs, et, now;
- char *l;
- sprint(buf, "%s/expire", user);
- et = readnumfile(buf);
- now = time(0);
- /* start warning 2 weeks ahead of time */
- if(et <= now || et > now+14*24*60*60)
- return;
- sprint(buf, "%s/warnings", user);
- nwarn = readnumfile(buf);
- if(et <= now+14*24*60*60 && et > now+7*24*60*60){
- /* one warning 2 weeks before expiration */
- if(nwarn > 0)
- return;
- nwarn = 1;
- } else {
- /* one warning 1 week before expiration */
- if(nwarn > 1)
- return;
- nwarn = 2;
- }
- /*
- * if we can't open the who file, just mail to the user and hope
- * for it makes it.
- */
- if(f->b){
- if(Bseek(f->b, 0, 0) < 0){
- Bterm(f->b);
- f->b = 0;
- }
- }
- if(f->b == 0){
- f->b = Bopen(f->who, OREAD);
- if(f->b == 0){
- if(mail(f, user, user, et) > 0)
- writenumfile(buf, nwarn);
- return;
- }
- }
- /*
- * look for matches in the who file and mail to every address on
- * matching lines
- */
- rcvrs = 0;
- while(l = Brdline(f->b, '\n')){
- n = strlen(user);
- if(strncmp(l, user, n) == 0 && (l[n] == ' ' || l[n] == '\t'))
- rcvrs += mailin(f, user, et, l, l+Blinelen(f->b));
- }
- /*
- * if no matches, try the user directly
- */
- if(rcvrs == 0)
- rcvrs = mail(f, user, user, et);
- rcvrs += mail(f, "netkeys", user, et);
- if(rcvrs)
- writenumfile(buf, nwarn);
- }
- /*
- * anything in <>'s is an address
- */
- int
- mailin(Fs *f, char *user, long et, char *l, char *e)
- {
- int n;
- int rcvrs;
- char *p;
- char addr[256];
- p = 0;
- rcvrs = 0;
- while(l < e){
- switch(*l){
- case '<':
- p = l + 1;
- break;
- case '>':
- if(p == 0)
- break;
- n = l - p;
- if(n > 0 && n <= sizeof(addr) - 2){
- memmove(addr, p, n);
- addr[n] = 0;
- rcvrs += mail(f, addr, user, et);
- }
- p = 0;
- break;
- }
- l++;
- }
- return rcvrs;
- }
- /*
- * send mail
- */
- int
- mail(Fs *f, char *rcvr, char *user, long et)
- {
- int pid, i, fd;
- int pfd[2];
- char *ct, *p;
- Waitmsg *w;
- char buf[128];
- if(pipe(pfd) < 0){
- complain("out of pipes: %r");
- return 0;
- }
- switch(pid = fork()){
- case -1:
- complain("can't fork: %r");
- return 0;
- case 0:
- break;
- default:
- if(debug)
- fprint(2, "started %d\n", pid);
- close(pfd[0]);
- ct = ctime(et);
- p = strchr(ct, '\n');
- *p = '.';
- fprint(pfd[1], "User '%s's %s expires on %s\n", user, f->msg, ct);
- if(f != fs)
- fprint(pfd[1], "If you wish to renew contact your local administrator.\n");
- p = strrchr(f->keys, '/');
- if(p)
- p++;
- else
- p = f->keys;
- sprint(buf, "/adm/warn.%s", p);
- fd = open(buf, OREAD);
- if(fd >= 0){
- while((i = read(fd, buf, sizeof(buf))) > 0)
- write(pfd[1], buf, i);
- close(fd);
- }
- close(pfd[1]);
- /* wait for warning to be mailed */
- for(;;){
- w = wait();
- if(w == nil)
- break;
- if(w->pid == pid){
- if(debug)
- fprint(2, "%d terminated: %s\n", pid, w->msg);
- if(w->msg[0] == 0){
- free(w);
- break;
- }else{
- free(w);
- return 0;
- }
- }else
- free(w);
- }
- return 1;
- }
- /* get out of the current namespace */
- newns("none", 0);
- dup(pfd[0], 0);
- close(pfd[0]);
- close(pfd[1]);
- putenv("upasname", "netkeys");
- if(debug){
- print("\nto %s\n", rcvr);
- execl("/bin/cat", "cat", nil);
- }
- execl("/bin/upas/send", "send", "-r", rcvr, nil);
- /* just in case */
- sysfatal("can't exec send: %r");
- return 0; /* for compiler */
- }
- void
- complain(char *fmt, ...)
- {
- char buf[8192], *s;
- va_list arg;
- s = buf;
- s += sprint(s, "%s: ", argv0);
- va_start(arg, fmt);
- s = vseprint(s, buf + sizeof(buf) / sizeof(*buf), fmt, arg);
- va_end(arg);
- *s++ = '\n';
- write(2, buf, s - buf);
- }
- long
- readnumfile(char *file)
- {
- int fd, n;
- char buf[64];
- fd = open(file, OREAD);
- if(fd < 0){
- complain("can't open %s: %r", file);
- return 0;
- }
- n = read(fd, buf, sizeof(buf)-1);
- close(fd);
- if(n < 0){
- complain("can't read %s: %r", file);
- return 0;
- }
- buf[n] = 0;
- return atol(buf);
- }
- void
- writenumfile(char *file, long num)
- {
- int fd;
- fd = open(file, OWRITE);
- if(fd < 0){
- complain("can't open %s: %r", file);
- return;
- }
- fprint(fd, "%ld", num);
- close(fd);
- }
|