Added acl.grant and acl.revoke functions.
[py-rsbac] / rsbac / auth.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__ = []
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 rsbac import lib, headers
33 from rsbac import transaction
34 from rsbac.errors import raiseIfError
35 from rsbac._utils import fetch, intToTtl, ttlToInt, unlimitedTtl
36
37 _g_range = headers.rsbac_auth_cap_range_t()
38
39 def _fromRange( r ) :
40     a , b = r.first , r.last
41     if a == b :
42         return int( a )
43     else :
44         return int( a ) , int( b )
45
46 def _simplifyRange( value ) :
47     if isinstance( value , tuple ) and len( value ) == 2 and value[ 0 ] == value[ 1 ] :
48         return value[ 0 ]
49     else :
50         return value
51
52 def _toRange( value ) :
53     range = _g_range
54     if isinstance( value , tuple ) :
55         range.first , range.last = map( int , value )
56     else :
57         value = int( value )
58         range.first = range.last = value
59     return range
60
61 def addProcessAuthCapList( pid , type , range , ttl = unlimitedTtl ) :
62     return raiseIfError( lib.rsbac_auth_add_p_cap( transaction._t ,
63                                                    pid , type ,
64                                                    _toRange( range ) ,
65                                                    ttlToInt( ttl ) ) )
66
67 def removeProcessAuthCapList( pid , type , range , ttl = unlimitedTtl ) :
68     return raiseIfError( lib.rsbac_auth_remove_p_cap( transaction._t ,
69                                                       pid , type ,
70                                                       _toRange( range ) ,
71                                                       ttlToInt( ttl ) ) )
72
73 def addFdAuthCapList( path , type , range , ttl = unlimitedTtl ) :
74     return raiseIfError( lib.rsbac_auth_add_f_cap( transaction._t ,
75                                                    path , type ,
76                                                    _toRange( range ) ,
77                                                    ttlToInt( ttl ) ) )
78
79 def removeFdAuthCapList( path , type , range , ttl = unlimitedTtl ) :
80     return raiseIfError( lib.rsbac_auth_remove_f_cap( transaction._t ,
81                                                       path , type ,
82                                                       _toRange( range ) ,
83                                                       ttlToInt( ttl ) ) )
84
85 def getFdAuthCapList( path , type ) :
86     ranges , ttls = \
87             fetch( ( headers.rsbac_auth_cap_range_t ,
88                      headers.rsbac_time_t ) ,
89                    lambda n , a , b :
90                    lib.rsbac_auth_get_f_caplist( transaction._t ,
91                                                  path , type ,
92                                                  a , b ,
93                                                  n ) ,
94                    32 )
95     return [ ( _fromRange( r ) , intToTtl( ttl ) ) for r , ttl in zip( ranges , ttls ) ]
96
97 def getProcessAuthCapList( pid , type ) :
98     ranges , ttls = \
99             fetch( ( headers.rsbac_auth_cap_range_t ,
100                      headers.rsbac_time_t ) ,
101                    lambda n , a , b :
102                    lib.rsbac_auth_get_p_caplist( transaction._t ,
103                                                  pid ,
104                                                  type ,
105                                                  a , b ,
106                                                  n ) ,
107                    32 )
108     return [ ( _range( r ) , intToTtl( ttl ) ) for r , ttl in zip( ranges , ttls ) ]
109
110 @export
111 def addAuthCapabilityList( target , type , range , ttl = unlimitedTtl ) :
112     if instance( target , Process ) :
113         return addProcessAuthCapList( type.pid , range , ttl )
114     elif isinstance( target , FDBase ) :
115         return addFdAuthCapList( type._id , range , ttl )
116     else :
117         raise RuntimeError , 'unexpected object %r' % ( target , )
118
119 @export
120 def delAuthCapabilityList( target , type , range ) :
121     if instance( target , Process ) :
122         return removeProcessAuthCapList( type.pid , range )
123     elif isinstance( target , FDBase ) :
124         return removeFdAuthCapList( type._id , range )
125     else :
126         raise RuntimeError , 'unexpected object %r' % ( target , )
127
128 @export
129 def getAuthCapabilityList( target , type ) :
130     if instance( target , Process ) :
131         return getProcessAuthCapList( type.pid )
132     elif isinstance( target , FDBase ) :
133         return getFdAuthCapList( type._id )
134     else :
135         raise RuntimeError , 'unexpected object %r' % ( target , )
136
137 _g_typeNames = {
138     headers.ACT_real       : 'Auth capabilities' ,
139     headers.ACT_eff        : 'Auth effective capabilities' ,
140     headers.ACT_fs         : 'Auth FS capabilities' ,
141     headers.ACT_group_real : 'Auth group capabilities' ,
142     headers.ACT_group_eff  : 'Auth group effective capabilities' ,
143     headers.ACT_group_fs   : 'Auth group FS capabilities'
144     }
145
146 class AuthCapDictProxyBase( object ) :
147     __slots__ = ()
148     def keys( self ) :
149         return [ i[ 0 ] for i in self.items() ]
150     def values( self ) :
151         return [ i[ 1 ] for i in self.items() ]
152     def add( self , range , ttl = unlimitedTtl ) :
153         self[ range ] = ttl
154     def discard( self , range ) :
155         del self[ range ]
156     def __contains__( self , key ) :
157         return key in self.keys()
158     def __getitem__( self , range ) :
159         range = _simplifyRange( range )
160         for k , v in self.items() :
161             if k == range :
162                 return v or True
163         else :
164             return False
165     def __delitem__( self , range ) :
166         self[ range ] = False
167     def __repr__( self ) :
168         return '<%s for %s: %d items>' \
169             % ( _g_typeNames[ self._type ] ,
170                 self._name() , len( self.items() ) )
171
172 class AuthCapDictProxyProcess( AuthCapDictProxyBase ) :
173     __slots__ = ( '_target' , '_type' )
174     def __init__( self , type , target ) :
175         super( AuthCapDictProxyProcess , self ).__init__()
176         self._target = target
177         self._type = type
178     def __setitem__( self , range , ttl ) :
179         range = _simplifyRange( range )
180         addProcessAuthCapList( self._target , self._type , range , ttl )
181     def _name( self ) :
182         return 'Process %d' % ( self._target , )
183     def items( self ) :
184         return getProcessAuthCapList( self._target , self._type )
185
186 class AuthCapDictProxyFd( AuthCapDictProxyBase ) :
187     __slots__ = ( '_target' , '_type' )
188     def __init__( self , type , target ) :
189         super( AuthCapDictProxyFd , self ).__init__()
190         self._target = target
191         self._type = type
192     def __setitem__( self , range , ttl ) :
193         range = _simplifyRange( range )
194         addFdAuthCapList( self._target , self._type , range , ttl )
195     def _name( self ) :
196         return 'FD %r' % ( self._target , )
197     def items( self ) :
198         return getFdAuthCapList( self._target , self._type )
199
200 from rsbac.objects import Process, FDBase
201
202 # Local Variables:
203 # indent-tabs-mode: nil
204 # python-indent: 4
205 # End: