Example #1
0
/*
 *  use dns to resolve the mx request
 */
static int
mxlookup(DS *ds, char *domain)
{
	int i, n, nmx;
	Ndbtuple *t, *tmx, *tpref, *tip;
	
	strcpy(domain, ds->host);
	ds->netdir = "/net";
	nmx = 0;
	if((t = dnsquery(nil, ds->host, "mx")) != nil){
		for(tmx=t; (tmx=ndbfindattr(tmx->entry, nil, "mx")) != nil && nmx<Nmx; ){
			for(tpref=tmx->line; tpref != tmx; tpref=tpref->line){
				if(strcmp(tpref->attr, "pref") == 0){
					strncpy(mx[nmx].host, tmx->val, sizeof(mx[n].host)-1);
					mx[nmx].pref = atoi(tpref->val);
					nmx++;
					break;
				}
			}	
		}
		ndbfree(t);
	}

	/*
	 * no mx record? try name itself.
	 */
	/*
	 * BUG? If domain has no dots, then we used to look up ds->host
	 * but return domain instead of ds->host in the list.  Now we return
	 * ds->host.  What will this break?
	 */
	if(nmx == 0){
		mx[0].pref = 1;
		strncpy(mx[0].host, ds->host, sizeof(mx[0].host));
		nmx++;
	}

	/*
	 * look up all ip addresses
	 */
	for(i = 0; i < nmx; i++){
		if((t = dnsquery(nil, mx[i].host, "ip")) == nil)
			goto no;
		if((tip = ndbfindattr(t, nil, "ip")) == nil){
			ndbfree(t);
			goto no;
		}
		strncpy(mx[i].ip, tip->val, sizeof(mx[i].ip)-1);
		ndbfree(t);
		continue;
	
	no:
		/* remove mx[i] and go around again */
		nmx--;
		mx[i] = mx[nmx];
		i--;
	}
	return nmx;		
}
Example #2
0
File: cs.c Project: brho/akaros
/*
 *  generic query lookup.  The query is of one of the following
 *  forms:
 *
 *  attr1=val1 attr2=val2 attr3=val3 ...
 *
 *  returns the matching tuple
 *
 *  ipinfo attr=val attr1 attr2 attr3 ...
 *
 *  is like ipinfo and returns the attr{1-n}
 *  associated with the ip address.
 */
static char *genquery(struct mfile *mf, char *query)
{
	int i, n;
	char *p;
	char *attr[Maxattr];
	char *val[Maxattr];
	struct ndbtuple *t;
	struct ndbs s;

	n = getfields(query, attr, COUNT_OF(attr), 1, " ");
	if (n == 0)
		return "bad query";

	if (strcmp(attr[0], "ipinfo") == 0)
		return ipinfoquery(mf, attr, n);

	/* parse pairs */
	for (i = 0; i < n; i++) {
		p = strchr(attr[i], '=');
		if (p == 0)
			return "bad query";
		*p++ = 0;
		val[i] = p;
	}

	/* give dns a chance */
	if ((strcmp(attr[0], "dom") == 0 || strcmp(attr[0], "ip") == 0)
	    && val[0]) {
		t = dnsiplookup(val[0], &s);
		if (t) {
			if (qmatch(t, attr, val, n)) {
				qreply(mf, t);
				ndbfree(t);
				return 0;
			}
			ndbfree(t);
		}
	}

	/* first pair is always the key.  It can't be a '*' */
	t = ndbsearch(db, &s, attr[0], val[0]);

	/* search is the and of all the pairs */
	while (t) {
		if (qmatch(t, attr, val, n)) {
			qreply(mf, t);
			ndbfree(t);
			return 0;
		}

		ndbfree(t);
		t = ndbsnext(&s, attr[0], val[0]);
	}

	return "no match";
}
Example #3
0
void
parse(char *file)
{
	int i;
	Ndb *db;
	Ndbtuple *t, *nt, *tt, *ipnett;
	char *p;

	db = ndbopen(file);
	if(db == 0)
		exits("no database");
	while(t = ndbparse(db)){
		for(nt = t; nt; nt = nt->entry){
			if(strcmp(nt->attr, "ip") == 0)
				break;
			if(strcmp(nt->attr, "flavor") == 0
			&& strcmp(nt->val, "console") == 0)
				return;
		}
		if(nt == 0){
			ndbfree(t);
			continue;
		}

		/* dump anything not on our nets */
		ipnett = 0;
		for(tt = t; tt; tt = tt->entry){
			if(strcmp(tt->attr, "ipnet") == 0){
				ipnett = tt;
				break;
			}
			if(strcmp(tt->attr, "dom") == 0){
				i = strlen(tt->val);
				p = tt->val+i-domnamlen;
				if(p >= tt->val && strcmp(p, domname) == 0)
					break;
			}
		}
		if(tt == 0){
			ndbfree(t);
			continue;
		}

		for(; nt; nt = nt->entry){
			if(strcmp(nt->attr, "ip") != 0)
				continue;
			x[nx].it = nt;
			x[nx].nt = ipnett;
			x[nx++].t = t;
		}
	}
}
Example #4
0
/*
 *  return true of the speaker may speak for the user
 *
 *  a speaker may always speak for himself/herself
 */
int
speaksfor(char *speaker, char *user)
{
	Ndbtuple *tp, *ntp;
	Ndbs s;
	int ok;
	char notuser[Maxpath];

	if(strcmp(speaker, user) == 0)
		return 1;

	if(db == 0)
		return 0;

	tp = ndbsearch(db, &s, "hostid", speaker);
	if(tp == 0)
		return 0;

	ok = 0;
	snprint(notuser, sizeof notuser, "!%s", user);
	for(ntp = tp; ntp; ntp = ntp->entry)
		if(strcmp(ntp->attr, "uid") == 0){
			if(strcmp(ntp->val, notuser) == 0){
				ok = 0;
				break;
			}
			if(*ntp->val == '*' || strcmp(ntp->val, user) == 0)
				ok = 1;
		}
	ndbfree(tp);
	return ok;
}
Example #5
0
/*
 *  lookup an ip address
 */
static int
getipaddr(Ndb *db, char *name, uchar *to, Ipinfo *iip)
{
	Ndbtuple *t, *nt;
	char buf[Ndbvlen];
	uchar subnet[IPaddrlen];
	Ndbs s;
	char *attr;

	attr = ipattr(name);
	if(strcmp(attr, "ip") == 0){
		parseip(to, name);
		return 1;
	}

	t = ndbgetval(db, &s, attr, name, "ip", buf);
	if(t){
		/* first look for match on same subnet */
		for(nt = t; nt; nt = nt->entry){
			if(strcmp(nt->attr, "ip") != 0)
				continue;
			parseip(to, nt->val);
			maskip(to, iip->ipmask, subnet);
			if(memcmp(subnet, iip->ipnet, sizeof(subnet)) == 0)
				return 1;
		}

		/* otherwise, just take what we have */
		ndbfree(t);
		parseip(to, buf);
		return 1;
	}
	return 0;
}
Example #6
0
int
nbnameresolve(NbName nbname, uchar *ipaddr)
{
	ulong r, ttl;
	char name[NETPATHLEN];
	NbName copy;
	Ndbtuple *t;

	/* for now, just use dns */
	if (nbremotenametablefind(nbname, ipaddr)) {
//print("%B found in cache\n", nbname);
		return 1;
	}
	if (nbnsfindname(nil, nbname, ipaddr, &ttl) == 0) {
		nbremotenametableadd(nbname, ipaddr, ttl);
		return 1;
	}
	nbnamecpy(copy, nbname);
	copy[NbNameLen - 1] = 0;
	nbmkstringfromname(name, sizeof(name), copy);
	t = dnsquery("/net", name, "ip");
	if (t == nil)
		return 0;
	r = parseip(ipaddr, t->line->val);
	ndbfree(t);
	return r != -1;
}
Example #7
0
/*
 *  look through a containing subset
 */
static Ndbtuple*
subnet(Ndb *db, uint8_t *net, Ndbtuple *f, int prefix)
{
	Ndbs s;
	Ndbtuple *t, *nt, *xt;
	char netstr[128];
	uint8_t mask[IPaddrlen];
	int masklen;

	t = nil;
	sprint(netstr, "%I", net);
	nt = ndbsearch(db, &s, "ip", netstr);
	while(nt != nil){
		xt = ndbfindattr(nt, nt, "ipnet");
		if(xt){
			xt = ndbfindattr(nt, nt, "ipmask");
			if(xt)
				parseipmask(mask, xt->val);
			else
				ipmove(mask, defmask(net));
			masklen = prefixlen(mask);
			if(masklen <= prefix){
				t = ndbconcatenate(t, filter(db, nt, f));
				nt = nil;
			}
		}
		ndbfree(nt);
		nt = ndbsnext(&s, "ip", netstr);
	}
	ndbsetmalloctag(t, getcallerpc(&db));
	return t;
}
Example #8
0
/*
 *  search for a tuple that has the given 'attr=val' and also 'rattr=x'.
 *  copy 'x' into 'buf' and return the whole tuple.
 *
 *  return 0 if not found.
 */
char*
ndbgetvalue(struct ndb *db, struct ndbs *s, char *attr, char *val, char *rattr,
	    struct ndbtuple **pp)
{
	struct ndbtuple *t, *nt;
	char *rv;
	struct ndbs temps;

	if(s == NULL)
		s = &temps;
	if(pp)
		*pp = NULL;
	t = ndbsearch(db, s, attr, val);
	while(t){
		/* first look on same line (closer binding) */
		nt = s->t;
		for(;;){
			if(strcmp(rattr, nt->attr) == 0){
				rv = strdup(nt->val);
				if(pp != NULL)
					*pp = t;
				else
					ndbfree(t);
				return rv;
			}
			nt = nt->line;
			if(nt == s->t)
				break;
		}
		/* search whole tuple */
		for(nt = t; nt; nt = nt->entry){
			if(strcmp(rattr, nt->attr) == 0){
				rv = strdup(nt->val);
				if(pp != NULL)
					*pp = t;
				else
					ndbfree(t);
				return rv;
			}
		}
		ndbfree(t);
		t = ndbsnext(s, attr, val);
	}
	return NULL;
}
Example #9
0
static void
ndbcachefree(Ndbcache *c)
{
	free(c->val);
	free(c->attr);
	if(c->t)
		ndbfree(c->t);
	free(c);
}
Example #10
0
void
search(Ndb *db, char *attr, char *val, char **rattr, int nrattr)
{
	Ndbtuple *t, *tt;

	tt = ndbipinfo(db, attr, val, rattr, nrattr);
	for(t = tt; t; t = t->entry)
		print("%s=%s ", t->attr, t->val);
	print("\n");
	ndbfree(tt);
}
Example #11
0
int
dbctlr(char* name, Vga* vga)
{
	Ndb *db;
	Ndbs s;
	Ndbtuple *tuple;
	Ndbtuple *pcituple;

	db = dbopen(name);

	/*
	 * Search vgadb for a matching BIOS string or PCI id.
	 * If we have both, the BIOS string wins.
	 */
	pcituple = nil;
	for(tuple = ndbsearch(db, &s, "ctlr", ""); tuple; tuple = ndbsnext(&s, "ctlr", "")){
		if(!pcituple && dbpci(vga, tuple))
			pcituple = tuple;
		if(dbbios(vga, tuple)){
			save(vga, tuple);
			if(pcituple && pcituple != tuple)
				ndbfree(pcituple);
			ndbfree(tuple);
			ndbclose(db);
			return 1;
		}
		if(tuple != pcituple)
			ndbfree(tuple);
	}

	if(pcituple){
		save(vga, pcituple);
		ndbfree(pcituple);
	}
	ndbclose(db);
	if(pcituple)
		return 1;
	return 0;
}
Example #12
0
File: cs.c Project: brho/akaros
/*
 *  translate an ip service name into a port number.  If it's a numeric port
 *  number, look for restricted access.
 *
 *  the service '*' needs no translation.
 */
static char *ipserv(struct network *np, char *name, char *buf, int blen)
{
	char *p;
	int alpha = 0;
	int restr = 0;
	char port[10];
	struct ndbtuple *t, *nt;
	struct ndbs s;

	/* '*' means any service */
	if (strcmp(name, "*") == 0) {
		strlcpy(buf, name, blen);
		return buf;
	}

	/*  see if it's numeric or symbolic */
	port[0] = 0;
	for (p = name; *p; p++) {
		if (!isdigit(*p)) {
			if (isalpha(*p) || *p == '-' || *p == '$')
				alpha = 1;
			else
				return 0;
		}
	}
	t = NULL;
	p = NULL;
	if (alpha) {
		p = ndbgetvalue(db, &s, np->net, name, "port", &t);
		if (p == NULL)
			return 0;
	} else {
		/* look up only for tcp ports < 1024 to get the restricted
		 * attribute
		 */
		if (atoi(name) < 1024 && strcmp(np->net, "tcp") == 0)
			p = ndbgetvalue(db, &s, "port", name, "port", &t);
		if (p == NULL)
			p = strdup(name);
	}

	if (t) {
		for (nt = t; nt; nt = nt->entry)
			if (strcmp(nt->attr, "restricted") == 0)
				restr = 1;
		ndbfree(t);
	}
	snprintf(buf, blen, "%s%s", p, restr ? "!r" : "");
	free(p);
	return buf;
}
Example #13
0
File: cs.c Project: brho/akaros
/*
 *  lookup an ip attribute
 */
static int ipattrlookup(struct ndb *db, char *ipa, char *attr, char *val,
                        int vlen)
{

	struct ndbtuple *t, *nt;
	char *alist[2];

	alist[0] = attr;
	t = ndbipinfo(db, "ip", ipa, alist, 1);
	if (t == NULL)
		return 0;
	for (nt = t; nt != NULL; nt = nt->entry) {
		if (strcmp(nt->attr, attr) == 0) {
			strlcpy(val, nt->val, vlen);
			ndbfree(t);
			return 1;
		}
	}

	/* we shouldn't get here */
	ndbfree(t);
	return 0;
}
Example #14
0
File: query.c Project: aahud/harvey
void
search(Ndb *db, char *attr, char *val, char *rattr)
{
	char *p;
	Ndbs s;
	Ndbtuple *t, *nt;

	/* first entry with a matching rattr */
	if(rattr && !all){
		p = ndbgetvalue(db, &s, attr, val, rattr, &t);
		if (multiple)
			prmatch(t, rattr);
		else if(p)
			Bprint(&bout, "%s\n", p);
		ndbfree(t);
		free(p);
		return;
	}

	/* all entries with matching rattrs */
	if(rattr) {
		for(t = ndbsearch(db, &s, attr, val); t != nil;
		    t = ndbsnext(&s, attr, val)){
			prmatch(t, rattr);
			ndbfree(t);
		}
		return;
	}

	/* all entries */
	for(t = ndbsearch(db, &s, attr, val); t; t = ndbsnext(&s, attr, val)){
		for(nt = t; nt; nt = nt->entry)
			Bprint(&bout, "%s=%s ", nt->attr, nt->val);
		Bprint(&bout, "\n");
		ndbfree(t);
	}
}
Example #15
0
/*
 *  the database entry in 'file' indicates the list of files
 *  that makeup the database.  Open each one and search in
 *  the same order.
 */
struct ndb*
ndbopen(char *file)
{

	struct ndb *db, *first, *last;
	struct ndbs s;
	struct ndbtuple *t, *nt;

	if(file == 0)
		file = deffile;
	db = doopen(file);
	if(db == 0) {
		return 0;
	}
	first = last = db;
	t = ndbsearch(db, &s, "database", "");
	fseek(db->b, 0, 0);
	if(t == 0) {
		return db;
	}
	for(nt = t; nt; nt = nt->entry){
		if(strcmp(nt->attr, "file") != 0)
			continue;
		if(strcmp(nt->val, file) == 0){
			/* default file can be reordered in the list */
			if(first->next == 0)
				continue;
			if(strcmp(first->file, file) == 0){
				db = first;
				first = first->next;
				last->next = db;
				db->next = 0;
				last = db;
			}
			continue;
		}
		db = doopen(nt->val);
		if(db == 0)
			continue;
		last->next = db;
		last = db;
	}
	ndbfree(t);
	return first;
}
Example #16
0
File: cs.c Project: brho/akaros
/*
 *  resolve an ip address
 */
static struct ndbtuple *ipresolve(char *attr, char *host)
{
	struct ndbtuple *t, *nt, **l;

	t = iplookup(&network[0], host, "*", 0);
	for (l = &t; *l != NULL;) {
		nt = *l;
		if (strcmp(nt->attr, "ip") != 0) {
			*l = nt->entry;
			nt->entry = NULL;
			ndbfree(nt);
			continue;
		}
		strlcpy(nt->attr, attr, sizeof(nt->attr));
		l = &nt->entry;
	}
	return t;
}
Example #17
0
/* return list of ip addresses for a name */
Ndbtuple*
ndbgetipaddr(Ndb *db, char *val)
{
	char *attr, *p;
	Ndbtuple *it, *first, *last, *next;
	Ndbs s;

	/* already an IP address? */
	attr = ipattr(val);
	if(strcmp(attr, "ip") == 0){
		it = ndbnew("ip", val);
		ndbsetmalloctag(it, getcallerpc(&db));
		return it;
	}

	/* look it up */
	p = ndbgetvalue(db, &s, attr, val, "ip", &it);
	if(p == nil)
		return nil;
	free(p);

	/* remove the non-ip entries */
	first = last = nil;
	for(; it; it = next){
		next = it->entry;
		if(strcmp(it->attr, "ip") == 0){
			if(first == nil)
				first = it;
			else
				last->entry = it;
			it->entry = nil;
			it->line = first;
			last = it;
		} else {
			it->entry = nil;
			ndbfree(it);
		}
	}

	ndbsetmalloctag(first, getcallerpc(&db));
	return first;
}
Example #18
0
static void
recursesubnet(Ndb *db, uchar *addr, uchar *mask, char *attr, char *name, char *name1)
{
	Ndbs s;
	Ndbtuple *t, *nt;
	uchar submask[IPaddrlen], net[IPaddrlen];
	char ip[Ndbvlen];
	int found;

	maskip(addr, mask, net);
	sprint(ip, "%I", net);
	t = ndbsearch(db, &s, "ip", ip);
	if(t == 0)
		return;

	for(nt = t; nt; nt = nt->entry){
		if(strcmp(nt->attr, "ipmask") == 0){
			parseip(submask, nt->val);
			if(memcmp(submask, mask, IPaddrlen) != 0)
				recursesubnet(db, addr, submask, attr, name, name1);
			break;
		}
	}

	if(name[0] == 0){
		found = 0;
		for(nt = t; nt; nt = nt->entry){
			if(strcmp(nt->attr, attr) == 0){
				if(found){
					strcpy(name, nt->val);
					name1[0] = 0;
					found = 1;
				} else {
					strcpy(name1, nt->val);
					break;
				}
			}
		}
	}

	ndbfree(t);
}
Example #19
0
/* remove a from t and free it */
Ndbtuple*
ndbdiscard(Ndbtuple *t, Ndbtuple *a)
{
	Ndbtuple *nt;

	/* unchain a */
	for(nt = t; nt != nil; nt = nt->entry){
		if(nt->line == a)
			nt->line = a->line;
		if(nt->entry == a)
			nt->entry = a->entry;
	}

	/* a may be start of chain */
	if(t == a)
		t = a->entry;

	/* free a */
	a->entry = nil;
	ndbfree(a);

	return t;
}
Example #20
0
/* remove a from t and free it */
struct ndbtuple*
ndbdiscard(struct ndbtuple *t, struct ndbtuple *a)
{
	struct ndbtuple *nt;

	/* unchain a */
	for(nt = t; nt != NULL; nt = nt->entry){
		if(nt->line == a)
			nt->line = a->line;
		if(nt->entry == a)
			nt->entry = a->entry;
	}

	/* a may be start of chain */
	if(t == a)
		t = a->entry;

	/* free a */
	a->entry = NULL;
	ndbfree(a);

	ndbsetmalloctag(t, getcallerpc(&t));
	return t;
}
Example #21
0
/*
 *  lookup a subnet and fill in anything we can
 */
static void
recursesubnet(Ndb *db, uint8_t *mask, Ipinfo *iip, char *fs, char *gw,
	      char *au)
{
	Ndbs s;
	Ndbtuple *t;
	uint8_t submask[IPaddrlen];
	char ip[Ndbvlen];

	memmove(iip->ipmask, mask, 4);
	maskip(iip->ipaddr, iip->ipmask, iip->ipnet);
	sprint(ip, "%I", iip->ipnet);
	t = ndbsearch(db, &s, "ip", ip);
print("%s->", ip);
	if(t){
		/* look for a further subnet */
		if(lookval(t, s.t, "ipmask", ip)){
			parseip(submask, ip);

			/* recurse only if it has changed */
			if(!equivip(submask, mask))
				recursesubnet(db, submask, iip, fs, gw, au);

		}

		/* fill in what we don't have */
		if(gw[0] == 0)
			lookval(t, s.t, "ipgw", gw);
		if(fs[0] == 0)
			lookval(t, s.t, "fs", fs);
		if(au[0] == 0)
			lookval(t, s.t, "auth", au);

		ndbfree(t);
	}
}
Example #22
0
File: cs.c Project: brho/akaros
/*
 *  get the system name
 */
static void ipid(void)
{
	uint8_t addr[6];
	struct ndbtuple *t, *tt;
	char *p, *attr;
	struct ndbs s;
	int f;
	char buf[Maxpath];

	/* use environment, ether addr, or ipaddr to get system name */
	if (mysysname == 0) {
		/*
		 *  environment has priority.
		 *
		 *  on the sgi power the default system name
		 *  is the ip address.  ignore that.
		 *
		 */
		p = getenv("sysname");
		if (p && *p) {
			attr = ipattr(p);
			if (strcmp(attr, "ip") != 0)
				mysysname = strdup(p);
		}

		/*
		 *  the /net/ndb contains what the network
		 *  figured out from DHCP.  use that name if
		 *  there is one.
		 */
		if (mysysname == 0 && netdb != NULL) {
			ndbreopen(netdb);
			for (tt = t = ndbparse(netdb); t != NULL; t = t->entry)
			{
				if (strcmp(t->attr, "sys") == 0) {
					mysysname = strdup(t->val);
					break;
				}
			}
			ndbfree(tt);
		}

		/* next network database, ip address, and ether address to find
		 * a name
		 */
		if (mysysname == 0) {
			t = NULL;
			if (isvalidip(ipa))
				free(ndbgetvalue(db, &s, "ip", ipaddr, "sys",
						 &t));
			if (t == NULL) {
				for (f = 0; f < 3; f++) {
					snprintf(buf, sizeof(buf), "%s/ether%d",
						 mntpt, f);
					if (myetheraddr(addr, buf) < 0)
						continue;
					snprintf(eaddr, sizeof(eaddr), "%E",
						 addr);
					free(ndbgetvalue(db, &s, "ether", eaddr,
							 "sys", &t));
					if (t != NULL)
						break;
				}
			}
			for (tt = t; tt != NULL; tt = tt->entry) {
				if (strcmp(tt->attr, "sys") == 0) {
					mysysname = strdup(tt->val);
					break;
				}
			}
			ndbfree(t);
		}

		/* nothing else worked, use the ip address */
		if (mysysname == 0 && isvalidip(ipa))
			mysysname = strdup(ipaddr);

		/* set /dev/sysname if we now know it */
		if (mysysname) {
			f = open("/dev/sysname", O_RDWR);
			if (f >= 0) {
				write(f, mysysname, strlen(mysysname));
				close(f);
			}
		}
	}
}
Example #23
0
/*
 *  search for a tuple that has the given 'attr=val' and also 'rattr=x'.
 *  copy 'x' into 'buf' and return the whole tuple.
 *
 *  return 0 if not found.
 */
char*
csgetvalue(char *netroot, char *attr, char *val, char *rattr, Ndbtuple **pp)
{
	Ndbtuple *t, *first, *last;
	int n, linefound;
	char line[1024];
	int fd;
	int oops = 0;
	char *rv;

	if(pp)
		*pp = nil;
	rv = nil;

	if(netroot)
		snprint(line, sizeof(line), "%s/cs", netroot);
	else
		strcpy(line, "/net/cs");
	fd = open(line, ORDWR);
	if(fd < 0)
		return 0;
	seek(fd, 0, 0);
	snprint(line, sizeof(line), "!%s=%s %s=*", attr, val, rattr);
	if(write(fd, line, strlen(line)) < 0){
		close(fd);
		return 0;
	}
	seek(fd, 0, 0);

	first = last = 0;
	linefound = 0;
	for(;;){
		n = read(fd, line, sizeof(line)-2);
		if(n <= 0)
			break;
		line[n] = '\n';
		line[n+1] = 0;

		t = _ndbparseline(line);
		if(t == 0)
			continue;
		if(first)
			last->entry = t;
		else
			first = t;
		last = t;

		while(last->entry)
			last = last->entry;

		for(; t; t = t->entry){
			if(linefound == 0){
				if(strcmp(rattr, t->attr) == 0){
					linefound = 1;
					rv = strdup(t->val);
				}
			}
		}
	}
	close(fd);

	if(oops){
		werrstr("buffer too short");
		ndbfree(first);
		return nil;
	}

	if(pp){
		setmalloctag(first, getcallerpc(&netroot));
		*pp = first;
	} else
		ndbfree(first);

	return rv;
}
Example #24
0
static int
dbmonitor(Ndb* db, Mode* mode, char* type, char* size)
{
	Ndbs s;
	Ndbtuple *t, *tuple;
	char *p, attr[Namelen+1], val[Namelen+1], buf[2*Namelen+1];
	int clock, x, i;

	/*
	 * Clock rate hack.
	 * If the size is 'XxYxZ@NMHz' then override the database entry's
	 * 'clock=' with 'N*1000000'.
	 */
	clock = 0;
	strcpy(buf, size);
	if(p = strchr(buf, '@')){
		*p++ = 0;
		if((clock = strtol(p, &p, 0)) && strcmp(p, "MHz") == 0)
			clock *= 1000000;
	}

	memset(mode, 0, sizeof(Mode));

	if((p = strchr(buf, 'x')) && (p = strchr(p+1, 'x'))){
		*p++ = 0;
		mode->z = atoi(p);
	}

	strcpy(attr, type);
	strcpy(val, buf);

	if(p = ndbgetvalue(db, &s, attr, "", "videobw", nil)){
		mode->videobw = atol(p)*1000000UL;
		free(p);
	}

	if(mode->x == 0 && ((mode->x = strtol(val, &p, 0)) == 0 || *p++ != 'x'))
		return 0;
	if(mode->y == 0 && (mode->y = strtol(p, &p, 0)) == 0)
		return 0;
	i = 0;
buggery:
	if((tuple = ndbsearch(db, &s, attr, val)) == 0)
		return 0;

	for(t = tuple->entry; t; t = t->entry){
		if(strcmp(t->attr, "clock") == 0 && mode->frequency == 0)
			mode->frequency = strtod(t->val, 0)*1000000;
		else if(strcmp(t->attr, "defaultclock") == 0 && mode->deffrequency == 0)
			mode->deffrequency = strtod(t->val, 0)*1000000;
		else if(strcmp(t->attr, "ht") == 0 && mode->ht == 0)
			mode->ht = strtol(t->val, 0, 0);
		else if(strcmp(t->attr, "shb") == 0 && mode->shb == 0)
			mode->shb = strtol(t->val, 0, 0);
		else if(strcmp(t->attr, "ehb") == 0 && mode->ehb == 0)
			mode->ehb = strtol(t->val, 0, 0);
		else if(strcmp(t->attr, "shs") == 0 && mode->shs == 0)
			mode->shs = strtol(t->val, 0, 0);
		else if(strcmp(t->attr, "ehs") == 0 && mode->ehs == 0)
			mode->ehs = strtol(t->val, 0, 0);
		else if(strcmp(t->attr, "vt") == 0 && mode->vt == 0)
			mode->vt = strtol(t->val, 0, 0);
		else if(strcmp(t->attr, "vrs") == 0 && mode->vrs == 0)
			mode->vrs = strtol(t->val, 0, 0);
		else if(strcmp(t->attr, "vre") == 0 && mode->vre == 0)
			mode->vre = strtol(t->val, 0, 0);
		else if(strcmp(t->attr, "hsync") == 0)
			mode->hsync = *t->val;
		else if(strcmp(t->attr, "vsync") == 0)
			mode->vsync = *t->val;
		else if(strcmp(t->attr, "interlace") == 0)
			mode->interlace = *t->val;
		else if(strcmp(t->attr, "include") == 0 /*&& strcmp(t->val, val) != 0*/){
			strcpy(attr, t->attr);
			strcpy(val, t->val);
			ndbfree(tuple);
			if(i++ > 5)
				error("dbmonitor: implausible include depth at %s=%s\n", attr, val);
			goto buggery;
		}
		else if(strcmp(t->attr, "include") == 0){
			print("warning: bailed out of infinite loop in attr %s=%s\n", attr, val);
		}
		else
			addattr(&mode->attr, t);
	}
	ndbfree(tuple);

	if((x = strtol(size, &p, 0)) == 0 || x != mode->x || *p++ != 'x')
		return 0;
	if((x = strtol(p, &p, 0)) == 0 || x != mode->y || *p++ != 'x')
		return 0;
	if((x = strtol(p, &p, 0)) == 0 || x != mode->z)
		return 0;

	if(clock)
		mode->frequency = clock;

	return 1;
}
Example #25
0
/*
 *  fill in all the requested attributes for a system.
 *  if the system's entry doesn't have all required,
 *  walk through successively more inclusive networks
 *  for inherited attributes.
 */
Ndbtuple*
ndbipinfo(Ndb *db, char *attr, char *val, char **alist, int n)
{
	Ndbtuple *t, *nt, *f;
	Ndbs s;
	char *ipstr;
	uint8_t net[IPaddrlen], ip[IPaddrlen];
	int prefix, smallestprefix, force;
	int64_t r;

	/* just in case */
	fmtinstall('I', eipfmt);
	fmtinstall('M', eipfmt);

	/* get needed attributes */
	f = mkfilter(n, alist);

	/*
	 *  first look for a matching entry with an ip address
	 */
	t = nil;
	ipstr = ndbgetvalue(db, &s, attr, val, "ip", &nt);
	if(ipstr == nil){
		/* none found, make one up */
		if(strcmp(attr, "ip") != 0) {
			ndbfree(f);
			return nil;	
		}
		t = ndbnew("ip", val);
		t->line = t;
		t->entry = nil;
		r = parseip(net, val);
		if(r == -1)
			ndbfree(t);
	} else {
		/* found one */
		while(nt != nil){
			nt = ndbreorder(nt, s.t);
			t = ndbconcatenate(t, nt);
			nt = ndbsnext(&s, attr, val);
		}
		r = parseip(net, ipstr);
		free(ipstr);
	}
	if(r < 0){
		ndbfree(f);
		return nil;
	}
	ipmove(ip, net);
	t = filter(db, t, f);

	/*
	 *  now go through subnets to fill in any missing attributes
	 */
	if(isv4(net)){
		prefix = 127;
		smallestprefix = 100;
		force = 0;
	} else {
		/* in v6, the last 8 bytes have no structure (we hope) */
		prefix = 64;
		smallestprefix = 2;
		memset(net+8, 0, 8);
		force = 1;
	}

	/*
	 *  to find a containing network, keep turning off
	 *  the lower bit and look for a network with
	 *  that address and a shorter mask.  tedius but
	 *  complete, we may need to find a trick to speed this up.
	 */
	for(; prefix >= smallestprefix; prefix--){
		if(filtercomplete(f))
			break;
		if(!force && (net[prefix/8] & (1<<(7-(prefix%8)))) == 0)
			continue;
		force = 0;
		net[prefix/8] &= ~(1<<(7-(prefix%8)));
		t = ndbconcatenate(t, subnet(db, net, f, prefix));
	}

	/*
	 *  if there's an unfulfilled ipmask, make one up
	 */
	nt = ndbfindattr(f, f, "ipmask");
	if(nt && !(nt->ptr & Fignore)){
		char x[64];

		snprint(x, sizeof(x), "%M", defmask(ip));
		t = ndbconcatenate(t, ndbnew("ipmask", x));
	}

	ndbfree(f);
	ndbsetmalloctag(t, getcallerpc(&db));
	return t;
}
Example #26
0
Mode*
dbmode(char* name, char* type, char* size)
{
	Ndb *db;
	Ndbs s;
	Ndbtuple *t, *tuple;
	Mode *mode;
	char attr[Namelen+1];
	ulong videobw;

	db = dbopen(name);
	mode = alloc(sizeof(Mode));
	strcpy(attr, type);

	videobw = 0;
	/*
	 * Look for the attr=size entry.
	 */
	if(dbmonitor(db, mode, attr, size)){
		strcpy(mode->type, type);
		strcpy(mode->size, size);
		ndbclose(db);
		return mode;
	}

	if(mode->videobw && videobw == 0)	/* we at least found that; save it away */
		videobw = mode->videobw;

	/*
	 * Not found. Look for an attr="" entry and then
	 * for an alias=attr within.
	 */
buggery:
	for(tuple = ndbsearch(db, &s, attr, ""); tuple; tuple = ndbsnext(&s, attr, "")){
		for(t = tuple->entry; t; t = t->entry){
			if(strcmp(t->attr, "alias"))
				continue;
			strcpy(attr, t->val);
			if(dbmonitor(db, mode, attr, size)){
				strcpy(mode->type, type);
				strcpy(mode->size, size);
				ndbfree(tuple);
				ndbclose(db);
				if(videobw)
					mode->videobw = videobw;
				return mode;
			}

			/*
			 * Found an alias but no match for size,
			 * restart looking for attr="" with the
			 * new attr.
			 */
			ndbfree(tuple);
			goto buggery;
		}
		ndbfree(tuple);
	}

	free(mode);
	ndbclose(db);
	return 0;
}
Example #27
0
File: cs.c Project: brho/akaros
/*
 *  lookup a request.  the network "net" means we should pick the
 *  best network to get there.
 */
static int lookup(struct mfile *mf)
{
	struct network *np;
	char *cp;
	struct ndbtuple *nt, *t;
	char reply[Maxreply];
	int i, rv;
	int hack;

	/* open up the standard db files */
	if (db == 0)
		ndbinit();
	if (db == 0)
		error(1, 0, "%s: %r", "can't open mf->network database\n");

	rv = 0;

	if (mf->net == NULL)
		return 0; /* must have been a genquery */

	if (strcmp(mf->net, "net") == 0) {
		/*
		 *  go through set of default nets
		 */
		for (np = mf->nextnet; np; np = np->next) {
			nt = (*np->lookup)(np, mf->host, mf->serv, 1);
			if (nt == NULL)
				continue;
			hack = np->fasttimeouthack && !lookforproto(nt,
								    np->net);
			for (t = nt; mf->nreply < Nreply && t; t = t->entry) {
				cp = (*np->trans)(t, np, mf->serv, mf->rem,
						  hack);
				if (!cp)
					continue;
				/* avoid duplicates */
				for (i = 0; i < mf->nreply; i++)
					if (strcmp(mf->reply[i], cp) == 0)
						break;
				if (i == mf->nreply) {
					/* save the reply */
					mf->replylen[mf->nreply] = strlen(cp);
					mf->reply[mf->nreply++] = cp;
					rv++;
				}
			}
			ndbfree(nt);
			np = np->next;
			break;
		}
		mf->nextnet = np;
		return rv;
	}

	/*
	 *  if not /net, we only get one lookup
	 */
	if (mf->nreply != 0)
		return 0;
	/*
	 *  look for a specific network
	 */
	for (np = netlist; np && np->net != NULL; np++) {
		if (np->fasttimeouthack)
			continue;
		if (strcmp(np->net, mf->net) == 0)
			break;
	}

	if (np && np->net != NULL) {
		/*
		 *  known network
		 */
		nt = (*np->lookup)(np, mf->host, mf->serv, 1);
		for (t = nt; mf->nreply < Nreply && t; t = t->entry) {
			cp = (*np->trans)(t, np, mf->serv, mf->rem, 0);
			if (cp) {
				mf->replylen[mf->nreply] = strlen(cp);
				mf->reply[mf->nreply++] = cp;
				rv++;
			}
		}
		ndbfree(nt);
		return rv;
	}
	/*
	 *  not a known network, don't translate host or service
	 */
	if (mf->serv)
		snprintf(reply, sizeof(reply), "%s/%s/clone %s!%s", mntpt,
			 mf->net, mf->host, mf->serv);
	else
		snprintf(reply, sizeof(reply), "%s/%s/clone %s", mntpt, mf->net,
		         mf->host);
	mf->reply[0] = strdup(reply);
	mf->replylen[0] = strlen(reply);
	mf->nreply = 1;
	return 1;
}
Example #28
0
/* returns 0 on success, error message on failure */
char*
secureidcheck(char *user, char *response)
{
	Packet *req = nil, *resp = nil;
	ulong u[4];
	uchar x[16];
	char *radiussecret;
	char ruser[ 64];
	char dest[3*IPaddrlen+20];
	Secret shared, pass;
	char *rv = "authentication failed";
	Ndbs s;
	Ndbtuple *t, *nt, *tt;
	uchar *ip;
	static Ndb *netdb;

	if(netdb == nil)
		netdb = ndbopen(0);

	/* bad responses make them disable the fob, avoid silly checks */
	if(strlen(response) < 4 || strpbrk(response,"abcdefABCDEF") != nil)
		goto out;

	/* get radius secret */
	radiussecret = ndbgetvalue(db, &s, "radius", "lra-radius", "secret", &t);
	if(radiussecret == nil){
		syslog(0, AUTHLOG, "secureidcheck: nil radius secret: %r");
		goto out;
	}

	/* translate user name if we have to */
	strcpy(ruser, user);
	for(nt = t; nt; nt = nt->entry){
		if(strcmp(nt->attr, "uid") == 0 && strcmp(nt->val, user) == 0)
			for(tt = nt->line; tt != nt; tt = tt->line)
				if(strcmp(tt->attr, "rid") == 0){
					strcpy(ruser, tt->val);
					break;
				}
	}
	ndbfree(t);

	u[0] = fastrand();
	u[1] = fastrand();
	u[2] = fastrand();
	u[3] = fastrand();
	req = newRequest((uchar*)u);
	if(req == nil)
		goto out;
	shared.s = (uchar*)radiussecret;
	shared.len = strlen(radiussecret);
	ip = getipv4addr();
	if(ip == nil){
		syslog(0, AUTHLOG, "no interfaces: %r\n");
		goto out;
	}
	if(setAttribute(req, R_NASIPAddress, ip + IPv4off, 4) < 0)
		goto out;

	if(setAttribute(req, R_UserName, (uchar*)ruser, strlen(ruser)) < 0)
		goto out;
	pass.s = (uchar*)response;
	pass.len = strlen(response);
	hide(&shared, req->authenticator, &pass, x);
	if(setAttribute(req, R_UserPassword, x, 16) < 0)
		goto out;

	t = ndbsearch(netdb, &s, "sys", "lra-radius");
	if(t == nil){
		syslog(0, AUTHLOG, "secureidcheck: nil radius sys search: %r\n");
		goto out;
	}
	for(nt = t; nt; nt = nt->entry){
		if(strcmp(nt->attr, "ip") != 0)
			continue;

		snprint(dest,sizeof dest,"udp!%s!oradius", nt->val);
		resp = rpc(dest, &shared, req);
		if(resp == nil){
			syslog(0, AUTHLOG, "%s nil response", dest);
			continue;
		}
		if(resp->ID != req->ID){
			syslog(0, AUTHLOG, "%s mismatched ID  req=%d resp=%d",
				dest, req->ID, resp->ID);
			freePacket(resp);
			resp = nil;
			continue;
		}
	
		switch(resp->code){
		case R_AccessAccept:
			syslog(0, AUTHLOG, "%s accepted ruser=%s", dest, ruser);
			rv = nil;
			break;
		case R_AccessReject:
			syslog(0, AUTHLOG, "%s rejected ruser=%s %s", dest, ruser, replymsg(resp));
			rv = "secureid failed";
			break;
		case R_AccessChallenge:
			syslog(0, AUTHLOG, "%s challenge ruser=%s %s", dest, ruser, replymsg(resp));
			rv = "secureid out of sync";
			break;
		default:
			syslog(0, AUTHLOG, "%s code=%d ruser=%s %s", dest, resp->code, ruser, replymsg(resp));
			break;
		}
		break; /* we have a proper reply, no need to ask again */
	}
	ndbfree(t);
	free(radiussecret);
out:
	freePacket(req);
	freePacket(resp);
	return rv;
}
Example #29
0
/*
 *  find out everything we can about a system from what has been
 *  specified.
 */
int
ipinfo(Ndb *db, char *etherin, char *ipin, char *name, Ipinfo *iip)
{
	Ndbtuple *t;
	Ndbs s;
	char ether[Ndbvlen];
	char ip[Ndbvlen];
	char fsname[Ndbvlen];
	char gwname[Ndbvlen];
	char auname[Ndbvlen];

	memset(iip, 0, sizeof(Ipinfo));
	fsname[0] = 0;
	gwname[0] = 0;
	auname[0] = 0;

	/*
	 *  look for a matching entry
	 */
	t = 0;
	if(etherin)
		t = ndbgetval(db, &s, "ether", etherin, "ip", ip);
	if(t == 0 && ipin)
		t = ndbsearch(db, &s, "ip", ipin);
	if(t == 0 && name)
		t = ndbgetval(db, &s, ipattr(name), name, "ip", ip);
	if(t){
		/*
		 *  copy in addresses and name
		 */
		if(lookval(t, s.t, "ip", ip))
			parseip(iip->ipaddr, ip);
		if(lookval(t, s.t, "ether", ether))
			parseether(iip->etheraddr, ether);
		lookval(t, s.t, "dom", iip->domain);

		/*
		 *  Look for bootfile, fs, and gateway.
		 *  If necessary, search through all entries for
		 *  this ip address.
		 */
		while(t){
			if(iip->bootf[0] == 0)
				lookval(t, s.t, "bootf", iip->bootf);
			if(fsname[0] == 0)
				lookval(t, s.t, "fs", fsname);
			if(gwname[0] == 0)
				lookval(t, s.t, "ipgw", gwname);
			if(auname[0] == 0)
				lookval(t, s.t, "auth", auname);
			ndbfree(t);
			if(iip->bootf[0] && fsname[0] && gwname[0] && auname[0])
				break;
			t = ndbsnext(&s, "ether", ether);
		}
	} else if(ipin) {
		/*
		 *  copy in addresses (all we know)
		 */
		parseip(iip->ipaddr, ipin);
		if(etherin)
			parseether(iip->etheraddr, etherin);
	} else
		return -1;

	/*
	 *  Look up the client's network and find a subnet mask for it.
	 *  Fill in from the subnet (or net) entry anything we can't figure
	 *  out from the client record.
	 */
	recursesubnet(db, classmask[CLASS(iip->ipaddr)], iip, fsname, gwname, auname);

	/* lookup fs's and gw's ip addresses */
	
	if(fsname[0])
		lookupip(db, fsname, iip->fsip, iip);
	if(gwname[0])
		lookupip(db, gwname, iip->gwip, iip);
	if(auname[0])
		lookupip(db, auname, iip->auip, iip);
	return 0;
}
Example #30
0
File: cs.c Project: brho/akaros
static char *ipinfoquery(struct mfile *mf, char **list, int n)
{
	int i, nresolve;
	int resolve[Maxattr];
	struct ndbtuple *t, *nt, **l;
	char *attr, *val;

	/* skip 'ipinfo' */
	list++;
	n--;

	if (n < 1)
		return "bad query";

	/* get search attribute=value, or assume ip=myipaddr */
	attr = *list;
	val = strchr(attr, '=');
	if (val != NULL) {
		*val++ = 0;
		list++;
		n--;
	} else {
		attr = "ip";
		val = ipaddr;
	}

	if (n < 1)
		return "bad query";

	/*
	 *  don't let ndbipinfo resolve the addresses, we're
	 *  better at it.
	 */
	nresolve = 0;
	for (i = 0; i < n; i++)
		if (*list[i] == '@') { /* @attr=val ? */
			list[i]++;
			resolve[i] = 1; /* we'll resolve it */
			nresolve++;
		} else
			resolve[i] = 0;

	t = ndbipinfo(db, attr, val, list, n);
	if (t == NULL)
		return "no match";

	if (nresolve != 0) {
		for (l = &t; *l != NULL;) {
			nt = *l;

			/* already an address? */
			if (strcmp(ipattr(nt->val), "ip") == 0) {
				l = &(*l)->entry;
				continue;
			}

			/* user wants it resolved? */
			for (i = 0; i < n; i++)
				if (strcmp(list[i], nt->attr) == 0)
					break;
			if (i >= n || resolve[i] == 0) {
				l = &(*l)->entry;
				continue;
			}

			/* resolve address and replace entry */
			*l = ipresolve(nt->attr, nt->val);
			while (*l != NULL)
				l = &(*l)->entry;
			*l = nt->entry;

			nt->entry = NULL;
			ndbfree(nt);
		}
	}

	/* make it all one line */
	for (nt = t; nt != NULL; nt = nt->entry) {
		if (nt->entry == NULL)
			nt->line = t;
		else
			nt->line = nt->entry;
	}

	qreply(mf, t);

	return NULL;
}