#include #include #include #include #include <9p.h> #include "ncp.h" typedef struct Node Node; typedef struct Node { ulong id; char *u, *g; Node *l, *r; }; static Node *Base = nil; static Node * addmap(Node *n, ulong id, char *u, char *g) { if (n == nil){ if ((n = emalloc9p(sizeof(Node))) == nil) sysfatal("No memory"); n->id = id; n->u = estrdup9p(u); n->g = estrdup9p(g); n->l = n->r = nil; } else if (n->id == id) sysfatal("duplicate ID - programmer error"); else if (n->id < id) n->l = addmap(n->l, id, u, g); else n->r = addmap(n->r, id, u, g); return n; } static int lookmap(Node *n, ulong id, char **u, char **g) { if (n != nil) { if (id == n->id){ if (u) *u = n->u; if (g) *g = n->g; return 0; } if (lookmap(n->l, id, u, g) != -1) return 0; if (lookmap(n->r, id, u, g) != -1) return 0; } return -1; } /* * pick the first group the user is in, * avoiding 'everyone' if possible. */ static ulong user2gid(Session *s, char *usr) { ulong maybe, gid; int more, seq, type, flags; uchar buf[PROPLEN], *p; char group[OBJNAMLEN]; maybe = 0; for (more = 1, seq = 1; more; seq++) { if (ReadPropertyValue(s, usr, OTuser, "groups_i'm_in", seq, buf, &more, &flags) == -1) break; p = buf; while(1){ gid = *p++ << 24; gid |= *p++ << 16; gid |= *p++ << 8; gid |= *p++; if (GetBinderyObjectName(s, gid, group, &type) != 0) break; if (*group){ maybe = gid; if (strcmp(strlwr(group), "everyone") != 0) return gid; } } } return maybe; } void uid2names(Session *s, ulong uid, char **usr, char **grp) { int type; ulong gid; static char user[OBJNAMLEN]; static char group[OBJNAMLEN]; if (lookmap(Base, uid, usr, grp) == 0) return; if (GetBinderyObjectName(s, uid, user, &type) == -1) if (uid == 0) strcpy(user, "none"); else snprint(user, sizeof(user), "%lux", uid); gid = user2gid(s, user); if (GetBinderyObjectName(s, gid, group, &type) == -1) if (gid == 0) strcpy(group, "none"); else snprint(group, sizeof(group), "%lux", gid); strlwr(user); strlwr(group); Base = addmap(Base, uid, user, group); if (usr) *usr = user; if (grp) *grp = group; }