Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
SPOPS::Secure::HierarcUser)Contributed Perl DocumenSPOPS::Secure::Hierarchy(3)

       SPOPS::Secure::Hierarchy	- Define hierarchical security

	# In your SPOPS	configuration
	'myobj'	=> {
	   'class' => 'My::FileObject',
	   'isa' => [ qw/ ... SPOPS::Secure::Hierarchy	... / ],
	   'hierarchy_separator' => '/',
	   'hierarchy_field'	 => 'myobj_id',

	# Every	normal SPOPS security check will now go	through	a hierarchy
	# check	using '/' as a separator on the	value of the object parameter
	# 'myobj_id'

	 my $file_object = eval	{ My::FileObject->fetch(
				    '/docs/release/devel-only/v1.3/mydoc.html' ) };

	# You can also use it as a standalone service. Note that the 'class'
	# in this example is controlled	by you and used	as an identifier
	# only.

	my $level = eval { SPOPS::Secure::Hierarchy->check_security({
			     class		   => 'My::Nonexistent::File::Class',
			     user		   => $my_user,
			     group		   => $my_group_list,
			     security_object_class => 'My::SecurityObject',
			     object_id		   => '/docs/release/devel-only/v1.3/mydoc.html',
			     hierarchy_separator   => '/' }) };

       The existing SPOPS security framework relies on a one-to-one mapping of
       security	value to object. Sometimes you need security to	filter down
       from a parent to	any number of children,	such as	in a pseudo-filesystem
       of objects.

       To accomplish this, every record	needs to have an identifier that can
       be manipulated into a parent identifier.	With filesystems (or URLs)
       this is simple. Given the pseudo-file:


       You have	the following parents:

	<ROOT OBJECT> (explained below)

       What this module	does is	check the security of each parent in the
       hierarchy. If no	security settings are found for	an item, the module
       tries to	find security of its parent. This continues until either the
       parent hierarchy	is exhausted or	one of the parents has a security

       If the security were defined like this:

       (Note: this is pseudo-code, and not necessarily the internal

	     { world =>	SEC_LEVEL_READ,
	       group =>	{ admin	=> SEC_LEVEL_WRITE } }

	/docs/release/devel-only =>
	     { world =>	SEC_LEVEL_NONE,
	       group =>	{ devel	=> SEC_LEVEL_WRITE } }

       And our sample file is:


       And our users are:

       o   racerx is a member of groups	'public', 'devel' and

       o   chimchim is a member	of groups 'public', 'sidekicks'

       o   speed is a member of	groups 'public'	and 'devel'

       Then both the users racerx and speed would have SEC_LEVEL_WRITE access
       to the file while chimchim would	have no	access at all.

       For the file:


       All three users would have SEC_LEVEL_READ access	since the permissions
       inherit from the	"ROOT OBJECT".

   What	is the ROOT OBJECT?
       If you have a hierarchy of security, you	are going to need one object
       from which all security flows. No matter	what kind of identifiers,
       separators, etc.	that you are using, the	root object always has the
       same object ID (For the curious,	this object ID is available as the
       exported	scalar $ROOT_OBJECT_NAME from this module.)

       If you do not create security for the root object manually,
       "SPOPS::Secure::Hierarchy" will do so for you. However, you should be
       aware that it will create the most stringent permissions	for such an
       object and that you might have a	difficult time creating/updating
       objects once this happens.

       Here is how to create such security:

		 level => { SEC_SCOPE_WORLD() => SEC_LEVEL_READ,
			    SEC_SCOPE_GROUP() => { 3 =>	SEC_LEVEL_WRITE	} }

       Now, every object created in your class will default to having READ
       permissions for WORLD and WRITE permissions for group ID	3.

       Most of the functionality in this class is found	in SPOPS::Secure. We
       override	one of its methods and add another to implement	the
       functionality of	this module.

       get_hierarchy_levels( \%params )

       Retrieve	security for each level	of the hierarchy. Returns a list --
       the first element is a hashref with the keys as hierarchy elements and
       the values as the security settings for that element (like what you
       would get back if you checked only one item). The second	element	is a
       scalar with the key of the first	item encountered which actually	had


	my ( $all_levels, $first ) = $obj->get_hierarchy_levels();
	print "Level Info:\n", Data::Dumper::Dumper( $all_levels );

	>Level Info:
	> $VAR1	= {
	>  '/docs/release/devel-only/v1.3/mydoc.html' => undef,
	>  '/docs/release/devel-only/v1.3' => undef,
	>  '/docs/release/devel-only' => { u =>	4, g =>	undef, w => 8 },
	>  '/docs/release/' => undef,
	>  '/docs/' => undef,
	>  'ROOT_OBJECT' => { u	=> undef, g => undef, w	=> 4 }

	print "First Level: ", $first;

	> First	Level: /docs/release/devel-only

       get_security( \%params )

       Returns:	hashref	of security information	indexed	by the scopes.


       o   class ($) (not required if calling from object)

	   Class (or generic identifier) for which we would like to check

       o   object_id ($) (not required if calling from object)

	   Unique identifier for the object (or	generic	thing) needing to be

       o   hierarchy_field ($) (only required if calling from object with no

	   Field to be used for	the hierarchy check. Most (all?) of the	time
	   this	will be	the same as your configured 'id_field' in your SPOPS

       o   hierarchy_separator ($) (not	required if calling from object	with

	   Character or	characters used	to split the hierarchy value into

       o   hierarchy_manip (optional)

	   Code	reference that,	given the value	to be broken into chunks, will
	   return a hashref of information that	describe the ways the
	   hierarchy information can be	used.


       This is overridden and a	no-op, since we	do not want SPOPS::Secure to
       create the default WORLD	settings for us	and mess up our	inheritance.

       create_root_object_security( \%params )

       If you are trying to retrofit this security system into a class with
       already existing	objects, you will need a way to	bootstrap it so	that
       you can perform the actions you like. This method will create initial
       security	for you.


       o   scope (\@ or	$)

	   One or more SPOPS::Secure "SEC_SCOPE_*" constants that define the
	   scopes that you are defining	security for.

       o   level (\% or	$)

	   If you have specified more than one item in the 'scope' parameter,
	   this	is a hashref, the keys of which	are the	scopes defined.	The
	   value may be	a SPOPS::Secure	LEVEL constant if the matching scope
	   is WORLD, or	a hashref of object-id - LEVEL pairs if	the matching
	   scope is USER or GROUP. (See	"What is the ROOT OBJECT?" above.)

       None known.

       Revisit when hierarchy field != primary key

       the _get_hierarchy_parameters has an assumption that the	object ID will
       always be the hierarchy value. Fix this.	(Putting off because this is

       Security	for Each Parent	not Required

       Note that each parent as	we go up the hierarchy does not	have to	exist
       in terms	of security. That is, since an object can be both a child and
       a parent, and a child can inherit from a	parent,	then the inheritance
       needs to	be able	to flow	through	more than one generation.


       Copyright (c) 2001-2004, inc..	All rights reserved.

       This library is free software; you can redistribute it and/or modify it
       under the same terms as Perl itself.

       Chris Winters <>

       Christian Lemburg <>

perl v5.32.0			  2004-06-02	   SPOPS::Secure::Hierarchy(3)


Want to link to this manual page? Use this URL:

home | help