Index: fedd/federation/access.py
===================================================================
--- fedd/federation/access.py	(revision 4692a16f80ee32a32078e4466dc3a56e9783590d)
+++ fedd/federation/access.py	(revision c324ad3254730c1436e8bd4ac106e49dd7195996)
@@ -132,5 +132,5 @@
 
 
-    def read_access(self, fn, access_obj=None):
+    def read_access(self, fn, access_obj=None, default=[]):
 	"""
 	Read an access DB of the form
@@ -188,4 +188,11 @@
 	    if a.attr in priorities:
 		a.priority = priorities[a.attr]
+
+	# default access mappings
+	for a, v in default:
+	    self.access.append(
+		    access_base.access_attribute(attr=a, value=v, pri=0))
+
+
 
     def write_state(self):
@@ -226,4 +233,43 @@
                 self.log.warning(("[read_state]: No saved state: " + \
                         "Unpickling failed: %s") % e)
+
+    def lookup_access(self, req, fid, filter=None, compare=None): 
+	"""
+	Check all the attributes that this controller knows how to map and see
+	if the requester is allowed to use any of them.  If so return one.
+	Filter defined the objects to check - it's a function that returns true
+	for the objects to check - and cmp defines the order to check them in
+	as the cmp field of sorted().  If filter is None, all possibilities are
+	checked.  If cmp is None, the choices are sorted by priority.
+	"""
+
+	# Import request credentials into this (clone later??)
+	if self.auth.import_credentials(
+		data_list=req.get('abac_credential', [])):
+	    self.auth.save()
+
+	# NB: in the default case (the else), the comparison order is reversed
+	# so numerically larger priorities are checked first.
+	if compare: c = compare
+	else: c = lambda(a, b): cmp(b,a)
+
+	if filter: f = filter
+	else: f = lambda(x): True
+
+	check = sorted([ a for a in self.access if f(a)], cmp=c)
+
+	# Check every attribute that we know how to map and take the first
+	# success.
+	for attr in check:
+	    if self.auth.check_attribute(fid, attr.attr):
+		self.log.debug("Access succeeded for %s %s" % (attr.attr, fid))
+		# XXX: needs to deal with dynamics
+		return copy.copy(attr.value), (False, False, False), \
+			[ fid ]
+	    else:
+		self.log.debug("Access failed for %s %s" % (attr.attr, fid))
+	else:
+            raise service_error(service_error.access, "Access denied")
+
 
 
Index: fedd/federation/authorizer.py
===================================================================
--- fedd/federation/authorizer.py	(revision 4692a16f80ee32a32078e4466dc3a56e9783590d)
+++ fedd/federation/authorizer.py	(revision c324ad3254730c1436e8bd4ac106e49dd7195996)
@@ -6,5 +6,5 @@
 from threading import Lock
 
-from string import join
+from string import join, hexdigits
 
 from fedid import fedid
@@ -240,4 +240,5 @@
 	return abac_authorizer.clean_attr_re.sub('_', attr)
 
+
     def import_credentials(self, file_list=None, data_list=None):
 	if data_list:
@@ -272,4 +273,5 @@
 	    if not isinstance(attr, basestring):
 		attr = "%s" % attr
+
 	    if self.me and self.key:
 		# Create a credential and insert it into context
@@ -338,4 +340,15 @@
 	self.lock.release()
 
+    @staticmethod
+    def starts_with_fedid(attr):
+	"""
+	Return true if the first 40 characters of the string are hex digits
+	followed by a dot.  False otherwise.  Used in check_attribute.
+	"""
+	if attr.find('.') == 40:
+	    return all([ x in hexdigits for x in attr[0:40]])
+	else:
+	    return False
+
 
     def check_attribute(self, name, attr):
@@ -348,13 +361,20 @@
 	    if not isinstance(attr, basestring):
 		attr = "%s" % attr
-	    # Naked attributes are attested by this principal
-	    if attr.find('.') == -1: 
-		a = "%s.%s" % (self.fedid, self.clean_attr(attr))
-	    else: 
+	    # Attributes that start with a fedid only have the part of the
+	    # attribute after the dot cleaned.  Others are completely cleaned
+	    # and have the owner fedid attached.
+	    if self.starts_with_fedid(attr):
 		r, a = attr.split('.',1)
 		a = "%s.%s" % ( r, self.clean_attr(a))
+	    else: 
+		a = "%s.%s" % (self.fedid, self.clean_attr(attr))
+
+	    a = str(a)
+	    n = str("%s" % name)
 
 	    self.lock.acquire()
-	    rv, proof = self.context.query(a, "%s" % name)
+	    # Sigh. Unicode vs swig and swig seems to lose.  Make sure
+	    # everything we pass into ABAC is a str not a unicode.
+	    rv, proof = self.context.query(a, n)
 	    # XXX delete soon
 	    if not rv and attr in self.globals: rv = True
Index: fedd/federation/deter_internal_access.py
===================================================================
--- fedd/federation/deter_internal_access.py	(revision 4692a16f80ee32a32078e4466dc3a56e9783590d)
+++ fedd/federation/deter_internal_access.py	(revision c324ad3254730c1436e8bd4ac106e49dd7195996)
@@ -15,5 +15,5 @@
 from allocate_project import allocate_project_local, allocate_project_remote
 from fedid import fedid, generate_fedid
-from authorizer import authorizer
+from authorizer import authorizer, abac_authorizer
 from service_error import service_error
 from remote_service import xmlrpc_handler, soap_handler, service_caller
@@ -29,4 +29,5 @@
 
 from access import access_base
+from legacy_access import legacy_access
 
 # Make log messages disappear if noone configures a fedd logger
@@ -37,5 +38,5 @@
 fl.addHandler(nullHandler())
 
-class access(access_base):
+class access(access_base, legacy_access):
     @staticmethod
     def parse_vlans(v, log=None):
@@ -81,23 +82,43 @@
         set_log_level(config, "access", self.log)
 
-        if config.has_option("access", "accessdb"):
-            self.read_access(config.get("access", "accessdb"))
-
-	# Add the ownership attributes to the authorizer.  Note that the
-	# indices of the allocation dict are strings, but the attributes are
-	# fedids, so there is a conversion.
-	self.state_lock.acquire()
-	for k in self.state.keys():
-	    for o in self.state[k].get('owners', []):
-		self.auth.set_attribute(o, fedid(hexstr=k))
-	    self.auth.set_attribute(fedid(hexstr=k),fedid(hexstr=k))
-	    # If the allocation has a vlan assigned, remove it from the
-	    # available vlans
-	    v = self.state[k].get('vlan', None)
-	    if v:
-		self.vlans.discard(v)
-	self.state_lock.release()
-
-	self.lookup_access = self.lookup_access_base
+
+	# authorization information
+	self.auth_type = config.get('access', 'auth_type') \
+		or 'legacy'
+	self.auth_dir = config.get('access', 'auth_dir')
+	accessdb = config.get("access", "accessdb")
+	# initialize the authorization system
+	if self.auth_type == 'legacy':
+	    self.access = { }
+	    if accessdb:
+		self.legacy_read_access(accessdb)
+	elif self.auth_type == 'abac':
+	    self.auth = abac_authorizer(load=self.auth_dir)
+	    self.access = [ ]
+	    if accessdb:
+		self.read_access(accessdb, default=[('access', None)])
+	else:
+	    raise service_error(service_error.internal, 
+		    "Unknown auth_type: %s" % self.auth_type)
+
+	if self.auth_type == 'legacy':
+	    # Add the ownership attributes to the authorizer.  Note that the
+	    # indices of the allocation dict are strings, but the attributes are
+	    # fedids, so there is a conversion.
+	    self.state_lock.acquire()
+	    for k in self.state.keys():
+		for o in self.state[k].get('owners', []):
+		    self.auth.set_attribute(o, fedid(hexstr=k))
+		self.auth.set_attribute(fedid(hexstr=k),fedid(hexstr=k))
+		# If the allocation has a vlan assigned, remove it from the
+		# available vlans
+		v = self.state[k].get('vlan', None)
+		if v:
+		    self.vlans.discard(v)
+	    self.state_lock.release()
+
+	    self.lookup_access = self.legacy_lookup_access_base
+	# under ABAC we use access.lookup_access
+
 
 	self.call_GetValue= service_caller('GetValue')
@@ -135,5 +156,5 @@
             raise service_error(service_error.req, "No request!?")
 
-	found, match = self.lookup_access(req, fid)
+	found, match, owners = self.lookup_access(req, fid)
 	# keep track of what's been added
 	allocID, alloc_cert = generate_fedid(subj="alloc", log=self.log)
@@ -143,5 +164,5 @@
 	self.state[aid] = { }
 	self.state[aid]['user'] = found
-	self.state[aid]['owners'] = [ fid ]
+	self.state[aid]['owners'] = owners
 	self.state[aid]['vlan'] = None
 	self.write_state()
@@ -149,4 +170,5 @@
 	self.auth.set_attribute(fid, allocID)
 	self.auth.set_attribute(allocID, allocID)
+	self.auth.save()
 
 	try:
Index: fedd/federation/emulab_access.py
===================================================================
--- fedd/federation/emulab_access.py	(revision 4692a16f80ee32a32078e4466dc3a56e9783590d)
+++ fedd/federation/emulab_access.py	(revision c324ad3254730c1436e8bd4ac106e49dd7195996)
@@ -328,43 +328,4 @@
                 [ fid ]
 
-    def lookup_access(self, req, fid, filter=None, compare=None): 
-	"""
-	Check all the attributes that this controller knows how to map and see
-	if the requester is allowed to use any of them.  If so return one.
-	Filter defined the objects to check - it's a function that returns true
-	for the objects to check - and cmp defines the order to check them in
-	as the cmp field of sorted().  If filter is None, all possibilities are
-	checked.  If cmp is None, the choices are sorted by priority.
-	"""
-
-	# Import request credentials into this (clone later??)
-	if self.auth.import_credentials(
-		data_list=req.get('abac_credential', [])):
-	    self.auth.save()
-
-	# NB: in the default case (the else), the comparison order is reversed
-	# so numerically larger priorities are checked first.
-	if compare: c = compare
-	else: c = lambda(a, b): cmp(b,a)
-
-	if filter: f = filter
-	else: f = lambda(x): True
-
-	check = sorted([ a for a in self.access if f(a)], cmp=c)
-
-	# Check every attribute that we know how to map and take the first
-	# success.
-	for attr in check:
-	    if self.auth.check_attribute(fid, attr.attr):
-		self.log.debug("Access succeeded for %s %s" % (attr.attr, fid))
-		# XXX: needs to deal with dynamics
-		return copy.copy(attr.value), (False, False, False), \
-			[ fid ]
-	    else:
-		self.log.debug("Access failed for %s %s" % (attr.attr, fid))
-	else:
-            raise service_error(service_error.access, "Access denied")
-
-
     def do_project_allocation(self, dyn, project, user):
 	"""
Index: fedd/federation/experiment_control.py
===================================================================
--- fedd/federation/experiment_control.py	(revision 4692a16f80ee32a32078e4466dc3a56e9783590d)
+++ fedd/federation/experiment_control.py	(revision c324ad3254730c1436e8bd4ac106e49dd7195996)
@@ -1999,5 +1999,13 @@
 	    for tb in [ t for t in topo if t not in allocated]:
 		#XXX: ABAC
-		self.get_access(tb, None, tbparams, access_user, masters, tbmap)
+		if self.auth_type =='legacy':
+		    self.get_access(tb, None, tbparams, access_user, 
+			    masters, tbmap)
+		elif self.auth_type == 'abac':
+		    self.get_abac_access(tb, tbparams, fid, masters, tbmap, 
+			    expid, expcert_file)
+		else:
+		    raise service_error(service_error.internal, 
+			    "Unknown auth_type %s" % self.auth_type)
 		allocated[tb] = 1
 		store_keys = topo[tb].get_attribute('store_keys')
@@ -2044,4 +2052,6 @@
             if self.state_filename: self.write_state()
             self.state_lock.release()
+	    if tmpdir and self.cleanup:
+		self.remove_dirs(tmpdir)
             raise e
 
