Index: fedd/federation/access.py
===================================================================
--- fedd/federation/access.py	(revision d2e86f6db04f8ac68bba3cae6ccbbb0e34edd0b6)
+++ fedd/federation/access.py	(revision ee950c2260d0e0d90dc0a6a4d78740b92459415b)
@@ -15,5 +15,4 @@
 
 from util import *
-from allocate_project import allocate_project_local, allocate_project_remote
 from fedid import fedid, generate_fedid
 from authorizer import authorizer
@@ -305,7 +304,5 @@
 	    if access_ok:
 		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 ], proof
+		return copy.copy(attr.value), [ fid ], proof
 	    else:
 		fail_proofs.append(proof)
@@ -451,5 +448,5 @@
 	return (exp, state)
 
-    def build_access_response(self, alloc_id, ap, services, proof):
+    def build_access_response(self, alloc_id, pname, services, proof):
         """
         Create the SOAP response.
@@ -467,9 +464,9 @@
 		'fedAttr': [
 		    { 'attribute': 'domain', 'value': self.domain } , 
-		    { 'attribute': 'project', 'value': 
-			ap['project'].get('name', {}).get('localname', "???") },
 		]
             }
 
+	if pname:
+	    msg['fedAttr'].append({ 'attribute': 'project', 'value': pname })
 	if self.dragon_endpoint:
 	    msg['fedAttr'].append({'attribute': 'dragon',
Index: fedd/federation/allocate_project.py
===================================================================
--- fedd/federation/allocate_project.py	(revision d2e86f6db04f8ac68bba3cae6ccbbb0e34edd0b6)
+++ 	(revision )
@@ -1,784 +1,0 @@
-#!/usr/local/bin/python
-
-import os,sys
-import re
-import random
-import string
-import subprocess
-import threading
-import pickle
-import tempfile
-
-from util import *
-from fedid import fedid
-from remote_service import xmlrpc_handler, soap_handler, service_caller
-from service_error import service_error
-import logging
-
-
-# Configure loggers to dump to /dev/null which avoids errors if calling classes
-# don't configure them.
-class nullHandler(logging.Handler):
-    def emit(self, record): pass
-
-fl = logging.getLogger("fedd.allocate.local")
-fl.addHandler(nullHandler())
-fl = logging.getLogger("fedd.allocate.remote")
-fl.addHandler(nullHandler())
-
-
-class allocate_project_local:
-    """
-    Allocate projects on this machine in response to an access request.
-    """
-    dynamic_projects = 4
-    dynamic_keys= 2
-    confirm_keys = 1
-    none = 0
-
-    levels = {
-	    'dynamic_projects': dynamic_projects,
-	    'dynamic_keys': dynamic_keys,
-	    'confirm_keys': confirm_keys,
-	    'none': none,
-    }
-
-    def __init__(self, config, auth=None):
-	"""
-	Initializer.  Parses a configuration if one is given.
-	"""
-
-	self.debug = config.getboolean("allocate", "debug", False)
-	self.wap = config.get('allocate', 'wap', '/usr/testbed/sbin/wap')
-	self.newproj = config.get('allocate', 'newproj',
-		'/usr/testbed/sbin/newproj')
-	self.mkproj = config.get('allocate', 'mkproj', 
-		'/usr/testbed/sbin/mkproj')
-	self.rmproj = config.get('allocate', 'rmproj',
-		'/usr/testbed/sbin/rmproj')
-	self.rmuser = config.get('allocate', 'rmuser',
-		'/usr/testbed/sbin/rmuser')
-	self.newuser = config.get('allocate', 'newuser',
-		'/usr/testbed/sbin/newuser')
-	self.addpubkey = config.get('allocate', 'addpubkey', 
-		'/usr/testbed/sbin/addpubkey')
-	self.grantnodetype = config.get('allocate', 'grantnodetype', 
-		'/usr/testbed/sbin/grantnodetype')
-	self.confirmkey = config.get('allocate', 'confirmkey', 
-		'/usr/testbed/sbin/taddpubkey')
-	self.user_to_project=config.get("allocate", 'user_to_project',
-		'/usr/local/bin/user_to_project.py')
-	self.allocation_level = config.get("allocate", "allocation_level", 
-		"none")
-	self.log = logging.getLogger("fedd.allocate.local")
-	set_log_level(config, "allocate", self.log)
-
-	if auth:
-	    self.auth = auth
-	else:
-	    auth = authorizer()
-	    log.warn("[allocate] No authorizer passed in, using local one")
-
-	try:
-	    self.allocation_level = \
-		    self.levels[self.allocation_level.strip().lower()]
-	except KeyError:
-	    self.log.error("Bad allocation_level %s.  Defaulting to none" % \
-		    self.allocation_error)
-	    self.allocation_level = self.none
-
-	self.state = { 
-		'keys': set(), 
-		'types': set(),
-		'projects': set(),
-		'users': set(),
-		}
-	self.state_filename = config.get('allocate', 'allocation_state')
-	self.state_lock = threading.Lock()
-	self.read_state()
-
-	access_db = config.get("allocate", "accessdb")
-	if access_db:
-	    try:
-		read_simple_accessdb(access_db, self.auth, 'allocate')
-	    except EnvironmentError, e:
-		raise service_error(service_error.internal,
-			"Error reading accessDB %s: %s" % (access_db, e))
-	    except ValueError:
-		raise service_error(service_error.internal, "%s" % e)
-
-
-	# Internal services are SOAP only
-	self.soap_services = {\
-		"AllocateProject": soap_handler("AllocateProject", 
-		    self.dynamic_project),
-		"StaticProject": soap_handler("StaticProject", 
-		    self.static_project),
-		"ReleaseProject": soap_handler("ReleaseProject", 
-		    self.release_project),
-		}
-	self.xmlrpc_services = { }
-
-    def read_state(self):
-	"""
-	Read a new copy of access state.  Old state is overwritten.
-
-	State format is a simple pickling of the state dictionary.
-	"""
-	if self.state_filename:
-	    try:
-		f = open(self.state_filename, "r")
-		self.state = pickle.load(f)
-		self.log.debug("[allocation]: Read state from %s" % \
-			self.state_filename)
-	    except EnvironmentError, e:
-		self.log.warning(("[allocation]: No saved state: " +\
-			"Can't open %s: %s") % (self.state_filename, e))
-	    except EOFError, e:
-		self.log.warning(("[allocation]: " +\
-			"Empty or damaged state file: %s:") % \
-			self.state_filename)
-	    except pickle.UnpicklingError, e:
-		self.log.warning(("[allocation]: No saved state: " + \
-			"Unpickling failed: %s") % e)
-	    # These should all be in the picked representation, but make sure
-	    if not self.state.has_key('keys'): self.state['keys'] = set()
-	    if not self.state.has_key('types'): self.state['types'] = set()
-	    if not self.state.has_key('projects'):
-		self.state['projects'] = set()
-	    if not self.state.has_key('users'): self.state['users'] = set()
-
-    def write_state(self):
-	if self.state_filename:
-	    try:
-		f = open(self.state_filename, 'w')
-		pickle.dump(self.state, f)
-	    except EnvironmentError, e:
-		self.log.error("Can't write file %s: %s" % \
-			(self.state_filename, e))
-	    except pickle.PicklingError, e:
-		self.log.error("Pickling problem: %s" % e)
-	    except TypeError, e:
-		self.log.error("Pickling problem (TypeError): %s" % e)
-
-
-    def random_string(self, s, n=3):
-	"""Append n random ASCII characters to s and return the string"""
-	rv = s
-	for i in range(0,n):
-	    rv += random.choice(string.ascii_letters)
-	return rv
-
-    def write_attr_xml(self, file, root, lines):
-	"""
-	Write an emulab config file for a dynamic project.
-
-	Format is <root><attribute name=lines[0]>lines[1]</attribute></root>
-	"""
-	# Convert a pair to an attribute line
-	out_attr = lambda a,v : \
-		'<attribute name="%s"><value>%s</value></attribute>' % (a, v)
-
-	f = os.fdopen(file, "w")
-	f.write("<%s>\n" % root)
-	f.write("\n".join([out_attr(*l) for l in lines]))
-	f.write("</%s>\n" % root)
-	f.close()
-
-    def run_cmd(self, cmd, log_prefix='allocate'):
-	"""
-	Run the command passed in.  Cmd is a list containing the words of the
-	command.  Return the exit value from the subprocess - that is 0 on
-	success.  On an error running the command -  python or OS error, raise
-	a service exception.
-	"""
-	try:
-	    dnull = open("/dev/null", "w")
-	except EnvironmentError:
-	    self.log.warn("[run_cmd]: failed to open /dev/null for redirect")
-	    dnull = None
-
-	self.log.debug("[%s]: %s" % (log_prefix, ' '.join(cmd)))
-	if not self.debug:
-	    try:
-		return subprocess.call(cmd, stdout=dnull, stderr=dnull)
-	    except OSError, e:
-		raise service_error(service_error.internal,
-			"Static project subprocess creation error "+ \
-				"[%s] (%s)" %  (cmd[0], e.strerror))
-	else:
-	    return 0
-
-    def confirm_key(self, user, key):
-	"""
-	Call run_cmd to comfirm the key.  Return a boolean rather
-	than the subprocess code.
-	"""
-	return self.run_cmd((self.wap, self.confirmkey, '-C',  
-	    '-u', user, '-k', key)) ==0
-
-    def add_key(self, user, key):
-	"""
-	Call run_cmd to add the key.  Return a boolean rather
-	than the subprocess code.
-	"""
-	return self.run_cmd((self.wap, self.addpubkey, '-u', user,
-	    '-k', key)) == 0
-
-    def remove_key(self, user, key):
-	"""
-	Call run_cmd to remove the key.  Return a boolean rather
-	than the subprocess code.
-	"""
-	return self.run_cmd((self.wap, self.addpubkey, '-R', '-u', user, 
-	    '-k', key)) == 0
-
-    def confirm_access(self, project, type):
-	"""
-	Call run_cmd to comfirm the key.  Return a boolean rather
-	than the subprocess code.
-	"""
-	return self.run_cmd((self.wap, self.grantnodetype, '-C',  
-	    '-p', project, type)) ==0
-
-    def add_access(self, project, type):
-	"""
-	Call run_cmd to add the key.  Return a boolean rather
-	than the subprocess code.
-	"""
-	return self.run_cmd((self.wap, self.grantnodetype, 
-	    '-p', project, type)) == 0
-
-    def remove_access(self, project, type):
-	"""
-	Call run_cmd to remove the key.  Return a boolean rather
-	than the subprocess code.
-	"""
-
-	return self.run_cmd((self.wap, self.grantnodetype, '-R', 
-	    '-p', project, type)) == 0
-
-    def add_project(self, project, projfile):
-	"""
-	Create a project using run_cmd.  This is two steps, and assumes that
-	the relevant XML files are in place and correct.  Make the return value
-	boolean.  Note that if a new user is specified in the XML, that user is
-	created on success.
-	"""
-
-	if self.run_cmd((self.wap, self.newproj, projfile)) == 0:
-	    return self.run_cmd((self.wap, self.mkproj, project)) ==0
-	else:
-	    return False
-
-    def remove_project(self, project):
-	"""
-	Call run_cmd to remove the project.  Make the return value boolean.
-	"""
-
-	return self.run_cmd(self.wap, self.rmproj, project) == 0
-
-   
-    def add_user(self, name, param_file, project):
-	"""
-	Create a user and link them to the given project.  Similar to
-	add_project, this requires a two step approach.  Returns True on success
-	False on failure.
-	"""
-
-	if self.run_cmd((self.wap, self.newuser, param_file)) == 0:
-	   return self.run_cmd((self.wap, self.user_to_project,
-	       user, project)) == 0
-	else:
-	   return False
-
-    def remove_user(self, user):
-	"""
-	Call run_cmd to remove the user.  Make the return value boolean.
-	"""
-
-	return self.run_cmd(self.wap, self.rmuser, user) == 0
-
-
-
-    def dynamic_project(self, req, fedid=None):
-	"""
-	Create a dynamic project with ssh access
-
-	Req includes the project and resources as a dictionary
-	"""
-
-	# Internal calls do not have a fedid parameter (i.e., local calls on
-	# behalf of already vetted fedids)
-	if fedid and not self.auth.check_attribute(fedid, "allocate"):
-	    self.log.debug("[allocate] Access denied (%s)" % fedid)
-	    raise service_error(service_error.access, "Access Denied")
-
-	if self.allocation_level < self.dynamic_projects:
-	    raise service_error(service_error.access, 
-		    "[dynamic_project] dynamic project allocation not " + \
-			    "permitted: check allocation level")
-	# tempfiles for the parameter files
-	cuf, create_userfile = tempfile.mkstemp(prefix="usr", suffix=".xml",
-		dir="/tmp")
-	suf, service_userfile = tempfile.mkstemp(prefix="usr", suffix=".xml",
-		dir="/tmp")
-	pf, projfile = tempfile.mkstemp(prefix="proj", suffix=".xml",
-		dir="/tmp")
-
-	if req.has_key('AllocateProjectRequestBody'):
-	    proj = req['AllocateProjectRequestBody'].get('project', None)
-	    if not proj:
-		raise service_error(service_error.req, 
-			"Badly formed allocation request")
-	    resources = req['AllocateProjectRequestBody'].get('resources', { })
-	else:
-	    raise service_error(service_error.req, 
-		    "Badly formed allocation request")
-	# Take the first user and ssh key
-	name = proj.get('name', None) or self.random_string("proj",4)
-	user = proj.get('user', [])
-
-	uname = { }
-	ssh = { }
-	for u in user:
-	    role = u.get('role', None)
-	    if not role: continue
-	    if u.has_key('userID'):
-		uid = u['userID']
-		uname[role] = uid.get('localname', None) or \
-			uid.get('kerberosUsername', None) or \
-			uid.get('uri', None)
-		if uname[role] == None:
-		    raise service_error(service_error.req, "No ID for user")
-	    else:
-		uname[role] = self.random_string("user", 3)
-
-	    access = u.get('access', None)
-	    if access:
-		# XXX collect and call addpubkey later, for now use first one.
-		for a in access:
-		    ssh[role] = a.get('sshPubkey', None)
-		    if ssh: break
-		else:
-		    raise service_error(service_error.req,
-			    "No SSH key for user %s" % uname[role])
-	    else:
-		raise service_error(service_error.req,
-			"No access mechanisms for for user %s" % uname[role])
-
-	if not (uname.has_key('experimentCreation') and \
-		uname.has_key('serviceAccess')):
-	    raise service_error(service_error.req,
-		    "Must specify both user roles")
-	
-
-	create_user_fields = [
-		("name", "Federation User %s" % uname['experimentCreation']),
-		("email", "%s-fed@isi.deterlab.net" % \
-			uname['experimentCreation']),
-		("password", self.random_string("", 8)),
-		("login", uname['experimentCreation']),
-		("address", "4676 Admiralty"),
-		("city", "Marina del Rey"),
-		("state", "CA"),
-		("zip", "90292"),
-		("country", "USA"),
-		("phone", "310-448-9190"),
-		("title", "None"),
-		("affiliation", "USC/ISI"),
-		("pubkey", ssh['experimentCreation'])
-	]
-
-	service_user_fields = [
-		("name", "Federation User %s" % uname['serviceAccess']),
-		("email", "%s-fed@isi.deterlab.net" % uname['serviceAccess']),
-		("password", self.random_string("", 8)),
-		("login", uname['serviceAccess']),
-		("address", "4676 Admiralty"),
-		("city", "Marina del Rey"),
-		("state", "CA"),
-		("zip", "90292"),
-		("country", "USA"),
-		("phone", "310-448-9190"),
-		("title", "None"),
-		("affiliation", "USC/ISI"),
-		("pubkey", ssh['serviceAccess'])
-	]
-
-	proj_fields = [
-		("name", name),
-		("short description", "dynamic federated project"),
-		("URL", "http://www.isi.edu/~faber"),
-		("funders", "USC/USU"),
-		("long description", "Federation access control"),
-		("public", "1"),
-		("num_pcs", "100"),
-		("linkedtous", "1"),
-		("newuser_xml", create_userfile)
-	]
-	
-
-
-	added_projects = [ ]
-	added_users = [ ]
-	added_types = [ ]
-
-	self.state_lock.acquire()
-	try:
-	    # Write out the files
-	    self.write_attr_xml(cuf, "user", create_user_fields)
-	    self.write_attr_xml(suf, "user", service_user_fields)
-	    self.write_attr_xml(pf, "project", proj_fields)
-	    try:
-		if self.add_project(name, projfile):
-		    # add_project adds a user as well in this case
-		    added_projects.append(name)
-		    added_users.append(uname['createExperiment'])
-		    self.state['projects'].add(name)
-		    self.state['users'].add(uname['createExperiment'])
-
-		    if self.add_user(uname['serviceAccess'], 
-			    service_userfile, name):
-			added_users.append(uname['serviceAccess'])
-			self.state['users'].add(uname['serviceAccess'])
-		    else:
-			raise service_error("Unable to create user %s" % \
-				uname['serviceAccess'])
-		else:
-		    raise service_error("Unable to create project/user %s/%s" % \
-			    (name, uname['experimentCreation']))
-
-		nodes = resources.get('node', [])
-		# Grant access to restricted resources.  This is simpler than
-		# the corresponding loop from static_project because this is a
-		# clean slate.
-		for nt in [ h for n in nodes\
-			if n.has_key('hardware')\
-			    for h in n['hardware'] ] :
-		    if self.add_access(name, nt):
-			self.state['types'].add((name, nt))
-			added_types.append((name, nt))
-		    else:
-			raise service_error(service_error.internal,
-				"Failed to add access for %s to %s"\
-					% (name, nt))
-	    except service_error, e:
-		# Something failed.  Back out the partial allocation as
-		# completely as possible and re-raise the error.
-		for p, t in added_types:
-		    self.state['types'].discard((p, t))
-		    try:
-			self.remove_access(p, t)
-		    except service_error:
-			pass
-		for u in added_users:
-		    self.state['users'].discard(u)
-		    try:
-			self.remove_user(u)
-		    except service_error:
-			pass
-
-		for p in added_projects:
-		    self.state['projects'].discard(p)
-		    try:
-			self.remove_project(p)
-		    except service_error:
-			pass
-		self.state_lock.release()
-		raise e
-	finally:
-	    # Clean up tempfiles
-	    os.unlink(create_userfile)
-	    os.unlink(service_userfile)
-	    os.unlink(projfile)
-
-	rv = {\
-	    'project': {\
-		'name': { 'localname': name }, 
-		'user' : [\
-		    {\
-			'userID': { 'localname' : uname['experimentCreation'] },
-			'access': [ {'sshPubkey': ssh['experimentCreation'] } ],
-			'role': 'experimentCreation',
-		    }, \
-		    {\
-			'userID': { 'localname' : uname['serviceAccess'] },
-			'access': [ { 'sshPubkey' : ssh['serviceAccess'] } ], 
-			'role': 'serviceAccess',
-		    } \
-		]\
-	    }\
-	}
-	return rv
-
-    def static_project(self, req, fedid=None):
-	"""
-	Be certain that the local project in the request has access to the
-	proper resources and users have correct keys.  Add them if necessary.
-	"""
-	# Internal calls do not have a fedid parameter (i.e., local calls on
-	# behalf of already vetted fedids)
-	if fedid and not self.auth.check_attribute(fedid, "allocate"):
-	    self.log.debug("[allocate] Access denied (%s)" % fedid)
-	    raise service_error(service_error.access, "Access Denied")
-	# While we should be more careful about this, for the short term, add
-	# the keys to the specified users.
-
-	try:
-	    users = req['StaticProjectRequestBody']['project']['user']
-	    pname = req['StaticProjectRequestBody']['project']\
-		    ['name']['localname']
-	    resources = req['StaticProjectRequestBody'].get('resources', { })
-	except KeyError:
-	    raise service_error(service_error.req, "Badly formed request")
-
-	added_keys = [ ]
-	added_types = [ ]
-	# Keep track of changes made to the system
-	self.state_lock.acquire()
-
-	try:
-	    for u in users:
-		try:
-		    name = u['userID']['localname']
-		except KeyError:
-		    raise service_error(service_error.req, "Badly formed user")
-		for sk in [ k['sshPubkey'] for k in u.get('access', []) \
-			if k.has_key('sshPubkey')]:
-		    if self.allocation_level >=self.confirm_keys:
-			key_ok = self.confirm_key(name, sk)
-			if not key_ok:
-			    if self.allocation_level >= self.dynamic_keys:
-				if self.add_key(name, sk):
-				    self.state['keys'].add((name, sk))
-				    added_keys.append((name, sk))
-				else:
-				    raise service_error(service_error.internal,
-					    "Failed to add key for %s" % name)
-			    else:
-				raise service_error(service_error.internal,
-					"Failed to confirm key for %s" % name)
-		    else:
-			self.log.warning("[static_project] no checking of " + \
-			    "static keys")
-
-	    # Grant access to any resources in the request.  The
-	    # list comprehension pulls out the hardware types in the node
-	    # entries in the resources list.  The access module knows to
-	    # only send resources that are restricted and needed by the
-	    # project.
-	    nodes = resources.get('node', [])
-	    for nt in [ h for n in nodes\
-		    if n.has_key('hardware')\
-			for h in n['hardware'] ] :
-		if self.allocation_level >= self.confirm_keys:
-		    access_ok = self.confirm_access(pname, nt)
-		    if not access_ok:
-			if self.allocation_level >= self.dynamic_keys:
-			    if self.add_access(pname, nt):
-				self.state['types'].add((pname, nt))
-				added_types.append((pname, nt))
-			    else:
-				raise service_error(service_error.internal,
-					"Failed to add access for %s to %s"\
-						% (pname, nt))
-			else:
-			    raise service_error(service_error.internal,
-				    "Failed to confirm access for %s to %s"\
-					    % (pname, nt))
-		else:
-		    self.log.warning("[static_project] no checking of " + \
-			"node access")
-	except service_error, e:
-	    # Do our best to clean up partial allocation and reraise the
-	    # error.  Do our best to make sure that both allocation state and
-	    # testbed state is restored.
-	    for u, k in added_keys:
-		self.state['keys'].discard((u, k))
-		try:
-		    self.remove_key(u, k)
-		except service_error:
-		    pass
-	    for p, t in added_types:
-		self.state['types'].discard((p, t))
-		try:
-		    self.remove_access(p, t)
-		except service_error:
-		    pass
-	    self.state_lock.release()
-	    raise e
-	# All is well, save state and release the lock
-	self.write_state()
-	self.state_lock.release()
-	# return { 'project': req['StaticProjectRequestBody']['project']}
-	return req['StaticProjectRequestBody']
-
-    def release_project(self, req, fedid=None):
-	"""
-	Remove user keys from users and delete dynamic projects.
-
-	Only keys this service created are deleted and there are
-	similar protections for projects.
-	"""
-	# Internal calls do not have a fedid parameter (i.e., local calls on
-	# behalf of already vetted fedids)
-	if fedid and not self.auth.check_attribute(fedid, "allocate"):
-	    self.log.debug("[allocate] Access denied (%s)" % fedid)
-	    raise service_error(service_error.access, "Access Denied")
-
-	pname = None
-	users = []
-	nodes = [ ]
-
-	try:
-	    if req['ReleaseProjectRequestBody']['project'].has_key('name'):
-		pname = req['ReleaseProjectRequestBody']['project']\
-			['name']['localname']
-	    if req['ReleaseProjectRequestBody']['project'].has_key('user'):
-		users = req['ReleaseProjectRequestBody']['project']['user']
-	    if req['ReleaseProjectRequestBody'].has_key('resources'):
-		nodes = req['ReleaseProjectRequestBody']\
-			['resources'].get('node', [])
-	except KeyError:
-	    raise service_error(service_error.req, "Badly formed request")
-
-	if nodes and not pname:
-	    raise service_error(service_error.req, 
-		    "Badly formed request (nodes without project)")
-
-	self.state_lock.acquire()
-	try:
-	    for nt in [ h for n in nodes if n.has_key('hardware')\
-		    for h in n['hardware'] ] :
-		if (pname, nt ) in self.state['types']:
-		    self.remove_access(pname, nt)
-		    self.state['types'].discard((pname, nt))
-
-	    for u in users:
-		try:
-		    name = u['userID']['localname']
-		except KeyError:
-		    raise service_error(service_error.req, "Badly formed user")
-		if name in self.state['users']:
-		    # If we created this user, discard the user, keys and all
-		    self.remove_user(name)
-		    self.state['users'].discard(name)
-		else:
-		    # If not, just strip any keys we added
-		    for sk in [ k['sshPubkey'] for k in u.get('access', []) \
-			    if k.has_key('sshPubkey')]:
-			if (name, sk) in self.state['keys']:
-			    self.remove_key(name, sk)
-			    self.state['keys'].discard((name, sk))
-	    if pname in self.state['projects']:
-		self.remove_project(pname)
-		self.state['projects'].discard(pname)
-
-	except service_error, e:
-	    self.write_state()
-	    self.state_lock.release()
-	    raise e
-	self.write_state()
-	self.state_lock.release()
-
-	return { 'project': req['ReleaseProjectRequestBody']['project']}
-
-class allocate_project_remote:
-    """
-    Allocate projects on a remote machine using the internal SOAP interface
-    """
-    class proxy(service_caller):
-	"""
-	This class is a proxy functor (callable) that has the same signature as
-	a function called by soap_handler or xmlrpc_handler, but that used the
-	service_caller class to call the function remotely.
-	"""
-
-	def __init__(self, url, cert_file, cert_pwd, trusted_certs, auth, 
-		method):
-	    service_caller.__init__(self, method)
-	    self.url = url
-	    self.cert_file = cert_file
-	    self.cert_pwd = cert_pwd
-	    self.trusted_certs = trusted_certs
-	    self.request_body__name = "%sRequestBody" % method
-	    self.resp_name = "%sResponseBody" % method
-	    self.auth = auth
-	    # Calling the proxy object directly invokes the proxy_call method,
-	    # not the service_call method.
-	    self.__call__ = self.proxy_call
-	    
-
-	# Define the proxy, NB, the parameters to make_proxy are visible to the
-	# definition of proxy.
-	def proxy_call(self, req, fid=None):
-	    """
-	    Send req on to a remote project instantiator.
-
-	    Req is just the message to be sent.  This function re-wraps it.
-	    It also rethrows any faults.
-	    """
-
-	    if req.has_key(self.request_body_name):
-		req = req[self.request_body_name]
-	    else:
-		raise service_error(service_error.req, "Bad formated request");
-
-	    try:
-		r = self.call_service(self.url, req, self.cert_file,
-			self.cert_pwd, self.trusted_certs)
-	    except service_error, e:
-		if e.code == service_error.connect:
-		    raise service_error(service_error.internal, 
-			    "Cannot connect to internal service: (%d) %s" % \
-				    (e.code, e.desc))
-		else: raise
-	    if r.has_key(self.resp_name):
-		return r[self.resp_name]
-	    else:
-		raise service_error(service_error.protocol, 
-			"Bad proxy response")
-
-    # back to defining the allocate_project_remote class
-    def __init__(self, config, auth=None):
-	"""
-	Initializer.  Parses a configuration if one is given.
-	"""
-
-	self.debug = config.get("allocate", "debug", False)
-	self.url = config.get("allocate", "uri", "")
-
-	# Keep cert file and password coming from the same source
-	self.cert_file = config.get("allocate", "cert_file", None)
-	if self.cert_file:
-	    self.cert_pwd = config.get("allocate", "cert_pwd", None)
-	else:
-	    self.cert_file = config.get("globals", "cert_file", None)
-	    self.cert_pwd = config.get("globals", "cert_pwd", None)
-
-	self.trusted_certs = config.get("allocate", "trusted_certs", None) or \
-		config.get("globals", "trusted_certs")
-
-	self.soap_services = { }
-	self.xmlrpc_services = { }
-	self.log = logging.getLogger("fedd.allocate.remote")
-	set_log_level(config, "allocate", self.log)
-
-	if auth:
-	    self.auth = auth
-	else:
-	    auth = authorizer()
-	    log.warn("[allocate] No authorizer passed in, using local one")
-
-	# The specializations of the proxy functions
-	self.dynamic_project = self.proxy(self.url, self.cert_file, 
-		self.cert_pwd, self.trusted_certs, self.auth, 
-		"AllocateProject")
-	self.static_project = self.proxy(self.url, self.cert_file, 
-		self.cert_pwd, self.trusted_certs, self.auth, 
-		"StaticProject")
-	self.release_project = self.proxy(self.url, self.cert_file,
-		self.cert_pwd, self.trusted_certs, self.auth, 
-		"ReleaseProject")
-
Index: fedd/federation/deter_internal_access.py
===================================================================
--- fedd/federation/deter_internal_access.py	(revision d2e86f6db04f8ac68bba3cae6ccbbb0e34edd0b6)
+++ fedd/federation/deter_internal_access.py	(revision ee950c2260d0e0d90dc0a6a4d78740b92459415b)
@@ -13,5 +13,4 @@
 
 from util import *
-from allocate_project import allocate_project_local, allocate_project_remote
 from fedid import fedid, generate_fedid
 from authorizer import authorizer, abac_authorizer
@@ -27,5 +26,4 @@
 
 from access import access_base
-from legacy_access import legacy_access
 
 # Make log messages disappear if noone configures a fedd logger
@@ -36,5 +34,5 @@
 fl.addHandler(nullHandler())
 
-class access(access_base, legacy_access):
+class access(access_base):
     @staticmethod
     def parse_vlans(v, log=None):
@@ -83,13 +81,9 @@
 	# authorization information
 	self.auth_type = config.get('access', 'auth_type') \
-		or 'legacy'
+		or 'abac'
 	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':
+	if self.auth_type == 'abac':
 	    self.auth = abac_authorizer(load=self.auth_dir)
 	    self.access = [ ]
@@ -99,24 +93,4 @@
 	    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')
Index: fedd/federation/dragon_access.py
===================================================================
--- fedd/federation/dragon_access.py	(revision d2e86f6db04f8ac68bba3cae6ccbbb0e34edd0b6)
+++ fedd/federation/dragon_access.py	(revision ee950c2260d0e0d90dc0a6a4d78740b92459415b)
@@ -12,8 +12,6 @@
 from subprocess import Popen, call, PIPE, STDOUT
 from access import access_base
-from legacy_access import legacy_access
 
 from util import *
-from allocate_project import allocate_project_local, allocate_project_remote
 from fedid import fedid, generate_fedid
 from authorizer import authorizer, abac_authorizer
@@ -36,5 +34,5 @@
 fl.addHandler(nullHandler())
 
-class access(access_base, legacy_access):
+class access(access_base):
     """
     The implementation of access control based on mapping users to projects.
@@ -63,23 +61,9 @@
 	# authorization information
 	self.auth_type = config.get('access', 'auth_type') \
-		or 'legacy'
+		or 'abac'
 	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, self.make_repo)
-	    # 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))
-	    self.state_lock.release()
-	    self.lookup_access = self.legacy_lookup_access_base
-	elif self.auth_type == 'abac':
+	if self.auth_type == 'abac':
 	    self.auth = abac_authorizer(load=self.auth_dir)
 	    self.access = [ ]
Index: fedd/federation/emulab_access.py
===================================================================
--- fedd/federation/emulab_access.py	(revision d2e86f6db04f8ac68bba3cae6ccbbb0e34edd0b6)
+++ fedd/federation/emulab_access.py	(revision ee950c2260d0e0d90dc0a6a4d78740b92459415b)
@@ -16,8 +16,6 @@
 
 from access import access_base
-from legacy_access import legacy_access
 
 from util import *
-from allocate_project import allocate_project_local, allocate_project_remote
 from fedid import fedid, generate_fedid
 from authorizer import authorizer, abac_authorizer
@@ -42,5 +40,5 @@
 fl.addHandler(nullHandler())
 
-class access(access_base, legacy_access):
+class access(access_base):
     """
     The implementation of access control based on mapping users to projects.
@@ -109,13 +107,9 @@
 	# authorization information
 	self.auth_type = config.get('access', 'auth_type') \
-		or 'legacy'
+		or 'abac'
 	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, self.legacy_access_tuple)
-	elif self.auth_type == 'abac':
+	if self.auth_type == 'abac':
 	    self.auth = abac_authorizer(load=self.auth_dir)
 	    self.access = [ ]
@@ -128,22 +122,6 @@
 	# read_state in the base_class
 	self.state_lock.acquire()
-	for a  in ('allocation', 'projects', 'keys', 'types'):
-	    if a not in self.state:
-		self.state[a] = { }
+	if 'allocation' not in self.state: self.state['allocation']= { }
 	self.allocation = self.state['allocation']
-	self.projects = self.state['projects']
-	self.keys = self.state['keys']
-	self.types = self.state['types']
-	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.
-	    for k in self.allocation.keys():
-		for o in self.allocation[k].get('owners', []):
-		    self.auth.set_attribute(o, fedid(hexstr=k))
-		if self.allocation[k].has_key('userconfig'):
-		    sfid = self.allocation[k]['userconfig']
-		    fid = fedid(hexstr=sfid)
-		    self.auth.set_attribute(fid, "/%s" % sfid)
 	self.state_lock.release()
 	self.exports = {
@@ -195,47 +173,4 @@
 	self.call_GetValue = service_caller('GetValue', log=self.log)
 
-        if not config.has_option("allocate", "uri"):
-            self.allocate_project = \
-                allocate_project_local(config, auth)
-        else:
-            self.allocate_project = \
-                allocate_project_remote(config, auth)
-
-
-        # If the project allocator exports services, put them in this object's
-        # maps so that classes that instantiate this can call the services.
-        self.soap_services.update(self.allocate_project.soap_services)
-        self.xmlrpc_services.update(self.allocate_project.xmlrpc_services)
-
-    @staticmethod
-    def legacy_access_tuple(str):
-	"""
-	Convert a string of the form (id[:resources:resouces], id, id) into a
-	tuple of the form (project, user, user) where users may be names or
-	fedids.  The resources strings are obsolete and ignored.
-	"""
-        def parse_name(n):
-            if n.startswith('fedid:'): return fedid(hexstr=n[len('fedid:'):])
-            else: return n
-
-	str = str.strip()
-	if str.startswith('(') and str.endswith(')'):
-	    str = str[1:-1]
-	    names = [ s.strip() for s in str.split(",")]
-	    if len(names) > 3:
-		raise self.parse_error("More than three fields in name")
-	    first = names[0].split(":")
-	    if first == 'fedid:':
-		del first[0]
-		first[0] = fedid(hexstr=first[0])
-	    names[0] = first[0]
-
-	    for i in range(1,2):
-		names[i] = parse_name(names[i])
-
-	    return tuple(names)
-	else:
-	    raise self.parse_error('Bad mapping (unbalanced parens)')
-
     @staticmethod
     def access_tuple(str):
@@ -243,6 +178,5 @@
 	Convert a string of the form (id, id) into an access_project.  This is
 	called by read_access to convert to local attributes.  It returns
-	a tuple of the form (project, user, user) where the two users are
-	always the same.
+	a tuple of the form (project, user).
 	"""
 
@@ -251,5 +185,5 @@
 	    # The slice takes the parens off the string.
 	    proj, user = str[1:-1].split(',')
-	    return (proj.strip(), user.strip(), user.strip())
+	    return (proj.strip(), user.strip())
 	else:
 	    raise self.parse_error(
@@ -258,167 +192,13 @@
     # RequestAccess support routines
 
-    def legacy_lookup_access(self, req, fid):
-        """
-	Look up the local access control information mapped to this fedid and
-	credentials.  In this case it is a (project, create_user, access_user)
-	triple, and a triple of three booleans indicating which, if any will
-	need to be dynamically created.  Finally a list of owners for that
-	allocation is returned.
-
-	lookup_access_base pulls the first triple out, and it is parsed by this
-	routine into the boolean map.  Owners is always the controlling fedid.
-        """
-        # Return values
-        rp = None
-        ru = None
-        # This maps a valid user to the Emulab projects and users to use
-        found, match = self.legacy_lookup_access_base(req, fid)
-	tb, project, user = match
-        
-        if found == None:
-            raise service_error(service_error.access,
-                    "Access denied - cannot map access")
-
-        # resolve <dynamic> and <same> in found
-        dyn_proj = False
-        dyn_create_user = False
-        dyn_service_user = False
-
-        if found[0] == "<same>":
-            if project != None:
-                rp = project
-            else : 
-                raise service_error(\
-                        service_error.server_config,
-                        "Project matched <same> when no project given")
-        elif found[0] == "<dynamic>":
-            rp = None
-            dyn_proj = True
-        else:
-            rp = found[0]
-
-        if found[1] == "<same>":
-            if user_match == "<any>":
-                if user != None: rcu = user[0]
-                else: raise service_error(\
-                        service_error.server_config,
-                        "Matched <same> on anonymous request")
-            else:
-                rcu = user_match
-        elif found[1] == "<dynamic>":
-            rcu = None
-            dyn_create_user = True
-        else:
-            rcu = found[1]
-        
-        if found[2] == "<same>":
-            if user_match == "<any>":
-                if user != None: rsu = user[0]
-                else: raise service_error(\
-                        service_error.server_config,
-                        "Matched <same> on anonymous request")
-            else:
-                rsu = user_match
-        elif found[2] == "<dynamic>":
-            rsu = None
-            dyn_service_user = True
-        else:
-            rsu = found[2]
-
-        return (rp, rcu, rsu), (dyn_create_user, dyn_service_user, dyn_proj),\
-                [ fid ]
-
-    def do_project_allocation(self, dyn, project, user):
-	"""
-	Call the project allocation routines and return the info.
-	"""
-	if dyn: 
-	    # Compose the dynamic project request 
-	    # (only dynamic, dynamic currently allowed)
-	    preq = { 'AllocateProjectRequestBody': \
-			{ 'project' : {\
-			    'user': [ \
-			    { \
-				'access': [ { 
-				    'sshPubkey': self.ssh_pubkey_file } ],
-				 'role': "serviceAccess",\
-			    }, \
-			    { \
-				'access': [ { 
-				    'sshPubkey': self.ssh_pubkey_file } ],
-				 'role': "experimentCreation",\
-			    }, \
-			    ], \
-			    }\
-			}\
-		    }
-	    return self.allocate_project.dynamic_project(preq)
-	else:
-	    preq = {'StaticProjectRequestBody' : \
-		    { 'project': \
-			{ 'name' : { 'localname' : project },\
-			  'user' : [ \
-			    {\
-				'userID': { 'localname' : user }, \
-				'access': [ { 
-				    'sshPubkey': self.ssh_pubkey_file } ],
-				'role': 'experimentCreation'\
-			    },\
-			    {\
-				'userID': { 'localname' : user}, \
-				'access': [ { 
-				    'sshPubkey': self.ssh_pubkey_file } ],
-				'role': 'serviceAccess'\
-			    },\
-			]}\
-		    }\
-	    }
-	    return self.allocate_project.static_project(preq)
-
-    def save_project_state(self, aid, ap, dyn, owners):
-	"""
-	Parse out and save the information relevant to the project created for
-	this experiment.  That info is largely in ap and owners.  dyn indicates
-	that the project was created dynamically.  Return the user and project
-	names.
+    def save_project_state(self, aid, pname, uname, owners):
+	"""
+	Save the project, user, and owners associated with this allocation.
+	This creates the allocation entry.
 	"""
 	self.state_lock.acquire()
 	self.allocation[aid] = { }
-	self.allocation[aid]['auth'] = set()
-	try:
-	    pname = ap['project']['name']['localname']
-	except KeyError:
-	    pname = None
-
-	if dyn:
-	    if not pname:
-		self.state_lock.release()
-		raise service_error(service_error.internal,
-			"Misformed allocation response?")
-	    if pname in self.projects: self.projects[pname] += 1
-	    else: self.projects[pname] = 1
-	    self.allocation[aid]['project'] = pname
-	else:
-	    # sproject is a static project associated with this allocation.
-	    self.allocation[aid]['sproject'] = pname
-
-	self.allocation[aid]['keys'] = [ ]
-
-	try:
-	    for u in ap['project']['user']:
-		uname = u['userID']['localname']
-		if u['role'] == 'experimentCreation':
-		    self.allocation[aid]['user'] = uname
-		for k in [ k['sshPubkey'] for k in u['access'] \
-			if k.has_key('sshPubkey') ]:
-		    kv = "%s:%s" % (uname, k)
-		    if self.keys.has_key(kv): self.keys[kv] += 1
-		    else: self.keys[kv] = 1
-		    self.allocation[aid]['keys'].append((uname, k))
-	except KeyError:
-	    self.state_lock.release()
-	    raise service_error(service_error.internal,
-		    "Misformed allocation response?")
-
+	self.allocation[aid]['project'] = pname
+	self.allocation[aid]['user'] = uname
 	self.allocation[aid]['owners'] = owners
 	self.write_state()
@@ -481,9 +261,6 @@
 	    self.auth.save()
 
-	if self.auth_type == "legacy":
-	    found, dyn, owners= self.legacy_lookup_access(req, fid)
-	    proof = access_proof("me", fid, "create")
-	elif self.auth_type == 'abac':
-	    found, dyn, owners, proof = self.lookup_access(req, fid, filter=pf)
+	if self.auth_type == 'abac':
+	    found, owners, proof = self.lookup_access(req, fid, filter=pf)
 	else:
 	    raise service_error(service_error.internal, 
@@ -491,20 +268,9 @@
 	ap = None
 
-	# This only happens in legacy lookups, but if this user has access to
-	# the testbed but not the project to be exported, raise the error.
-	if ep and ep != found[0]:
-	    raise service_error(service_error.access,
-		    "Cannot export %s" % ep)
-
-	if self.ssh_pubkey_file:
-	    ap = self.do_project_allocation(dyn[1], found[0], found[1])
-	else:
-	    raise service_error(service_error.internal, 
-		    "SSH access parameters required")
 	# keep track of what's been added
 	allocID, alloc_cert = generate_fedid(subj="alloc", log=self.log)
 	aid = unicode(allocID)
 
-	pname, uname = self.save_project_state(aid, ap, dyn[1], owners)
+	pname, uname = self.save_project_state(aid, found[0], found[1], owners)
 
 	services, svc_state = self.export_services(req.get('service',[]),
@@ -526,29 +292,6 @@
 		    "Can't open %s/%s : %s" % (self.certdir, aid, e))
 	resp = self.build_access_response({ 'fedid': allocID } ,
-		ap, services, proof)
+		pname, services, proof)
 	return resp
-
-    def do_release_project(self, del_project, del_users, del_types):
-	"""
-	If a project and users has to be deleted, make the call.
-	"""
-	msg = { 'project': { }}
-	if del_project:
-	    msg['project']['name']= {'localname': del_project}
-	users = [ ]
-	for u in del_users.keys():
-	    users.append({ 'userID': { 'localname': u },\
-		'access' :  \
-			[ {'sshPubkey' : s } for s in del_users[u]]\
-	    })
-	if users: 
-	    msg['project']['user'] = users
-	if len(del_types) > 0:
-	    msg['resources'] = { 'node': \
-		    [ {'hardware': [ h ] } for h in del_types ]\
-		}
-	if self.allocate_project.release_project:
-	    msg = { 'ReleaseProjectRequestBody' : msg}
-	    self.allocate_project.release_project(msg)
 
     def ReleaseAccess(self, req, fid):
@@ -579,51 +322,12 @@
 	    raise service_error(service_error.access, "Access Denied")
 
-	# If we know this allocation, reduce the reference counts and
-	# remove the local allocations.  Otherwise report an error.  If
-	# there is an allocation to delete, del_users will be a dictonary
-	# of sets where the key is the user that owns the keys in the set.
-	# We use a set to avoid duplicates.  del_project is just the name
-	# of any dynamic project to delete.  We're somewhat lazy about
-	# deleting authorization attributes.  Having access to something
-	# that doesn't exist isn't harmful.
-	del_users = { }
-	del_project = None
-	del_types = set()
-
 	self.state_lock.acquire()
 	if aid in self.allocation:
 	    self.log.debug("Found allocation for %s" %aid)
 	    self.clear_allocation_authorization(aid, state_attr='allocation')
-	    for k in self.allocation[aid]['keys']:
-		kk = "%s:%s" % k
-		self.keys[kk] -= 1
-		if self.keys[kk] == 0:
-		    if not del_users.has_key(k[0]):
-			del_users[k[0]] = set()
-		    del_users[k[0]].add(k[1])
-		    del self.keys[kk]
-
-	    if 'project' in self.allocation[aid]:
-		pname = self.allocation[aid]['project']
-		self.projects[pname] -= 1
-		if self.projects[pname] == 0:
-		    del_project = pname
-		    del self.projects[pname]
-
-	    if 'types' in self.allocation[aid]:
-		for t in self.allocation[aid]['types']:
-		    self.types[t] -= 1
-		    if self.types[t] == 0:
-			if not del_project: del_project = t[0]
-			del_types.add(t[1])
-			del self.types[t]
-
 	    del self.allocation[aid]
 	    self.write_state()
 	    self.state_lock.release()
-	    # If we actually have resources to deallocate, prepare the call.
-	    if del_project or del_users:
-		self.do_release_project(del_project, del_users, del_types)
-	    # And remove the access cert
+	    # Remove the access cert
 	    cf = "%s/%s.pem" % (self.certdir, aid)
 	    self.log.debug("Removing %s" % cf)
@@ -939,6 +643,4 @@
 	if aid in self.allocation:
 	    proj = self.allocation[aid].get('project', None)
-	    if not proj: 
-		proj = self.allocation[aid].get('sproject', None)
 	self.state_lock.release()
 
@@ -1215,6 +917,4 @@
 	if aid in self.allocation:
 	    proj = self.allocation[aid].get('project', None)
-	    if not proj: 
-		proj = self.allocation[aid].get('sproject', None)
 	    user = self.allocation[aid].get('user', None)
 	    ename = self.allocation[aid].get('experiment', None)
@@ -1265,6 +965,4 @@
 	    if topo: topo = topo.clone()
 	    proj = self.allocation[aid].get('project', None)
-	    if not proj: 
-		proj = self.allocation[aid].get('sproject', None)
 	    user = self.allocation[aid].get('user', None)
 	    ename = self.allocation[aid].get('experiment', None)
Index: fedd/federation/legacy_access.py
===================================================================
--- fedd/federation/legacy_access.py	(revision d2e86f6db04f8ac68bba3cae6ccbbb0e34edd0b6)
+++ 	(revision )
@@ -1,196 +1,0 @@
-#!/usr/local/bin/python
-
-import os,sys
-import stat # for chmod constants
-import re
-import random
-import string
-import copy
-import pickle
-import logging
-import subprocess
-
-from threading import *
-from M2Crypto.SSL import SSLError
-
-from util import *
-from allocate_project import allocate_project_local, allocate_project_remote
-from fedid import fedid, generate_fedid
-from authorizer import authorizer
-from service_error import service_error
-from remote_service import xmlrpc_handler, soap_handler, service_caller
-
-import httplib
-import tempfile
-from urlparse import urlparse
-
-import topdl
-import list_log
-
-
-# Make log messages disappear if noone configures a fedd logger
-class nullHandler(logging.Handler):
-    def emit(self, record): pass
-
-fl = logging.getLogger("fedd.access")
-fl.addHandler(nullHandler())
-
-class legacy_access:
-    """
-    This collects the legacy access control helpers in one place.
-    """
-
-    class parse_error(RuntimeError): pass
-
-    def __init__(self): pass
-
-    def legacy_read_access(self, config, access_obj=None):
-        """
-	Read an access DB with filename config  of the form:
-	    (id, id, id) -> attribute, something
-	where the ids can be fedids, strings, or <any> or <none>, attribute is
-	the attribute to assign , and something is any set of charcters.  The
-	hash self.access is populated with mappings from those triples to the
-	results of access_obj being called on the remainder of the line (if
-	present).  If access_obj is not given, the string itself is entered in
-	the hash.  Additionally, a triple with <any> and <none> mapped to None
-	is entered in self.auth with the attribute given.
-
-	Parsing errors result in a self.parse_error exception being raised.
-	access_obj should throw that as well.
-        """
-        lineno=0
-        name_expr = "["+string.ascii_letters + string.digits + "\.\-_]+"
-        fedid_expr = "fedid:[" + string.hexdigits + "]+"
-        key_name = "(<ANY>|<NONE>|"+fedid_expr + "|"+ name_expr + ")"
-        access_re = re.compile('\('+key_name+'\s*,\s*'+key_name+'\s*,\s*'+
-                key_name+'\s*\)\s*->\s*([^,]+)\s*(.*)', re.IGNORECASE)
-
-        def parse_name(n):
-            if n.startswith('fedid:'): return fedid(hexstr=n[len('fedid:'):])
-            else: return n
-        
-        def auth_name(n):
-            if isinstance(n, basestring):
-                if n =='<any>' or n =='<none>': return None
-                else: return unicode(n)
-            else:
-                return n
-	def strip_comma(s):
-	    s = s.strip()
-	    if s.startswith(','):
-		s = s[1:].strip()
-	    return s
-
-	if access_obj is None:
-	    access_obj = lambda(x): "%s" % x
-
-        f = open(config, "r");
-	try:
-	    for line in f:
-		lineno += 1
-		line = line.strip();
-		if len(line) == 0 or line.startswith('#'):
-		    continue
-
-		# Access line (t, p, u) -> anything
-		m = access_re.match(line)
-		if m != None:
-		    access_key = tuple([ parse_name(x) \
-			    for x in m.group(1,2,3)])
-		    attribute = m.group(4)
-		    auth_key = tuple([ auth_name(x) for x in access_key])
-		    self.auth.set_attribute(auth_key, attribute)
-		    if len(m.group(5)) > 0:
-			access_val = access_obj(strip_comma(m.group(5)))
-			self.access[access_key] = access_val
-		    continue
-
-		# Nothing matched to here: unknown line - raise exception
-		f.close()
-		raise self.parse_error(
-			"Unknown statement at line %d of %s" % \
-			(lineno, config))
-	finally:
-	    if f: f.close()
-
-    @staticmethod
-    def permute_wildcards(a, p):
-        """Return a copy of a with various fields wildcarded.
-
-        The bits of p control the wildcards.  A set bit is a wildcard
-        replacement with the lowest bit being user then project then testbed.
-        """
-        if p & 1: user = ["<any>"]
-        else: user = a[2]
-        if p & 2: proj = "<any>"
-        else: proj = a[1]
-        if p & 4: tb = "<any>"
-        else: tb = a[0]
-
-        return (tb, proj, user)
-
-    def legacy_find_access(self, search):
-        """
-        Search the access DB for a match on this tuple.  Return the matching
-        access tuple and the user that matched.
-        
-        NB, if the initial tuple fails to match we start inserting wildcards in
-        an order determined by self.project_priority.  Try the list of users in
-        order (when wildcarded, there's only one user in the list).
-        """
-        if self.project_priority: perm = (0, 1, 2, 3, 4, 5, 6, 7)
-        else: perm = (0, 2, 1, 3, 4, 6, 5, 7)
-
-        for p in perm: 
-            s = self.permute_wildcards(search, p)
-            # s[2] is None on an anonymous, unwildcarded request
-            if s[2] != None:
-                for u in s[2]:
-                    if self.access.has_key((s[0], s[1], u)):
-                        return (self.access[(s[0], s[1], u)], u)
-            else:
-                if self.access.has_key(s):
-                    return (self.access[s], None)
-        return None, None
-
-    def legacy_lookup_access_base(self, req, fid):
-        """
-        Determine the allowed access for this request.  Return the access and
-        which fields are dynamic.
-
-        The fedid is needed to construct the request
-        """
-	user_re = re.compile("user:\s(.*)")
-	project_re = re.compile("project:\s(.*)")
-
-        # Search keys
-	tb = fid
-	user = [ user_re.findall(x)[0] for x in req.get('credential', []) \
-		if user_re.match(x)]
-	project = [ project_re.findall(x)[0] \
-		for x in req.get('credential', []) \
-		    if project_re.match(x)]
-
-	if len(project) == 1: project = project[0]
-	elif len(project) == 0: project = None
-	else: 
-	    raise service_error(service_error.req, 
-		    "More than one project credential")
-
-        # Confirm authorization
-        for u in user:
-            self.log.debug("[lookup_access] Checking access for %s" % \
-                    ((tb, project, u),))
-            if self.auth.check_attribute((tb, project, u), 'access'):
-                self.log.debug("[lookup_access] Access granted")
-                break
-            else:
-                self.log.debug("[lookup_access] Access Denied")
-        else:
-            raise service_error(service_error.access, "Access denied")
-
-        # This maps a valid user to the Emulab projects and users to use
-        found, user_match = self.legacy_find_access((tb, project, user))
-
-	return (found, (tb, project, user_match))
Index: fedd/federation/protogeni_access.py
===================================================================
--- fedd/federation/protogeni_access.py	(revision d2e86f6db04f8ac68bba3cae6ccbbb0e34edd0b6)
+++ fedd/federation/protogeni_access.py	(revision ee950c2260d0e0d90dc0a6a4d78740b92459415b)
@@ -27,5 +27,4 @@
 
 from access import access_base
-from legacy_access import legacy_access
 from protogeni_proxy import protogeni_proxy
 from geniapi_proxy import geniapi_proxy
@@ -42,5 +41,5 @@
 fl.addHandler(nullHandler())
 
-class access(access_base, legacy_access):
+class access(access_base):
     """
     The implementation of access control based on mapping users to projects.
@@ -115,24 +114,9 @@
 	# authorization information
 	self.auth_type = config.get('access', 'auth_type') \
-		or 'legacy'
+		or 'abac'
 	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, self.make_access_info)
-	    # 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.get('allocation', {}).keys():
-		for o in self.state['allocation'][k].get('owners', []):
-		    self.auth.set_attribute(o, fedid(hexstr=k))
-		self.auth.set_attribute(fedid(hexstr=k),fedid(hexstr=k))
-
-	    self.state_lock.release()
-	    self.lookup_access = self.legacy_lookup_access_base
-	elif self.auth_type == 'abac':
+	if self.auth_type == 'abac':
 	    self.auth = abac_authorizer(load=self.auth_dir)
 	    self.access = [ ]
Index: fedd/federation/skeleton_access.py
===================================================================
--- fedd/federation/skeleton_access.py	(revision d2e86f6db04f8ac68bba3cae6ccbbb0e34edd0b6)
+++ fedd/federation/skeleton_access.py	(revision ee950c2260d0e0d90dc0a6a4d78740b92459415b)
@@ -18,5 +18,4 @@
 
 from access import access_base
-from legacy_access import legacy_access
 
 # Make log messages disappear if noone configures a fedd logger.  This is
@@ -32,5 +31,5 @@
 
 # The plug-in itself.
-class access(access_base, legacy_access):
+class access(access_base):
     """
     This is a demonstration plug-in for fedd.  It responds to all the
@@ -78,43 +77,12 @@
 	# authorization information
 	self.auth_type = config.get('access', 'auth_type') \
-		or 'legacy'
+		or 'abac'
 	self.auth_dir = config.get('access', 'auth_dir')
 	accessdb = config.get("access", "accessdb")
-	# initialize the authorization system.  In each case we make a call to
+	# initialize the authorization system.  We make a call to
 	# read the access database that maps from authorization information
 	# into local information.  The local information is parsed by the
 	# translator above.
-	if self.auth_type == 'legacy':
-	    self.access = { }
-	    if accessdb:
-		try:
-		    self.legacy_read_access(accessdb, self.parse_access_string)
-		except EnvironmentError, e:
-		    self.log.error("Cannot read %s: %s" % \
-			    (config.get("access", "accessdb"), e))
-		    raise e
-	    # The base class initializer has read the state dictionary from the
-	    # state file, if there is one.  The state variable includes
-	    # information about each active allocation, keyed by the allocation
-	    # identifier.  This loop extracts the owners stored with each
-	    # allocation and associates an access attribute with them.  Each
-	    # owner is allowed to access each thing they own.  This is a
-	    # specialization of the state handling.  ABAC records this
-	    # information explicitly so this loop only executes for legacy
-	    # code.
-	    self.state_lock.acquire()
-	    for k in self.state.keys():
-		# Add the owners
-		for o in self.state[k].get('owners', []):
-		    self.auth.set_attribute(o, fedid(hexstr=k))
-		# The principal represented by the allocation itself is also
-		# allowed to make accesses.
-		self.auth.set_attribute(fedid(hexstr=k),fedid(hexstr=k))
-	    self.state_lock.release()
-	    # This access controller does not specialize the process of looking
-	    # up local information.  This aliases the lookup_access method to
-	    # be easier to read.
-	    self.lookup_access = self.legacy_lookup_access_base
-	elif self.auth_type == 'abac':
+	if self.auth_type == 'abac':
 	    #  Load the current authorization state
 	    self.auth = abac_authorizer(load=self.auth_dir)
