| Win32::Security::Recursor - Security recursion for named objects | 
Win32::Security::Recursor - Security recursion for named objects
    use Win32::Security::Recursor;
    my $recursor = Win32::Security::Recursor::SE_FILE_OBJECT->new(
      payload => sub {
        my $self = shift;
        my($node_info, $cont_info) = @_;
        print $self->node_name($node_info)."\n";
      }
    );
    $recursor->recurse($ARGV[0]);
This module is designed to support scripts that need to recurse through a 
hierarchy of objects (i.e. a directory tree, registry hive, etc.), and 
interfacing with the security information on every node.  There are a number of 
reasons this module was developed, instead of simply reusing File::Find.
Win32::File::GetAttributes is over twice as fast as the built-in -d 
operator, at least under Perl 5.6.1 - this shaves roughly 0.3 ms per node on a 
Pent III Xeon 450 (or 30 seconds when scanning 100,000 files!), and even more 
given that it lets one test for JUNCTION points with almost no additional 
overhead.
Error handling.  Error handling is passed through well defined interfaces, thus
letting the developer choose how to display and/or record errors.
All of this comes at a price, however, and that is complexity.  Some of that is 
because the problem itself is complex - objects fail to respond to API calls, 
JUNCTION points can complicate recursion, etc.  Some of it is because the module 
was designed to be as flexible as possible, and so code was broken up into a 
wide variety of methods, thus making granual overriding possible.  The module 
makes use of Class::Prototyped to support object-level method overriding 
without the need for explicit subclassing.
This installs as part of Win32-Security.  See 
Win32::Security::NamedObject for more information.
It depends upon the other Win32-Security modules and Class::Prototyped.
The docs for this module are still under development. The documentation present is correct, but to really understand the module you need to look at the source.
There are subclasses of Win32::Security::Recursor for each type of supported 
Win32::Security::NamedObject (i.e. 'SE_FILE_OBJECT' for now - 
'SE_REGISTRY_KEY' is not yet supported).  The subclasses are responsible for 
implementing hierarchy specific behavior, such as enumerating child nodes, 
determining whether a node is a container, etc.
newThe new method is entirely inherited from Class::Prototyped.  A list of 
slot names and values may be passed if desired using the normal 
Class::Prototyped::addSlots syntax.
recurseThe recurse method is the heart of Win32::Security::Recursor.  It accepts 
a single object name and recurses through the tree of objects rooted by that 
object.  It does not use recursion, though, but rather a stack-based approach 
that flattens the recursion into a loop.
First, though, it creates an entirely new object to handle the call sequence.  
This object inherits from the object upon which recurse was called, and has a 
nodes slot that consists of an anonymous array of nodes remaining to be 
processed.  Each node is a hash consisting of a name which stores the 
object-name in question, a parent which is a reference to the parent node,
and keys which store cached responses for the various node information calls.
The currently ``active'' node is always the last one on the array. Nodes are pushed onto the array in reverse order so that a depth-first search is effected.
Once the first node is on the array, basic flow through the loop looks like this:
node_filternode on current nodenode_filternode to filter individual node.  If node_filternode 
returns true, execution proceeds through the loop.  The call to 
node_filternode traps die with an eval, so a die is treated like a 
false value.  If the call fails or dies, then the node is popped off of the 
array and the loop restarted.  This happens here to that node_filternode 
filters the nodes in the proper order so that any output is sorted 
appropriately.
payload on current nodepayload is wrapped in an eval and any returned $@ is 
printed to STDERR if $self->debug() is true.
eval.  If any part of it fails, any 
returned $@ is printed to STDERR if $self->debug() is true and then 
the last node is popped off of the array.  The code first calls 
node_iscontainer, and if false simply pops the last node off the array.  
Otherwise, node_enumchildren is called to build a list of child nodes (each 
of which has a parent that points to the current node).  
node_filterchildren is then called, which is responsible for ordering the 
child nodes as desired and for filtering out any nodes which wouldn't result in 
any output.  Finally, the list of child nodes is reversed and used to replace 
the active node.
objectTypeThis returns the objectType for a given Recursor.  Should be overridden by
child classes.
debugThis defaults to true.  Pass in ``[qw(debug constant)] => 0,'' to new to 
turn debug off.
payloadNeeds to be overridden to actually do anything!
node_getinfoUsed to get information about a node and/or the parent node.  This accepts a 
list of ``requests'' and then returns the requested information.  Each request 
consists of a pair of values.  The first value should be either 'node', 
'parent', or a node HASH.  The second value should be either an info
name or a reference to an array of info names.  The permitted info names are:
Win32::Security::NamedObject object for this node.
Win32::Security::ACL object for the DACL of this node.
The information is returned in a list in the order requested.
In order to make it easier to reuse some of my code, I have taken the liberty of 
putting some of my recursors into Win32::Security::Recursor.
Win32::Security::Recursor::SE_FILE_OBJECT::PermDump->new($options)This takes a ref to an options hash and returns a recursor that implements the 
same behavior displayed by PermDump.pl.  It takes an optional list of 
parameters that will be passed to Win32::Security::Recursor::SE_FILE_OBJECT->new so 
as to override or define new methods for the recursor.
Options passable in the options hash are:
Toby Ovod-Everett, toby@ovod-everett.org
| Win32::Security::Recursor - Security recursion for named objects |