19a747e4fSDavid du Colombier #include "all.h"
29a747e4fSDavid du Colombier
39a747e4fSDavid du Colombier static void uxfree(Unixid*);
49a747e4fSDavid du Colombier
59a747e4fSDavid du Colombier static Unixid * xfree;
69a747e4fSDavid du Colombier
79a747e4fSDavid du Colombier Unixidmap *idhead, *idtail;
89a747e4fSDavid du Colombier
99a747e4fSDavid du Colombier Unixscmap *scmap;
109a747e4fSDavid du Colombier
119a747e4fSDavid du Colombier #define UNUSED 0x7FFFFFFF
129a747e4fSDavid du Colombier
139a747e4fSDavid du Colombier /*
149a747e4fSDavid du Colombier * Sadly we have to use the IP address, since some systems (FreeBSD in particular)
159a747e4fSDavid du Colombier * do not believe it to be safe to depend on the hostname and so refuse to send it.
169a747e4fSDavid du Colombier * I dislike making this IP-centric, but so be it.
179a747e4fSDavid du Colombier * We keep a cache of host names in getdom.
189a747e4fSDavid du Colombier */
199a747e4fSDavid du Colombier Unixidmap *
pair2idmap(char * server,ulong clientip)209a747e4fSDavid du Colombier pair2idmap(char *server, ulong clientip)
219a747e4fSDavid du Colombier {
229a747e4fSDavid du Colombier Resub match;
239a747e4fSDavid du Colombier Unixscmap *m, *mp;
249a747e4fSDavid du Colombier Unixidmap *r;
259a747e4fSDavid du Colombier char dom[256];
269a747e4fSDavid du Colombier
279a747e4fSDavid du Colombier for(mp=0,m=scmap; m; mp=m,m=m->next){
289a747e4fSDavid du Colombier if(m->server[0] != server[0])
299a747e4fSDavid du Colombier continue;
309a747e4fSDavid du Colombier if(strcmp(m->server, server))
319a747e4fSDavid du Colombier continue;
329a747e4fSDavid du Colombier if(m->clientip != clientip)
339a747e4fSDavid du Colombier continue;
349a747e4fSDavid du Colombier if(mp){
359a747e4fSDavid du Colombier mp->next = m->next;
369a747e4fSDavid du Colombier m->next = scmap;
379a747e4fSDavid du Colombier scmap = m;
389a747e4fSDavid du Colombier }
399a747e4fSDavid du Colombier r = m->map;
409a747e4fSDavid du Colombier if(r->u.timestamp != 0 && r->g.timestamp != 0)
419a747e4fSDavid du Colombier return r;
429a747e4fSDavid du Colombier scmap = m->next;
439a747e4fSDavid du Colombier free(m);
449a747e4fSDavid du Colombier break;
459a747e4fSDavid du Colombier }
46*4fc7c356SDavid du Colombier if(rpcdebug)
479a747e4fSDavid du Colombier fprint(2, "looking for %lux\n", clientip);
489a747e4fSDavid du Colombier if(getdom(clientip, dom, sizeof dom)<0){
499a747e4fSDavid du Colombier clog("auth: unknown ip address");
509a747e4fSDavid du Colombier return nil;
519a747e4fSDavid du Colombier }
52*4fc7c356SDavid du Colombier if(rpcdebug)
539a747e4fSDavid du Colombier fprint(2, "dom is %s\n", dom);
549a747e4fSDavid du Colombier for(r=idhead; r; r=r->next){
559a747e4fSDavid du Colombier if(r->u.timestamp == 0 || r->g.timestamp == 0)
569a747e4fSDavid du Colombier continue;
579a747e4fSDavid du Colombier match.sp = match.ep = 0;
589a747e4fSDavid du Colombier if(regexec(r->sexp, server, &match, 1) == 0)
599a747e4fSDavid du Colombier continue;
609a747e4fSDavid du Colombier if(match.sp != server || match.ep <= match.sp || *match.ep)
619a747e4fSDavid du Colombier continue;
629a747e4fSDavid du Colombier match.sp = match.ep = 0;
639a747e4fSDavid du Colombier if(regexec(r->cexp, dom, &match, 1) == 0)
649a747e4fSDavid du Colombier continue;
659a747e4fSDavid du Colombier if(match.sp != dom || match.ep <= match.sp || *match.ep)
669a747e4fSDavid du Colombier continue;
679a747e4fSDavid du Colombier m = malloc(sizeof(Unixscmap));
689a747e4fSDavid du Colombier m->next = scmap;
699a747e4fSDavid du Colombier scmap = m;
709a747e4fSDavid du Colombier m->server = strstore(server);
719a747e4fSDavid du Colombier m->clientip = clientip;
729a747e4fSDavid du Colombier m->map = r;
739a747e4fSDavid du Colombier break;
749a747e4fSDavid du Colombier }
759a747e4fSDavid du Colombier return r;
769a747e4fSDavid du Colombier }
779a747e4fSDavid du Colombier
789a747e4fSDavid du Colombier int
readunixidmaps(char * file)799a747e4fSDavid du Colombier readunixidmaps(char *file)
809a747e4fSDavid du Colombier {
819a747e4fSDavid du Colombier Waitmsg *w;
829a747e4fSDavid du Colombier Biobuf *in;
839a747e4fSDavid du Colombier Unixidmap *m;
849a747e4fSDavid du Colombier int i, arc; char *arv[16], buf[256];
859a747e4fSDavid du Colombier char *l;
866ab4d0ffSDavid du Colombier // long savalarm;
879a747e4fSDavid du Colombier
886ab4d0ffSDavid du Colombier // savalarm = alarm(0);
899a747e4fSDavid du Colombier in = Bopen(file, OREAD);
909a747e4fSDavid du Colombier if(in == 0){
919a747e4fSDavid du Colombier clog("readunixidmaps can't open %s: %r\n", file);
926ab4d0ffSDavid du Colombier // alarm(savalarm);
939a747e4fSDavid du Colombier return -1;
949a747e4fSDavid du Colombier }
959a747e4fSDavid du Colombier for(m=idhead; m; m=m->next)
969a747e4fSDavid du Colombier m->flag = 0;
979a747e4fSDavid du Colombier while(l = Brdline(in, '\n')){ /* assign = */
989a747e4fSDavid du Colombier l[Blinelen(in)-1] = 0;
999a747e4fSDavid du Colombier arc = strparse(l, nelem(arv), arv);
1009a747e4fSDavid du Colombier if(arc > 0 && arv[0][0] == '!'){
1019a747e4fSDavid du Colombier ++arv[0];
1029a747e4fSDavid du Colombier snprint(buf, sizeof buf, "/bin/%s", arv[0]);
1039a747e4fSDavid du Colombier if(chatty){
1049a747e4fSDavid du Colombier chat("!");
1059a747e4fSDavid du Colombier for(i=0; i<arc; i++)
1069a747e4fSDavid du Colombier chat(" %s", arv[i]);
1079a747e4fSDavid du Colombier chat("...");
1089a747e4fSDavid du Colombier }
1099a747e4fSDavid du Colombier w = system(buf, arv);
1109a747e4fSDavid du Colombier if(w == nil)
1119a747e4fSDavid du Colombier chat("err: %r\n");
1129a747e4fSDavid du Colombier else if(w->msg && w->msg[0])
1139a747e4fSDavid du Colombier chat("status: %s\n", w->msg);
1149a747e4fSDavid du Colombier else
1159a747e4fSDavid du Colombier chat("OK\n");
1169a747e4fSDavid du Colombier free(w);
1179a747e4fSDavid du Colombier continue;
1189a747e4fSDavid du Colombier }
1199a747e4fSDavid du Colombier if(arc != 4)
1209a747e4fSDavid du Colombier continue;
1219a747e4fSDavid du Colombier for(m=idhead; m; m=m->next)
1229a747e4fSDavid du Colombier if(strcmp(arv[0], m->server) == 0 &&
1239a747e4fSDavid du Colombier strcmp(arv[1], m->client) == 0)
1249a747e4fSDavid du Colombier break;
1259a747e4fSDavid du Colombier if(m == 0){
1269a747e4fSDavid du Colombier m = malloc(sizeof(Unixidmap));
1279a747e4fSDavid du Colombier if(idtail)
1289a747e4fSDavid du Colombier idtail->next = m;
1299a747e4fSDavid du Colombier else
1309a747e4fSDavid du Colombier idhead = m;
1319a747e4fSDavid du Colombier idtail = m;
1329a747e4fSDavid du Colombier m->next = 0;
1339a747e4fSDavid du Colombier m->server = strstore(arv[0]);
1349a747e4fSDavid du Colombier m->client = strstore(arv[1]);
1359a747e4fSDavid du Colombier m->sexp = regcomp(m->server);
1369a747e4fSDavid du Colombier m->cexp = regcomp(m->client);
1379a747e4fSDavid du Colombier m->u.file = strstore(arv[2]);
1389a747e4fSDavid du Colombier m->u.style = 'u';
1399a747e4fSDavid du Colombier m->u.timestamp = 0;
1409a747e4fSDavid du Colombier m->u.ids = 0;
1419a747e4fSDavid du Colombier m->g.file = strstore(arv[3]);
1429a747e4fSDavid du Colombier m->g.style = 'u';
1439a747e4fSDavid du Colombier m->g.timestamp = 0;
1449a747e4fSDavid du Colombier m->g.ids = 0;
1459a747e4fSDavid du Colombier }else{
1469a747e4fSDavid du Colombier if(!m->u.file || strcmp(m->u.file, arv[2]) != 0){
1479a747e4fSDavid du Colombier m->u.file = strstore(arv[2]);
1489a747e4fSDavid du Colombier m->u.timestamp = 0;
1499a747e4fSDavid du Colombier }
1509a747e4fSDavid du Colombier if(!m->g.file || strcmp(m->g.file, arv[3]) != 0){
1519a747e4fSDavid du Colombier m->g.file = strstore(arv[3]);
1529a747e4fSDavid du Colombier m->g.timestamp = 0;
1539a747e4fSDavid du Colombier }
1549a747e4fSDavid du Colombier }
1559a747e4fSDavid du Colombier m->flag = 1;
1569a747e4fSDavid du Colombier checkunixmap(&m->u);
1579a747e4fSDavid du Colombier checkunixmap(&m->g);
1589a747e4fSDavid du Colombier }
1599a747e4fSDavid du Colombier Bterm(in);
1609a747e4fSDavid du Colombier for(m=idhead; m; m=m->next)
1619a747e4fSDavid du Colombier if(m->flag == 0){
1629a747e4fSDavid du Colombier m->u.file = 0;
1639a747e4fSDavid du Colombier m->u.timestamp = 0;
1649a747e4fSDavid du Colombier uxfree(m->u.ids);
1659a747e4fSDavid du Colombier m->u.ids = 0;
1669a747e4fSDavid du Colombier m->g.file = 0;
1679a747e4fSDavid du Colombier m->g.timestamp = 0;
1689a747e4fSDavid du Colombier uxfree(m->g.ids);
1699a747e4fSDavid du Colombier m->g.ids = 0;
1709a747e4fSDavid du Colombier }
1716ab4d0ffSDavid du Colombier // alarm(savalarm);
1729a747e4fSDavid du Colombier return 0;
1739a747e4fSDavid du Colombier }
1749a747e4fSDavid du Colombier
1759a747e4fSDavid du Colombier static void
uxfree(Unixid * x)1769a747e4fSDavid du Colombier uxfree(Unixid *x)
1779a747e4fSDavid du Colombier {
1789a747e4fSDavid du Colombier Unixid *tail;
1799a747e4fSDavid du Colombier int count=0;
1809a747e4fSDavid du Colombier
1819a747e4fSDavid du Colombier if(x){
1829a747e4fSDavid du Colombier tail = x;
1839a747e4fSDavid du Colombier if(tail->id < 0)
1849a747e4fSDavid du Colombier abort();
1859a747e4fSDavid du Colombier tail->id = UNUSED;
1869a747e4fSDavid du Colombier while(tail->next){
1879a747e4fSDavid du Colombier tail = tail->next;
1889a747e4fSDavid du Colombier ++count;
1899a747e4fSDavid du Colombier if(tail->id == UNUSED)
1909a747e4fSDavid du Colombier abort();
1919a747e4fSDavid du Colombier tail->id = UNUSED;
1929a747e4fSDavid du Colombier }
1939a747e4fSDavid du Colombier tail->next = xfree;
1949a747e4fSDavid du Colombier xfree = x;
1959a747e4fSDavid du Colombier }
1969a747e4fSDavid du Colombier }
1979a747e4fSDavid du Colombier
1989a747e4fSDavid du Colombier int
checkunixmap(Unixmap * u)1999a747e4fSDavid du Colombier checkunixmap(Unixmap *u)
2009a747e4fSDavid du Colombier {
2019a747e4fSDavid du Colombier Dir *dir;
2029a747e4fSDavid du Colombier
2039a747e4fSDavid du Colombier dir = dirstat(u->file);
2049a747e4fSDavid du Colombier if(dir == nil){
2059a747e4fSDavid du Colombier clog("checkunixmap can't stat %s: %r\n", u->file);
2069a747e4fSDavid du Colombier return -1;
2079a747e4fSDavid du Colombier }
2089a747e4fSDavid du Colombier if(u->timestamp > dir->mtime){
2099a747e4fSDavid du Colombier free(dir);
2109a747e4fSDavid du Colombier return 0;
2119a747e4fSDavid du Colombier }
2129a747e4fSDavid du Colombier uxfree(u->ids);
2139a747e4fSDavid du Colombier u->ids = readunixids(u->file, u->style);
2149a747e4fSDavid du Colombier u->timestamp = time(0);
2159a747e4fSDavid du Colombier free(dir);
2169a747e4fSDavid du Colombier return 1;
2179a747e4fSDavid du Colombier }
2189a747e4fSDavid du Colombier
2199a747e4fSDavid du Colombier int
name2id(Unixid ** list,char * name)2209a747e4fSDavid du Colombier name2id(Unixid **list, char *name)
2219a747e4fSDavid du Colombier {
2229a747e4fSDavid du Colombier Unixid *x, *xp;
2239a747e4fSDavid du Colombier
2249a747e4fSDavid du Colombier for(xp=0,x=*list; x; xp=x,x=x->next){
2259a747e4fSDavid du Colombier if(x->name[0] == name[0] && strcmp(x->name, name) == 0){
2269a747e4fSDavid du Colombier if(xp){
2279a747e4fSDavid du Colombier xp->next = x->next;
2289a747e4fSDavid du Colombier x->next = *list;
2299a747e4fSDavid du Colombier *list = x;
2309a747e4fSDavid du Colombier }
2319a747e4fSDavid du Colombier return x->id;
2329a747e4fSDavid du Colombier }
2339a747e4fSDavid du Colombier }
2349a747e4fSDavid du Colombier return -1;
2359a747e4fSDavid du Colombier }
2369a747e4fSDavid du Colombier
2379a747e4fSDavid du Colombier char *
id2name(Unixid ** list,int id)2389a747e4fSDavid du Colombier id2name(Unixid **list, int id)
2399a747e4fSDavid du Colombier {
2409a747e4fSDavid du Colombier Unixid *x, *xp;
2419a747e4fSDavid du Colombier
2429a747e4fSDavid du Colombier for(xp=0,x=*list; x; xp=x,x=x->next){
2439a747e4fSDavid du Colombier if(x->id == id){
2449a747e4fSDavid du Colombier if(xp){
2459a747e4fSDavid du Colombier xp->next = x->next;
2469a747e4fSDavid du Colombier x->next = *list;
2479a747e4fSDavid du Colombier *list = x;
2489a747e4fSDavid du Colombier }
2499a747e4fSDavid du Colombier return x->name;
2509a747e4fSDavid du Colombier }
2519a747e4fSDavid du Colombier }
2529a747e4fSDavid du Colombier return "none";
2539a747e4fSDavid du Colombier }
2549a747e4fSDavid du Colombier
2559a747e4fSDavid du Colombier void
idprint(int fd,Unixid * xp)2569a747e4fSDavid du Colombier idprint(int fd, Unixid *xp)
2579a747e4fSDavid du Colombier {
2589a747e4fSDavid du Colombier while(xp){
2599a747e4fSDavid du Colombier fprint(fd, "%d\t%s\n", xp->id, xp->name);
2609a747e4fSDavid du Colombier xp = xp->next;
2619a747e4fSDavid du Colombier }
2629a747e4fSDavid du Colombier }
2639a747e4fSDavid du Colombier
2649a747e4fSDavid du Colombier /*
2659a747e4fSDavid du Colombier * style '9': 3:tom:tom:
2669a747e4fSDavid du Colombier * style 'u': sysadm:*:0:0:System-Administrator:/usr/admin:/bin/sh
2679a747e4fSDavid du Colombier */
2689a747e4fSDavid du Colombier
2699a747e4fSDavid du Colombier Unixid *
readunixids(char * file,int style)2709a747e4fSDavid du Colombier readunixids(char *file, int style)
2719a747e4fSDavid du Colombier {
2729a747e4fSDavid du Colombier Biobuf *in;
2739a747e4fSDavid du Colombier char *l, *name = 0;
2749a747e4fSDavid du Colombier Unixid *x, *xp = 0;
2759a747e4fSDavid du Colombier int id = 0;
2769a747e4fSDavid du Colombier
2779a747e4fSDavid du Colombier in = Bopen(file, OREAD);
2789a747e4fSDavid du Colombier if(in == 0){
2799a747e4fSDavid du Colombier clog("readunixids can't open %s: %r\n", file);
2809a747e4fSDavid du Colombier return 0;
2819a747e4fSDavid du Colombier }
2829a747e4fSDavid du Colombier while(l = Brdline(in, '\n')){ /* assign = */
2839a747e4fSDavid du Colombier l[Blinelen(in)-1] = 0;
2849a747e4fSDavid du Colombier switch(style){
2859a747e4fSDavid du Colombier case '9':
2869a747e4fSDavid du Colombier id = strtol(l, &l, 10);
2879a747e4fSDavid du Colombier if(*l != ':')
2889a747e4fSDavid du Colombier continue;
2899a747e4fSDavid du Colombier name = ++l;
2909a747e4fSDavid du Colombier l = strchr(l, ':');
2919a747e4fSDavid du Colombier if(l == 0)
2929a747e4fSDavid du Colombier continue;
2939a747e4fSDavid du Colombier *l = 0;
2949a747e4fSDavid du Colombier break;
2959a747e4fSDavid du Colombier case 'u':
2969a747e4fSDavid du Colombier name = l;
2979a747e4fSDavid du Colombier l = strchr(l, ':');
2989a747e4fSDavid du Colombier if(l == 0)
2999a747e4fSDavid du Colombier continue;
3009a747e4fSDavid du Colombier *l++ = 0;
3019a747e4fSDavid du Colombier /* skip password */
3029a747e4fSDavid du Colombier l = strchr(l, ':');
3039a747e4fSDavid du Colombier if(l == 0)
3049a747e4fSDavid du Colombier continue;
3059a747e4fSDavid du Colombier id = strtol(l+1, 0, 10);
3069a747e4fSDavid du Colombier break;
3079a747e4fSDavid du Colombier default:
3089a747e4fSDavid du Colombier panic("unknown unixid style %d\n", style);
3099a747e4fSDavid du Colombier }
3109a747e4fSDavid du Colombier if(id == UNUSED)
3119a747e4fSDavid du Colombier id = -1; /* any value will do */
3129a747e4fSDavid du Colombier if(!(x = xfree)) /* assign = */
3139a747e4fSDavid du Colombier x = listalloc(1024/sizeof(Unixid), sizeof(Unixid));
3149a747e4fSDavid du Colombier xfree = x->next;
3159a747e4fSDavid du Colombier x->id = id;
3169a747e4fSDavid du Colombier x->name = strstore(name);
3179a747e4fSDavid du Colombier x->next = xp;
3189a747e4fSDavid du Colombier xp = x;
3199a747e4fSDavid du Colombier }
3209a747e4fSDavid du Colombier Bterm(in);
3219a747e4fSDavid du Colombier return xp;
3229a747e4fSDavid du Colombier }
323