Index: fedd/fedd_access.py
===================================================================
--- fedd/fedd_access.py	(revision a398ec93840873fca1b07a44d5d2162d29608227)
+++ fedd/fedd_access.py	(revision c35207dd940eb2d05f02f9e0c200351e3930ed77)
@@ -50,4 +50,9 @@
 		    feddServiceLocator, RequestAccessRequestMessage,
 		    'RequestAccessRequestBody')
+
+    proxy_ReleaseAccess= \
+	    service_caller('ReleaseAccess', 'getfeddPortType', 
+		    feddServiceLocator, ReleaseAccessRequestMessage,
+		    'ReleaseAccessRequestBody')
 
     def __init__(self, config=None, auth=None):
@@ -705,71 +710,88 @@
 	    raise service_error(service_error.req, "No request!?")
 
-	try:
-	    if req['allocID'].has_key('localname'):
-		auth_attr = aid = req['allocID']['localname']
-	    elif req['allocID'].has_key('fedid'):
-		aid = unicode(req['allocID']['fedid'])
-		auth_attr = req['allocID']['fedid']
-	    else:
-		raise service_error(service_error.req,
-			"Only localnames and fedids are understood")
-	except KeyError:
-	    raise service_error(service_error.req, "Badly formed request")
-
-	print "Checking for %s %s" % (fid, auth_attr)
-	if not self.auth.check_attribute(fid, auth_attr):
-	    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
-	if self.allocation.has_key(aid):
-	    self.state_lock.acquire()
-	    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 self.allocation[aid].has_key('project'):
-		pname = self.allocation[aid]['project']
-		self.projects[pname] -= 1
-		if self.projects[pname] == 0:
-		    del_project = pname
-		    del self.projects[pname]
-
-	    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:
-		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 self.allocate_project.release_project:
-		    msg = { 'ReleaseProjectRequestBody' : msg}
-		    self.allocate_project.release_project(msg)
-	    return { 'allocID': req['allocID'] } 
-	else:
-	    raise service_error(service_error.req, "No such allocation")
-
-
-
+	if req.has_key('destinationTestbed'):
+	    dt = unpack_id(req['destinationTestbed'])
+
+	if dt == None or dt == self.testbed:
+	    # Local request
+	    try:
+		if req['allocID'].has_key('localname'):
+		    auth_attr = aid = req['allocID']['localname']
+		elif req['allocID'].has_key('fedid'):
+		    aid = unicode(req['allocID']['fedid'])
+		    auth_attr = req['allocID']['fedid']
+		else:
+		    raise service_error(service_error.req,
+			    "Only localnames and fedids are understood")
+	    except KeyError:
+		raise service_error(service_error.req, "Badly formed request")
+
+	    print "Checking for %s %s" % (fid, auth_attr)
+	    if not self.auth.check_attribute(fid, auth_attr):
+		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
+	    if self.allocation.has_key(aid):
+		self.state_lock.acquire()
+		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 self.allocation[aid].has_key('project'):
+		    pname = self.allocation[aid]['project']
+		    self.projects[pname] -= 1
+		    if self.projects[pname] == 0:
+			del_project = pname
+			del self.projects[pname]
+
+		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:
+		    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 self.allocate_project.release_project:
+			msg = { 'ReleaseProjectRequestBody' : msg}
+			self.allocate_project.release_project(msg)
+		return { 'allocID': req['allocID'] } 
+	    else:
+		raise service_error(service_error.req, "No such allocation")
+
+	else:
+	    if self.allow_proxy:
+		resp = self.proxy_ReleaseAccess.call_service(dt, req,
+			    self.proxy_cert_file, self.proxy_cert_pwd,
+			    self.proxy_trusted_certs)
+		if resp.has_key('ReleaseAccessResponseBody'):
+		    return resp['ReleaseAccessResponseBody']
+		else:
+		    return None
+	    else:
+		raise service_error(service_error.access,
+			"Access proxying denied")
+
+
