246 lines · 4.5 KB · C
RawDownload
/* Copyright © 2003 Russ Cox, MIT; see /sys/src/libsunrpc/COPYING */ /* * name <-> int translation from nfs(4) */ #include "fxp.h" static Map emptymap;static int verbose; static User*finduser(User **u, int nu, char *s){	int lo, hi, mid, n; 	hi = nu;	lo = 0;	while(hi > lo){		mid = (lo+hi)/2;		n = strcmp(u[mid]->name, s);		if(n == 0)			return u[mid];		if(n < 0)			lo = mid+1;		else			hi = mid;	}	return nil;} static intstrtoid(User **u, int nu, char *s, u32int *id){	u32int x;	char *p;	User *uu; 	x = strtoul(s, &p, 10);	if(*s != 0 && *p == 0){		*id = x;		return 0;	} 	uu = finduser(u, nu, s);	if(uu == nil)		return -1;	*id = uu->uid;	return 0;} static char*idtostr(User **u, int nu, u32int id){	char buf[32];	int lo, hi, mid; 	hi = nu;	lo = 0;	while(hi > lo){		mid = (lo+hi)/2;		if(u[mid]->uid == id)			return estrdup9p(u[mid]->name);		if(u[mid]->uid < id)			lo = mid+1;		else			hi = mid;	}	snprint(buf, sizeof buf, "%ud", id);		return estrdup9p(buf);} char*uidtostr(Map *map, u32int uid){	return idtostr(map->ubyid, map->nuser, uid);} char*gidtostr(Map *map, u32int gid){	return idtostr((User**)map->gbyid, map->ngroup, gid);} static intstrtouid(Map *map, char *s, u32int *id){	return strtoid(map->ubyname, map->nuser, s, id);} static intstrtogid(Map *map, char *s, u32int *id){	return strtoid((User**)map->gbyid, map->ngroup, s, id);}  static intidcmp(const void *va, const void *vb){	User **a, **b; 	a = (User**)va;	b = (User**)vb;	return (*a)->uid - (*b)->uid;} static intnamecmp(const void *va, const void *vb){	User **a, **b; 	a = (User**)va;	b = (User**)vb;	return strcmp((*a)->name, (*b)->name);} voidclosemap(Map *m){	int i; 	for(i=0; i<m->nuser; i++){		free(m->user[i].name);		free(m->user[i].auth);	}	for(i=0; i<m->ngroup; i++)		free(m->group[i].name);	free(m->user);	free(m->group);	free(m->ubyid);	free(m->ubyname);	free(m->gbyid);	free(m->gbyname);	free(m);} Map*readmap(char *passwd, char *group){	char *s, *f[10], *p, *nextp, *name;	int i, nf, line, uid, gid;	Biobuf *b;	Map *m;	User *u;	Group *g; 	m = emalloc9p(sizeof(Map)); 	if((b = Bopen(passwd, OREAD)) == nil){		free(m);		return nil;	}	line = 0;	for(; (s = Brdstr(b, '\n', 1)) != nil; free(s)){		line++;		if(s[0] == '#')			continue;		nf = getfields(s, f, nelem(f), 0, ":");		if(nf < 4)			continue;		name = f[0];		uid = strtol(f[2], &p, 10);		if(f[2][0] == 0 || *p != 0){			fprint(2, "%s:%d: non-numeric id in third field\n", passwd, line);			continue;		}		gid = strtol(f[3], &p, 10);		if(f[3][0] == 0 || *p != 0){			fprint(2, "%s:%d: non-numeric id in fourth field\n", passwd, line);			continue;		}		if(m->nuser%32 == 0)			m->user = erealloc9p(m->user, (m->nuser+32)*sizeof(m->user[0]));		u = &m->user[m->nuser++];		u->name = estrdup9p(name);		u->uid = uid;		u->gid = gid;		u->ng = 0;		u->auth = 0;		u->nauth = 0;	}	Bterm(b);	m->ubyname = emalloc9p(m->nuser*sizeof(User*));	m->ubyid = emalloc9p(m->nuser*sizeof(User*));	for(i=0; i<m->nuser; i++){		m->ubyname[i] = &m->user[i];		m->ubyid[i] = &m->user[i];	}	qsort(m->ubyname, m->nuser, sizeof(m->ubyname[0]), namecmp);	qsort(m->ubyid, m->nuser, sizeof(m->ubyid[0]), idcmp); 	if((b = Bopen(group, OREAD)) == nil){		closemap(m);		return nil;	}	line = 0;	for(; (s = Brdstr(b, '\n', 1)) != nil; free(s)){		line++;		if(s[0] == '#')			continue;		nf = getfields(s, f, nelem(f), 0, ":");		if(nf < 4)			continue;		name = f[0];		gid = strtol(f[2], &p, 10);		if(f[2][0] == 0 || *p != 0){			fprint(2, "%s:%d: non-numeric id in third field\n", group, line);			continue;		}		if(m->ngroup%32 == 0)			m->group = erealloc9p(m->group, (m->ngroup+32)*sizeof(m->group[0]));		g = &m->group[m->ngroup++];		g->name = estrdup9p(name);		g->gid = gid; 		for(p=f[3]; *p; p=nextp){			if((nextp = strchr(p, ',')) != nil)				*nextp++ = 0;			else				nextp = p+strlen(p);			u = finduser(m->ubyname, m->nuser, p);			if(u == nil){				if(verbose)					fprint(2, "%s:%d: unknown user %s\n", group, line, p);				continue;			}			if(u->ng >= nelem(u->g)){				fprint(2, "%s:%d: user %s is in too many groups; ignoring %s\n", group, line, p, name);				continue;			}			u->g[u->ng++] = gid;		}	}	Bterm(b);	m->gbyname = emalloc9p(m->ngroup*sizeof(Group*));	m->gbyid = emalloc9p(m->ngroup*sizeof(Group*));	for(i=0; i<m->ngroup; i++){		m->gbyname[i] = &m->group[i];		m->gbyid[i] = &m->group[i];	}	qsort(m->gbyname, m->ngroup, sizeof(m->gbyname[0]), namecmp);	qsort(m->gbyid, m->ngroup, sizeof(m->gbyid[0]), idcmp); 	return m;}