Index: libabac/abac.c
===================================================================
--- libabac/abac.c	(revision 605ee1d0321bea1ee1f140db62517cdb638b2e9c)
+++ libabac/abac.c	(revision d4b3b529e2089c1d6789e5f0d05d99ff3aa4c533)
@@ -193,8 +193,29 @@
         *success = 0;
         abac_list_free(result);
-
-        // TODO: fix this when we can return a sane value for partial proofs
-        // result = abac_graph_postorder_credentials(ctx->graph, role);
-        result = abac_graph_credentials(ctx->graph);
+	result_graph = abac_graph_new();
+
+	// TODO: This can probably be better, but it now returns an
+	// approximation of a partial proof.  It returns all the attributes the
+	// principal can reach and all the attributes that will lead to a
+	// success.
+
+	/* Get all the attributes of the principal.  This calls sub-queries to
+	 * flesh out the indirect proofs. */
+        result_graph = abac_graph_principal_creds(ctx->graph, principal);
+
+	/* This gets all the attributes linked to the target en route to the
+	 * principal. */
+        result = abac_graph_postorder_credentials(ctx->graph, role);
+
+	/* Merge responses */
+	abac_list_foreach(result, cur,
+	    abac_graph_add_credential(result_graph, cur);
+	);
+        abac_list_free(result);
+	abac_graph_derive_links(result_graph);
+
+	result = abac_graph_credentials(result_graph);
+	abac_graph_free(result_graph);
+
         size = abac_list_size(result);
     }
Index: libabac/abac_graph.c
===================================================================
--- libabac/abac_graph.c	(revision 605ee1d0321bea1ee1f140db62517cdb638b2e9c)
+++ libabac/abac_graph.c	(revision d4b3b529e2089c1d6789e5f0d05d99ff3aa4c533)
@@ -15,4 +15,5 @@
 
     abac_list_t *edges;
+    abac_list_t *reverse_edges;
 
     // only relevant to intersection edges
@@ -25,4 +26,5 @@
 typedef struct _abac_edge_t {
     abac_vertex_t *vertex;
+    abac_vertex_t *reverse_vertex;
     abac_credential_t *credential;
 } abac_edge_t;
@@ -100,4 +102,5 @@
         // create the list of edges
         vertex->edges = abac_list_new();
+        vertex->reverse_edges = abac_list_new();
 
         // for intersections, always NULL on normal vertices
@@ -151,7 +154,9 @@
     edge = abac_xmalloc(sizeof(abac_edge_t));
     edge->vertex = tail_vertex;
+    edge->reverse_vertex = head_vertex;
     edge->credential = abac_credential_dup(cred);
 
     abac_list_add(head_vertex->edges, edge);
+    abac_list_add(tail_vertex->reverse_edges, edge);
 
     // must re-derive edges
@@ -192,4 +197,5 @@
         // this can fail, but we assume the data structures are consistent
         abac_list_remove(head->edges, tail);
+        abac_list_remove(tail->reverse_vertex->edges, tail);
 
         free(current);
@@ -212,6 +218,8 @@
     edge = abac_xmalloc(sizeof(abac_edge_t));
     edge->vertex = tail;
+    edge->reverse_vertex = head;
     edge->credential = NULL;
     abac_list_add(head->edges, edge);
+    abac_list_add(tail->reverse_edges, edge);
 
     // add to list of derived edges
@@ -350,4 +358,39 @@
 }
 
+static void _reverse_order_recurse(abac_vertex_t *vertex, abac_set_t *seen, int preorder, abac_list_t *stack) {
+    abac_edge_t *outgoing;
+
+    // don't revisit nodes
+    if (!abac_set_add(seen, abac_role_string(vertex->role)))
+        return;
+
+    if (preorder)
+        abac_list_add(stack, vertex);
+
+    // recurse along the incoming vertices
+    abac_list_foreach(vertex->reverse_edges, outgoing,
+        _reverse_order_recurse(outgoing->reverse_vertex, seen, preorder, stack);
+    );
+
+    if (!preorder)
+        abac_list_add(stack, vertex);
+}
+
+static abac_list_t *_reverse_order(abac_graph_t *graph, abac_role_t *start, int preorder) {
+    debug_printf("%sorder at %s\n", preorder ? "pre" : "post", abac_role_string(start));
+
+    abac_vertex_t *start_vertex = _get_vertex(graph, start);
+    abac_set_t *seen = abac_set_new();
+
+    // create the return list
+    abac_list_t *stack = abac_list_new();
+
+    _reverse_order_recurse(start_vertex, seen, preorder, stack);
+
+    abac_set_free(seen);
+
+    return stack;
+}
+
 static void _order_recurse(abac_vertex_t *vertex, abac_set_t *seen, int preorder, abac_list_t *stack) {
     abac_edge_t *incoming;
@@ -415,4 +458,35 @@
 }
 
+
+abac_list_t *abac_graph_postorder_reverse(abac_graph_t *graph, abac_role_t *start) {
+    return _reverse_order(graph, start, 0);
+}
+
+/**
+ * Postorder traverse the graph and return all the credentials within.
+ */
+abac_list_t *abac_graph_postorder_reverse_credentials(abac_graph_t *graph, char *start) {
+    abac_vertex_t *vertex;
+    abac_edge_t *outgoing;
+
+    // get the postorder of vertices
+    abac_role_t *role = abac_role_from_string(start);
+    abac_list_t *order = abac_graph_postorder_reverse(graph, role);
+
+    // go through the list and dup all the credentials
+    abac_list_t *credentials = abac_list_new();
+    abac_list_foreach(order, vertex,
+        abac_list_foreach(vertex->reverse_edges, outgoing,
+            if (outgoing->credential != NULL)
+                abac_list_add(credentials, abac_credential_dup(outgoing->credential));
+        );
+    );
+
+    abac_role_free(role);
+    abac_list_free(order);
+
+    return credentials;
+}
+
 static void _query(abac_graph_t *graph, char *role_name, char *principal, abac_graph_t *return_graph) {
     abac_vertex_t *vertex;
@@ -481,4 +555,27 @@
 }
 
+abac_graph_t *abac_graph_principal_creds(abac_graph_t *graph, char *principal) {
+    abac_graph_derive_links(graph);
+    abac_graph_t *result_graph = abac_graph_new();
+    abac_list_t *result = abac_graph_postorder_reverse_credentials(graph, 
+	    principal);
+    abac_credential_t *cur = NULL;
+    abac_list_foreach(result, cur,
+	abac_graph_add_credential(result_graph, cur);
+    );
+    abac_list_free(result);
+    /* For each terminal role that the principal can reach, roll a proof into
+       the result_graph. */
+    abac_vertex_t *vertex = NULL;
+    for (vertex = result_graph->vertices; vertex != NULL; 
+	    vertex = vertex->hh.next) {
+	if ( abac_list_size(vertex->reverse_edges) == 0) 
+	    _query(graph, vertex->name, principal, result_graph);
+    }
+    abac_graph_derive_links(result_graph);
+    return result_graph;
+}
+
+
 /**
  * Get all the credentials (attribute/issuer cert pairs) from the graph.
Index: libabac/abac_graph.h
===================================================================
--- libabac/abac_graph.h	(revision 605ee1d0321bea1ee1f140db62517cdb638b2e9c)
+++ libabac/abac_graph.h	(revision d4b3b529e2089c1d6789e5f0d05d99ff3aa4c533)
@@ -21,4 +21,7 @@
 abac_list_t *abac_graph_postorder(abac_graph_t *graph, abac_role_t *start);
 abac_list_t *abac_graph_postorder_credentials(abac_graph_t *graph, char *start);
+abac_list_t *abac_graph_postorder_reverse(abac_graph_t *graph, abac_role_t *start);
+abac_list_t *abac_graph_postorder_reverse_credentials(abac_graph_t *graph, char *start);
+abac_graph_t *abac_graph_principal_creds(abac_graph_t *graph, char *principal);
 abac_graph_t *abac_graph_query(abac_graph_t *graph, char *role, char *principal);
 abac_list_t *abac_graph_credentials(abac_graph_t *graph);
