1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_stoc.hxx"
26 
27 #include <stdio.h>
28 
29 #include <sal/main.h>
30 #include <osl/diagnose.h>
31 #include <osl/socket.hxx>
32 #include <rtl/string.hxx>
33 #include <rtl/ustrbuf.hxx>
34 #include <uno/current_context.hxx>
35 
36 #include <cppuhelper/implbase1.hxx>
37 #include <cppuhelper/bootstrap.hxx>
38 #include <cppuhelper/access_control.hxx>
39 
40 #include <com/sun/star/lang/XComponent.hpp>
41 #include <com/sun/star/uno/XCurrentContext.hpp>
42 
43 #include <com/sun/star/io/FilePermission.hpp>
44 
45 #define USER_CREDS "access-control.user-credentials"
46 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
47 
48 
49 using namespace ::osl;
50 using namespace ::rtl;
51 using namespace ::cppu;
52 using namespace ::com::sun::star;
53 using namespace ::com::sun::star::uno;
54 
55 //--------------------------------------------------------------------------------------------------
localhost(OUString const & addition)56 static OUString localhost( OUString const & addition ) SAL_THROW( () )
57 {
58     static OUString ip;
59     if (! ip.getLength())
60     {
61         // dns lookup
62         SocketAddr addr;
63         SocketAddr::resolveHostname( OUSTR("localhost"), addr );
64         ::oslSocketResult rc = ::osl_getDottedInetAddrOfSocketAddr( addr.getHandle(), &ip.pData );
65         if (::osl_Socket_Ok != rc)
66             fprintf(stdout, "### cannot resolve localhost!" );
67     }
68     OUStringBuffer buf( 48 );
69     buf.append( ip );
70     buf.append( addition );
71     return buf.makeStringAndClear();
72 }
73 
74 //--------------------------------------------------------------------------------------------------
dispose(Reference<XInterface> const & x)75 static inline void dispose( Reference< XInterface > const & x )
76     SAL_THROW( (RuntimeException) )
77 {
78     Reference< lang::XComponent > xComp( x, UNO_QUERY );
79     if (xComp.is())
80     {
81         xComp->dispose();
82     }
83 }
84 //==================================================================================================
85 class user_CurrentContext
86     : public ImplHelper1< XCurrentContext >
87 {
88     oslInterlockedCount m_refcount;
89 
90     Reference< XCurrentContext > m_xDelegate;
91     Any m_userId;
92 
93 public:
user_CurrentContext(Reference<XCurrentContext> const & xDelegate,OUString const & userId)94     inline user_CurrentContext(
95         Reference< XCurrentContext > const & xDelegate,
96         OUString const & userId )
97         SAL_THROW( () )
98         : m_refcount( 0 )
99         , m_xDelegate( xDelegate )
100         , m_userId( makeAny( userId ) )
101         {}
102 
103     // XInterface impl
104     virtual void SAL_CALL acquire()
105         throw ();
106     virtual void SAL_CALL release()
107         throw ();
108 
109     // XCurrentContext impl
110     virtual Any SAL_CALL getValueByName( OUString const & name )
111         throw (RuntimeException);
112 };
113 //__________________________________________________________________________________________________
acquire()114 void user_CurrentContext::acquire()
115     throw ()
116 {
117     ::osl_incrementInterlockedCount( &m_refcount );
118 }
119 //__________________________________________________________________________________________________
release()120 void user_CurrentContext::release()
121     throw ()
122 {
123     if (! ::osl_decrementInterlockedCount( &m_refcount ))
124     {
125         delete this;
126     }
127 }
128 //__________________________________________________________________________________________________
getValueByName(OUString const & name)129 Any user_CurrentContext::getValueByName( OUString const & name )
130     throw (RuntimeException)
131 {
132     if (name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(USER_CREDS ".id") ))
133     {
134         return m_userId;
135     }
136     else if (m_xDelegate.is())
137     {
138         return m_xDelegate->getValueByName( name );
139     }
140     else
141     {
142         return Any();
143     }
144 }
145 
146 // prepends line number
147 #define CHECK( check, negative_test ) \
148 { \
149     try \
150     { \
151         if (negative_test) \
152         { \
153             bool thrown = true; \
154             try \
155             { \
156                 check; \
157                 thrown = false; \
158             } \
159             catch (RuntimeException &) \
160             { \
161             } \
162             if (! thrown) \
163             { \
164                 throw RuntimeException( \
165                     OUSTR("expected RuntimeException upon check!"), Reference< XInterface >() ); \
166             } \
167         } \
168         else \
169         { \
170             check; \
171         } \
172     } \
173     catch (RuntimeException & exc) \
174     { \
175         OUStringBuffer buf( 64 ); \
176         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[line ") ); \
177         buf.append( (sal_Int32)__LINE__ ); \
178         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") ); \
179         buf.append( exc.Message ); \
180         throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() ); \
181     } \
182 }
183 
184 /*
185 grant
186 {
187 permission com.sun.star.io.FilePermission "file:///usr/bin/ *", "read";
188 permission com.sun.star.io.FilePermission "file:///tmp/-", "read,write";
189 permission com.sun.star.io.FilePermission "file:///etc/profile", "read";
190 
191 permission com.sun.star.security.RuntimePermission "DEF";
192 
193 permission com.sun.star.connection.SocketPermission "127.0.0.1:-1023", "resolve, connect, listen";
194 permission com.sun.star.connection.SocketPermission "localhost:1024-", "accept, connect, listen, resolve,";
195 permission com.sun.star.connection.SocketPermission "*.sun.com:1024-", "resolve";
196 };
197 */
check_defaults_pos(AccessControl & ac,bool invert=false)198 static void check_defaults_pos( AccessControl & ac, bool invert = false )
199 {
200     // positive tests
201     CHECK( ac.checkFilePermission( OUSTR("file:///usr/bin/bla"), OUSTR("read") ), invert );
202     CHECK( ac.checkFilePermission( OUSTR("file:///tmp/bla"), OUSTR("read,write") ), invert );
203     CHECK( ac.checkFilePermission( OUSTR("file:///tmp/path/path/bla"), OUSTR("write") ), invert );
204     CHECK( ac.checkFilePermission( OUSTR("file:///etc/profile"), OUSTR("read") ), invert );
205     CHECK( ac.checkRuntimePermission( OUSTR("DEF") ), invert );
206     CHECK( ac.checkSocketPermission( OUSTR("localhost:1024"), OUSTR("connect") ), invert );
207     CHECK( ac.checkSocketPermission( OUSTR("localhost:65535"), OUSTR("resolve") ), invert );
208     CHECK( ac.checkSocketPermission( localhost(OUSTR(":2048")), OUSTR("accept,listen") ), invert );
209     CHECK( ac.checkSocketPermission( localhost(OUSTR(":1024-")), OUSTR("accept,connect,listen,resolve") ), invert );
210     CHECK( ac.checkSocketPermission( OUSTR("localhost:-1023"), OUSTR("resolve,listen,connect") ), invert );
211     CHECK( ac.checkSocketPermission( OUSTR("jl-1036.germany.sun.com:1024-"), OUSTR("resolve") ), invert );
212 }
check_defaults_neg(AccessControl & ac,bool invert=false)213 static void check_defaults_neg( AccessControl & ac, bool invert = false )
214 {
215     // negative tests
216     CHECK( ac.checkFilePermission( OUSTR("file:///usr/tmp"), OUSTR("read") ), !invert );
217     CHECK( ac.checkFilePermission( OUSTR("file:///"), OUSTR("read") ), !invert );
218     CHECK( ac.checkFilePermission( OUSTR("file:///usr/bin"), OUSTR("read") ), !invert );
219     CHECK( ac.checkFilePermission( OUSTR("file:///usr/bin/bla"), OUSTR("write") ), !invert );
220     CHECK( ac.checkFilePermission( OUSTR("file:///usr/bin/bla"), OUSTR("execute") ), !invert );
221     CHECK( ac.checkFilePermission( OUSTR("file:///usr/bin/path/bla"), OUSTR("read") ), !invert );
222     CHECK( ac.checkFilePermission( OUSTR("file:///tmp"), OUSTR("read") ), !invert );
223     CHECK( ac.checkFilePermission( OUSTR("file:///tmp/"), OUSTR("read") ), !invert );
224     CHECK( ac.checkFilePermission( OUSTR("file:///tm"), OUSTR("read") ), !invert );
225     CHECK( ac.checkFilePermission( OUSTR("file:///etc/profile"), OUSTR("write") ), !invert );
226     CHECK( ac.checkFilePermission( OUSTR("file:///etc/profile/bla"), OUSTR("read") ), !invert );
227     CHECK( ac.checkFilePermission( OUSTR("file:///etc/blabla"), OUSTR("read,write,execute") ), !invert );
228     CHECK( ac.checkFilePermission( OUSTR("file:///home/root"), OUSTR("read,write,execute") ), !invert );
229     CHECK( ac.checkFilePermission( OUSTR("file:///root"), OUSTR("read,write,execute") ), !invert );
230     CHECK( ac.checkFilePermission( OUSTR("file:///root"), OUSTR("delete") ), !invert );
231     CHECK( ac.checkFilePermission( OUSTR("file:///root"), OUString() ), !invert );
232     CHECK( ac.checkRuntimePermission( OUSTR("ROOT") ), !invert );
233     CHECK( ac.checkSocketPermission( OUSTR("localhost:1023"), OUSTR("accept") ), !invert );
234     CHECK( ac.checkSocketPermission( OUSTR("localhost:123-"), OUSTR("accept") ), !invert );
235     CHECK( ac.checkSocketPermission( localhost(OUSTR(":-1023")), OUSTR("accept") ), !invert );
236     CHECK( ac.checkSocketPermission( OUSTR("localhost:-1023"), OUSTR("accept,resolve") ), !invert );
237     CHECK( ac.checkSocketPermission( OUSTR("sun.com:1024-"), OUSTR("resolve") ), !invert );
238 }
239 
240 /*
241 grant user "dbo"
242 {
243 permission com.sun.star.io.FilePermission "file:///home/dbo/-", "read,write";
244 permission com.sun.star.io.FilePermission "-", "read,write";
245 permission com.sun.star.io.FilePermission "file:///usr/local/dbo/ *", "read";
246 
247 permission com.sun.star.security.RuntimePermission "DBO";
248 
249 permission com.sun.star.connection.SocketPermission "dbo-1:1024-", "listen";
250 permission com.sun.star.connection.SocketPermission "dbo-11081:-1023", "resolve";
251 permission com.sun.star.connection.SocketPermission "dbo-11081:18", "listen";
252 permission com.sun.star.connection.SocketPermission "dbo-11081:20-24", "listen";
253 permission com.sun.star.connection.SocketPermission "dbo-11081", "connect";
254 };
255 */
check_dbo_pos(AccessControl & ac,bool invert=false)256 static void check_dbo_pos( AccessControl & ac, bool invert = false )
257 {
258     check_defaults_pos( ac, invert );
259     // positive tests
260     CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read") ), invert );
261     CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("write") ), invert );
262     CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read,write") ), invert );
263     CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/path/bla"), OUSTR("read,write") ), invert );
264     CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/path/path/bla"), OUSTR("read,write") ), invert );
265     CHECK( ac.checkFilePermission( OUSTR("file:///usr/local/dbo/*"), OUSTR("read") ), invert );
266     CHECK( ac.checkFilePermission( OUSTR("file:///usr/local/dbo/bla"), OUSTR("read") ), invert );
267     CHECK( ac.checkRuntimePermission( OUSTR("DBO") ), invert );
268     CHECK( ac.checkSocketPermission( OUSTR("dbo-1:1024-"), OUSTR("listen") ), invert );
269     CHECK( ac.checkSocketPermission( OUSTR("dbo-1:2048-3122"), OUSTR("listen") ), invert );
270     CHECK( ac.checkSocketPermission( OUSTR("dbo-1:2048-"), OUSTR("listen") ), invert );
271     CHECK( ac.checkSocketPermission( OUSTR("dbo-11081:-1023"), OUSTR("resolve") ), invert );
272     CHECK( ac.checkSocketPermission( OUSTR("dbo-11081:20-1023"), OUSTR("resolve") ), invert );
273     CHECK( ac.checkSocketPermission( OUSTR("dbo-11081:18"), OUSTR("listen") ), invert );
274     CHECK( ac.checkSocketPermission( OUSTR("dbo-11081:20-24"), OUSTR("listen") ), invert );
275     CHECK( ac.checkSocketPermission( OUSTR("dbo-11081:22"), OUSTR("listen") ), invert );
276     CHECK( ac.checkSocketPermission( OUSTR("dbo-11081"), OUSTR("connect") ), invert );
277     CHECK( ac.checkSocketPermission( OUSTR("dbo-11081:22"), OUSTR("connect") ), invert );
278 }
check_dbo_neg(AccessControl & ac,bool invert=false)279 static void check_dbo_neg( AccessControl & ac, bool invert = false )
280 {
281     check_defaults_neg( ac, invert );
282     // negative tests
283     CHECK( ac.checkFilePermission( OUSTR("file:///home/-"), OUSTR("read") ), !invert );
284     CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("read") ), !invert );
285     CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("write") ), !invert );
286     CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("read,write") ), !invert );
287     CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/path/bla"), OUSTR("read") ), !invert );
288     CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/path/path/bla"), OUSTR("read,execute") ), !invert );
289     CHECK( ac.checkFilePermission( OUSTR("file:///usr/local/-"), OUSTR("read") ), !invert );
290     CHECK( ac.checkFilePermission( OUSTR("file:///usr/local/dbo/path/bla"), OUSTR("read") ), !invert );
291     CHECK( ac.checkFilePermission( OUSTR("file:///usr/local/dbo/path/path/bla"), OUSTR("read") ), !invert );
292     CHECK( ac.checkRuntimePermission( OUSTR("JBU") ), !invert );
293     CHECK( ac.checkSocketPermission( OUSTR("dbo-11081"), OUSTR("listen") ), !invert );
294     CHECK( ac.checkSocketPermission( OUSTR("dbo-11081:22"), OUSTR("accept") ), !invert );
295     CHECK( ac.checkSocketPermission( OUSTR("jbu-11096:22"), OUSTR("resolve") ), !invert );
296 }
297 
298 /*
299 grant user "jbu"
300 {
301 permission com.sun.star.io.FilePermission  "file:///home/jbu/-", "read,write";
302 permission com.sun.star.io.FilePermission "*", "read,write";
303 
304 permission com.sun.star.security.RuntimePermission "JBU";
305 
306 permission com.sun.star.connection.SocketPermission "jbu-11096","resolve";
307 };
308 */
check_jbu_pos(AccessControl & ac,bool invert=false)309 static void check_jbu_pos( AccessControl & ac, bool invert = false )
310 {
311     check_defaults_pos( ac, invert );
312     // positive tests
313     CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("read") ), invert );
314     CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("write") ), invert );
315     CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/bla"), OUSTR("read,write") ), invert );
316     CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/path/bla"), OUSTR("read,write") ), invert );
317     CHECK( ac.checkFilePermission( OUSTR("file:///home/jbu/path/path/bla"), OUSTR("read,write") ), invert );
318     CHECK( ac.checkRuntimePermission( OUSTR("JBU") ), invert );
319     CHECK( ac.checkSocketPermission( OUSTR("jbu-11096"), OUSTR("resolve") ), invert );
320     CHECK( ac.checkSocketPermission( OUSTR("jbu-11096:20-24"), OUSTR("resolve") ), invert );
321     CHECK( ac.checkSocketPermission( OUSTR("dbo-11081.germany.sun.com:2048"), OUSTR("resolve") ), invert );
322 }
check_jbu_neg(AccessControl & ac,bool invert=false)323 static void check_jbu_neg( AccessControl & ac, bool invert = false )
324 {
325     check_defaults_neg( ac, invert );
326     // negative tests
327     CHECK( ac.checkFilePermission( OUSTR("file:///home/-"), OUSTR("read") ), !invert );
328     CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/path/bla"), OUSTR("read") ), !invert );
329     CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/path/path/bla"), OUSTR("read") ), !invert );
330     CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read") ), !invert );
331     CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("write") ), !invert );
332     CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read,write") ), !invert );
333     CHECK( ac.checkFilePermission( OUSTR("file:///usr/local/-"), OUSTR("read") ), !invert );
334     CHECK( ac.checkFilePermission( OUSTR("file:///usr/local/dbo/bla"), OUSTR("read") ), !invert );
335     CHECK( ac.checkFilePermission( OUSTR("file:///usr/local/dbo/path/path/bla"), OUSTR("read") ), !invert );
336     CHECK( ac.checkRuntimePermission( OUSTR("DBO") ), !invert );
337     CHECK( ac.checkSocketPermission( OUSTR("jbu-11096:20-24"), OUSTR("accept") ), !invert );
338     CHECK( ac.checkSocketPermission( OUSTR("dbo-11081"), OUSTR("connect") ), !invert );
339     CHECK( ac.checkSocketPermission( OUSTR("dbo-11081.germany.sun.com"), OUSTR("connect") ), !invert );
340 }
341 
342 /*
343 grant principal "root"
344 {
345 permission com.sun.star.security.AllPermission;
346 };
347 */
348 //==================================================================================================
check_root_pos(AccessControl & ac,bool invert=false)349 static void check_root_pos( AccessControl & ac, bool invert = false )
350 {
351     check_defaults_pos( ac, invert );
352     check_defaults_neg( ac, !invert );
353     check_dbo_pos( ac, invert );
354     check_dbo_neg( ac, !invert );
355     check_jbu_pos( ac, invert );
356     check_jbu_neg( ac, !invert );
357     // some more root positive
358     CHECK( ac.checkFilePermission( OUSTR("file:///etc/blabla"), OUSTR("read,write,execute") ), invert );
359     CHECK( ac.checkFilePermission( OUSTR("file:///home/root"), OUSTR("read,write,execute") ), invert );
360     CHECK( ac.checkFilePermission( OUSTR("file:///root"), OUSTR("read,write,execute") ), invert );
361     CHECK( ac.checkRuntimePermission( OUSTR("ROOT") ), invert );
362 }
363 
364 //==================================================================================================
365 class acc_Restr
366     : public WeakImplHelper1< security::XAccessControlContext >
367 {
368     Any m_perm;
369 
370 public:
371     inline acc_Restr( Any const & perm = Any() ) SAL_THROW( () )
372         : m_perm( perm )
373         {}
374 
375     // XAccessControlContext impl
376     virtual void SAL_CALL checkPermission( Any const & perm )
377         throw (RuntimeException);
378 };
379 //__________________________________________________________________________________________________
checkPermission(Any const & perm)380 void acc_Restr::checkPermission( Any const & perm )
381     throw (RuntimeException)
382 {
383     if (perm != m_perm)
384     {
385         throw security::AccessControlException(
386             OUSTR("dyn violation!"), Reference< XInterface >(), perm );
387     }
388 }
389 
390 typedef void (* t_action)( AccessControl &, Any const & arg );
391 
392 //==================================================================================================
393 class Action
394     : public WeakImplHelper1< security::XAction >
395 {
396     t_action m_action;
397     AccessControl & m_ac;
398     Any m_arg;
399 
400 public:
Action(t_action action,AccessControl & ac,Any const & arg=Any ())401     inline Action( t_action action, AccessControl & ac, Any const & arg = Any() ) SAL_THROW( () )
402         : m_action( action )
403         , m_ac( ac )
404         , m_arg( arg )
405         {}
406 
407     // XAction impl
408     virtual Any SAL_CALL run()
409         throw (Exception);
410 };
411 //__________________________________________________________________________________________________
run()412 Any Action::run()
413     throw (Exception)
414 {
415     (*m_action)( m_ac, m_arg );
416     return Any();
417 }
418 
419 //==================================================================================================
420 // static void restr_file_permissions( AccessControl & ac )
421 // {
422 //     // running in dbo's domain
423 //     /* permission com.sun.star.io.FilePermission "file:///home/dbo/-", ",,read , write "; */
424 //     CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read,write,execute") ), true );
425 //     CHECK( ac.checkFilePermission( OUSTR("file:///home/dbo/bla"), OUSTR("read,write") ), false );
426 // }
427 //==================================================================================================
all_dbo_permissions(AccessControl & ac,Any const &)428 static void all_dbo_permissions( AccessControl & ac, Any const & )
429 {
430     check_dbo_pos( ac );
431     check_dbo_neg( ac );
432 }
433 //==================================================================================================
no_permissions(AccessControl & ac,Any const & arg)434 static void no_permissions( AccessControl & ac, Any const & arg )
435 {
436     check_dbo_pos( ac, true );
437     check_dbo_neg( ac );
438     // set privs to old dbo restr
439     Reference< security::XAccessControlContext > xContext;
440     OSL_VERIFY( arg >>= xContext );
441     ac->doPrivileged(
442         new Action( all_dbo_permissions, ac ),
443         xContext );
444 }
445 //==================================================================================================
check_dbo_dynamic(AccessControl & ac)446 static void check_dbo_dynamic( AccessControl & ac )
447 {
448     Any arg( makeAny( ac->getContext() ) );
449     ac->doRestricted(
450         new Action( no_permissions, ac, arg ),
451         new acc_Restr() );
452 }
453 
SAL_IMPLEMENT_MAIN()454 SAL_IMPLEMENT_MAIN()
455 {
456     try
457     {
458         // single-user test
459         Reference< XComponentContext > xContext( defaultBootstrap_InitialComponentContext(
460             OUSTR("../../test/security/test_security_singleuser.ini") ) );
461         {
462         ::fprintf( stderr, "[security test] single-user checking dbo..." );
463         AccessControl ac( xContext );
464         check_dbo_pos( ac );
465         check_dbo_neg( ac );
466         check_dbo_dynamic( ac );
467         ::fprintf( stderr, "dbo checked.\n" );
468         }
469 
470         // multi-user test
471         dispose( xContext );
472         xContext = defaultBootstrap_InitialComponentContext(
473             OUSTR("../../test/security/test_security.ini") ); // UNO_AC=on
474         AccessControl ac( xContext );
475 
476         {
477         // set up dbo current context
478         ContextLayer layer( new user_CurrentContext( getCurrentContext(), OUSTR("dbo") ) );
479         ::fprintf( stderr, "[security test] multi-user checking dbo..." );
480         check_dbo_pos( ac );
481         check_dbo_neg( ac );
482         check_dbo_dynamic( ac );
483         ::fprintf( stderr, "dbo checked.\n" );
484         }
485         {
486         // set up jbu current context
487         ContextLayer layer( new user_CurrentContext( getCurrentContext(), OUSTR("jbu") ) );
488         ::fprintf( stderr, "[security test] multi-user checking jbu..." );
489         check_jbu_pos( ac );
490         check_jbu_neg( ac );
491         ::fprintf( stderr, "jbu checked.\n" );
492         }
493         {
494         // set up root current context
495         ContextLayer layer( new user_CurrentContext( getCurrentContext(), OUSTR("root") ) );
496         ::fprintf( stderr, "[security test] multi-user checking root..." );
497         check_root_pos( ac );
498         ::fprintf( stderr, "root checked.\n" );
499         }
500         {
501         // set up unknown guest user current context => default permissions
502         ContextLayer layer( new user_CurrentContext( getCurrentContext(), OUSTR("guest") ) );
503         ::fprintf( stderr, "[security test] multi-user checking guest..." );
504         check_defaults_pos( ac );
505         check_defaults_neg( ac );
506         ::fprintf( stderr, "guest checked.\n" );
507         }
508 
509         dispose( xContext );
510         ::fprintf( stderr, "security test succeeded.\n" );
511         return 0;
512     }
513     catch (Exception & exc)
514     {
515         OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
516         ::fprintf( stderr, "[security test] error: %s!\n", str.getStr() );
517         return 1;
518     }
519 }
520