Fixed acl.clear() for objects.defaultProcess. Fixed acl.Group._id name.
[py-rsbac] / rsbac / acl.py
1 # -*- coding:utf-8 -*-
2
3 # py-rsbac - RSBAC Python bindings
4 # Copyright (C) 2006  Frederic Jolliton <pyrsbac@tuxee.net>
5
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.
10
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.
15
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
19
20 __all__ = [ 'Group' , 'groups' ]
21
22 def export( o ) :
23     if not isinstance( o , basestring ) :
24         name = o.__name__
25     else :
26         name , o = o , None
27     if name in __all__ :
28         raise ImportError , 'duplicate name %r in module %r' % ( name , __name__ )
29     __all__.append( name )
30     return o
31
32 from ctypes import byref, pointer
33
34 from rsbac import headers, lib, transaction
35 from rsbac._data import AclRequestVector
36 from rsbac.errors import raiseIfError, Error
37 from rsbac._utils import fetch, intToTtl, ttlToInt
38
39 g_aclSyscallArg = headers.rsbac_acl_syscall_arg_t()
40 g_aclSyscallArgRef = byref( g_aclSyscallArg )
41
42 g_aclSyscallByNameArg = headers.rsbac_acl_syscall_n_arg_t()
43 g_aclSyscallByNameArgRef = byref( g_aclSyscallByNameArg )
44
45 # for acl_remove_user
46 g_targetId = headers.rsbac_target_id_t()
47
48 def _acl_preset( target , tid , subjectType , subjectId , rights , ttl ) :
49     g_aclSyscallArg.target = target
50     g_aclSyscallArg.tid = tid
51     g_aclSyscallArg.subj_type = subjectType
52     g_aclSyscallArg.subj_id = subjectId
53     g_aclSyscallArg.rights = rights
54     g_aclSyscallArg.ttl = ttl
55     return g_aclSyscallArgRef
56
57 def _acl_preset_n( target , name , subjectType , subjectId , rights , ttl ) :
58     g_aclSyscallByNameArg.target = target
59     g_aclSyscallByNameArg.name = name
60     g_aclSyscallByNameArg.subj_type = subjectType
61     g_aclSyscallByNameArg.subj_id = subjectId
62     g_aclSyscallByNameArg.rights = rights
63     g_aclSyscallByNameArg.ttl = ttl
64     return g_aclSyscallByNameArgRef
65
66 def _to_acl_subject( object ) :
67     from rsbac.objects import User
68     if isinstance( object , Role ) :
69         return headers.ACLS_ROLE , object._role
70     elif isinstance( object , User ) :
71         return headers.ACLS_USER , object.uid
72     elif isinstance( object , Group ) :
73         return headers.ACLS_GROUP , object._id
74     else :
75         raise RuntimeError , 'unexpected ACL subject of type %r' % ( object.__class__ , )
76
77 def _from_acl_subject( type , id ) :
78     if type == headers.ACLS_USER :
79         return User( id )
80     elif type == headers.ACLS_ROLE :
81         return Role( id )
82     elif type == headers.ACLS_GROUP :
83         return Group( id )
84     else :
85         raise RuntimeError , 'unexpected subject type %r' % ( type , )
86
87 #
88 # set_acl_entry
89 #
90
91 def setAclEntryById( target , subject , rights , ttl = None ) :
92     st , si = _to_acl_subject( subject )
93     raiseIfError( lib.rsbac_acl( transaction._t ,
94                                  headers.ACLC_set_acl_entry ,
95                                  _acl_preset( target.type , target._id._obj ,
96                                               st , si ,
97                                               int( rights ) , ttlToInt( ttl ) ) ) )
98
99 def setAclEntryByName( target , subject , rights , ttl = None ) :
100     st , si = _to_acl_subject( subject )
101     raiseIfError( lib.rsbac_acl_n( transaction._t ,
102                                    headers.ACLC_set_acl_entry ,
103                                    _acl_preset_n( target.type , target._id ,
104                                                   st , si ,
105                                                   int( rights ) , ttlToInt( ttl ) ) ) )
106
107 #
108 # remove_acl_entry
109 #
110
111 def removeAclEntryById( target , subject ) :
112     st , si = _to_acl_subject( subject )
113     raiseIfError( lib.rsbac_acl( transaction._t ,
114                                  headers.ACLC_remove_acl_entry ,
115                                  _acl_preset( target.type , target._id._obj ,
116                                               st , si ,
117                                               0 , 0 ) ) )
118
119 def removeAclEntryByName( target , subject ) :
120     st , si = _to_acl_subject( subject )
121     raiseIfError( lib.rsbac_acl_n( transaction._t ,
122                                    headers.ACLC_remove_acl_entry ,
123                                    _acl_preset_n( target.type , target._id ,
124                                                   st , si ,
125                                                   0 , 0 ) ) )
126
127 #
128 # remove_acl
129 #
130
131 def removeAclById( target ) :
132     raiseIfError( lib.rsbac_acl( transaction._t ,
133                                  headers.ACLC_remove_acl ,
134                                  _acl_preset( target.type , target._id._obj ,
135                                               0 , 0 , 0 , 0 ) ) )
136
137 def removeAclByName( target ) :
138     raiseIfError( lib.rsbac_acl_n( transaction._t ,
139                                    headers.ACLC_remove_acl ,
140                                    _acl_preset_n( target.type , target._id ,
141                                                   0 , 0 , 0 , 0 ) ) )
142
143 # add_to_acl_entry
144 # remove_from_acl_entry
145
146 #
147 # set_mask
148 #
149
150 def setAclMaskById( target , mask ) :
151     raiseIfError( lib.rsbac_acl( transaction._t ,
152                                  headers.ACLC_remove_acl ,
153                                  _acl_preset( target.type , target._id._obj ,
154                                               0 , 0 ,
155                                               mask , 0 ) ) )
156
157 def setAclMaskByName( target , mask ) :
158     raiseIfError( lib.rsbac_acl_n( transaction._t ,
159                                    headers.ACLC_remove_acl ,
160                                    _acl_preset_n( target.type , target._id ,
161                                                   0 , 0 ,
162                                                   mask , 0 ) ) )
163
164 #
165 # remove_user
166 #
167
168 @export
169 def aclRemoveUser( user ) :
170     """Remove user from all groups and all ACLs.
171
172     user -- UID as integer
173
174     """
175     g_targetId.user = user
176     raiseIfError( lib.rsbac_acl( transaction._t ,
177                                  headers.ACLC_remove_user ,
178                                  _acl_preset( headers.T_USER , g_targetId ,
179                                               0 , 0 , 0 , 0 ) ) )
180
181 #
182 # get_acl_rights
183 #
184
185 def getAclRightsById( target , subject , effective = False ) :
186     st , si = _to_acl_subject( subject )
187     rights = headers.rsbac_acl_rights_vector_t()
188     raiseIfError( lib.rsbac_acl_get_rights( transaction._t ,
189                                             _acl_preset( target.type , target._id._obj ,
190                                                          st , si ,
191                                                          0 , 0 ) ,
192                                             byref( rights ) ,
193                                             effective ) )
194     return AclRequestVector( rights.value )
195
196 def getAclRightsByName( target , subject , effective = False ) :
197     st , si = _to_acl_subject( subject )
198     rights = headers.rsbac_acl_rights_vector_t()
199     raiseIfError( lib.rsbac_acl_get_rights_n( transaction._t ,
200                                               _acl_preset_n( target.type , target._id ,
201                                                              st , si ,
202                                                              0 , 0 ) ,
203                                               byref( rights ) ,
204                                               effective ) )
205     return AclRequestVector( rights.value )
206
207 #
208 # acl_get_tlist
209 #
210
211 def _unpackAclTlist( entries , ttls ) :
212     return [ ( _from_acl_subject( entry.subj_type , entry.subj_id ) ,
213                AclRequestVector( entry.rights ) ,
214                intToTtl( ttl ) )
215              for entry , ttl in zip( entries , ttls ) ]
216
217 def getAclTargetListById( target ) :
218     arrs = fetch( ( headers.rsbac_acl_entry_t ,
219                     headers.rsbac_time_t ) ,
220                   lambda n , a , b : lib.rsbac_acl_get_tlist( transaction._t ,
221                                                               target.type ,
222                                                               target._id._obj ,
223                                                               a , b , n ) ,
224                   32 )
225     return _unpackAclTlist( *arrs )
226
227 def getAclTargetListByName( target ) :
228     arrs = fetch( ( headers.rsbac_acl_entry_t ,
229                     headers.rsbac_time_t ) ,
230                   lambda n , a , b : lib.rsbac_acl_get_tlist_n( transaction._t ,
231                                                                 target.type ,
232                                                                 target._id ,
233                                                                 a , b , n ) ,
234                   32 )
235     return _unpackAclTlist( *arrs )
236
237 #
238 # acl_get_mask
239 #
240
241 def getAclMaskById( target ) :
242     rights = headers.rsbac_acl_rights_vector_t()
243     raiseIfError( lib.rsbac_acl_get_mask( transaction._t ,
244                                           target.type , target._id._obj ,
245                                           byref( rights ) ) )
246     return AclRequestVector( rights.value )
247
248 def getAclMaskByName( target ) :
249     rights = headers.rsbac_acl_rights_vector_t()
250     raiseIfError( lib.rsbac_acl_get_mask_n( transaction._t ,
251                                             target.type , target._id ,
252                                             byref( rights ) ) )
253     return AclRequestVector( rights.value )
254
255 #
256 # dispatchers
257 #
258
259 @export
260 def setAclEntry( target , subject , rights , ttl = None ) :
261     """Set an ACL entry for a target-subject couple.
262
263     target -- Object
264     subject -- either an instance of objects.User, acl.Group or rc.Role.
265     rights -- AclRequestVector
266     ttl -- None or a positive integer
267
268     """
269     if target._byName :
270         return setAclEntryByName( target , subject , rights , ttl )
271     else :
272         return setAclEntryById( target , subject , rights , ttl )
273
274 @export
275 def removeAclEntry( target , subject ) :
276     """Remove an ACL entry.
277
278     target -- Object
279     subject -- either an instance of objects.User, acl.Group or rc.Role.
280
281     """
282     if target._byName :
283         return removeAclEntryByName( target , subject )
284     else :
285         return removeAclEntryById( target , subject )
286
287 @export
288 def removeAcl( target ) :
289     """Remove all ACL entries on a target.
290
291     target -- Object
292
293     """
294     if target._byName :
295         return removeAclByName( target )
296     else :
297         return removeAclById( target )
298
299 @export
300 def setAclMask( target , mask ) :
301     """Set ACL mask on a target.
302
303     target -- Object
304     mask -- AclRequestVector
305
306     """
307     if target._byName :
308         return setAclMaskByName( target , mask )
309     else :
310         return setAclMaskById( target , mask )
311
312 @export
313 def getAclRights( target , subject , effective = False ) :
314     """Get ACL rights for a target-subject couple.
315
316     target -- Object
317     subject -- either an instance of objects.User, acl.Group or rc.Role.
318     effective -- True to retrieve effective rights, False otherwise.
319
320     Returns an AclRequestVector.
321
322     """
323     if target._byName :
324         return getAclRightsByName( target , subject , effective )
325     else :
326         return getAclRightsById( target , subject , effective )
327
328 @export
329 def getAclMask( target ) :
330     """Get ACL mask for a target.
331
332     target -- Object
333
334     Returns an AclRequestVector.
335
336     """
337     if target._byName :
338         return getAclMaskByName( target , mask )
339     else :
340         return getAclMaskById( target , mask )
341
342 @export
343 def getAclTargetList( target ) :
344     """Get all ACL entries for a target.
345
346     target -- Object
347
348     Returns a list of 3-tuple (Object, AclRequestVector, ttl).
349
350     """
351     if target._byName :
352         return getAclTargetListByName( target )
353     else :
354         return getAclTargetListById( target )
355
356 class AclBase( object ) :
357     def __init__( self , target ) :
358         object.__init__( self )
359         self.target = target
360     def __len__( self ) :
361         return len( self._list() )
362     def __iter__( self ) :
363         return iter( self.keys() )
364     def __repr__( self ) :
365         return '<ACL for %s: %d entries>' % ( repr( self.target ).strip( '<>' ) , len( self ) )
366     def keys( self ) :
367         return [ e[ 0 ] for e in self._list() ]
368     def values( self ) :
369         return [ ( e[ 1 ] , e[ 2 ] ) for e in self._list() ]
370     def items( self ) :
371         return [ ( e[ 0 ] , ( e[ 1 ] , e[ 2 ] ) ) for e in self._list() ]
372
373 class AclById( AclBase ) :
374     def _list( self ) :
375         return getAclTargetListById( self.target )
376     def __getitem__( self , subject ) :
377         # FIXME: temporary solution. Waiting for an O(1) way to get
378         # (right,TTL) couple.
379         for k , v in self.items() :
380             if k == subject :
381                 return v
382         #return AclRequestVector() , None
383         raise RuntimeError
384     def __setitem__( self , subject , value ) :
385         if not isinstance( value , tuple ) :
386             value = value , None
387         rights , ttl = value
388         setAclEntryById( self.target , subject , rights , ttl )
389     def __delitem__( self , subject ) :
390         removeAclEntryById( self.target , subject )
391     # def update( self ) : pass
392     def clear( self ) :
393         # FIXME: temporary solution. Should sys_rsbac_remove_acl
394         # handle T_PROCESS instead?
395         if isinstance( self.target , Process ) :
396             map( self.__delitem__ , self )
397         else :
398             removeAclById( self.target )
399
400 class AclByName( AclBase ) :
401     def _list( self ) :
402         return getAclTargetListByName( self.target )
403     def __iter__( self ) :
404         return ( n[ 0 ] for n in self.__list() )
405     def __getitem__( self , subject ) :
406         # FIXME: temporary solution. Waiting for an O(1) way to get
407         # (right,TTL) couple.
408         for k , v in self.items() :
409             if k == subject :
410                 return v
411         #return RequestVector() , None
412         raise RuntimeError
413     def __setitem__( self , subject , value ) :
414         if not isinstance( value , tuple ) :
415             value = value , None
416         rights , ttl = value
417         setAclEntryByName( self.target , subject , rights , ttl )
418     def __delitem__( self , subject ) :
419         removeAclEntryByName( self.target , subject )
420     def clear( self ) :
421         removeAclByName( self.target )
422
423 #--[ Group ]------------------------------------------------------------------
424
425 @export
426 def addGroup( name , type = headers.ACLG_PRIVATE , id = None ) :
427     """Add an ACL group.
428
429     type -- type of group (either ACLG_GLOBAL or ACLG_PRIVATE)
430     name -- group name as string
431     id -- a positive integer or None (automatic ID)
432
433     Returns the ID of the new group.
434
435     """
436     if id is None :
437         id = 0
438     id_ = headers.rsbac_acl_group_id_t()
439     id_.value = id
440     arg = headers.rsbac_acl_group_syscall_arg_t()
441     arg.add_group.type = type
442     arg.add_group.name = name
443     arg.add_group.group_id_p = pointer( id_ )
444     raiseIfError( lib.rsbac_acl_group( transaction._t ,
445                                        headers.ACLGS_add_group ,
446                                        byref( arg ) ) )
447     return int( id_.value )
448
449 @export
450 def addGlobalGroup( name , id = None ) :
451     """Add an ACL global group.
452
453     name -- group name as string
454     id -- a positive integer or None (automatic ID)
455
456     Returns the ID of the new group.
457
458     """
459     return addGroup( name , headers.ACLG_GLOBAL , id )
460
461 @export
462 def addPrivateGroup( name , id = None ) :
463     """Add an ACL private group.
464
465     name -- group name as string
466     id -- a positive integer or None (automatic ID)
467
468     Returns the ID of the new group.
469
470     """
471     return addGroup( name , headers.ACLG_PRIVATE , id )
472
473 @export
474 def changeGroup( id , owner , type , name ) :
475     """Change ACL group attributes.
476
477     Change the owner, type and name of an existing ACL group.
478
479     id -- ACL group as integer
480     owner -- user as integer
481     type -- either headers.ACLG_PRIVATE or headers.ACLG_GLOBAL
482     name -- group name
483
484     """
485     arg = headers.rsbac_acl_group_syscall_arg_t()
486     arg.change_group.id = id
487     arg.change_group.owner = owner
488     arg.change_group.type = type
489     arg.change_group.name = name
490     raiseIfError( lib.rsbac_acl_group( transaction._t ,
491                                        headers.ACLGS_change_group ,
492                                        byref( arg ) ) )
493
494 @export
495 def removeGroup( id ) :
496     """Remove an ACL group
497
498     id -- ACL group as integer
499
500     """
501     arg = headers.rsbac_acl_group_syscall_arg_t()
502     arg.remove_group.id = id
503     raiseIfError( lib.rsbac_acl_group( transaction._t ,
504                                        headers.ACLGS_remove_group ,
505                                        byref( arg ) ) )
506
507 def _unpackEntry( entry ) :
508     return int( entry.id ) , int( entry.owner ) , int( entry.type ) , entry.name
509
510 @export
511 def getGroupEntry( id ) :
512     """Get group entry attributes.
513
514     id -- ACL group as integer
515
516     Returns a tuple with 4 attributes: id, owner, type and name.
517
518     """
519     entry = headers.rsbac_acl_group_entry_t()
520     arg = headers.rsbac_acl_group_syscall_arg_t()
521     arg.get_group_entry.id = id
522     arg.get_group_entry.entry_p = pointer( entry )
523     raiseIfError( lib.rsbac_acl_group( transaction._t ,
524                                        headers.ACLGS_get_group_entry ,
525                                        byref( arg ) ) )
526     return _unpackEntry( entry )
527
528 def _listGroups( includeGlobal , arr , n ) :
529     arg = headers.rsbac_acl_group_syscall_arg_t()
530     arg.list_groups.include_global = includeGlobal
531     arg.list_groups.group_entry_array = arr
532     arg.list_groups.maxnum = n
533     return raiseIfError( lib.rsbac_acl_group( transaction._t ,
534                                               headers.ACLGS_list_groups ,
535                                               byref( arg ) ) )
536
537 # FIXME: Other groups may be viewed/changed while not listed by
538 # _listGroups (the groups belonging to other users.)
539 @export
540 def getGroupList( includeGlobal = False ) :
541     """Get the list of ACL group.
542
543     includeGlobal -- boolean. If True, include global groups.
544
545     Returns list of group ID.
546
547     """
548     arr = fetch( headers.rsbac_acl_group_entry_t ,
549                  lambda n , a : _listGroups( includeGlobal , a , n ) ,
550                  32 )
551     return map( _unpackEntry , arr )
552
553 @export
554 def addGroupMember( group , user , ttl = None ) :
555     """Add a member to an ACL group.
556
557     group -- ACL group as integer
558     user -- user as integer
559     ttl -- None or a positive integer
560
561     """
562     arg = headers.rsbac_acl_group_syscall_arg_t()
563     arg.add_member.group = int( group )
564     arg.add_member.user = int( user )
565     arg.add_member.ttl = ttlToInt( ttl )
566     return raiseIfError( lib.rsbac_acl_group( transaction._t ,
567                                               headers.ACLGS_add_member ,
568                                               byref( arg ) ) )
569
570 @export
571 def removeGroupMember( group , user ) :
572     """Remove a member from an ACL group.
573
574     group -- ACL group as integer
575     user -- user as integer
576
577     """
578     arg = headers.rsbac_acl_group_syscall_arg_t()
579     arg.remove_member.group = int( group )
580     arg.remove_member.user = int( user )
581     return raiseIfError( lib.rsbac_acl_group( transaction._t ,
582                                               headers.ACLGS_remove_member ,
583                                               byref( arg ) ) )
584
585 def _getUserGroups( user , groups , ttls , n ) :
586     arg = headers.rsbac_acl_group_syscall_arg_t()
587     arg.get_user_groups.user = user
588     arg.get_user_groups.group_array = groups
589     arg.get_user_groups.ttl_array = ttls
590     arg.get_user_groups.maxnum = n
591     return raiseIfError( lib.rsbac_acl_group( transaction._t ,
592                                               headers.ACLGS_get_user_groups ,
593                                               byref( arg ) ) )
594
595 @export
596 def getUserGroups( uid ) :
597     """Get the ACL groups to which a user belong.
598
599     uid -- user as integer
600
601     Returns a list of pair (id,ttl).
602
603     """
604     arrs = fetch( ( headers.rsbac_acl_group_id_t ,
605                     headers.rsbac_time_t ) ,
606                   lambda n , a , b : _getUserGroups( uid , a , b , n ) ,
607                   32 )
608     return [ ( int( a ) , int( b ) ) for a , b in zip( *arrs ) ]
609
610 def _getGroupMembers( group , users , ttls , n ) :
611     arg = headers.rsbac_acl_group_syscall_arg_t()
612     arg.get_group_members.group = group
613     arg.get_group_members.user_array = users
614     arg.get_group_members.ttl_array = ttls
615     arg.get_group_members.maxnum = n
616     return raiseIfError( lib.rsbac_acl_group( transaction._t ,
617                                               headers.ACLGS_get_group_members ,
618                                               byref( arg ) ) )
619
620 @export
621 def getGroupMembers( id ) :
622     """Get the members of the given ACL group.
623
624     id -- ACL group
625
626     Returns a list of pair (uid,ttl).
627
628     """
629     arrs = fetch( ( headers.rsbac_uid_t ,
630                     headers.rsbac_time_t ) ,
631                   lambda n , a , b : _getGroupMembers( id , a , b , n ) ,
632                   32 )
633     return [ ( int( a ) , intToTtl( b ) ) for a , b in zip( *arrs ) ]
634
635 class AclGroupMembersTtlDictProxy( object ) :
636     def __init__( self , id ) :
637         self.__group = id
638     def __getitem__( self , user ) :
639         for uid , ttl in getGroupMembers( self.__group ) :
640             if uid == user :
641                 if ttl is None :
642                     ttl = True
643                 return ttl
644         return False
645     def __setitem__( self , user , value ) :
646         addGroupMember( self.__group , user , value )
647     def __iter__( self ) :
648         return ( n[ 0 ] for n in getGroupMembers( self.__group ) )
649     def __repr__( self ) :
650         r = []
651         for user , ttl in getGroupMembers( self.__group ) :
652             if ttl is None :
653                 r.append( str( user ) )
654             else :
655                 r.append( '%s(%ds)' % ( user , ttl ) )
656         return '<Members for ACL group %d: %s>' \
657             % ( self.__group , ', '.join( r ) or 'none' )
658     def add( self , user , ttl = None ) :
659         addGroupMember( self.__group , user , ttl )
660     def discard( self , user ) :
661         removeGroupMember( self.__group , user )
662     def clear( self ) :
663         map( self.discard , self )
664
665 # FIXME: Add a note about settings (not settable individually
666 # normally)
667 class Group( object ) :
668     def __init__( self , id ) :
669         self._id = id
670         self.members = AclGroupMembersTtlDictProxy( id )
671     def __repr__( self ) :
672         try :
673             entry = getGroupEntry( self._id )
674             assert entry[ 2 ] in ( headers.ACLG_GLOBAL , headers.ACLG_PRIVATE )
675             desc = '%r %s' % \
676                 ( entry[ 3 ] ,
677                   ( 'PRIVATE' , 'GLOBAL' )[ entry[ 2 ] == headers.ACLG_GLOBAL ] )
678         except Error , e :
679             if e[ 0 ] != headers.RSBAC_ENOTFOUND :
680                 raise
681             desc = 'undefined'
682         return '<ACL Group [%d] %s>' % ( self._id , desc )
683     #
684     # members
685     #
686     members = None
687     #
688     # owner
689     #
690     def getOwner( self ) :
691         return User( getGroupEntry( self._id )[ 1 ] )
692     def setOwner( self , value ) :
693         entry = getGroupEntry( self._id )
694         changeGroup( self._id , int( value ) , entry[ 2 ] , entry[ 3 ] )
695     owner = property( getOwner , setOwner )
696     #
697     # private (not really a boolean, but let's say it is)
698     #
699     def getPrivate( self ) :
700         entry = getGroupEntry( self._id )
701         type = entry[ 2 ]
702         assert type in ( headers.ACLG_GLOBAL , headers.ACLG_PRIVATE )
703         return type == headers.ACLG_PRIVATE
704     def setPrivate( self , value ) :
705         entry = getGroupEntry( self._id )
706         if value :
707             value = headers.ACLG_PRIVATE
708         else :
709             value = headers.ACLG_GLOBAL
710         changeGroup( self._id , entry[ 1 ] , value , entry[ 3 ] )
711     private = property( getPrivate , setPrivate )
712     #
713     # name
714     #
715     def getName( self ) :
716         return getGroupEntry( self._id )[ 3 ]
717     def setName( self , value ) :
718         entry = getGroupEntry( self._id )
719         changeGroup( self._id , entry[ 1 ] , entry[ 2 ] , value )
720     name = property( getName , setName )
721
722 class GroupDict( object ) :
723     def __iter__( self ) :
724         return ( item[ 0 ] for item in getGroupList( True ) )
725     def __getitem__( self , id ) :
726         return Group( id )
727     def __delitem__( self , id ) :
728         return removeGroup( id )
729     def __repr__( self ) :
730         return '{' + ', '.join( '%s: %s' % ( a , b ) for a , b in self.items() ) + '}'
731     def keys( self ) :
732         return list( self )
733     def values( self ) :
734         return map( Group , self )
735     def items( self ) :
736         return [ ( group , Group( group ) ) for group in self ]
737
738 groups = GroupDict()
739
740 from rsbac.rc import Role
741 from rsbac.objects import User, Process
742
743 # Local Variables:
744 # indent-tabs-mode: nil
745 # python-indent: 4
746 # End: