Added acl.grant and acl.revoke functions.
[py-rsbac] / rsbac / _misc.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 from ctypes import c_char, byref, create_string_buffer
23
24 from rsbac import headers, lib
25 from rsbac.errors import raiseIfError
26 from rsbac._utils import aptr
27
28 def export( fun ) :
29     __all__.append( fun.__name__ )
30     return fun
31
32 @export
33 def libraryVersion() :
34     """Return the RSBAC library version as a 3-tuple.
35
36     """
37     v = lib.rsbac_lib_version()
38     v , z = divmod( v , 256 )
39     v , y = divmod( v , 256 )
40     x = v
41     return x , y , z
42
43 @export
44 def kernelVersion() :
45     """Return the RSBAC kernel version as a 3-tuple.
46
47     """
48     v = lib.rsbac_version()
49     v , z = divmod( v , 256 )
50     v , y = divmod( v , 256 )
51     x = v
52     return x , y , z
53
54 @export
55 def dumpStats() :
56     """Dump statistics about RSBAC to kernel log.
57
58     """
59     return raiseIfError( lib.rsbac_stats() )
60
61 @export
62 def checkConsistency( correct , checkInode ) :
63     """Consistency checking (as far as possible)
64
65     correct = 0: do not correct errors
66     correct = 1: correct errors
67     correct = 2: correct more
68     checkInode = 0: do not check inode numbers
69     checkInode = 1: also check inode numbers (only ext2/3 on 2.4 kernels)
70
71     """
72     return raiseIfError( lib.rsbac_check( correct , checkInode ) )
73
74 @export
75 def writeDirtyLists() :
76     """Write all dirty lists to disk. Returns number of lists written.
77
78     """
79     return raiseIfError( lib.rsbac_write() )
80
81 def _rsbacLog( type , size = None ) :
82     if type in ( 2 , 3 , 4 ) :
83         if size is None :
84             size = 4096
85         buffer = ( c_char * size )()
86         raiseIfError( lib.rsbac_log( type , aptr( buffer ) , size ) )
87         return buffer.value
88     else :
89         return raiseIfError( lib.rsbac_log( type , None , 0 ) )
90
91 @export
92 def openLog() :
93     """Open RSBAC log (Warning: no-op)
94
95     """
96     return _rsbacLog( 1 )
97
98 @export
99 def closeLog() :
100     """Close RSBAC log (Warning: no-op)
101
102     """
103     return _rsbacLog( 0 )
104
105 @export
106 def readLog( size = 4096 ) :
107     """Read RSBAC log.
108
109     """
110     return _rsbacLog( 2 , size )
111
112 @export
113 def readRingBuffer( size = 4096 ) :
114     """Read the ring buffer.
115
116     """
117     return _rsbacLog( 3 , size )
118
119 @export
120 def readAndClearRingBuffer( size = 4096 ) :
121     """Read and clear the ring buffer.
122
123     """
124     return _rsbacLog( 4 , size )
125
126 @export
127 def clearRingBuffer() :
128     """Clear the ring buffer.
129
130     """
131     return _rsbacLog( 5 )
132
133 @export
134 def init( path ) :
135     """Initialize a filesystem with RSBAC.
136
137     """
138     return raiseIfError( lib.rsbac_init( path ) )
139
140 #--[ getname ]----------------------------------------------------------------
141
142 g_nameBuffer = create_string_buffer( 65536 )
143
144 #
145 # This function creates 3 functions to wrap get_XX_name and get_XX_nr
146 # RSBAC functions. The resulting functions are named getXxxName,
147 # getXxxNames and getXxxNumber.
148 #
149 # __makeGetNameFunctions( 'Foo' , 'foo' , .. ) creates
150 # getFooName(value), getFooNames(), getFooNumber(name)
151 #
152 def __makeGetNameFunctions( name , fname , limit ) :
153     byName = getattr( lib , 'get_' + fname + '_name' )
154     byNumber = getattr( lib , 'get_' + fname + '_nr' )
155     names = []
156     def getName( value ) :
157         if 0 <= value < limit :
158             return byName( g_nameBuffer , value )
159     def getNames() :
160         if not names :
161             names[ : ] = map( getName , range( limit ) )
162         return names
163     def getNumber( name ) :
164         result = byNumber( name )
165         if getName( result ) == name :
166             return result
167     import sys
168     m = sys.modules[ __name__ ]
169     a = 'get' + name + 'Name'
170     b = 'get' + name + 'Names'
171     c = 'get' + name + 'Number'
172     setattr( m , a , getName )
173     setattr( m , b , getNames )
174     setattr( m , c , getNumber )
175     __all__.extend( [ a , b , c ] )
176
177 # getname.c
178
179 __makeGetNameFunctions( 'Request' , 'request' , headers.R_NONE )
180 __makeGetNameFunctions( 'Result' , 'result' , headers.UNDEFINED + 1 )
181
182 @export
183 def getAttributeModule( attribute ) :
184     if 0 <= attribute <= headers.A_none :
185         return lib.get_attr_module( attribute )
186
187 __makeGetNameFunctions( 'Attribute' , 'attribute' , headers.A_none + 1 )
188
189 # def getAttributeValueName( .. ) : pass
190
191 __makeGetNameFunctions( 'ScdType' , 'scd_type' , headers.ST_none + 1 )
192
193 # We choose the following mapping:
194 # get_target_name -> getTargetNameFull
195 # get_target_name_only -> getTargetName
196
197 # def getTargetNameFull( .. ) : pass
198
199 # FIXME: Update __makeGetNameFunctions to handle this. (Allowing to
200 # use an alternative suffix.)
201 @export
202 def getTargetName( target ) :
203     if 0 <= target <= headers.T_NONE :
204         return lib.get_target_name_only( g_nameBuffer , target )
205
206 @export
207 def getTargetNames( __r = [] ) :
208     if not __r :
209         __r[ : ] = map( getTargetName , range( headers.T_NONE + 1 ) )
210     return __r
211
212 @export
213 def getTargetNumber( name ) :
214     target = lib.get_target_nr( name )
215     if getTargetName( target ) == name :
216         return target
217
218 __makeGetNameFunctions( 'IpcTarget' , 'ipc_target' , headers.I_none + 1 )
219 __makeGetNameFunctions( 'SwitchTarget' , 'switch_target' , headers.SW_NONE + 1 )
220
221 @export
222 def getErrorName( error ) :
223     return lib.get_error_name( g_nameBuffer , error )
224
225 @export
226 def getAttributeParameters( attribute ) :
227     if 0 <= attribute <= headers.A_none :
228         return lib.get_attribute_param( g_nameBuffer , attribute )
229
230 __makeGetNameFunctions( 'LogLevel' , 'log_level' , headers.LL_invalid + 1 )
231
232 @export
233 def getCapName( value ) :
234     name = lib.get_cap_name( g_nameBuffer , value )
235     if name != 'ERROR!' :
236         return name
237
238 @export
239 def getCapNames( __r = [] ) :
240     if not __r :
241         i = 0
242         while 1 :
243             name = getCapName( i )
244             if not name :
245                 break
246             __r.append( name )
247             i += 1
248     return __r
249
250 @export
251 def getCapNumber( name ) :
252     value = lib.get_cap_nr( name )
253     if getCapName( value ) == name :
254         return value
255
256 # rc_getname.c
257
258 __makeGetNameFunctions( 'RcTarget' , 'rc_target' , headers.RT_NONE + 1 )
259 __makeGetNameFunctions( 'RcAdmin' , 'rc_admin' , headers.RC_none + 1 )
260
261 @export
262 def getRcScdTypeName( value ) :
263     name = lib.get_rc_scd_type_name( g_nameBuffer , value )
264     if name != 'ERROR!' :
265         return name
266
267 @export
268 def getRcScdTypeNames( __r = [] ) :
269     if not __r :
270         __r[ : ] = map( getRcScdTypeName , range( headers.RST_none + 1 ) )
271     return __r
272
273 @export
274 def getRcScdTypeNumber( name ) :
275     value = lib.get_rc_scd_type_nr( name )
276     if getRcScdTypeName( value ) == name :
277         return value
278
279 __makeGetNameFunctions( 'RcItem' , 'rc_item' , headers.RI_none + 1 )
280
281 @export
282 def getRcItemParameters( value ) :
283     if 0 <= value <= headers.RI_none :
284         return lib.get_rc_item_param( g_nameBuffer , value )
285
286 @export
287 def getRcSpecialRightName( value ) :
288     name = lib.get_rc_special_right_name( g_nameBuffer , value )
289     if name != 'ERROR!' :
290         return name
291
292 @export
293 def getRcSpecialRightNames( __r = [] ) :
294     if not __r :
295         __r[ : ] = map( getRcSpecialRightName , range( headers.RCR_NONE + 1 ) )
296     return __r
297
298 @export
299 def getRcSpecialRightNumber( name ) :
300     value = lib.get_rc_special_right_nr( name )
301     if getRcSpecialRightName( value ) == name :
302         return value
303
304 # res_getname.c
305
306 @export
307 def getRessourceName( value ) :
308     name = lib.get_res_name( g_nameBuffer , value )
309     if name != 'ERROR!' :
310         return name
311
312 @export
313 def getRessourceNames( __r = [] ) :
314     if not __r :
315         i = 0
316         while 1 :
317             name = getRessourceName( i )
318             if not name :
319                 break
320             __r.append( name )
321             i += 1
322     return __r
323
324 @export
325 def getRessourceNumber( name ) :
326     value = lib.get_res_nr( name )
327     if getRessourceName( value ) == name :
328         return value
329
330 # Local Variables:
331 # indent-tabs-mode: nil
332 # python-indent: 4
333 # End: