3 # py-rsbac - RSBAC Python bindings
4 # Copyright (C) 2006 Frederic Jolliton <pyrsbac@tuxee.net>
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 This module provides access to RC type and RC role objects for the
23 RSBAC Python bindings.
30 if not isinstance( o , basestring ) :
35 raise ImportError , 'duplicate name %r in module %r' % ( name , __name__ )
36 __all__.append( name )
41 from ctypes import byref, c_uint32
43 from rsbac import headers, lib, transaction
44 from rsbac.errors import Error, raiseIfError
45 from rsbac._utils import aptr, slowButCorrectStringAssignation, fetch
47 # Singletons. Obviously bad for MT. But good for performance..
48 g_rcItemValue = headers.rsbac_rc_item_value_t()
49 g_rcItemValueRef = byref( g_rcItemValue )
51 g_rcTargetValue = headers.rsbac_rc_target_id_t()
52 g_rcTargetValueRef = byref( g_rcTargetValue )
54 g_rcTargetValue2 = headers.rsbac_rc_target_id_t()
55 g_rcTargetValue2Ref = byref( g_rcTargetValue2 )
57 g_ttl = headers.rsbac_time_t()
58 g_ttlRef = byref( g_ttl )
60 g_rcNameTargetToItem = {
61 headers.T_FD : headers.RI_type_fd_name ,
62 headers.T_FILE : headers.RI_type_fd_name ,
63 headers.T_DIR : headers.RI_type_fd_name ,
64 headers.T_FIFO : headers.RI_type_fd_name ,
65 headers.T_DEV : headers.RI_type_dev_name ,
66 headers.T_IPC : headers.RI_type_ipc_name ,
67 headers.T_USER : headers.RI_type_user_name ,
68 headers.T_GROUP : headers.RI_type_group_name ,
69 headers.T_PROCESS : headers.RI_type_process_name ,
70 headers.T_NETDEV : headers.RI_type_netdev_name ,
71 headers.T_NETTEMP : headers.RI_type_nettemp_name ,
72 headers.T_NETOBJ : headers.RI_type_netobj_name ,
73 headers.T_SCD : headers.RI_type_scd_name
76 g_rcCompatibilityTargetToItem = {
77 headers.T_FD : headers.RI_type_comp_fd ,
78 headers.T_FILE : headers.RI_type_comp_fd ,
79 headers.T_DIR : headers.RI_type_comp_fd ,
80 headers.T_FIFO : headers.RI_type_comp_fd ,
81 headers.T_DEV : headers.RI_type_comp_dev ,
82 headers.T_IPC : headers.RI_type_comp_ipc ,
83 headers.T_USER : headers.RI_type_comp_user ,
84 headers.T_GROUP : headers.RI_type_comp_group ,
85 headers.T_PROCESS : headers.RI_type_comp_process ,
86 headers.T_NETDEV : headers.RI_type_comp_netdev ,
87 headers.T_NETTEMP : headers.RI_type_comp_nettemp ,
88 headers.T_NETOBJ : headers.RI_type_comp_netobj ,
89 headers.T_SCD : headers.RI_type_comp_scd
92 g_rcTargetToTypeRemove = {
93 headers.T_FD : headers.RI_type_fd_remove ,
94 headers.T_FILE : headers.RI_type_fd_remove ,
95 headers.T_DIR : headers.RI_type_fd_remove ,
96 headers.T_FIFO : headers.RI_type_fd_remove ,
97 headers.T_DEV : headers.RI_type_dev_remove ,
98 headers.T_IPC : headers.RI_type_ipc_remove ,
99 headers.T_USER : headers.RI_type_user_remove ,
100 headers.T_GROUP : headers.RI_type_group_remove ,
101 headers.T_PROCESS : headers.RI_type_process_remove ,
102 headers.T_NETDEV : headers.RI_type_netdev_remove ,
103 headers.T_NETTEMP : headers.RI_type_nettemp_remove ,
104 headers.T_NETOBJ : headers.RI_type_netobj_remove
107 # RC role specific data
108 _g_role_mod = headers.rsbac_rc_role_id_t( -1 ).value + 1
109 assert _g_role_mod > 0
110 _g_role_max_value = headers.rsbac_rc_role_id_t( -32 ).value
113 if n >= _g_role_max_value :
114 return int( n - _g_role_mod )
117 _g_roles = weakref.WeakValueDictionary()
119 -1 : 'inherit_user' ,
120 -2 : 'inherit_process' ,
121 -3 : 'inherit_parent' ,
122 -4 : 'inherit_up_mixed' ,
123 -5 : 'use_force_role'
126 # RC type specific data
127 _g_type_mod = headers.rsbac_rc_type_id_t( -1 ).value + 1
128 assert _g_type_mod > 0
129 _g_type_max_value = headers.rsbac_rc_type_id_t( -32 ).value
132 if n >= _g_type_max_value :
133 return int( n - _g_type_mod )
136 _g_types = weakref.WeakValueDictionary()
138 -1 : 'inherit_process' ,
139 -2 : 'inherit_parent' ,
142 -5 : 'use_new_role_def_create' ,
148 def copyRole( source , dest ) :
151 source -- RC role as integer
152 dest -- RC role as integer
155 raiseIfError( lib.rsbac_rc_copy_role( transaction._t ,
159 def grant( role , type , requests ) :
160 """Grant 'requests' to 'role' for the given 'type'.
164 requests -- RequestVector
167 rights , ttl = role.typeCompatibility[ type ]
168 rights |= rsbac.RequestVector( requests )
169 role.typeCompatibility[ type ] = rights , ttl
172 def revoke( role , type , requests ) :
173 """Revoke 'requests' to 'role' for the given 'type'.
177 requests -- RequestVector
180 rights , ttl = role.typeCompatibility[ type ]
181 rights &= ~rsbac.RequestVector( requests )
182 role.typeCompatibility[ type ] = rights , ttl
184 def findUnnamedRole( start = 0 ) :
185 """Find an unnamed role.
187 start -- Minimal RC role id to use, as integer.
197 if e[ 0 ] != headers.RSBAC_ENOTFOUND :
203 def findUnnamedRoles( n = 1 , start = 0 ) :
204 """Find a set of unnammed roles.
206 n -- Number of unnnamed roles to find.
207 start -- Minimal RC role id to use, as integer.
209 Return a list of integers.
214 for j in range( n ) :
215 role = findUnnamedRole( i )
221 def newRole( name , start = 0 ) :
222 """Create a new RC role.
224 name -- Name for the new RC role.
229 role = findUnnamedRole( start )
230 setRoleName( role , name )
234 def cloneRole( source , start = 0 ) :
235 """Clone a RC role under another name.
237 source -- RC role as integer
238 name -- Name of the new role
241 role = findUnnamedRole( start )
242 copyRole( source , role )
245 def findUnnamedType( target , start = 0 ) :
246 """Find an unnamed type.
248 start -- Minimal RC type id to use, as integer.
255 getTypeName( ( target , i ) )
257 if e[ 0 ] != headers.RSBAC_ENOTFOUND :
263 def findUnnamedTypes( target , n = 1 , start = 0 ) :
264 """Find a set of unnammed types.
266 n -- Number of unnnamed types to find.
267 start -- Minimal RC type id to use, as integer.
269 Return a list of integers.
274 for j in range( n ) :
275 type = findUnnamedType( target , i )
281 def copyType( target , source , dest ) :
284 The target specify which type of RC type should be copied.
286 target -- RSBAC object type as integer
287 source -- RC type as integer
288 dest -- RC Type as integer
291 raiseIfError( lib.rsbac_rc_copy_type( transaction._t , target ,
295 def cloneType( target , source , start = 0 ) :
296 """Clone a RC type under another name.
298 source -- RC type as integer
299 name -- Name of the new type
302 type = findUnnamedType( target , start )
303 copyType( target , source , type )
307 def getList( rcTarget , rcId , item ) :
308 """Retrieve a list of RC items (role or type).
310 rcTarget -- RT_ROLE, RT_TYPE or None.
311 rcId -- role or target as integer.
312 item -- a value from RI_* defines.
315 # FIXME: I'm assuming that all roles are returned when querying
316 # with RI_name, and that target can be NULL. Is that right?
319 elif rcTarget == headers.RT_ROLE :
320 g_rcTargetValue.role = rcId
321 elif rcTarget == headers.RT_TYPE :
322 g_rcTargetValue.type = rcId
324 raise RuntimeError , 'unexpected rc target %d' % ( rcTarget , )
325 arr = fetch( c_uint32 ,
326 lambda n , a : lib.rsbac_rc_get_list( transaction._t ,
327 rcTarget , g_rcTargetValueRef ,
328 item , n , a , None ) )
329 return sorted( map( int , arr ) )
332 def getRoleList( role , item ) :
333 """Retrieve a list of items associated with a role.
335 role -- RC role as integer or None
336 item -- a value from RI_* defines.
339 return getList( headers.RT_ROLE , role , item )
342 def getTypeList( type , item ) :
343 """Retrieve a list of items associated with a type.
345 type -- RC type as integer (or None?)
346 item -- a value from RI_* defines.
349 return getList( headers.RT_TYPE , type , item )
353 """Retrieve a list of all defined roles (those with a name.)
356 # FIXME: I'm assuming that all roles are returned when querying
357 # with RI_name, and that target can be NULL. Is that correct?
358 return getRoleList( None , headers.RI_name )
363 def getTypes( target ) :
364 """Retrieve a list of all defined types (those with a name.)
366 target -- RSBAC object type as integer
369 if target == headers.T_SCD :
371 if g_scdRcTypes is None :
373 for key in dir( headers ) :
374 if ( key.startswith( 'ST_' ) or key.startswith( 'AST_' ) ) \
375 and not key.endswith( '_none' ) :
376 r.append( int( getattr( headers , key ) ) )
381 if target not in g_rcNameTargetToItem :
382 raise RuntimeError , 'Unexpected target %r' % ( target , )
383 return getTypeList( None , g_rcNameTargetToItem[ target ] )
386 def changeRole( role , password = None ) :
387 """Change the role of the current process.
389 role -- RC role as integer
390 password -- the password as a string or None
393 raiseIfError( lib.rsbac_rc_change_role( role , password ) )
396 def getCurrentRole() :
397 """Return the role of the current process.
399 Return a RC role as an integer.
402 role = headers.rsbac_rc_role_id_t()
403 raiseIfError( lib.rsbac_rc_get_current_role( byref( role ) ) )
404 return int( role.value )
407 def getRoleName( role ) :
408 """Get the name of a RC role.
410 role -- RC role as integer
413 g_rcTargetValue.role = role
414 raiseIfError( lib.rsbac_rc_get_item( transaction._t , headers.RT_ROLE ,
415 g_rcTargetValueRef , None ,
416 headers.RI_name , g_rcItemValueRef ,
418 return g_rcItemValue.name
421 def setRoleName( role , name ) :
422 """Set the name of a RC role.
424 role -- RC role as integer
425 name -- the new name as string
428 g_rcTargetValue.role = role
429 slowButCorrectStringAssignation( g_rcItemValue , 'name' , name )
430 raiseIfError( lib.rsbac_rc_set_item( transaction._t , headers.RT_ROLE ,
431 g_rcTargetValueRef , None ,
432 headers.RI_name , g_rcItemValueRef ,
436 def getRoleTypeCompatibility( role , type ) :
437 """Get RC role compatibility with the given type.
439 role -- RC role as integer
440 type -- RC type as either a tuple (target,type) or an Object class
443 Return a tuple (RequestVector,ttl).
446 g_rcTargetValue.role = role
447 target , type = _type( type )
448 g_rcTargetValue2.type = type
449 item = g_rcCompatibilityTargetToItem[ target ]
450 raiseIfError( lib.rsbac_rc_get_item( transaction._t , headers.RT_ROLE ,
451 g_rcTargetValueRef , g_rcTargetValue2Ref ,
452 item , g_rcItemValueRef ,
454 return RequestVector( g_rcItemValue.rights ) , g_ttl.value
457 def setRoleTypeCompatibility( role , type , value ) :
458 """Set RC role compatibility with the given type.
460 role -- RC role as integer
462 value -- A tuple (RequestVector,ttl) or a RequestVector (implying
466 g_rcTargetValue.role = role
467 target , type = _type( type )
468 g_rcTargetValue2.type = type
469 item = g_rcCompatibilityTargetToItem[ target ]
470 if not isinstance( value , ( tuple , list ) ) :
471 value = ( value , 0 )
473 g_rcItemValue.rights = int( rights )
474 raiseIfError( lib.rsbac_rc_set_item( transaction._t , headers.RT_ROLE ,
475 g_rcTargetValueRef , g_rcTargetValue2Ref ,
476 item , g_rcItemValueRef ,
480 def getRoleDefaultIndividualFdCreateType( role , type ) :
481 """Get RC role default individual FD create type
483 role -- RC role as integer
489 # FIXME.. Return an integer, and use Type in the class wrapper
491 g_rcTargetValue.role = role
492 g_rcTargetValue2.type = int( type ) # FIXME: Check target type
493 raiseIfError( lib.rsbac_rc_get_item( transaction._t , headers.RT_ROLE ,
494 g_rcTargetValueRef , g_rcTargetValue2Ref ,
495 headers.RI_def_fd_ind_create_type ,
496 g_rcItemValueRef , None ) )
497 return Type( headers.T_FD , g_rcItemValue.type_id )
500 def setRoleDefaultIndividualFdCreateType( role , type1 , type2 ) :
501 """Set RC role default individual FD create type
503 role -- RC role as integer
508 g_rcTargetValue.role = role
509 g_rcTargetValue2.type = int( type1 ) # FIXME: Check target type
510 g_rcItemValue.type_id = int( type2 ) # FIXME: Check target type
511 raiseIfError( lib.rsbac_rc_set_item( transaction._t , headers.RT_ROLE ,
512 g_rcTargetValueRef , g_rcTargetValue2Ref ,
513 headers.RI_def_fd_ind_create_type ,
514 g_rcItemValueRef , 0 ) )
517 def delRoleDefaultIndividualFdCreateType( role , type ) :
518 """Remove RC role default individidual FD create type setting
520 role -- RC role as integer
523 g_rcTargetValue.role = role
524 g_rcTargetValue2.type = int( type ) # FIXME: Check target type
525 raiseIfError( lib.rsbac_rc_set_item( transaction._t , headers.RT_ROLE ,
526 g_rcTargetValueRef , g_rcTargetValue2Ref ,
527 headers.RI_def_fd_ind_create_type_remove ,
531 def getRoleAdminType( role ) :
532 """Get the RC role admin type.
534 role -- RC role as integer
537 g_rcTargetValue.role = role
538 raiseIfError( lib.rsbac_rc_get_item( transaction._t , headers.RT_ROLE ,
539 g_rcTargetValueRef , None ,
540 headers.RI_admin_type , g_rcItemValueRef ,
542 return g_rcItemValue.admin_type
545 def setRoleAdminType( role , value ) :
546 """Set the RC role admin type.
548 role -- RC role as integer
549 value -- RC role admin type (0 [no admin], 1 [role admin] or 2 [system admin])
552 g_rcTargetValue.role = role
553 g_rcItemValue.admin_type = value
554 raiseIfError( lib.rsbac_rc_set_item( transaction._t , headers.RT_ROLE ,
555 g_rcTargetValueRef , None ,
556 headers.RI_admin_type , g_rcItemValueRef ,
560 def getRoleBootRole( role ) :
561 """Test if the RC role is a boot role.
563 role -- RC role as integer
566 g_rcTargetValue.role = role
567 raiseIfError( lib.rsbac_rc_get_item( transaction._t , headers.RT_ROLE ,
568 g_rcTargetValueRef , None ,
569 headers.RI_boot_role ,
570 g_rcItemValueRef , None ) )
571 return bool( g_rcItemValue.boot_role )
574 def setRoleBootRole( role , value ) :
575 """Set if the RC role is a boot role.
577 role -- RC role as integer
581 g_rcTargetValue.role = role
582 g_rcItemValue.boot_role = value
583 raiseIfError( lib.rsbac_rc_set_item( transaction._t , headers.RT_ROLE ,
584 g_rcTargetValueRef , None ,
585 headers.RI_boot_role ,
586 g_rcItemValueRef , 0 ) )
589 def getRoleRequireReauthentication( role ) :
590 """Test if the role requires reauthentication
592 role -- RC role as integer
595 g_rcTargetValue.role = role
596 raiseIfError( lib.rsbac_rc_get_item( transaction._t , headers.RT_ROLE ,
597 g_rcTargetValueRef , None ,
598 headers.RI_req_reauth ,
599 g_rcItemValueRef , None ) )
600 return bool( g_rcItemValue.req_reauth )
603 def setRoleRequireReauthentication( role , value ) :
604 """Set if the role requires reauthentication
606 role -- RC role as integer
610 g_rcTargetValue.role = role
611 g_rcItemValue.req_reauth = value
612 raiseIfError( lib.rsbac_rc_set_item( transaction._t , headers.RT_ROLE ,
613 g_rcTargetValueRef , None ,
614 headers.RI_req_reauth ,
615 g_rcItemValueRef , 0 ) )
618 def removeRole( role ) :
621 role -- RC role as integer
624 g_rcTargetValue.role = role
625 raiseIfError( lib.rsbac_rc_set_item( transaction._t , headers.RT_ROLE ,
626 g_rcTargetValueRef , None ,
627 headers.RI_remove_role , None , 0 ) )
629 def makeGetSetRoles( name , item , docGet = None , docSet = None ) :
631 RT_ROLE = headers.RT_ROLE
632 def get( roleA , roleB ) :
633 g_rcTargetValue.role = roleA
634 g_rcTargetValue2.role = roleB
635 raiseIfError( lib.rsbac_rc_get_item( transaction._t , RT_ROLE ,
636 g_rcTargetValueRef , g_rcTargetValue2Ref ,
637 item , g_rcItemValueRef , g_ttlRef ) )
638 return int( g_ttl.value ) or bool( g_rcItemValue.comp )
639 if docGet is not None :
640 get.__doc__ = docGet + """
642 roleA -- RC role as integer
643 roleB -- RC role as integer
646 def set( roleA , roleB , value ) :
647 g_rcTargetValue.role = roleA
648 g_rcTargetValue2.role = roleB
650 flag , ttl = True , 0
651 elif not value or value < 1 :
652 flag , ttl = False , 0
654 flag , ttl = True , value
655 g_rcItemValue.comp = flag
656 raiseIfError( lib.rsbac_rc_set_item( transaction._t , RT_ROLE ,
657 g_rcTargetValueRef , g_rcTargetValue2Ref ,
658 item , g_rcItemValueRef , ttl ) )
659 if docSet is not None :
660 set.__doc__ = docSet + """
662 roleA -- RC role as integer
663 roleB -- RC role as integer
664 value -- False, True or an integer.
668 return getList( RT_ROLE , role , item )
669 m = sys.modules[ __name__ ]
670 setattr( m , 'get' + name , get )
671 setattr( m , 'set' + name , set )
672 setattr( m , 'list' + name + 's' , list )
673 __all__.append( 'get' + name )
674 __all__.append( 'set' + name )
675 __all__.append( 'list' + name + 's' )
677 makeGetSetRoles( 'RoleCompatibilityRole' , headers.RI_role_comp ,
678 'Test if the RC role is compatible with another one.' ,
679 'Set if the RC role is compatible with another one.' )
681 makeGetSetRoles( 'RoleAdminRole' , headers.RI_admin_roles ,
685 makeGetSetRoles( 'RoleAssignRole' , headers.RI_assign_roles ,
689 # FIXME: dict interface!
690 class RoleTtlDictProxy( object ) :
691 __slots__ = ( '__name' , '__role' , '__get' , '__set' , '__list' )
692 def __init__( self , name , role , get , set , list ) :
698 def __iter__( self ) :
699 return iter( self.__list( self.__role ) )
700 def __contains__( self , role ) :
701 return bool( self.__get( self.__role , role ) )
702 def __getitem__( self , role ) :
703 return self.__get( self.__role , role )
704 def __setitem__( self , role , value ) :
705 # FIXME: __setitem__ = Role( self.role ).setRoleCompatibility?
706 self.__set( self.__role , role , value )
707 def __delitem__( self , role ) :
708 self.__set( self.__role , role , False )
709 def __repr__( self ) :
712 value = self.__get( self.__role , role )
714 r.append( str( role ) )
715 elif value is False :
718 r.append( '%s(%ds)' % ( role , value ) )
720 name = `getRoleName( self.__role )`
722 if e[ 0 ] != headers.RSBAC_ENOTFOUND :
725 return '<%s for RC Role %d (%s): %s>' \
726 % ( self.__name , self.__role , name ,
727 ', '.join( r ) or 'none' )
732 # Be careful with TTL..
734 value = self.__get( self.__role , role )
736 r.append( ( role , value ) )
738 def add( self , role ) :
739 self.__set( self.__role , role , True )
740 def discard( self , role ) :
741 self.__set( self.__role , role , False )
744 self.__set( self.__role , role , False )
746 class RoleTypeCompatibility( object ) :
747 __slots__ = ( 'role' , )
748 def __init__( self , role ) :
750 def __getitem__( self , type ) :
751 return getRoleTypeCompatibility( self.role , type )
752 def __setitem__( self , type , value ) :
753 return setRoleTypeCompatibility( self.role , type , value )
754 def __repr__( self ) :
755 return '<RoleTypeCompatibility with RC role %d>' % ( self.role , )
757 class DefaultIndividualFdCreateType( object ) :
758 __slots__ = ( 'role' , )
759 def __init__( self , role ) :
761 def __getitem__( self , type ) :
762 return self.role.getDefaultIndividualFdCreateType( type )
763 def get( self , type ) :
767 if e[ 0 ] != headers.RSBAC_ENOTFOUND :
769 def __setitem__( self , type , value ) :
770 self.role.setDefaultIndividualFdCreateType( type , value )
771 def __delitem__( self , type ) :
772 self.role.delDefaultIndividualFdCreateType( type )
774 class DefaultTypes( object ) :
775 __slots__ = ( 'role' , )
776 def __init__( self , role ) :
778 def __getitem__( self , action ) :
779 return self.role.getDefaultType( action )
780 def __setitem__( self , action , value ) :
781 self.role.setDefaultType( action , value )
784 from objects import Scd
785 if isinstance( t , Type ) :
786 return t.target , t.type
787 elif isinstance( t , Scd ) :
792 class RoleBase( object ) :
793 __slots__ = ( '__weakref__' ,
795 'compatibility' , 'adminRoles' , 'assignRoles' ,
796 'typeCompatibility' , 'defaultIndividualFdCreateType' )
797 def __new__( cls , role ) :
798 role = _nrole( role )
799 instance = _g_roles.get( role )
800 if instance is None :
801 instance = object.__new__( cls )
802 instance.__init_singleton__( role )
803 _g_roles[ role ] = instance
805 def __init_singleton__( self , role ) :
806 self._role = int( role )
807 id = headers.rsbac_rc_target_id_t()
809 self._id = byref( id )
810 self.compatibility = \
811 RoleTtlDictProxy( 'RoleCompatibility' , self._role ,
812 getRoleCompatibilityRole ,
813 setRoleCompatibilityRole ,
814 listRoleCompatibilityRoles )
816 RoleTtlDictProxy( 'AdminRoles' , self._role ,
821 RoleTtlDictProxy( 'AssignRoles' , self._role ,
824 listRoleAssignRoles )
825 self.typeCompatibility = \
826 RoleTypeCompatibility( self._role )
827 self.defaultIndividualFdCreateType = \
828 DefaultIndividualFdCreateType( self._role )
829 def __int__( self ) :
830 return int( self._role )
831 def __long__( self ) :
832 return long( self._role )
833 def __repr__( self ) :
835 return '<RC PseudoRole [%d] %s>' \
837 _g_pseudoRoles.get( self._role , 'unknown' ) )
840 name = `self.getName()`
843 return '<RC Role [%d] %s>' % ( self._role , name )
844 def copyTo( self , dest ) :
845 copyRole( self._role , int( dest ) )
846 def clone( self , name = None ) :
847 role = Role( cloneRole( self._role ) )
848 if name is not None :
856 id = property( getId )
860 def getName( self ) :
861 return getRoleName( self._role )
862 def setName( self , name ) :
863 return setRoleName( self._role , name )
864 name = property( getName , setName )
868 def getRoleCompatibility( self , role ) :
869 return getRoleRoleCompatibility( self._role , role )
870 def setRoleCompatibility( self , role , value ) :
871 return setRoleRoleCompatibility( self._role , role , value )
875 def getAdminRole( self , role ) :
876 return getRoleAdminRole( self._role , role )
877 def setAdminRole( self , role , value ) :
878 return setRoleAdminRole( self._role , role , value )
882 def getAssignRole( self , role ) :
883 return getRoleAssignRole( self._role , role )
884 def setAssignRole( self , role , value ) :
885 return setRoleAssignRole( self._role , role , value )
889 def getTypeCompatibility( self , type ) :
890 return getRoleTypeCompatibility( self._role , type )
891 def setTypeCompatibility( self , type , value ) :
892 return setRoleTypeCompatibility( self._role , type , value )
894 # def_fd_ind_create_type
896 def getDefaultIndividualFdCreateType( self , type ) :
897 return getRoleDefaultIndividualFdCreateType( self._role , type )
898 def setDefaultIndividualFdCreateType( self , type1 , type2 ) :
899 return setRoleDefaultIndividualFdCreateType( self._role , type1 , type2 )
900 def delDefaultIndividualFdCreateType( self , type ) :
901 return delRoleDefaultIndividualFdCreateType( self._role , type )
905 def getBootRole( self ) :
906 return getRoleBootRole( self._role )
907 def setBootRole( self , value ) :
908 return setRoleBootRole( self._role , value )
909 bootRole = property( getBootRole , setBootRole )
913 def getRequireReauthentication( self ) :
914 return getRoleRequireReauthentication( self._role )
915 def setRequireReauthentication( self , value ) :
916 return setRoleRequireReauthentication( self._role , value )
917 requireReauthentication = property( getRequireReauthentication ,
918 setRequireReauthentication )
922 def getAdminType( self ) :
923 return getRoleAdminType( self._role )
924 def setAdminType( self , value ) :
925 return setRoleAdminType( self._role , value )
926 adminType = property( getAdminType , setAdminType )
931 removeRole( self._role )
933 def createRoleClass() :
934 attrs = { '__slots__' : () }
935 def addAttribute( target , name ) :
936 pname = 'default' + ''.join( [ s.capitalize() for s in name.split( '_' ) ] ) + 'Type'
937 cpname = pname[ 0 ].upper() + pname[ 1 : ]
938 #pname = 'def_%s_type' % name
939 item = getattr( headers , 'RI_def_%s_type' % name )
941 raiseIfError( lib.rsbac_rc_get_item( 0 , headers.RT_ROLE ,
943 item , g_rcItemValueRef ,
945 return g_rcItemValue.type_id
946 def setter( id , value ) :
947 g_rcItemValue.type_id = value
948 raiseIfError( lib.rsbac_rc_set_item( 0 , headers.RT_ROLE ,
950 item , g_rcItemValueRef ,
953 return Type( target , getter( self._id ) )
954 def mset( self , value ) :
955 return setter( self._id , int( value ) )
956 attrs[ 'getter_' + pname ] = staticmethod( getter )
957 attrs[ 'setter_' + pname ] = staticmethod( setter )
959 attrs[ 'get' + cpname ] = mget
960 attrs[ 'set' + cpname ] = mset
961 attrs[ pname ] = property( mget , mset )
962 for target , name in (
963 ( headers.T_FD , 'fd_create' ) ,
964 ( headers.T_USER , 'user_create' ) ,
965 ( headers.T_GROUP , 'group_create' ) ,
966 ( headers.T_PROCESS , 'process_create' ) ,
967 ( headers.T_PROCESS , 'process_chown' ) ,
968 ( headers.T_PROCESS , 'process_execute' ) ,
969 ( headers.T_IPC , 'ipc_create' ) ,
970 ( headers.T_FD , 'unixsock_create' ) ) :
971 addAttribute( target , name )
972 return type( 'Role' , ( RoleBase , ) , attrs )
975 Role = createRoleClass()
977 #-----------------------------------------------------------------------------
980 def getTypeName( type ) :
981 """Get the name of a RC type
986 target , type = _type( type )
987 g_rcTargetValue.type = type
988 raiseIfError( lib.rsbac_rc_get_item( transaction._t , headers.RT_TYPE ,
989 g_rcTargetValueRef , None ,
990 g_rcNameTargetToItem[ target ] ,
991 g_rcItemValueRef , None ) )
992 return g_rcItemValue.name
995 def setTypeName( type , name ) :
996 """Set the name of a RC type
999 name -- the new name as string
1002 target , type = _type( type )
1003 g_rcTargetValue.type = type
1004 slowButCorrectStringAssignation( g_rcItemValue , 'name' , name )
1005 raiseIfError( lib.rsbac_rc_set_item( transaction._t , headers.RT_TYPE ,
1006 g_rcTargetValueRef , None ,
1007 g_rcNameTargetToItem[ target ] ,
1008 g_rcItemValueRef , 0 ) )
1011 def getTypeNeedSecureDelete( type ) :
1012 """Test if the RC type need secure delete.
1017 target , type = _type( type )
1018 g_rcTargetValue.type = type
1019 if target != headers.T_FD :
1020 raise RuntimeError , 'attribute available for the FD type only'
1021 raiseIfError( lib.rsbac_rc_get_item( transaction._t , headers.RT_TYPE ,
1022 g_rcTargetValueRef , None ,
1023 headers.RI_type_fd_need_secdel ,
1024 g_rcItemValueRef , None ) )
1025 return bool( g_rcItemValue.need_secdel )
1028 def setTypeNeedSecureDelete( type , value ) :
1029 """Set if the RC type need secure delete.
1035 target , type = _type( type )
1036 g_rcTargetValue.type = type
1037 if target != headers.T_FD :
1038 raise RuntimeError , 'attribute available for the FD type only'
1039 g_rcItemValue.need_secdel = value
1040 raiseIfError( lib.rsbac_rc_set_item( transaction._t , headers.RT_TYPE ,
1041 g_rcTargetValueRef , None ,
1042 headers.RI_type_fd_need_secdel ,
1043 g_rcItemValueRef , 0 ) )
1046 def removeType( type ) :
1047 """Remove a RC type.
1052 target , type = _type( type )
1053 g_rcTargetValue.type = type
1054 raiseIfError( lib.rsbac_rc_set_item( transaction._t , headers.RT_TYPE ,
1055 g_rcTargetValueRef , None ,
1056 g_rcTargetToTypeRemove[ target ] ,
1059 class Type( object ) :
1060 __slots__ = ( '__weakref__' ,
1062 def __new__( cls , target , type ) :
1063 if hasattr( target , 'type' ) :
1064 target = target.type
1065 type = _ntype( type )
1068 t = ( target , type )
1069 instance = _g_types.get( t )
1070 if instance is None :
1071 instance = object.__new__( cls )
1072 instance.__init_singleton__( target , type )
1073 _g_types[ t ] = instance
1075 def __init_singleton__( self , target , type ) :
1076 self.__id = ( target , type )
1077 def __eq__( self , other ) :
1078 if isinstance( other , ( int , long ) ) :
1079 return self.type == _ntype( other )
1081 return ( self is other
1082 or ( isinstance( other , Type )
1083 and self.__id == other.__id ) )
1084 def __int__( self ) :
1085 return int( self.__id[ 1 ] )
1086 def __long__( self ) :
1087 return long( self.__id[ 1 ] )
1088 def __repr__( self ) :
1089 target , type = self.__id
1091 return '<RC PseudoType [%d] %s>' \
1093 _g_pseudoTypes.get( type , 'unknown' ) , )
1096 name = `self.getName()`
1099 return '<RC Type [%d:%d] %s>' % ( target , type , name )
1100 def copyTo( self , dest ) :
1101 copyType( self.__id[ 0 ] , self.__id[ 1 ] , int( dest ) )
1102 def clone( self , name = None ) :
1103 type = Type( self.__id[ 0 ] , cloneType( *self.__id ) )
1104 if name is not None :
1110 target = property( lambda self : self.__id[ 0 ] )
1111 type = property( lambda self : self.__id[ 1 ] )
1115 def getName( self ) :
1116 return getTypeName( self.__id )
1117 def setName( self , name ) :
1118 return setTypeName( self.__id , name )
1119 name = property( getName , setName )
1123 def getNeedSecureDelete( self ) :
1124 return getTypeNeedSecureDelete( self.__id )
1125 def setNeedSecureDelete( self , value ) :
1126 return setTypeNeedSecureDelete( self.__id , value )
1127 needSecureDelete = property( getNeedSecureDelete , setNeedSecureDelete )
1131 def delete( self ) :
1132 removeType( self.__id )
1134 pseudoRoles = new.module( 'pseudoRoles' )
1135 for k , v in _g_pseudoRoles.items() :
1136 setattr( pseudoRoles , v , Role( k ) )
1137 pseudoTypes = new.module( 'pseudoTypes' )
1138 for k , v in _g_pseudoTypes.items() :
1139 setattr( pseudoTypes , v , Type( None , k ) )
1141 class RcRoleDict( object ) :
1146 return [ ( id , Role( id ) ) for id in self.keys() ]
1147 def values( self ) :
1148 return [ Role( id ) for id in self.keys() ]
1149 def __iter__( self ) :
1150 return iter( self.keys() )
1151 def __getitem__( self , id ) :
1153 def __setitem__( self , *args ) :
1155 def __delitem__( self , id ) :
1157 def __repr__( self ) :
1158 return '{' + ', '.join( [ ': '.join( map( repr , item ) ) for item in self.items() ] ) + '}'
1160 def newType( target , name , start = 0 ) :
1162 if hasattr( target , 'type' ) :
1163 target = target.type
1166 Type( target , i ).name
1168 if e[ 0 ] != headers.RSBAC_ENOTFOUND :
1170 t = Type( target , i )
1175 class RcTypeDict( object ) :
1176 __slots__ = ( 'target' , )
1177 def __init__( self , target ) :
1178 self.target = target
1180 return getTypes( self.target )
1182 return [ ( id , Type( self.target , id ) ) for id in self.keys() ]
1183 def values( self ) :
1184 return [ Type( self.target , id ) for id in self.keys() ]
1185 def __iter__( self ) :
1186 return iter( self.keys() )
1187 def __getitem__( self , id ) :
1188 return Type( self.target , id )
1189 def __setitem__( self , *args ) :
1191 def __delitem__( self , id ) :
1192 Type( self.target , id ).delete()
1193 def __repr__( self ) :
1194 return '{' + ', '.join( [ ': '.join( map( repr , item ) ) for item in self.items() ] ) + '}'
1196 roles = RcRoleDict()
1198 from rsbac._data import RequestVector
1201 # indent-tabs-mode: nil