xref: /plan9/sys/src/cmd/9nfs/unixnames.c (revision 4fc7c3569bd2d80cd473f6db4bc2d3605434c9fb)
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