Index: fedd/federation/emulab_access.py
===================================================================
--- fedd/federation/emulab_access.py	(revision ee950c2260d0e0d90dc0a6a4d78740b92459415b)
+++ fedd/federation/emulab_access.py	(revision f77a256d1f481032d22a5052d21211d6cb913daa)
@@ -176,21 +176,21 @@
     def access_tuple(str):
 	"""
-	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).
+	Convert a string of the form (id, 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, certificate_file).
 	"""
 
 	str = str.strip()
-	if str.startswith('(') and str.endswith(')') and str.count(',') == 1:
+	if str.startswith('(') and str.endswith(')') and str.count(',') == 2:
 	    # The slice takes the parens off the string.
-	    proj, user = str[1:-1].split(',')
-	    return (proj.strip(), user.strip())
+	    proj, user, cert = str[1:-1].split(',')
+	    return (proj.strip(), user.strip(), cert.strip())
 	else:
 	    raise self.parse_error(
-		    'Bad mapping (unbalanced parens or more than 1 comma)')
+		    'Bad mapping (unbalanced parens or more than 2 commas)')
 
     # RequestAccess support routines
 
-    def save_project_state(self, aid, pname, uname, owners):
+    def save_project_state(self, aid, pname, uname, certf, owners):
 	"""
 	Save the project, user, and owners associated with this allocation.
@@ -201,4 +201,5 @@
 	self.allocation[aid]['project'] = pname
 	self.allocation[aid]['user'] = uname
+	self.allocation[aid]['cert'] = certf
 	self.allocation[aid]['owners'] = owners
 	self.write_state()
@@ -272,5 +273,6 @@
 	aid = unicode(allocID)
 
-	pname, uname = self.save_project_state(aid, found[0], found[1], owners)
+	pname, uname = self.save_project_state(aid, found[0], found[1], 
+		found[2], owners)
 
 	services, svc_state = self.export_services(req.get('service',[]),
@@ -690,4 +692,5 @@
 	if aid in self.allocation:
 	    user = self.allocation[aid].get('user', None)
+	    cert = self.allocation[aid].get('cert', None)
 	    self.allocation[aid]['experiment'] = ename
 	    self.allocation[aid]['nonce'] = nonce_experiment
@@ -711,5 +714,5 @@
 		    "Can't find creation user for %s" %aid)
 
-	return (ename, proj, user, pubkey_base, secretkey_base, alloc_log)
+	return (ename, proj, user, cert, pubkey_base, secretkey_base, alloc_log)
 
     def decorate_topology(self, info, t):
@@ -853,7 +856,7 @@
 	try:
 	    self.retrieve_software(topo, certfile, softdir)
-	    ename, proj, user, pubkey_base, secretkey_base, alloc_log = \
-		    self.initialize_experiment_info(attrs, aid, 
-			    certfile, tmpdir)
+	    ename, proj, user, xmlrpc_cert, pubkey_base, secretkey_base, \
+		alloc_log =  self.initialize_experiment_info(attrs, aid, 
+			certfile, tmpdir)
 
 	    if '/' in proj: proj, gid = proj.split('/')
@@ -877,5 +880,5 @@
 	    starter = self.start_segment(keyfile=self.ssh_privkey_file, 
 		    debug=self.create_debug, log=alloc_log, boss=self.boss,
-		    ops=self.ops, cert=self.xmlrpc_cert)
+		    ops=self.ops, cert=xmlrpc_cert)
 	    rv = starter(self, ename, proj, user, expfile, tmpdir, gid=gid)
 	except service_error, e:
@@ -918,4 +921,5 @@
 	    proj = self.allocation[aid].get('project', None)
 	    user = self.allocation[aid].get('user', None)
+	    xmlrpc_cert = self.allocation[aid].get('cert', None)
 	    ename = self.allocation[aid].get('experiment', None)
 	    nonce = self.allocation[aid].get('nonce', False)
@@ -925,4 +929,5 @@
 	    ename = None
 	    nonce = False
+	    xmlrpc_cert = None
 	self.state_lock.release()
 
@@ -942,5 +947,5 @@
 	stopper = self.stop_segment(keyfile=self.ssh_privkey_file,
 		debug=self.create_debug, boss=self.boss, ops=self.ops,
-		cert=self.xmlrpc_cert)
+		cert=xmlrpc_cert)
 	stopper(self, user, proj, ename, gid, nonce)
 	return { 'allocID': req['allocID'], 'proof': proof.to_dict() }
@@ -966,4 +971,5 @@
 	    proj = self.allocation[aid].get('project', None)
 	    user = self.allocation[aid].get('user', None)
+	    xmlrpc_cert = self.allocation[aid].get('cert', None)
 	    ename = self.allocation[aid].get('experiment', None)
 	else:
@@ -972,4 +978,5 @@
 	    ename = None
 	    topo = None
+	    xmlrpc_cert = None
 	self.state_lock.release()
 
@@ -989,5 +996,5 @@
 	info = self.info_segment(keyfile=self.ssh_privkey_file,
 		debug=self.create_debug, boss=self.boss, ops=self.ops,
-		cert=self.xmlrpc_cert)
+		cert=xmlrpc_cert)
 	info(self, user, proj, ename)
 	self.decorate_topology(info, topo)
@@ -1038,9 +1045,13 @@
 	    raise service_error(service_error.req, "no targets")
 
+	self.state_lock.acquire()
 	if aid in self.allocation:
 	    topo = self.allocation[aid].get('topo', None)
 	    if topo: topo = topo.clone()
+	    xmlrpc_cert = self.allocation[aid].get('cert', None)
 	else:
 	    topo = None
+	    xmlrpc_cert = None
+	self.state_lock.release()
 
 	targets = copy.copy(targets)
@@ -1058,5 +1069,5 @@
 	ops = self.operation_segment(keyfile=self.ssh_privkey_file,
 		debug=self.create_debug, boss=self.boss, ops=self.ops,
-		cert=self.xmlrpc_cert)
+		cert=xmlrpc_cert)
 	ops(self, op, ptargets, params, topo)
 	
