1*9a747e4fSDavid du Colombier #include "all.h" 2*9a747e4fSDavid du Colombier 3*9a747e4fSDavid du Colombier static void uxfree(Unixid*); 4*9a747e4fSDavid du Colombier 5*9a747e4fSDavid du Colombier static Unixid * xfree; 6*9a747e4fSDavid du Colombier 7*9a747e4fSDavid du Colombier Unixidmap *idhead, *idtail; 8*9a747e4fSDavid du Colombier 9*9a747e4fSDavid du Colombier Unixscmap *scmap; 10*9a747e4fSDavid du Colombier 11*9a747e4fSDavid du Colombier #define UNUSED 0x7FFFFFFF 12*9a747e4fSDavid du Colombier 13*9a747e4fSDavid du Colombier /* 14*9a747e4fSDavid du Colombier * Sadly we have to use the IP address, since some systems (FreeBSD in particular) 15*9a747e4fSDavid du Colombier * do not believe it to be safe to depend on the hostname and so refuse to send it. 16*9a747e4fSDavid du Colombier * I dislike making this IP-centric, but so be it. 17*9a747e4fSDavid du Colombier * We keep a cache of host names in getdom. 18*9a747e4fSDavid du Colombier */ 19*9a747e4fSDavid du Colombier Unixidmap * 20*9a747e4fSDavid du Colombier pair2idmap(char *server, ulong clientip) 21*9a747e4fSDavid du Colombier { 22*9a747e4fSDavid du Colombier Resub match; 23*9a747e4fSDavid du Colombier Unixscmap *m, *mp; 24*9a747e4fSDavid du Colombier Unixidmap *r; 25*9a747e4fSDavid du Colombier char dom[256]; 26*9a747e4fSDavid du Colombier 27*9a747e4fSDavid du Colombier for(mp=0,m=scmap; m; mp=m,m=m->next){ 28*9a747e4fSDavid du Colombier if(m->server[0] != server[0]) 29*9a747e4fSDavid du Colombier continue; 30*9a747e4fSDavid du Colombier if(strcmp(m->server, server)) 31*9a747e4fSDavid du Colombier continue; 32*9a747e4fSDavid du Colombier if(m->clientip != clientip) 33*9a747e4fSDavid du Colombier continue; 34*9a747e4fSDavid du Colombier if(mp){ 35*9a747e4fSDavid du Colombier mp->next = m->next; 36*9a747e4fSDavid du Colombier m->next = scmap; 37*9a747e4fSDavid du Colombier scmap = m; 38*9a747e4fSDavid du Colombier } 39*9a747e4fSDavid du Colombier r = m->map; 40*9a747e4fSDavid du Colombier if(r->u.timestamp != 0 && r->g.timestamp != 0) 41*9a747e4fSDavid du Colombier return r; 42*9a747e4fSDavid du Colombier scmap = m->next; 43*9a747e4fSDavid du Colombier free(m); 44*9a747e4fSDavid du Colombier break; 45*9a747e4fSDavid du Colombier } 46*9a747e4fSDavid du Colombier fprint(2, "looking for %lux\n", clientip); 47*9a747e4fSDavid du Colombier if(getdom(clientip, dom, sizeof dom)<0){ 48*9a747e4fSDavid du Colombier clog("auth: unknown ip address"); 49*9a747e4fSDavid du Colombier return nil; 50*9a747e4fSDavid du Colombier } 51*9a747e4fSDavid du Colombier fprint(2, "dom is %s\n", dom); 52*9a747e4fSDavid du Colombier for(r=idhead; r; r=r->next){ 53*9a747e4fSDavid du Colombier if(r->u.timestamp == 0 || r->g.timestamp == 0) 54*9a747e4fSDavid du Colombier continue; 55*9a747e4fSDavid du Colombier match.sp = match.ep = 0; 56*9a747e4fSDavid du Colombier if(regexec(r->sexp, server, &match, 1) == 0) 57*9a747e4fSDavid du Colombier continue; 58*9a747e4fSDavid du Colombier if(match.sp != server || match.ep <= match.sp || *match.ep) 59*9a747e4fSDavid du Colombier continue; 60*9a747e4fSDavid du Colombier match.sp = match.ep = 0; 61*9a747e4fSDavid du Colombier if(regexec(r->cexp, dom, &match, 1) == 0) 62*9a747e4fSDavid du Colombier continue; 63*9a747e4fSDavid du Colombier if(match.sp != dom || match.ep <= match.sp || *match.ep) 64*9a747e4fSDavid du Colombier continue; 65*9a747e4fSDavid du Colombier m = malloc(sizeof(Unixscmap)); 66*9a747e4fSDavid du Colombier m->next = scmap; 67*9a747e4fSDavid du Colombier scmap = m; 68*9a747e4fSDavid du Colombier m->server = strstore(server); 69*9a747e4fSDavid du Colombier m->clientip = clientip; 70*9a747e4fSDavid du Colombier m->map = r; 71*9a747e4fSDavid du Colombier break; 72*9a747e4fSDavid du Colombier } 73*9a747e4fSDavid du Colombier return r; 74*9a747e4fSDavid du Colombier } 75*9a747e4fSDavid du Colombier 76*9a747e4fSDavid du Colombier int 77*9a747e4fSDavid du Colombier readunixidmaps(char *file) 78*9a747e4fSDavid du Colombier { 79*9a747e4fSDavid du Colombier Waitmsg *w; 80*9a747e4fSDavid du Colombier Biobuf *in; 81*9a747e4fSDavid du Colombier Unixidmap *m; 82*9a747e4fSDavid du Colombier int i, arc; char *arv[16], buf[256]; 83*9a747e4fSDavid du Colombier char *l; 84*9a747e4fSDavid du Colombier long savalarm; 85*9a747e4fSDavid du Colombier 86*9a747e4fSDavid du Colombier savalarm = alarm(0); 87*9a747e4fSDavid du Colombier in = Bopen(file, OREAD); 88*9a747e4fSDavid du Colombier if(in == 0){ 89*9a747e4fSDavid du Colombier clog("readunixidmaps can't open %s: %r\n", file); 90*9a747e4fSDavid du Colombier alarm(savalarm); 91*9a747e4fSDavid du Colombier return -1; 92*9a747e4fSDavid du Colombier } 93*9a747e4fSDavid du Colombier for(m=idhead; m; m=m->next) 94*9a747e4fSDavid du Colombier m->flag = 0; 95*9a747e4fSDavid du Colombier while(l = Brdline(in, '\n')){ /* assign = */ 96*9a747e4fSDavid du Colombier l[Blinelen(in)-1] = 0; 97*9a747e4fSDavid du Colombier arc = strparse(l, nelem(arv), arv); 98*9a747e4fSDavid du Colombier if(arc > 0 && arv[0][0] == '!'){ 99*9a747e4fSDavid du Colombier ++arv[0]; 100*9a747e4fSDavid du Colombier snprint(buf, sizeof buf, "/bin/%s", arv[0]); 101*9a747e4fSDavid du Colombier if(chatty){ 102*9a747e4fSDavid du Colombier chat("!"); 103*9a747e4fSDavid du Colombier for(i=0; i<arc; i++) 104*9a747e4fSDavid du Colombier chat(" %s", arv[i]); 105*9a747e4fSDavid du Colombier chat("..."); 106*9a747e4fSDavid du Colombier } 107*9a747e4fSDavid du Colombier w = system(buf, arv); 108*9a747e4fSDavid du Colombier if(w == nil) 109*9a747e4fSDavid du Colombier chat("err: %r\n"); 110*9a747e4fSDavid du Colombier else if(w->msg && w->msg[0]) 111*9a747e4fSDavid du Colombier chat("status: %s\n", w->msg); 112*9a747e4fSDavid du Colombier else 113*9a747e4fSDavid du Colombier chat("OK\n"); 114*9a747e4fSDavid du Colombier free(w); 115*9a747e4fSDavid du Colombier continue; 116*9a747e4fSDavid du Colombier } 117*9a747e4fSDavid du Colombier if(arc != 4) 118*9a747e4fSDavid du Colombier continue; 119*9a747e4fSDavid du Colombier for(m=idhead; m; m=m->next) 120*9a747e4fSDavid du Colombier if(strcmp(arv[0], m->server) == 0 && 121*9a747e4fSDavid du Colombier strcmp(arv[1], m->client) == 0) 122*9a747e4fSDavid du Colombier break; 123*9a747e4fSDavid du Colombier if(m == 0){ 124*9a747e4fSDavid du Colombier m = malloc(sizeof(Unixidmap)); 125*9a747e4fSDavid du Colombier if(idtail) 126*9a747e4fSDavid du Colombier idtail->next = m; 127*9a747e4fSDavid du Colombier else 128*9a747e4fSDavid du Colombier idhead = m; 129*9a747e4fSDavid du Colombier idtail = m; 130*9a747e4fSDavid du Colombier m->next = 0; 131*9a747e4fSDavid du Colombier m->server = strstore(arv[0]); 132*9a747e4fSDavid du Colombier m->client = strstore(arv[1]); 133*9a747e4fSDavid du Colombier m->sexp = regcomp(m->server); 134*9a747e4fSDavid du Colombier m->cexp = regcomp(m->client); 135*9a747e4fSDavid du Colombier m->u.file = strstore(arv[2]); 136*9a747e4fSDavid du Colombier m->u.style = 'u'; 137*9a747e4fSDavid du Colombier m->u.timestamp = 0; 138*9a747e4fSDavid du Colombier m->u.ids = 0; 139*9a747e4fSDavid du Colombier m->g.file = strstore(arv[3]); 140*9a747e4fSDavid du Colombier m->g.style = 'u'; 141*9a747e4fSDavid du Colombier m->g.timestamp = 0; 142*9a747e4fSDavid du Colombier m->g.ids = 0; 143*9a747e4fSDavid du Colombier }else{ 144*9a747e4fSDavid du Colombier if(!m->u.file || strcmp(m->u.file, arv[2]) != 0){ 145*9a747e4fSDavid du Colombier m->u.file = strstore(arv[2]); 146*9a747e4fSDavid du Colombier m->u.timestamp = 0; 147*9a747e4fSDavid du Colombier } 148*9a747e4fSDavid du Colombier if(!m->g.file || strcmp(m->g.file, arv[3]) != 0){ 149*9a747e4fSDavid du Colombier m->g.file = strstore(arv[3]); 150*9a747e4fSDavid du Colombier m->g.timestamp = 0; 151*9a747e4fSDavid du Colombier } 152*9a747e4fSDavid du Colombier } 153*9a747e4fSDavid du Colombier m->flag = 1; 154*9a747e4fSDavid du Colombier checkunixmap(&m->u); 155*9a747e4fSDavid du Colombier checkunixmap(&m->g); 156*9a747e4fSDavid du Colombier } 157*9a747e4fSDavid du Colombier Bterm(in); 158*9a747e4fSDavid du Colombier for(m=idhead; m; m=m->next) 159*9a747e4fSDavid du Colombier if(m->flag == 0){ 160*9a747e4fSDavid du Colombier m->u.file = 0; 161*9a747e4fSDavid du Colombier m->u.timestamp = 0; 162*9a747e4fSDavid du Colombier uxfree(m->u.ids); 163*9a747e4fSDavid du Colombier m->u.ids = 0; 164*9a747e4fSDavid du Colombier m->g.file = 0; 165*9a747e4fSDavid du Colombier m->g.timestamp = 0; 166*9a747e4fSDavid du Colombier uxfree(m->g.ids); 167*9a747e4fSDavid du Colombier m->g.ids = 0; 168*9a747e4fSDavid du Colombier } 169*9a747e4fSDavid du Colombier alarm(savalarm); 170*9a747e4fSDavid du Colombier return 0; 171*9a747e4fSDavid du Colombier } 172*9a747e4fSDavid du Colombier 173*9a747e4fSDavid du Colombier static void 174*9a747e4fSDavid du Colombier uxfree(Unixid *x) 175*9a747e4fSDavid du Colombier { 176*9a747e4fSDavid du Colombier Unixid *tail; 177*9a747e4fSDavid du Colombier int count=0; 178*9a747e4fSDavid du Colombier 179*9a747e4fSDavid du Colombier if(x){ 180*9a747e4fSDavid du Colombier tail = x; 181*9a747e4fSDavid du Colombier if(tail->id < 0) 182*9a747e4fSDavid du Colombier abort(); 183*9a747e4fSDavid du Colombier tail->id = UNUSED; 184*9a747e4fSDavid du Colombier while(tail->next){ 185*9a747e4fSDavid du Colombier tail = tail->next; 186*9a747e4fSDavid du Colombier ++count; 187*9a747e4fSDavid du Colombier if(tail->id == UNUSED) 188*9a747e4fSDavid du Colombier abort(); 189*9a747e4fSDavid du Colombier tail->id = UNUSED; 190*9a747e4fSDavid du Colombier } 191*9a747e4fSDavid du Colombier tail->next = xfree; 192*9a747e4fSDavid du Colombier xfree = x; 193*9a747e4fSDavid du Colombier } 194*9a747e4fSDavid du Colombier } 195*9a747e4fSDavid du Colombier 196*9a747e4fSDavid du Colombier int 197*9a747e4fSDavid du Colombier checkunixmap(Unixmap *u) 198*9a747e4fSDavid du Colombier { 199*9a747e4fSDavid du Colombier Dir *dir; 200*9a747e4fSDavid du Colombier 201*9a747e4fSDavid du Colombier dir = dirstat(u->file); 202*9a747e4fSDavid du Colombier if(dir == nil){ 203*9a747e4fSDavid du Colombier clog("checkunixmap can't stat %s: %r\n", u->file); 204*9a747e4fSDavid du Colombier return -1; 205*9a747e4fSDavid du Colombier } 206*9a747e4fSDavid du Colombier if(u->timestamp > dir->mtime){ 207*9a747e4fSDavid du Colombier free(dir); 208*9a747e4fSDavid du Colombier return 0; 209*9a747e4fSDavid du Colombier } 210*9a747e4fSDavid du Colombier uxfree(u->ids); 211*9a747e4fSDavid du Colombier u->ids = readunixids(u->file, u->style); 212*9a747e4fSDavid du Colombier u->timestamp = time(0); 213*9a747e4fSDavid du Colombier free(dir); 214*9a747e4fSDavid du Colombier return 1; 215*9a747e4fSDavid du Colombier } 216*9a747e4fSDavid du Colombier 217*9a747e4fSDavid du Colombier int 218*9a747e4fSDavid du Colombier name2id(Unixid **list, char *name) 219*9a747e4fSDavid du Colombier { 220*9a747e4fSDavid du Colombier Unixid *x, *xp; 221*9a747e4fSDavid du Colombier 222*9a747e4fSDavid du Colombier for(xp=0,x=*list; x; xp=x,x=x->next){ 223*9a747e4fSDavid du Colombier if(x->name[0] == name[0] && strcmp(x->name, name) == 0){ 224*9a747e4fSDavid du Colombier if(xp){ 225*9a747e4fSDavid du Colombier xp->next = x->next; 226*9a747e4fSDavid du Colombier x->next = *list; 227*9a747e4fSDavid du Colombier *list = x; 228*9a747e4fSDavid du Colombier } 229*9a747e4fSDavid du Colombier return x->id; 230*9a747e4fSDavid du Colombier } 231*9a747e4fSDavid du Colombier } 232*9a747e4fSDavid du Colombier return -1; 233*9a747e4fSDavid du Colombier } 234*9a747e4fSDavid du Colombier 235*9a747e4fSDavid du Colombier char * 236*9a747e4fSDavid du Colombier id2name(Unixid **list, int id) 237*9a747e4fSDavid du Colombier { 238*9a747e4fSDavid du Colombier Unixid *x, *xp; 239*9a747e4fSDavid du Colombier 240*9a747e4fSDavid du Colombier for(xp=0,x=*list; x; xp=x,x=x->next){ 241*9a747e4fSDavid du Colombier if(x->id == id){ 242*9a747e4fSDavid du Colombier if(xp){ 243*9a747e4fSDavid du Colombier xp->next = x->next; 244*9a747e4fSDavid du Colombier x->next = *list; 245*9a747e4fSDavid du Colombier *list = x; 246*9a747e4fSDavid du Colombier } 247*9a747e4fSDavid du Colombier return x->name; 248*9a747e4fSDavid du Colombier } 249*9a747e4fSDavid du Colombier } 250*9a747e4fSDavid du Colombier return "none"; 251*9a747e4fSDavid du Colombier } 252*9a747e4fSDavid du Colombier 253*9a747e4fSDavid du Colombier void 254*9a747e4fSDavid du Colombier idprint(int fd, Unixid *xp) 255*9a747e4fSDavid du Colombier { 256*9a747e4fSDavid du Colombier while(xp){ 257*9a747e4fSDavid du Colombier fprint(fd, "%d\t%s\n", xp->id, xp->name); 258*9a747e4fSDavid du Colombier xp = xp->next; 259*9a747e4fSDavid du Colombier } 260*9a747e4fSDavid du Colombier } 261*9a747e4fSDavid du Colombier 262*9a747e4fSDavid du Colombier /* 263*9a747e4fSDavid du Colombier * style '9': 3:tom:tom: 264*9a747e4fSDavid du Colombier * style 'u': sysadm:*:0:0:System-Administrator:/usr/admin:/bin/sh 265*9a747e4fSDavid du Colombier */ 266*9a747e4fSDavid du Colombier 267*9a747e4fSDavid du Colombier Unixid * 268*9a747e4fSDavid du Colombier readunixids(char *file, int style) 269*9a747e4fSDavid du Colombier { 270*9a747e4fSDavid du Colombier Biobuf *in; 271*9a747e4fSDavid du Colombier char *l, *name = 0; 272*9a747e4fSDavid du Colombier Unixid *x, *xp = 0; 273*9a747e4fSDavid du Colombier int id = 0; 274*9a747e4fSDavid du Colombier 275*9a747e4fSDavid du Colombier in = Bopen(file, OREAD); 276*9a747e4fSDavid du Colombier if(in == 0){ 277*9a747e4fSDavid du Colombier clog("readunixids can't open %s: %r\n", file); 278*9a747e4fSDavid du Colombier return 0; 279*9a747e4fSDavid du Colombier } 280*9a747e4fSDavid du Colombier while(l = Brdline(in, '\n')){ /* assign = */ 281*9a747e4fSDavid du Colombier l[Blinelen(in)-1] = 0; 282*9a747e4fSDavid du Colombier switch(style){ 283*9a747e4fSDavid du Colombier case '9': 284*9a747e4fSDavid du Colombier id = strtol(l, &l, 10); 285*9a747e4fSDavid du Colombier if(*l != ':') 286*9a747e4fSDavid du Colombier continue; 287*9a747e4fSDavid du Colombier name = ++l; 288*9a747e4fSDavid du Colombier l = strchr(l, ':'); 289*9a747e4fSDavid du Colombier if(l == 0) 290*9a747e4fSDavid du Colombier continue; 291*9a747e4fSDavid du Colombier *l = 0; 292*9a747e4fSDavid du Colombier break; 293*9a747e4fSDavid du Colombier case 'u': 294*9a747e4fSDavid du Colombier name = l; 295*9a747e4fSDavid du Colombier l = strchr(l, ':'); 296*9a747e4fSDavid du Colombier if(l == 0) 297*9a747e4fSDavid du Colombier continue; 298*9a747e4fSDavid du Colombier *l++ = 0; 299*9a747e4fSDavid du Colombier /* skip password */ 300*9a747e4fSDavid du Colombier l = strchr(l, ':'); 301*9a747e4fSDavid du Colombier if(l == 0) 302*9a747e4fSDavid du Colombier continue; 303*9a747e4fSDavid du Colombier id = strtol(l+1, 0, 10); 304*9a747e4fSDavid du Colombier break; 305*9a747e4fSDavid du Colombier default: 306*9a747e4fSDavid du Colombier panic("unknown unixid style %d\n", style); 307*9a747e4fSDavid du Colombier } 308*9a747e4fSDavid du Colombier if(id == UNUSED) 309*9a747e4fSDavid du Colombier id = -1; /* any value will do */ 310*9a747e4fSDavid du Colombier if(!(x = xfree)) /* assign = */ 311*9a747e4fSDavid du Colombier x = listalloc(1024/sizeof(Unixid), sizeof(Unixid)); 312*9a747e4fSDavid du Colombier xfree = x->next; 313*9a747e4fSDavid du Colombier x->id = id; 314*9a747e4fSDavid du Colombier x->name = strstore(name); 315*9a747e4fSDavid du Colombier x->next = xp; 316*9a747e4fSDavid du Colombier xp = x; 317*9a747e4fSDavid du Colombier } 318*9a747e4fSDavid du Colombier Bterm(in); 319*9a747e4fSDavid du Colombier return xp; 320*9a747e4fSDavid du Colombier } 321