1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: access_controller.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_stoc.hxx"
37 #include <osl/diagnose.h>
38 #include <osl/interlck.h>
39 #include <osl/mutex.hxx>
40 #include <osl/thread.hxx>
42 #include <rtl/ustrbuf.hxx>
43 #include <rtl/string.hxx>
45 #include <uno/current_context.h>
47 #include <cppuhelper/implbase1.hxx>
48 #include <cppuhelper/compbase3.hxx>
49 #include <cppuhelper/factory.hxx>
50 #include <cppuhelper/implementationentry.hxx>
52 #include <com/sun/star/uno/XCurrentContext.hpp>
53 #include <com/sun/star/uno/DeploymentException.hpp>
54 #include <com/sun/star/lang/DisposedException.hpp>
55 #include <com/sun/star/lang/XComponent.hpp>
56 #include <com/sun/star/lang/XServiceInfo.hpp>
57 #include <com/sun/star/lang/XInitialization.hpp>
58 #include <com/sun/star/security/XAccessController.hpp>
59 #include <com/sun/star/security/XPolicy.hpp>
61 #include "lru_cache.h"
62 #include "permissions.h"
64 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
65 #define SERVICE_NAME "com.sun.star.security.AccessController"
66 #define IMPL_NAME "com.sun.star.security.comp.stoc.AccessController"
67 #define USER_CREDS "access-control.user-credentials"
70 using namespace ::std
;
71 using namespace ::osl
;
72 using namespace ::cppu
;
73 using namespace ::com::sun::star
;
74 using namespace ::com::sun::star::uno
;
75 using ::rtl::OUString
;
76 using ::rtl::OUStringBuffer
;
79 extern ::rtl_StandardModuleCount g_moduleCount
;
83 // static stuff initialized when loading lib
84 static OUString s_envType
= OUSTR(CPPU_CURRENT_LANGUAGE_BINDING_NAME
);
85 static OUString s_implName
= OUSTR(IMPL_NAME
);
86 static OUString s_serviceName
= OUSTR(SERVICE_NAME
);
87 static OUString s_acRestriction
= OUSTR("access-control.restriction");
89 static Sequence
< OUString
> s_serviceNames
= Sequence
< OUString
>( &s_serviceName
, 1 );
91 //##################################################################################################
93 /** ac context intersects permissions of two ac contexts
95 class acc_Intersection
96 : public WeakImplHelper1
< security::XAccessControlContext
>
98 Reference
< security::XAccessControlContext
> m_x1
, m_x2
;
100 inline acc_Intersection(
101 Reference
< security::XAccessControlContext
> const & x1
,
102 Reference
< security::XAccessControlContext
> const & x2
)
106 virtual ~acc_Intersection()
109 static inline Reference
< security::XAccessControlContext
> create(
110 Reference
< security::XAccessControlContext
> const & x1
,
111 Reference
< security::XAccessControlContext
> const & x2
)
114 // XAccessControlContext impl
115 virtual void SAL_CALL
checkPermission(
117 throw (RuntimeException
);
119 //__________________________________________________________________________________________________
120 inline acc_Intersection::acc_Intersection(
121 Reference
< security::XAccessControlContext
> const & x1
,
122 Reference
< security::XAccessControlContext
> const & x2
)
127 g_moduleCount
.modCnt
.acquire( &g_moduleCount
.modCnt
);
129 //__________________________________________________________________________________________________
130 acc_Intersection::~acc_Intersection()
133 g_moduleCount
.modCnt
.release( &g_moduleCount
.modCnt
);
135 //--------------------------------------------------------------------------------------------------
136 inline Reference
< security::XAccessControlContext
> acc_Intersection::create(
137 Reference
< security::XAccessControlContext
> const & x1
,
138 Reference
< security::XAccessControlContext
> const & x2
)
145 return new acc_Intersection( x1
, x2
);
147 //__________________________________________________________________________________________________
148 void acc_Intersection::checkPermission(
150 throw (RuntimeException
)
152 m_x1
->checkPermission( perm
);
153 m_x2
->checkPermission( perm
);
156 /** ac context unifies permissions of two ac contexts
159 : public WeakImplHelper1
< security::XAccessControlContext
>
161 Reference
< security::XAccessControlContext
> m_x1
, m_x2
;
164 Reference
< security::XAccessControlContext
> const & x1
,
165 Reference
< security::XAccessControlContext
> const & x2
)
172 static inline Reference
< security::XAccessControlContext
> create(
173 Reference
< security::XAccessControlContext
> const & x1
,
174 Reference
< security::XAccessControlContext
> const & x2
)
177 // XAccessControlContext impl
178 virtual void SAL_CALL
checkPermission(
180 throw (RuntimeException
);
182 //__________________________________________________________________________________________________
183 inline acc_Union::acc_Union(
184 Reference
< security::XAccessControlContext
> const & x1
,
185 Reference
< security::XAccessControlContext
> const & x2
)
190 g_moduleCount
.modCnt
.acquire( &g_moduleCount
.modCnt
);
192 //__________________________________________________________________________________________________
193 acc_Union::~acc_Union()
196 g_moduleCount
.modCnt
.release( &g_moduleCount
.modCnt
);
198 //--------------------------------------------------------------------------------------------------
199 inline Reference
< security::XAccessControlContext
> acc_Union::create(
200 Reference
< security::XAccessControlContext
> const & x1
,
201 Reference
< security::XAccessControlContext
> const & x2
)
205 return Reference
< security::XAccessControlContext
>(); // unrestricted
207 return Reference
< security::XAccessControlContext
>(); // unrestricted
208 return new acc_Union( x1
, x2
);
210 //__________________________________________________________________________________________________
211 void acc_Union::checkPermission(
213 throw (RuntimeException
)
217 m_x1
->checkPermission( perm
);
219 catch (security::AccessControlException
&)
221 m_x2
->checkPermission( perm
);
225 /** ac context doing permission checks on static permissions
228 : public WeakImplHelper1
< security::XAccessControlContext
>
230 PermissionCollection m_permissions
;
234 PermissionCollection
const & permissions
)
236 virtual ~acc_Policy()
239 // XAccessControlContext impl
240 virtual void SAL_CALL
checkPermission(
242 throw (RuntimeException
);
244 //__________________________________________________________________________________________________
245 inline acc_Policy::acc_Policy(
246 PermissionCollection
const & permissions
)
248 : m_permissions( permissions
)
250 g_moduleCount
.modCnt
.acquire( &g_moduleCount
.modCnt
);
252 //__________________________________________________________________________________________________
253 acc_Policy::~acc_Policy()
256 g_moduleCount
.modCnt
.release( &g_moduleCount
.modCnt
);
258 //__________________________________________________________________________________________________
259 void acc_Policy::checkPermission(
261 throw (RuntimeException
)
263 m_permissions
.checkPermission( perm
);
266 /** current context overriding dynamic ac restriction
268 class acc_CurrentContext
269 : public ImplHelper1
< XCurrentContext
>
271 oslInterlockedCount m_refcount
;
273 Reference
< XCurrentContext
> m_xDelegate
;
277 inline acc_CurrentContext(
278 Reference
< XCurrentContext
> const & xDelegate
,
279 Reference
< security::XAccessControlContext
> const & xRestriction
)
281 virtual ~acc_CurrentContext() SAL_THROW( () );
284 virtual void SAL_CALL
acquire()
286 virtual void SAL_CALL
release()
289 // XCurrentContext impl
290 virtual Any SAL_CALL
getValueByName( OUString
const & name
)
291 throw (RuntimeException
);
293 //__________________________________________________________________________________________________
294 inline acc_CurrentContext::acc_CurrentContext(
295 Reference
< XCurrentContext
> const & xDelegate
,
296 Reference
< security::XAccessControlContext
> const & xRestriction
)
299 , m_xDelegate( xDelegate
)
301 g_moduleCount
.modCnt
.acquire( &g_moduleCount
.modCnt
);
303 if (xRestriction
.is())
305 m_restriction
= makeAny( xRestriction
);
307 // return empty any otherwise on getValueByName(), not null interface
309 //__________________________________________________________________________________________________
310 acc_CurrentContext::~acc_CurrentContext()
313 g_moduleCount
.modCnt
.release( &g_moduleCount
.modCnt
);
315 //__________________________________________________________________________________________________
316 void acc_CurrentContext::acquire()
319 ::osl_incrementInterlockedCount( &m_refcount
);
321 //__________________________________________________________________________________________________
322 void acc_CurrentContext::release()
325 if (! ::osl_decrementInterlockedCount( &m_refcount
))
330 //__________________________________________________________________________________________________
331 Any
acc_CurrentContext::getValueByName( OUString
const & name
)
332 throw (RuntimeException
)
334 if (name
.equals( s_acRestriction
))
336 return m_restriction
;
338 else if (m_xDelegate
.is())
340 return m_xDelegate
->getValueByName( name
);
348 //##################################################################################################
350 //--------------------------------------------------------------------------------------------------
351 static inline void dispose( Reference
< XInterface
> const & x
)
352 SAL_THROW( (RuntimeException
) )
354 Reference
< lang::XComponent
> xComp( x
, UNO_QUERY
);
360 //--------------------------------------------------------------------------------------------------
361 static inline Reference
< security::XAccessControlContext
> getDynamicRestriction(
362 Reference
< XCurrentContext
> const & xContext
)
363 SAL_THROW( (RuntimeException
) )
367 Any
acc( xContext
->getValueByName( s_acRestriction
) );
368 if (typelib_TypeClass_INTERFACE
== acc
.pType
->eTypeClass
)
370 // avoid ref-counting
371 OUString
const & typeName
=
372 *reinterpret_cast< OUString
const * >( &acc
.pType
->pTypeName
);
373 if (typeName
.equalsAsciiL(
374 RTL_CONSTASCII_STRINGPARAM("com.sun.star.security.XAccessControlContext") ))
376 return Reference
< security::XAccessControlContext
>(
377 *reinterpret_cast< security::XAccessControlContext
** const >( acc
.pData
) );
381 return Reference
< security::XAccessControlContext
>::query(
382 *reinterpret_cast< XInterface
** const >( acc
.pData
) );
386 return Reference
< security::XAccessControlContext
>();
388 //==================================================================================================
393 inline cc_reset( void * cc
) SAL_THROW( () )
395 inline ~cc_reset() SAL_THROW( () )
396 { ::uno_setCurrentContext( m_cc
, s_envType
.pData
, 0 ); }
399 //##################################################################################################
405 typedef WeakComponentImplHelper3
<
406 security::XAccessController
, lang::XServiceInfo
, lang::XInitialization
> t_helper
;
408 //==================================================================================================
409 class AccessController
413 Reference
< XComponentContext
> m_xComponentContext
;
415 Reference
< security::XPolicy
> m_xPolicy
;
416 Reference
< security::XPolicy
> const & getPolicy()
417 SAL_THROW( (RuntimeException
) );
420 enum Mode
{ OFF
, ON
, DYNAMIC_ONLY
, SINGLE_USER
, SINGLE_DEFAULT_USER
} m_mode
;
422 PermissionCollection m_defaultPermissions
;
423 // for single-user mode
424 PermissionCollection m_singleUserPermissions
;
425 OUString m_singleUserId
;
426 bool m_defaultPerm_init
;
427 bool m_singleUser_init
;
428 // for multi-user mode
429 lru_cache
< OUString
, PermissionCollection
, ::rtl::OUStringHash
, equal_to
< OUString
> >
433 typedef vector
< pair
< OUString
, Any
> > t_rec_vec
;
434 inline void clearPostPoned() SAL_THROW( () );
435 void checkAndClearPostPoned() SAL_THROW( (RuntimeException
) );
437 PermissionCollection
getEffectivePermissions(
438 Reference
< XCurrentContext
> const & xContext
,
439 Any
const & demanded_perm
)
440 SAL_THROW( (RuntimeException
) );
443 virtual void SAL_CALL
disposing();
446 AccessController( Reference
< XComponentContext
> const & xComponentContext
)
447 SAL_THROW( (RuntimeException
) );
448 virtual ~AccessController()
451 // XInitialization impl
452 virtual void SAL_CALL
initialize(
453 Sequence
< Any
> const & arguments
)
456 // XAccessController impl
457 virtual void SAL_CALL
checkPermission(
459 throw (RuntimeException
);
460 virtual Any SAL_CALL
doRestricted(
461 Reference
< security::XAction
> const & xAction
,
462 Reference
< security::XAccessControlContext
> const & xRestriction
)
464 virtual Any SAL_CALL
doPrivileged(
465 Reference
< security::XAction
> const & xAction
,
466 Reference
< security::XAccessControlContext
> const & xRestriction
)
468 virtual Reference
< security::XAccessControlContext
> SAL_CALL
getContext()
469 throw (RuntimeException
);
472 virtual OUString SAL_CALL
getImplementationName()
473 throw (RuntimeException
);
474 virtual sal_Bool SAL_CALL
supportsService( OUString
const & serviceName
)
475 throw (RuntimeException
);
476 virtual Sequence
< OUString
> SAL_CALL
getSupportedServiceNames()
477 throw (RuntimeException
);
479 //__________________________________________________________________________________________________
480 AccessController::AccessController( Reference
< XComponentContext
> const & xComponentContext
)
481 SAL_THROW( (RuntimeException
) )
482 : t_helper( m_mutex
)
483 , m_xComponentContext( xComponentContext
)
484 , m_mode( ON
) // default
485 , m_defaultPerm_init( false )
486 , m_singleUser_init( false )
489 g_moduleCount
.modCnt
.acquire( &g_moduleCount
.modCnt
);
492 if (m_xComponentContext
->getValueByName( OUSTR("/services/" SERVICE_NAME
"/mode") ) >>= mode
)
494 if (mode
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("off") ))
498 else if (mode
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("on") ))
502 else if (mode
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("dynamic-only") ))
504 m_mode
= DYNAMIC_ONLY
;
506 else if (mode
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("single-user") ))
508 m_xComponentContext
->getValueByName(
509 OUSTR("/services/" SERVICE_NAME
"/single-user-id") ) >>= m_singleUserId
;
510 if (! m_singleUserId
.getLength())
512 throw RuntimeException(
513 OUSTR("expected a user id in component context entry "
514 "\"/services/" SERVICE_NAME
"/single-user-id\"!"),
515 (OWeakObject
*)this );
517 m_mode
= SINGLE_USER
;
519 else if (mode
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("single-default-user") ))
521 m_mode
= SINGLE_DEFAULT_USER
;
525 // switch on caching for DYNAMIC_ONLY and ON (sharable multi-user process)
526 if (ON
== m_mode
|| DYNAMIC_ONLY
== m_mode
)
528 sal_Int32 cacheSize
= 0; // multi-user cache size
529 if (! (m_xComponentContext
->getValueByName(
530 OUSTR("/services/" SERVICE_NAME
"/user-cache-size") ) >>= cacheSize
))
532 cacheSize
= 128; // reasonable default?
534 #ifdef __CACHE_DIAGNOSE
537 m_user2permissions
.setSize( cacheSize
);
540 //__________________________________________________________________________________________________
541 AccessController::~AccessController()
544 g_moduleCount
.modCnt
.release( &g_moduleCount
.modCnt
);
546 //__________________________________________________________________________________________________
547 void AccessController::disposing()
549 m_mode
= OFF
; // avoid checks from now on xxx todo review/ better DYNAMIC_ONLY?
551 m_xComponentContext
.clear();
554 // XInitialization impl
555 //__________________________________________________________________________________________________
556 void AccessController::initialize(
557 Sequence
< Any
> const & arguments
)
560 // xxx todo: review for forking
561 // portal forking hack: re-initialize for another user-id
562 if (SINGLE_USER
!= m_mode
) // only if in single-user mode
564 throw RuntimeException(
565 OUSTR("invalid call: ac must be in \"single-user\" mode!"), (OWeakObject
*)this );
568 arguments
[ 0 ] >>= userId
;
569 if (! userId
.getLength())
571 throw RuntimeException(
572 OUSTR("expected a user-id as first argument!"), (OWeakObject
*)this );
574 // assured that no sync is necessary: no check happens at this forking time
575 m_singleUserId
= userId
;
576 m_singleUser_init
= false;
579 //__________________________________________________________________________________________________
580 Reference
< security::XPolicy
> const & AccessController::getPolicy()
581 SAL_THROW( (RuntimeException
) )
583 // get policy singleton
584 if (! m_xPolicy
.is())
586 Reference
< security::XPolicy
> xPolicy
;
587 m_xComponentContext
->getValueByName(
588 OUSTR("/singletons/com.sun.star.security.thePolicy") ) >>= xPolicy
;
591 MutexGuard
guard( m_mutex
);
592 if (! m_xPolicy
.is())
599 throw SecurityException(
600 OUSTR("cannot get policy singleton!"), (OWeakObject
*)this );
607 static void dumpPermissions(
608 PermissionCollection
const & collection
, OUString
const & userId
= OUString() ) SAL_THROW( () )
610 OUStringBuffer
buf( 48 );
611 if (userId
.getLength())
613 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("> dumping permissions of user \"") );
614 buf
.append( userId
);
615 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("\":") );
620 RTL_CONSTASCII_STRINGPARAM("> dumping default permissions:") );
622 OString
str( ::rtl::OUStringToOString( buf
.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US
) );
623 OSL_TRACE( str
.getStr() );
624 Sequence
< OUString
> permissions( collection
.toStrings() );
625 OUString
const * p
= permissions
.getConstArray();
626 for ( sal_Int32 nPos
= 0; nPos
< permissions
.getLength(); ++nPos
)
628 OString
str( ::rtl::OUStringToOString( p
[ nPos
], RTL_TEXTENCODING_ASCII_US
) );
629 OSL_TRACE( str
.getStr() );
631 OSL_TRACE( "> permission dump done" );
636 //__________________________________________________________________________________________________
637 inline void AccessController::clearPostPoned() SAL_THROW( () )
639 delete reinterpret_cast< t_rec_vec
* >( m_rec
.getData() );
642 //__________________________________________________________________________________________________
643 void AccessController::checkAndClearPostPoned() SAL_THROW( (RuntimeException
) )
645 // check postponed permissions
646 auto_ptr
< t_rec_vec
> rec( reinterpret_cast< t_rec_vec
* >( m_rec
.getData() ) );
647 m_rec
.setData( 0 ); // takeover ownership
648 OSL_ASSERT( rec
.get() );
651 t_rec_vec
const & vec
= *rec
.get();
656 OSL_ASSERT( m_singleUser_init
);
657 for ( size_t nPos
= 0; nPos
< vec
.size(); ++nPos
)
659 pair
< OUString
, Any
> const & p
= vec
[ nPos
];
660 OSL_ASSERT( m_singleUserId
.equals( p
.first
) );
661 m_singleUserPermissions
.checkPermission( p
.second
);
665 case SINGLE_DEFAULT_USER
:
667 OSL_ASSERT( m_defaultPerm_init
);
668 for ( size_t nPos
= 0; nPos
< vec
.size(); ++nPos
)
670 pair
< OUString
, Any
> const & p
= vec
[ nPos
];
671 OSL_ASSERT( !p
.first
.getLength() ); // default-user
672 m_defaultPermissions
.checkPermission( p
.second
);
678 for ( size_t nPos
= 0; nPos
< vec
.size(); ++nPos
)
680 pair
< OUString
, Any
> const & p
= vec
[ nPos
];
681 PermissionCollection
const * pPermissions
;
682 // lookup policy for user
684 MutexGuard
guard( m_mutex
);
685 pPermissions
= m_user2permissions
.lookup( p
.first
);
687 OSL_ASSERT( pPermissions
);
690 pPermissions
->checkPermission( p
.second
);
696 OSL_ENSURE( 0, "### this should never be called in this ac mode!" );
701 //__________________________________________________________________________________________________
702 /** this is the only function calling the policy singleton and thus has to take care
705 @param demanded_perm (if not empty) is the demanded permission of a checkPermission() call
706 which will be postponed for recurring calls
708 PermissionCollection
AccessController::getEffectivePermissions(
709 Reference
< XCurrentContext
> const & xContext
,
710 Any
const & demanded_perm
)
711 SAL_THROW( (RuntimeException
) )
719 if (m_singleUser_init
)
720 return m_singleUserPermissions
;
721 userId
= m_singleUserId
;
724 case SINGLE_DEFAULT_USER
:
726 if (m_defaultPerm_init
)
727 return m_defaultPermissions
;
734 xContext
->getValueByName( OUSTR(USER_CREDS
".id") ) >>= userId
;
736 if (! userId
.getLength())
738 throw SecurityException(
739 OUSTR("cannot determine current user in multi-user ac!"), (OWeakObject
*)this );
742 // lookup policy for user
743 MutexGuard
guard( m_mutex
);
744 PermissionCollection
const * pPermissions
= m_user2permissions
.lookup( userId
);
746 return *pPermissions
;
750 OSL_ENSURE( 0, "### this should never be called in this ac mode!" );
751 return PermissionCollection();
755 // iff this is a recurring call for the default user, then grant all permissions
756 t_rec_vec
* rec
= reinterpret_cast< t_rec_vec
* >( m_rec
.getData() );
757 if (rec
) // tls entry exists => this is recursive call
759 if (demanded_perm
.hasValue())
762 rec
->push_back( pair
< OUString
, Any
>( userId
, demanded_perm
) );
765 OUStringBuffer
buf( 48 );
766 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("> info: recurring call of user \"") );
767 buf
.append( userId
);
768 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"") );
770 ::rtl::OUStringToOString( buf
.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US
) );
771 OSL_TRACE( str
.getStr() );
773 return PermissionCollection( new AllPermission() );
778 m_rec
.setData( rec
);
783 // init default permissions
784 if (! m_defaultPerm_init
)
786 PermissionCollection
defaultPermissions(
787 getPolicy()->getDefaultPermissions() );
789 MutexGuard
guard( m_mutex
);
790 if (! m_defaultPerm_init
)
792 m_defaultPermissions
= defaultPermissions
;
793 m_defaultPerm_init
= true;
796 dumpPermissions( m_defaultPermissions
);
800 PermissionCollection ret
;
802 // init user permissions
807 ret
= PermissionCollection(
808 getPolicy()->getPermissions( userId
), m_defaultPermissions
);
811 MutexGuard
guard( m_mutex
);
812 if (m_singleUser_init
)
814 ret
= m_singleUserPermissions
;
818 m_singleUserPermissions
= ret
;
819 m_singleUser_init
= true;
823 dumpPermissions( ret
, userId
);
827 case SINGLE_DEFAULT_USER
:
829 ret
= m_defaultPermissions
;
834 ret
= PermissionCollection(
835 getPolicy()->getPermissions( userId
), m_defaultPermissions
);
838 MutexGuard
guard( m_mutex
);
839 m_user2permissions
.set( userId
, ret
);
842 dumpPermissions( ret
, userId
);
851 checkAndClearPostPoned();
854 catch (security::AccessControlException
& exc
) // wrapped into DeploymentException
856 clearPostPoned(); // safety: exception could have happened before checking postponed?
857 OUStringBuffer
buf( 64 );
859 RTL_CONSTASCII_STRINGPARAM("deployment error (AccessControlException occured): ") );
860 buf
.append( exc
.Message
);
861 throw DeploymentException( buf
.makeStringAndClear(), exc
.Context
);
863 catch (RuntimeException
&)
865 // dont check postponed, just cleanup
867 delete reinterpret_cast< t_rec_vec
* >( m_rec
.getData() );
873 // check postponed permissions first
874 // => AccessControlExceptions are errors, user exceptions not!
875 checkAndClearPostPoned();
880 // dont check postponed, just cleanup
886 // XAccessController impl
887 //__________________________________________________________________________________________________
888 void AccessController::checkPermission(
890 throw (RuntimeException
)
892 if (rBHelper
.bDisposed
)
894 throw lang::DisposedException(
895 OUSTR("checkPermission() call on disposed AccessController!"), (OWeakObject
*)this );
901 // first dynamic check of ac contexts
902 Reference
< XCurrentContext
> xContext
;
903 ::uno_getCurrentContext( (void **)&xContext
, s_envType
.pData
, 0 );
904 Reference
< security::XAccessControlContext
> xACC( getDynamicRestriction( xContext
) );
907 xACC
->checkPermission( perm
);
910 if (DYNAMIC_ONLY
== m_mode
)
914 getEffectivePermissions( xContext
, perm
).checkPermission( perm
);
916 //__________________________________________________________________________________________________
917 Any
AccessController::doRestricted(
918 Reference
< security::XAction
> const & xAction
,
919 Reference
< security::XAccessControlContext
> const & xRestriction
)
922 if (rBHelper
.bDisposed
)
924 throw lang::DisposedException(
925 OUSTR("doRestricted() call on disposed AccessController!"), (OWeakObject
*)this );
928 if (OFF
== m_mode
) // optimize this way, because no dynamic check will be performed
929 return xAction
->run();
931 if (xRestriction
.is())
933 Reference
< XCurrentContext
> xContext
;
934 ::uno_getCurrentContext( (void **)&xContext
, s_envType
.pData
, 0 );
936 // override restriction
937 Reference
< XCurrentContext
> xNewContext(
938 new acc_CurrentContext( xContext
, acc_Intersection::create(
939 xRestriction
, getDynamicRestriction( xContext
) ) ) );
940 ::uno_setCurrentContext( xNewContext
.get(), s_envType
.pData
, 0 );
941 cc_reset
reset( xContext
.get() );
942 return xAction
->run();
946 return xAction
->run();
949 //__________________________________________________________________________________________________
950 Any
AccessController::doPrivileged(
951 Reference
< security::XAction
> const & xAction
,
952 Reference
< security::XAccessControlContext
> const & xRestriction
)
955 if (rBHelper
.bDisposed
)
957 throw lang::DisposedException(
958 OUSTR("doPrivileged() call on disposed AccessController!"), (OWeakObject
*)this );
961 if (OFF
== m_mode
) // no dynamic check will be performed
963 return xAction
->run();
966 Reference
< XCurrentContext
> xContext
;
967 ::uno_getCurrentContext( (void **)&xContext
, s_envType
.pData
, 0 );
969 Reference
< security::XAccessControlContext
> xOldRestr(
970 getDynamicRestriction( xContext
) );
972 if (xOldRestr
.is()) // previous restriction
974 // override restriction
975 Reference
< XCurrentContext
> xNewContext(
976 new acc_CurrentContext( xContext
, acc_Union::create( xRestriction
, xOldRestr
) ) );
977 ::uno_setCurrentContext( xNewContext
.get(), s_envType
.pData
, 0 );
978 cc_reset
reset( xContext
.get() );
979 return xAction
->run();
981 else // no previous restriction => never current restriction
983 return xAction
->run();
986 //__________________________________________________________________________________________________
987 Reference
< security::XAccessControlContext
> AccessController::getContext()
988 throw (RuntimeException
)
990 if (rBHelper
.bDisposed
)
992 throw lang::DisposedException(
993 OUSTR("getContext() call on disposed AccessController!"), (OWeakObject
*)this );
996 if (OFF
== m_mode
) // optimize this way, because no dynamic check will be performed
998 return new acc_Policy( PermissionCollection( new AllPermission() ) );
1001 Reference
< XCurrentContext
> xContext
;
1002 ::uno_getCurrentContext( (void **)&xContext
, s_envType
.pData
, 0 );
1004 return acc_Intersection::create(
1005 getDynamicRestriction( xContext
),
1006 new acc_Policy( getEffectivePermissions( xContext
, Any() ) ) );
1009 // XServiceInfo impl
1010 //__________________________________________________________________________________________________
1011 OUString
AccessController::getImplementationName()
1012 throw (RuntimeException
)
1016 //__________________________________________________________________________________________________
1017 sal_Bool
AccessController::supportsService( OUString
const & serviceName
)
1018 throw (RuntimeException
)
1020 OUString
const * pNames
= s_serviceNames
.getConstArray();
1021 for ( sal_Int32 nPos
= s_serviceNames
.getLength(); nPos
--; )
1023 if (serviceName
.equals( pNames
[ nPos
] ))
1030 //__________________________________________________________________________________________________
1031 Sequence
< OUString
> AccessController::getSupportedServiceNames()
1032 throw (RuntimeException
)
1034 return s_serviceNames
;
1037 //##################################################################################################
1038 namespace stoc_bootstrap
{
1039 //--------------------------------------------------------------------------------------------------
1040 Reference
< XInterface
> SAL_CALL
ac_create(
1041 Reference
< XComponentContext
> const & xComponentContext
)
1042 SAL_THROW( (Exception
) )
1044 return (OWeakObject
*)new stoc_sec::AccessController( xComponentContext
);
1046 //--------------------------------------------------------------------------------------------------
1047 Sequence
< OUString
> ac_getSupportedServiceNames() SAL_THROW( () )
1049 return stoc_sec::s_serviceNames
;
1051 //--------------------------------------------------------------------------------------------------
1052 OUString
ac_getImplementationName() SAL_THROW( () )
1054 return stoc_sec::s_implName
;
1056 //--------------------------------------------------------------------------------------------------
1057 Reference
< XInterface
> SAL_CALL
filepolicy_create(
1058 Reference
< XComponentContext
> const & xComponentContext
)
1059 SAL_THROW( (Exception
) );
1060 //--------------------------------------------------------------------------------------------------
1061 Sequence
< OUString
> filepolicy_getSupportedServiceNames() SAL_THROW( () );
1062 //--------------------------------------------------------------------------------------------------
1063 OUString
filepolicy_getImplementationName() SAL_THROW( () );