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