Exemplo n.º 1
0
Arquivo: cs.c Projeto: 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;
}
Exemplo n.º 2
0
Arquivo: cs.c Projeto: brho/akaros
/*
 *  lookup a telephone number
 */
static struct ndbtuple *telcolookup(struct network *np, char *host, char *serv,
                                    int nolookup)
{
	struct ndbtuple *t;
	struct ndbs s;

	werrstr("can't translate address");
	free(ndbgetvalue(db, &s, "sys", host, "telco", &t));
	if (t == 0)
		return ndbnew("telco", host);

	return reorder(t, s.t);
}
Exemplo n.º 3
0
static void
expand_meta(DS *ds)
{
	static Ndb *db;
	Ndbs s;
	char *sys, *smtpserver;

	/* can't ask cs, so query database directly. */
	sys = sysname();
	if(db == nil)
		db = ndbopen(0);
	smtpserver = ndbgetvalue(db, &s, "sys", sys, "smtp", nil);
	snprint(ds->host, 128, "%s", smtpserver);
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
struct ndbtuple*
ndbgetval(struct ndb *db,
	  struct ndbs *s, char *attr, char *val, char *rattr, char *buf)
{
	struct ndbtuple *t;
	char *p;

	p = ndbgetvalue(db, s, attr, val, rattr, &t);
	if(p == NULL){
		if(buf != NULL)
			*buf = 0;
	} else {
		if(buf != NULL){
			strncpy(buf, p, Ndbvlen-1);
			buf[Ndbvlen-1] = 0;
		}
		free(p);
	}
	ndbsetmalloctag(t, getcallerpc(&db));
	return t;
}
Exemplo n.º 6
0
Arquivo: query.c Projeto: 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);
	}
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
0
Arquivo: cs.c Projeto: 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);
			}
		}
	}
}
Exemplo n.º 11
0
Arquivo: cs.c Projeto: brho/akaros
/*
 *  lookup (and translate) an ip destination
 */
static struct ndbtuple *iplookup(struct network *np, char *host, char *serv,
                                 int nolookup)
{
	char *attr, *dnsname;
	struct ndbtuple *t, *nt;
	struct ndbs s;
	char ts[Maxservice];
	char dollar[Maxhost];
	uint8_t ip[IPaddrlen];
	uint8_t net[IPaddrlen];
	uint8_t tnet[IPaddrlen];
	struct ipifc *ifc;
	struct iplifc *lifc;

	/*
	 *  start with the service since it's the most likely to fail
	 *  and costs the least
	 */
	werrstr("can't translate address");
	if (serv == 0 || ipserv(np, serv, ts, sizeof(ts)) == 0) {
		werrstr("can't translate service");
		return 0;
	}

	/* for dial strings with no host */
	if (strcmp(host, "*") == 0)
		return ndbnew("ip", "*");

	/*
	 *  hack till we go v6 :: = 0.0.0.0
	 */
	if (strcmp("::", host) == 0)
		return ndbnew("ip", "*");

	/*
	 *  '$' means the rest of the name is an attribute that we
	 *  need to search for
	 */
	if (*host == '$') {
		if (ipattrlookup(db, ipaddr, host + 1, dollar, sizeof(dollar)))
			host = dollar;
	}

	/*
	 *  turn '[ip address]' into just 'ip address'
	 */
	if (*host == '[' && host[strlen(host) - 1] == ']') {
		host++;
		host[strlen(host) - 1] = 0;
	}

	/*
	 *  just accept addresses
	 */
	attr = ipattr(host);
	if (strcmp(attr, "ip") == 0)
		return ndbnew("ip", host);

	/*
	 *  give the domain name server the first opportunity to
	 *  resolve domain names.  if that fails try the database.
	 */
	t = 0;
	werrstr("can't translate address");
	if (strcmp(attr, "dom") == 0)
		t = dnsiplookup(host, &s);
	if (t == 0)
		free(ndbgetvalue(db, &s, attr, host, "ip", &t));
	if (t == 0) {
		dnsname = ndbgetvalue(db, &s, attr, host, "dom", NULL);
		if (dnsname) {
			t = dnsiplookup(dnsname, &s);
			free(dnsname);
		}
	}
	if (t == 0)
		t = dnsiplookup(host, &s);
	if (t == 0)
		return 0;

	/*
	 *  reorder the tuple to have the matched line first and
	 *  save that in the request structure.
	 */
	t = reorder(t, s.t);

	/*
	 * reorder according to our interfaces
	 */
	spinlock_lock(&ipifclock);
	for (ifc = ipifcs; ifc != NULL; ifc = ifc->next) {
		for (lifc = ifc->lifc; lifc != NULL; lifc = lifc->next) {
			maskip(lifc->ip, lifc->mask, net);
			for (nt = t; nt; nt = nt->entry) {
				if (strcmp(nt->attr, "ip") != 0)
					continue;
				parseip(ip, nt->val);
				maskip(ip, lifc->mask, tnet);
				if (memcmp(net, tnet, IPaddrlen) == 0) {
					t = reorder(t, nt);
					spinlock_unlock(&ipifclock);
					return t;
				}
			}
		}
	}
	spinlock_unlock(&ipifclock);

	return t;
}