#include "all.h" static void uxfree(Unixid*); static Unixid * xfree; Unixidmap *idhead, *idtail; Unixscmap *scmap; Unixidmap * pair2idmap(char *server, char *client) { Resub match; Unixscmap *m, *mp; Unixidmap *r; for(mp=0,m=scmap; m; mp=m,m=m->next){ if(m->server[0] != server[0] || m->client[0] != client[0]) continue; if(strcmp(m->server, server) || strcmp(m->client, client)) continue; if(mp){ mp->next = m->next; m->next = scmap; scmap = m; } r = m->map; if(r->u.timestamp != 0 && r->g.timestamp != 0) return r; scmap = m->next; free(m); break; } for(r=idhead; r; r=r->next){ if(r->u.timestamp == 0 || r->g.timestamp == 0) continue; match.sp = match.ep = 0; if(regexec(r->sexp, server, &match, 1) == 0) continue; if(match.sp != server || match.ep <= match.sp || *match.ep) continue; match.sp = match.ep = 0; if(regexec(r->cexp, client, &match, 1) == 0) continue; if(match.sp != client || match.ep <= match.sp || *match.ep) continue; m = malloc(sizeof(Unixscmap)); m->next = scmap; scmap = m; m->server = strstore(server); m->client = strstore(client); m->map = r; break; } return r; } int readunixidmaps(char *file) { Waitmsg w; Biobuf *in; Unixidmap *m; int i, arc; char *arv[16], buf[2*NAMELEN]; char *l; long savalarm; savalarm = alarm(0); in = Bopen(file, OREAD); if(in == 0){ clog("readunixidmaps can't open %s: %r\n", file); alarm(savalarm); return -1; } for(m=idhead; m; m=m->next) m->flag = 0; while(l = Brdline(in, '\n')){ /* assign = */ l[BLINELEN(in)-1] = 0; arc = strparse(l, nelem(arv), arv); if(arc > 0 && arv[0][0] == '!'){ ++arv[0]; sprint(buf, "/bin/%s", arv[0]); if(chatty){ chat("!"); for(i=0; inext) if(strcmp(arv[0], m->server) == 0 && strcmp(arv[1], m->client) == 0) break; if(m == 0){ m = malloc(sizeof(Unixidmap)); if(idtail) idtail->next = m; else idhead = m; idtail = m; m->next = 0; m->server = strstore(arv[0]); m->client = strstore(arv[1]); m->sexp = regcomp(m->server); m->cexp = regcomp(m->client); m->u.file = strstore(arv[2]); m->u.style = 'u'; m->u.timestamp = 0; m->u.ids = 0; m->g.file = strstore(arv[3]); m->g.style = 'u'; m->g.timestamp = 0; m->g.ids = 0; }else{ if(!m->u.file || strcmp(m->u.file, arv[2]) != 0){ m->u.file = strstore(arv[2]); m->u.timestamp = 0; } if(!m->g.file || strcmp(m->g.file, arv[3]) != 0){ m->g.file = strstore(arv[3]); m->g.timestamp = 0; } } m->flag = 1; checkunixmap(&m->u); checkunixmap(&m->g); } Bterm(in); for(m=idhead; m; m=m->next) if(m->flag == 0){ m->u.file = 0; m->u.timestamp = 0; uxfree(m->u.ids); m->u.ids = 0; m->g.file = 0; m->g.timestamp = 0; uxfree(m->g.ids); m->g.ids = 0; } alarm(savalarm); return 0; } static void uxfree(Unixid *x) { Unixid *tail; int count=0; if(x){ tail = x; if(tail->id < 0) abort(); tail->id = -1; while(tail->next){ tail = tail->next; ++count; if(tail->id < 0) abort(); tail->id = -1; } tail->next = xfree; xfree = x; } } int checkunixmap(Unixmap *u) { Dir dir; if(dirstat(u->file, &dir) < 0){ clog("checkunixmap can't stat %s: %r\n", u->file); return -1; } if(u->timestamp > dir.mtime) return 0; uxfree(u->ids); u->ids = readunixids(u->file, u->style); u->timestamp = time(0); return 1; } int name2id(Unixid **list, char *name) { Unixid *x, *xp; for(xp=0,x=*list; x; xp=x,x=x->next){ if(x->name[0] == name[0] && strcmp(x->name, name) == 0){ if(xp){ xp->next = x->next; x->next = *list; *list = x; } return x->id; } } return -1; } char * id2name(Unixid **list, int id) { Unixid *x, *xp; for(xp=0,x=*list; x; xp=x,x=x->next){ if(x->id == id){ if(xp){ xp->next = x->next; x->next = *list; *list = x; } return x->name; } } return "none"; } void idprint(int fd, Unixid *xp) { while(xp){ fprint(fd, "%d\t%s\n", xp->id, xp->name); xp = xp->next; } } /* * style '9': 3:tom:tom: * style 'u': sysadm:*:0:0:System-Administrator:/usr/admin:/bin/sh */ Unixid * readunixids(char *file, int style) { Biobuf *in; char *l, *name = 0; Unixid *x, *xp = 0; int id = 0; in = Bopen(file, OREAD); if(in == 0){ clog("readunixids can't open %s: %r\n", file); return 0; } while(l = Brdline(in, '\n')){ /* assign = */ l[BLINELEN(in)-1] = 0; switch(style){ case '9': id = strtol(l, &l, 10); if(*l != ':') continue; name = ++l; l = strchr(l, ':'); if(l == 0) continue; *l = 0; break; case 'u': name = l; l = strchr(l, ':'); if(l == 0) continue; *l++ = 0; /* skip password */ l = strchr(l, ':'); if(l == 0) continue; id = strtol(l+1, 0, 10); break; default: panic("unknown unixid style %d\n", style); } if(!(x = xfree)) /* assign = */ x = listalloc(1024/sizeof(Unixid), sizeof(Unixid)); xfree = x->next; x->id = id; x->name = strstore(name); x->next = xp; xp = x; } Bterm(in); return xp; }