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