#include <u.h>
#include <libc.h>
#include <fcall.h>
#include <thread.h>
#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;
}
|