--- taxonomy_access_admin.inc.orig	2010-01-19 14:00:08.000000000 -0700
+++ taxonomy_access_admin.inc	2010-01-20 10:28:46.000000000 -0700
@@ -179,6 +179,10 @@ function taxonomy_access_admin_form($for
       '#type' => 'select',
       '#options' => $add_items,
     );
+    $form['new']['recursive'] = array(
+      '#type' => 'select',
+      '#options' => array('Normal', 'Recursive'),
+    );
     $form['new']['add'] = array(
       '#type' => 'submit',
       '#value' => t('Add'),
@@ -256,7 +260,8 @@ function theme_taxonomy_access_admin_for
   }
   if (isset($form['new'])) {
     $row = array(
-             array('data' => drupal_render($form['new']['item']), 'colspan' => 2), 
+             drupal_render($form['new']['item']), 
+             drupal_render($form['new']['recursive']), 
              drupal_render($form['new']['add'])
            );
     foreach ($node_grant_types as $grant) {
@@ -313,7 +318,11 @@ function taxonomy_access_admin_form_subm
     $new = $values['new'];
     list($type, $id) = explode(' ', $new['item']);
     if ($type == 'term') {
-      taxonomy_access_grant_update($id, $values['rid'], $new['grants']);
+      if ($new['recursive'] == 1) {
+		taxonomy_access_recursive_grant_update($id, $values['rid'], $new['grants']);
+	  } else {
+	    taxonomy_access_grant_update($id, $values['rid'], $new['grants']);
+	  }
     }
     elseif ($type == 'default') {
       taxonomy_access_defaults_update($id, $values['rid'], $new['grants']);
@@ -383,6 +392,50 @@ function taxonomy_access_grant_update($t
 }
 
 /**
+ * Recursively updates permissions for a role for a term
+ * - gets all the children terms and calls a grant update for each of them
+ 
+ We need to:
+ 	get children of a term id, and get their children, and their children, etc
+		while
+	set up a loop prevention
+ 
+ */
+function taxonomy_access_recursive_grant_update($tid, $rid = null, $grants = null) {
+  // run the original
+  taxonomy_access_grant_update($tid, $rid, $grants);
+  
+  // process the children
+  $ran_tids = array(); // tids that have been processed
+  $run_tids = array($tid); // tids that are in the queue to be processed
+  while(count($run_tids) > 0) { // while there are tids to be processed, run the following
+	foreach($run_tids as $run_key => $run_tid) {
+	  // some basic loop protection
+	  if (array_search($run_tid, $ran_tids) == true) {
+		drupal_set_message("Loop detected for tid <b>".$run_tid."</b>. Stopping.");
+		$run_tids = array(); // stop the execution
+	  } else {
+		$result = db_query('SELECT th.tid FROM {term_hierarchy} th WHERE th.parent = %d', $run_tid);
+		// if this tid has children, update grants and queue the children up for processing
+		while ($row = db_fetch_array($result)) {
+		  taxonomy_access_grant_update($row['tid'], $rid, $grants);
+		  $run_tids[] = $row['tid'];
+		}
+		unset($run_tids[$run_key]); // remove this tid from queue
+		$ran_tids[] = $run_tid; // mark this tid as processed
+	  }
+	}
+  }
+}
+
+function taxonomy_access_recursive_get_children($tid) {
+  $result = db_query('SELECT th.tid FROM {term_hierarchy} th WHERE th.parent = %d', $tid);
+  while ($row = db_fetch_array($result)) {
+	$tids[] = $row['tid'];
+  }
+}
+
+/**
  * Updates default permissions for a role for a vocabulary
  * @param $vid
  *   The vocab to add the permission for.
