1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_stoc.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <vector>
32*cdf0e10cSrcweir #include <memory>
33*cdf0e10cSrcweir 
34*cdf0e10cSrcweir #include <osl/diagnose.h>
35*cdf0e10cSrcweir #include <osl/interlck.h>
36*cdf0e10cSrcweir #include <osl/mutex.hxx>
37*cdf0e10cSrcweir #include <osl/thread.hxx>
38*cdf0e10cSrcweir 
39*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
40*cdf0e10cSrcweir #include <rtl/string.hxx>
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir #include <uno/current_context.h>
43*cdf0e10cSrcweir 
44*cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>
45*cdf0e10cSrcweir #include <cppuhelper/compbase3.hxx>
46*cdf0e10cSrcweir #include <cppuhelper/factory.hxx>
47*cdf0e10cSrcweir #include <cppuhelper/implementationentry.hxx>
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir #include <com/sun/star/uno/XCurrentContext.hpp>
50*cdf0e10cSrcweir #include <com/sun/star/uno/DeploymentException.hpp>
51*cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp>
52*cdf0e10cSrcweir #include <com/sun/star/lang/XComponent.hpp>
53*cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp>
54*cdf0e10cSrcweir #include <com/sun/star/lang/XInitialization.hpp>
55*cdf0e10cSrcweir #include <com/sun/star/security/XAccessController.hpp>
56*cdf0e10cSrcweir #include <com/sun/star/security/XPolicy.hpp>
57*cdf0e10cSrcweir 
58*cdf0e10cSrcweir #include "lru_cache.h"
59*cdf0e10cSrcweir #include "permissions.h"
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
62*cdf0e10cSrcweir #define SERVICE_NAME "com.sun.star.security.AccessController"
63*cdf0e10cSrcweir #define IMPL_NAME "com.sun.star.security.comp.stoc.AccessController"
64*cdf0e10cSrcweir #define USER_CREDS "access-control.user-credentials"
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir using namespace ::std;
68*cdf0e10cSrcweir using namespace ::osl;
69*cdf0e10cSrcweir using namespace ::cppu;
70*cdf0e10cSrcweir using namespace ::com::sun::star;
71*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
72*cdf0e10cSrcweir using ::rtl::OUString;
73*cdf0e10cSrcweir using ::rtl::OUStringBuffer;
74*cdf0e10cSrcweir using ::rtl::OString;
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir extern ::rtl_StandardModuleCount g_moduleCount;
77*cdf0e10cSrcweir 
78*cdf0e10cSrcweir namespace stoc_sec
79*cdf0e10cSrcweir {
80*cdf0e10cSrcweir // static stuff initialized when loading lib
81*cdf0e10cSrcweir static OUString s_envType = OUSTR(CPPU_CURRENT_LANGUAGE_BINDING_NAME);
82*cdf0e10cSrcweir static OUString s_implName = OUSTR(IMPL_NAME);
83*cdf0e10cSrcweir static OUString s_serviceName = OUSTR(SERVICE_NAME);
84*cdf0e10cSrcweir static OUString s_acRestriction = OUSTR("access-control.restriction");
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir static Sequence< OUString > s_serviceNames = Sequence< OUString >( &s_serviceName, 1 );
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir //##################################################################################################
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir /** ac context intersects permissions of two ac contexts
91*cdf0e10cSrcweir */
92*cdf0e10cSrcweir class acc_Intersection
93*cdf0e10cSrcweir     : public WeakImplHelper1< security::XAccessControlContext >
94*cdf0e10cSrcweir {
95*cdf0e10cSrcweir     Reference< security::XAccessControlContext > m_x1, m_x2;
96*cdf0e10cSrcweir 
97*cdf0e10cSrcweir     inline acc_Intersection(
98*cdf0e10cSrcweir         Reference< security::XAccessControlContext > const & x1,
99*cdf0e10cSrcweir         Reference< security::XAccessControlContext > const & x2 )
100*cdf0e10cSrcweir         SAL_THROW( () );
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir public:
103*cdf0e10cSrcweir     virtual ~acc_Intersection()
104*cdf0e10cSrcweir         SAL_THROW( () );
105*cdf0e10cSrcweir 
106*cdf0e10cSrcweir     static inline Reference< security::XAccessControlContext > create(
107*cdf0e10cSrcweir         Reference< security::XAccessControlContext > const & x1,
108*cdf0e10cSrcweir         Reference< security::XAccessControlContext > const & x2 )
109*cdf0e10cSrcweir         SAL_THROW( () );
110*cdf0e10cSrcweir 
111*cdf0e10cSrcweir     // XAccessControlContext impl
112*cdf0e10cSrcweir     virtual void SAL_CALL checkPermission(
113*cdf0e10cSrcweir         Any const & perm )
114*cdf0e10cSrcweir         throw (RuntimeException);
115*cdf0e10cSrcweir };
116*cdf0e10cSrcweir //__________________________________________________________________________________________________
117*cdf0e10cSrcweir inline acc_Intersection::acc_Intersection(
118*cdf0e10cSrcweir     Reference< security::XAccessControlContext > const & x1,
119*cdf0e10cSrcweir     Reference< security::XAccessControlContext > const & x2 )
120*cdf0e10cSrcweir     SAL_THROW( () )
121*cdf0e10cSrcweir     : m_x1( x1 )
122*cdf0e10cSrcweir     , m_x2( x2 )
123*cdf0e10cSrcweir {
124*cdf0e10cSrcweir     g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
125*cdf0e10cSrcweir }
126*cdf0e10cSrcweir //__________________________________________________________________________________________________
127*cdf0e10cSrcweir acc_Intersection::~acc_Intersection()
128*cdf0e10cSrcweir     SAL_THROW( () )
129*cdf0e10cSrcweir {
130*cdf0e10cSrcweir     g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
131*cdf0e10cSrcweir }
132*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
133*cdf0e10cSrcweir inline Reference< security::XAccessControlContext > acc_Intersection::create(
134*cdf0e10cSrcweir     Reference< security::XAccessControlContext > const & x1,
135*cdf0e10cSrcweir     Reference< security::XAccessControlContext > const & x2 )
136*cdf0e10cSrcweir     SAL_THROW( () )
137*cdf0e10cSrcweir {
138*cdf0e10cSrcweir     if (! x1.is())
139*cdf0e10cSrcweir         return x2;
140*cdf0e10cSrcweir     if (! x2.is())
141*cdf0e10cSrcweir         return x1;
142*cdf0e10cSrcweir     return new acc_Intersection( x1, x2 );
143*cdf0e10cSrcweir }
144*cdf0e10cSrcweir //__________________________________________________________________________________________________
145*cdf0e10cSrcweir void acc_Intersection::checkPermission(
146*cdf0e10cSrcweir     Any const & perm )
147*cdf0e10cSrcweir     throw (RuntimeException)
148*cdf0e10cSrcweir {
149*cdf0e10cSrcweir     m_x1->checkPermission( perm );
150*cdf0e10cSrcweir     m_x2->checkPermission( perm );
151*cdf0e10cSrcweir }
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir /** ac context unifies permissions of two ac contexts
154*cdf0e10cSrcweir */
155*cdf0e10cSrcweir class acc_Union
156*cdf0e10cSrcweir     : public WeakImplHelper1< security::XAccessControlContext >
157*cdf0e10cSrcweir {
158*cdf0e10cSrcweir     Reference< security::XAccessControlContext > m_x1, m_x2;
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir     inline acc_Union(
161*cdf0e10cSrcweir         Reference< security::XAccessControlContext > const & x1,
162*cdf0e10cSrcweir         Reference< security::XAccessControlContext > const & x2 )
163*cdf0e10cSrcweir         SAL_THROW( () );
164*cdf0e10cSrcweir 
165*cdf0e10cSrcweir public:
166*cdf0e10cSrcweir     virtual ~acc_Union()
167*cdf0e10cSrcweir         SAL_THROW( () );
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir     static inline Reference< security::XAccessControlContext > create(
170*cdf0e10cSrcweir         Reference< security::XAccessControlContext > const & x1,
171*cdf0e10cSrcweir         Reference< security::XAccessControlContext > const & x2 )
172*cdf0e10cSrcweir         SAL_THROW( () );
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir     // XAccessControlContext impl
175*cdf0e10cSrcweir     virtual void SAL_CALL checkPermission(
176*cdf0e10cSrcweir         Any const & perm )
177*cdf0e10cSrcweir         throw (RuntimeException);
178*cdf0e10cSrcweir };
179*cdf0e10cSrcweir //__________________________________________________________________________________________________
180*cdf0e10cSrcweir inline acc_Union::acc_Union(
181*cdf0e10cSrcweir     Reference< security::XAccessControlContext > const & x1,
182*cdf0e10cSrcweir     Reference< security::XAccessControlContext > const & x2 )
183*cdf0e10cSrcweir     SAL_THROW( () )
184*cdf0e10cSrcweir     : m_x1( x1 )
185*cdf0e10cSrcweir     , m_x2( x2 )
186*cdf0e10cSrcweir {
187*cdf0e10cSrcweir     g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
188*cdf0e10cSrcweir }
189*cdf0e10cSrcweir //__________________________________________________________________________________________________
190*cdf0e10cSrcweir acc_Union::~acc_Union()
191*cdf0e10cSrcweir     SAL_THROW( () )
192*cdf0e10cSrcweir {
193*cdf0e10cSrcweir     g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
194*cdf0e10cSrcweir }
195*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
196*cdf0e10cSrcweir inline Reference< security::XAccessControlContext > acc_Union::create(
197*cdf0e10cSrcweir     Reference< security::XAccessControlContext > const & x1,
198*cdf0e10cSrcweir     Reference< security::XAccessControlContext > const & x2 )
199*cdf0e10cSrcweir     SAL_THROW( () )
200*cdf0e10cSrcweir {
201*cdf0e10cSrcweir     if (! x1.is())
202*cdf0e10cSrcweir         return Reference< security::XAccessControlContext >(); // unrestricted
203*cdf0e10cSrcweir     if (! x2.is())
204*cdf0e10cSrcweir         return Reference< security::XAccessControlContext >(); // unrestricted
205*cdf0e10cSrcweir     return new acc_Union( x1, x2 );
206*cdf0e10cSrcweir }
207*cdf0e10cSrcweir //__________________________________________________________________________________________________
208*cdf0e10cSrcweir void acc_Union::checkPermission(
209*cdf0e10cSrcweir     Any const & perm )
210*cdf0e10cSrcweir     throw (RuntimeException)
211*cdf0e10cSrcweir {
212*cdf0e10cSrcweir     try
213*cdf0e10cSrcweir     {
214*cdf0e10cSrcweir         m_x1->checkPermission( perm );
215*cdf0e10cSrcweir     }
216*cdf0e10cSrcweir     catch (security::AccessControlException &)
217*cdf0e10cSrcweir     {
218*cdf0e10cSrcweir         m_x2->checkPermission( perm );
219*cdf0e10cSrcweir     }
220*cdf0e10cSrcweir }
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir /** ac context doing permission checks on static permissions
223*cdf0e10cSrcweir */
224*cdf0e10cSrcweir class acc_Policy
225*cdf0e10cSrcweir     : public WeakImplHelper1< security::XAccessControlContext >
226*cdf0e10cSrcweir {
227*cdf0e10cSrcweir     PermissionCollection m_permissions;
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir public:
230*cdf0e10cSrcweir     inline acc_Policy(
231*cdf0e10cSrcweir         PermissionCollection const & permissions )
232*cdf0e10cSrcweir         SAL_THROW( () );
233*cdf0e10cSrcweir     virtual ~acc_Policy()
234*cdf0e10cSrcweir         SAL_THROW( () );
235*cdf0e10cSrcweir 
236*cdf0e10cSrcweir     // XAccessControlContext impl
237*cdf0e10cSrcweir     virtual void SAL_CALL checkPermission(
238*cdf0e10cSrcweir         Any const & perm )
239*cdf0e10cSrcweir         throw (RuntimeException);
240*cdf0e10cSrcweir };
241*cdf0e10cSrcweir //__________________________________________________________________________________________________
242*cdf0e10cSrcweir inline acc_Policy::acc_Policy(
243*cdf0e10cSrcweir     PermissionCollection const & permissions )
244*cdf0e10cSrcweir     SAL_THROW( () )
245*cdf0e10cSrcweir     : m_permissions( permissions )
246*cdf0e10cSrcweir {
247*cdf0e10cSrcweir     g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
248*cdf0e10cSrcweir }
249*cdf0e10cSrcweir //__________________________________________________________________________________________________
250*cdf0e10cSrcweir acc_Policy::~acc_Policy()
251*cdf0e10cSrcweir     SAL_THROW( () )
252*cdf0e10cSrcweir {
253*cdf0e10cSrcweir     g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
254*cdf0e10cSrcweir }
255*cdf0e10cSrcweir //__________________________________________________________________________________________________
256*cdf0e10cSrcweir void acc_Policy::checkPermission(
257*cdf0e10cSrcweir     Any const & perm )
258*cdf0e10cSrcweir     throw (RuntimeException)
259*cdf0e10cSrcweir {
260*cdf0e10cSrcweir     m_permissions.checkPermission( perm );
261*cdf0e10cSrcweir }
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir /** current context overriding dynamic ac restriction
264*cdf0e10cSrcweir */
265*cdf0e10cSrcweir class acc_CurrentContext
266*cdf0e10cSrcweir     : public ImplHelper1< XCurrentContext >
267*cdf0e10cSrcweir {
268*cdf0e10cSrcweir     oslInterlockedCount m_refcount;
269*cdf0e10cSrcweir 
270*cdf0e10cSrcweir     Reference< XCurrentContext > m_xDelegate;
271*cdf0e10cSrcweir     Any m_restriction;
272*cdf0e10cSrcweir 
273*cdf0e10cSrcweir public:
274*cdf0e10cSrcweir     inline acc_CurrentContext(
275*cdf0e10cSrcweir         Reference< XCurrentContext > const & xDelegate,
276*cdf0e10cSrcweir         Reference< security::XAccessControlContext > const & xRestriction )
277*cdf0e10cSrcweir         SAL_THROW( () );
278*cdf0e10cSrcweir     virtual ~acc_CurrentContext() SAL_THROW( () );
279*cdf0e10cSrcweir 
280*cdf0e10cSrcweir     // XInterface impl
281*cdf0e10cSrcweir     virtual void SAL_CALL acquire()
282*cdf0e10cSrcweir         throw ();
283*cdf0e10cSrcweir     virtual void SAL_CALL release()
284*cdf0e10cSrcweir         throw ();
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir     // XCurrentContext impl
287*cdf0e10cSrcweir     virtual Any SAL_CALL getValueByName( OUString const & name )
288*cdf0e10cSrcweir         throw (RuntimeException);
289*cdf0e10cSrcweir };
290*cdf0e10cSrcweir //__________________________________________________________________________________________________
291*cdf0e10cSrcweir inline acc_CurrentContext::acc_CurrentContext(
292*cdf0e10cSrcweir     Reference< XCurrentContext > const & xDelegate,
293*cdf0e10cSrcweir     Reference< security::XAccessControlContext > const & xRestriction )
294*cdf0e10cSrcweir     SAL_THROW( () )
295*cdf0e10cSrcweir     : m_refcount( 0 )
296*cdf0e10cSrcweir     , m_xDelegate( xDelegate )
297*cdf0e10cSrcweir {
298*cdf0e10cSrcweir     g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
299*cdf0e10cSrcweir 
300*cdf0e10cSrcweir     if (xRestriction.is())
301*cdf0e10cSrcweir     {
302*cdf0e10cSrcweir         m_restriction = makeAny( xRestriction );
303*cdf0e10cSrcweir     }
304*cdf0e10cSrcweir     // return empty any otherwise on getValueByName(), not null interface
305*cdf0e10cSrcweir }
306*cdf0e10cSrcweir //__________________________________________________________________________________________________
307*cdf0e10cSrcweir acc_CurrentContext::~acc_CurrentContext()
308*cdf0e10cSrcweir     SAL_THROW( () )
309*cdf0e10cSrcweir {
310*cdf0e10cSrcweir     g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
311*cdf0e10cSrcweir }
312*cdf0e10cSrcweir //__________________________________________________________________________________________________
313*cdf0e10cSrcweir void acc_CurrentContext::acquire()
314*cdf0e10cSrcweir     throw ()
315*cdf0e10cSrcweir {
316*cdf0e10cSrcweir     ::osl_incrementInterlockedCount( &m_refcount );
317*cdf0e10cSrcweir }
318*cdf0e10cSrcweir //__________________________________________________________________________________________________
319*cdf0e10cSrcweir void acc_CurrentContext::release()
320*cdf0e10cSrcweir     throw ()
321*cdf0e10cSrcweir {
322*cdf0e10cSrcweir     if (! ::osl_decrementInterlockedCount( &m_refcount ))
323*cdf0e10cSrcweir     {
324*cdf0e10cSrcweir         delete this;
325*cdf0e10cSrcweir     }
326*cdf0e10cSrcweir }
327*cdf0e10cSrcweir //__________________________________________________________________________________________________
328*cdf0e10cSrcweir Any acc_CurrentContext::getValueByName( OUString const & name )
329*cdf0e10cSrcweir     throw (RuntimeException)
330*cdf0e10cSrcweir {
331*cdf0e10cSrcweir     if (name.equals( s_acRestriction ))
332*cdf0e10cSrcweir     {
333*cdf0e10cSrcweir         return m_restriction;
334*cdf0e10cSrcweir     }
335*cdf0e10cSrcweir     else if (m_xDelegate.is())
336*cdf0e10cSrcweir     {
337*cdf0e10cSrcweir         return m_xDelegate->getValueByName( name );
338*cdf0e10cSrcweir     }
339*cdf0e10cSrcweir     else
340*cdf0e10cSrcweir     {
341*cdf0e10cSrcweir         return Any();
342*cdf0e10cSrcweir     }
343*cdf0e10cSrcweir }
344*cdf0e10cSrcweir 
345*cdf0e10cSrcweir //##################################################################################################
346*cdf0e10cSrcweir 
347*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
348*cdf0e10cSrcweir static inline void dispose( Reference< XInterface > const & x )
349*cdf0e10cSrcweir     SAL_THROW( (RuntimeException) )
350*cdf0e10cSrcweir {
351*cdf0e10cSrcweir     Reference< lang::XComponent > xComp( x, UNO_QUERY );
352*cdf0e10cSrcweir     if (xComp.is())
353*cdf0e10cSrcweir     {
354*cdf0e10cSrcweir         xComp->dispose();
355*cdf0e10cSrcweir     }
356*cdf0e10cSrcweir }
357*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
358*cdf0e10cSrcweir static inline Reference< security::XAccessControlContext > getDynamicRestriction(
359*cdf0e10cSrcweir     Reference< XCurrentContext > const & xContext )
360*cdf0e10cSrcweir     SAL_THROW( (RuntimeException) )
361*cdf0e10cSrcweir {
362*cdf0e10cSrcweir     if (xContext.is())
363*cdf0e10cSrcweir     {
364*cdf0e10cSrcweir         Any acc( xContext->getValueByName( s_acRestriction ) );
365*cdf0e10cSrcweir         if (typelib_TypeClass_INTERFACE == acc.pType->eTypeClass)
366*cdf0e10cSrcweir         {
367*cdf0e10cSrcweir             // avoid ref-counting
368*cdf0e10cSrcweir             OUString const & typeName =
369*cdf0e10cSrcweir                 *reinterpret_cast< OUString const * >( &acc.pType->pTypeName );
370*cdf0e10cSrcweir             if (typeName.equalsAsciiL(
371*cdf0e10cSrcweir                     RTL_CONSTASCII_STRINGPARAM("com.sun.star.security.XAccessControlContext") ))
372*cdf0e10cSrcweir             {
373*cdf0e10cSrcweir                 return Reference< security::XAccessControlContext >(
374*cdf0e10cSrcweir                     *reinterpret_cast< security::XAccessControlContext ** const >( acc.pData ) );
375*cdf0e10cSrcweir             }
376*cdf0e10cSrcweir             else // try to query
377*cdf0e10cSrcweir             {
378*cdf0e10cSrcweir                 return Reference< security::XAccessControlContext >::query(
379*cdf0e10cSrcweir                     *reinterpret_cast< XInterface ** const >( acc.pData ) );
380*cdf0e10cSrcweir             }
381*cdf0e10cSrcweir         }
382*cdf0e10cSrcweir     }
383*cdf0e10cSrcweir     return Reference< security::XAccessControlContext >();
384*cdf0e10cSrcweir }
385*cdf0e10cSrcweir //==================================================================================================
386*cdf0e10cSrcweir class cc_reset
387*cdf0e10cSrcweir {
388*cdf0e10cSrcweir     void * m_cc;
389*cdf0e10cSrcweir public:
390*cdf0e10cSrcweir     inline cc_reset( void * cc ) SAL_THROW( () )
391*cdf0e10cSrcweir         : m_cc( cc ) {}
392*cdf0e10cSrcweir     inline ~cc_reset() SAL_THROW( () )
393*cdf0e10cSrcweir         { ::uno_setCurrentContext( m_cc, s_envType.pData, 0 ); }
394*cdf0e10cSrcweir };
395*cdf0e10cSrcweir 
396*cdf0e10cSrcweir //##################################################################################################
397*cdf0e10cSrcweir 
398*cdf0e10cSrcweir struct MutexHolder
399*cdf0e10cSrcweir {
400*cdf0e10cSrcweir     Mutex m_mutex;
401*cdf0e10cSrcweir };
402*cdf0e10cSrcweir typedef WeakComponentImplHelper3<
403*cdf0e10cSrcweir     security::XAccessController, lang::XServiceInfo, lang::XInitialization > t_helper;
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir //==================================================================================================
406*cdf0e10cSrcweir class AccessController
407*cdf0e10cSrcweir     : public MutexHolder
408*cdf0e10cSrcweir     , public t_helper
409*cdf0e10cSrcweir {
410*cdf0e10cSrcweir     Reference< XComponentContext > m_xComponentContext;
411*cdf0e10cSrcweir 
412*cdf0e10cSrcweir     Reference< security::XPolicy > m_xPolicy;
413*cdf0e10cSrcweir     Reference< security::XPolicy > const & getPolicy()
414*cdf0e10cSrcweir         SAL_THROW( (RuntimeException) );
415*cdf0e10cSrcweir 
416*cdf0e10cSrcweir     // mode
417*cdf0e10cSrcweir     enum Mode { OFF, ON, DYNAMIC_ONLY, SINGLE_USER, SINGLE_DEFAULT_USER } m_mode;
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir     PermissionCollection m_defaultPermissions;
420*cdf0e10cSrcweir     // for single-user mode
421*cdf0e10cSrcweir     PermissionCollection m_singleUserPermissions;
422*cdf0e10cSrcweir     OUString m_singleUserId;
423*cdf0e10cSrcweir     bool m_defaultPerm_init;
424*cdf0e10cSrcweir     bool m_singleUser_init;
425*cdf0e10cSrcweir     // for multi-user mode
426*cdf0e10cSrcweir     lru_cache< OUString, PermissionCollection, ::rtl::OUStringHash, equal_to< OUString > >
427*cdf0e10cSrcweir         m_user2permissions;
428*cdf0e10cSrcweir 
429*cdf0e10cSrcweir     ThreadData m_rec;
430*cdf0e10cSrcweir     typedef vector< pair< OUString, Any > > t_rec_vec;
431*cdf0e10cSrcweir     inline void clearPostPoned() SAL_THROW( () );
432*cdf0e10cSrcweir     void checkAndClearPostPoned() SAL_THROW( (RuntimeException) );
433*cdf0e10cSrcweir 
434*cdf0e10cSrcweir     PermissionCollection getEffectivePermissions(
435*cdf0e10cSrcweir         Reference< XCurrentContext > const & xContext,
436*cdf0e10cSrcweir         Any const & demanded_perm )
437*cdf0e10cSrcweir         SAL_THROW( (RuntimeException) );
438*cdf0e10cSrcweir 
439*cdf0e10cSrcweir protected:
440*cdf0e10cSrcweir     virtual void SAL_CALL disposing();
441*cdf0e10cSrcweir 
442*cdf0e10cSrcweir public:
443*cdf0e10cSrcweir     AccessController( Reference< XComponentContext > const & xComponentContext )
444*cdf0e10cSrcweir         SAL_THROW( (RuntimeException) );
445*cdf0e10cSrcweir     virtual ~AccessController()
446*cdf0e10cSrcweir         SAL_THROW( () );
447*cdf0e10cSrcweir 
448*cdf0e10cSrcweir     //  XInitialization impl
449*cdf0e10cSrcweir     virtual void SAL_CALL initialize(
450*cdf0e10cSrcweir         Sequence< Any > const & arguments )
451*cdf0e10cSrcweir         throw (Exception);
452*cdf0e10cSrcweir 
453*cdf0e10cSrcweir     // XAccessController impl
454*cdf0e10cSrcweir     virtual void SAL_CALL checkPermission(
455*cdf0e10cSrcweir         Any const & perm )
456*cdf0e10cSrcweir         throw (RuntimeException);
457*cdf0e10cSrcweir     virtual Any SAL_CALL doRestricted(
458*cdf0e10cSrcweir         Reference< security::XAction > const & xAction,
459*cdf0e10cSrcweir         Reference< security::XAccessControlContext > const & xRestriction )
460*cdf0e10cSrcweir         throw (Exception);
461*cdf0e10cSrcweir     virtual Any SAL_CALL doPrivileged(
462*cdf0e10cSrcweir         Reference< security::XAction > const & xAction,
463*cdf0e10cSrcweir         Reference< security::XAccessControlContext > const & xRestriction )
464*cdf0e10cSrcweir         throw (Exception);
465*cdf0e10cSrcweir     virtual Reference< security::XAccessControlContext > SAL_CALL getContext()
466*cdf0e10cSrcweir         throw (RuntimeException);
467*cdf0e10cSrcweir 
468*cdf0e10cSrcweir     // XServiceInfo impl
469*cdf0e10cSrcweir     virtual OUString SAL_CALL getImplementationName()
470*cdf0e10cSrcweir         throw (RuntimeException);
471*cdf0e10cSrcweir     virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName )
472*cdf0e10cSrcweir         throw (RuntimeException);
473*cdf0e10cSrcweir     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
474*cdf0e10cSrcweir         throw (RuntimeException);
475*cdf0e10cSrcweir };
476*cdf0e10cSrcweir //__________________________________________________________________________________________________
477*cdf0e10cSrcweir AccessController::AccessController( Reference< XComponentContext > const & xComponentContext )
478*cdf0e10cSrcweir     SAL_THROW( (RuntimeException) )
479*cdf0e10cSrcweir     : t_helper( m_mutex )
480*cdf0e10cSrcweir     , m_xComponentContext( xComponentContext )
481*cdf0e10cSrcweir     , m_mode( ON ) // default
482*cdf0e10cSrcweir     , m_defaultPerm_init( false )
483*cdf0e10cSrcweir     , m_singleUser_init( false )
484*cdf0e10cSrcweir     , m_rec( 0 )
485*cdf0e10cSrcweir {
486*cdf0e10cSrcweir     g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
487*cdf0e10cSrcweir 
488*cdf0e10cSrcweir     OUString mode;
489*cdf0e10cSrcweir     if (m_xComponentContext->getValueByName( OUSTR("/services/" SERVICE_NAME "/mode") ) >>= mode)
490*cdf0e10cSrcweir     {
491*cdf0e10cSrcweir         if (mode.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("off") ))
492*cdf0e10cSrcweir         {
493*cdf0e10cSrcweir             m_mode = OFF;
494*cdf0e10cSrcweir         }
495*cdf0e10cSrcweir         else if (mode.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("on") ))
496*cdf0e10cSrcweir         {
497*cdf0e10cSrcweir             m_mode = ON;
498*cdf0e10cSrcweir         }
499*cdf0e10cSrcweir         else if (mode.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("dynamic-only") ))
500*cdf0e10cSrcweir         {
501*cdf0e10cSrcweir             m_mode = DYNAMIC_ONLY;
502*cdf0e10cSrcweir         }
503*cdf0e10cSrcweir         else if (mode.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("single-user") ))
504*cdf0e10cSrcweir         {
505*cdf0e10cSrcweir             m_xComponentContext->getValueByName(
506*cdf0e10cSrcweir                 OUSTR("/services/" SERVICE_NAME "/single-user-id") ) >>= m_singleUserId;
507*cdf0e10cSrcweir             if (! m_singleUserId.getLength())
508*cdf0e10cSrcweir             {
509*cdf0e10cSrcweir                 throw RuntimeException(
510*cdf0e10cSrcweir                     OUSTR("expected a user id in component context entry "
511*cdf0e10cSrcweir                           "\"/services/" SERVICE_NAME "/single-user-id\"!"),
512*cdf0e10cSrcweir                     (OWeakObject *)this );
513*cdf0e10cSrcweir             }
514*cdf0e10cSrcweir             m_mode = SINGLE_USER;
515*cdf0e10cSrcweir         }
516*cdf0e10cSrcweir         else if (mode.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("single-default-user") ))
517*cdf0e10cSrcweir         {
518*cdf0e10cSrcweir             m_mode = SINGLE_DEFAULT_USER;
519*cdf0e10cSrcweir         }
520*cdf0e10cSrcweir     }
521*cdf0e10cSrcweir 
522*cdf0e10cSrcweir     // switch on caching for DYNAMIC_ONLY and ON (sharable multi-user process)
523*cdf0e10cSrcweir     if (ON == m_mode || DYNAMIC_ONLY == m_mode)
524*cdf0e10cSrcweir     {
525*cdf0e10cSrcweir         sal_Int32 cacheSize = 0; // multi-user cache size
526*cdf0e10cSrcweir         if (! (m_xComponentContext->getValueByName(
527*cdf0e10cSrcweir             OUSTR("/services/" SERVICE_NAME "/user-cache-size") ) >>= cacheSize))
528*cdf0e10cSrcweir         {
529*cdf0e10cSrcweir             cacheSize = 128; // reasonable default?
530*cdf0e10cSrcweir         }
531*cdf0e10cSrcweir #ifdef __CACHE_DIAGNOSE
532*cdf0e10cSrcweir         cacheSize = 2;
533*cdf0e10cSrcweir #endif
534*cdf0e10cSrcweir         m_user2permissions.setSize( cacheSize );
535*cdf0e10cSrcweir     }
536*cdf0e10cSrcweir }
537*cdf0e10cSrcweir //__________________________________________________________________________________________________
538*cdf0e10cSrcweir AccessController::~AccessController()
539*cdf0e10cSrcweir     SAL_THROW( () )
540*cdf0e10cSrcweir {
541*cdf0e10cSrcweir     g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
542*cdf0e10cSrcweir }
543*cdf0e10cSrcweir //__________________________________________________________________________________________________
544*cdf0e10cSrcweir void AccessController::disposing()
545*cdf0e10cSrcweir {
546*cdf0e10cSrcweir     m_mode = OFF; // avoid checks from now on xxx todo review/ better DYNAMIC_ONLY?
547*cdf0e10cSrcweir     m_xPolicy.clear();
548*cdf0e10cSrcweir     m_xComponentContext.clear();
549*cdf0e10cSrcweir }
550*cdf0e10cSrcweir 
551*cdf0e10cSrcweir // XInitialization impl
552*cdf0e10cSrcweir //__________________________________________________________________________________________________
553*cdf0e10cSrcweir void AccessController::initialize(
554*cdf0e10cSrcweir     Sequence< Any > const & arguments )
555*cdf0e10cSrcweir     throw (Exception)
556*cdf0e10cSrcweir {
557*cdf0e10cSrcweir     // xxx todo: review for forking
558*cdf0e10cSrcweir     // portal forking hack: re-initialize for another user-id
559*cdf0e10cSrcweir     if (SINGLE_USER != m_mode) // only if in single-user mode
560*cdf0e10cSrcweir     {
561*cdf0e10cSrcweir         throw RuntimeException(
562*cdf0e10cSrcweir             OUSTR("invalid call: ac must be in \"single-user\" mode!"), (OWeakObject *)this );
563*cdf0e10cSrcweir     }
564*cdf0e10cSrcweir     OUString userId;
565*cdf0e10cSrcweir     arguments[ 0 ] >>= userId;
566*cdf0e10cSrcweir     if (! userId.getLength())
567*cdf0e10cSrcweir     {
568*cdf0e10cSrcweir         throw RuntimeException(
569*cdf0e10cSrcweir             OUSTR("expected a user-id as first argument!"), (OWeakObject *)this );
570*cdf0e10cSrcweir     }
571*cdf0e10cSrcweir     // assured that no sync is necessary: no check happens at this forking time
572*cdf0e10cSrcweir     m_singleUserId = userId;
573*cdf0e10cSrcweir     m_singleUser_init = false;
574*cdf0e10cSrcweir }
575*cdf0e10cSrcweir 
576*cdf0e10cSrcweir //__________________________________________________________________________________________________
577*cdf0e10cSrcweir Reference< security::XPolicy > const & AccessController::getPolicy()
578*cdf0e10cSrcweir     SAL_THROW( (RuntimeException) )
579*cdf0e10cSrcweir {
580*cdf0e10cSrcweir     // get policy singleton
581*cdf0e10cSrcweir     if (! m_xPolicy.is())
582*cdf0e10cSrcweir     {
583*cdf0e10cSrcweir         Reference< security::XPolicy > xPolicy;
584*cdf0e10cSrcweir         m_xComponentContext->getValueByName(
585*cdf0e10cSrcweir             OUSTR("/singletons/com.sun.star.security.thePolicy") ) >>= xPolicy;
586*cdf0e10cSrcweir         if (xPolicy.is())
587*cdf0e10cSrcweir         {
588*cdf0e10cSrcweir             MutexGuard guard( m_mutex );
589*cdf0e10cSrcweir             if (! m_xPolicy.is())
590*cdf0e10cSrcweir             {
591*cdf0e10cSrcweir                 m_xPolicy = xPolicy;
592*cdf0e10cSrcweir             }
593*cdf0e10cSrcweir         }
594*cdf0e10cSrcweir         else
595*cdf0e10cSrcweir         {
596*cdf0e10cSrcweir             throw SecurityException(
597*cdf0e10cSrcweir                 OUSTR("cannot get policy singleton!"), (OWeakObject *)this );
598*cdf0e10cSrcweir         }
599*cdf0e10cSrcweir     }
600*cdf0e10cSrcweir     return m_xPolicy;
601*cdf0e10cSrcweir }
602*cdf0e10cSrcweir 
603*cdf0e10cSrcweir #ifdef __DIAGNOSE
604*cdf0e10cSrcweir static void dumpPermissions(
605*cdf0e10cSrcweir     PermissionCollection const & collection, OUString const & userId = OUString() ) SAL_THROW( () )
606*cdf0e10cSrcweir {
607*cdf0e10cSrcweir     OUStringBuffer buf( 48 );
608*cdf0e10cSrcweir     if (userId.getLength())
609*cdf0e10cSrcweir     {
610*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("> dumping permissions of user \"") );
611*cdf0e10cSrcweir         buf.append( userId );
612*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\":") );
613*cdf0e10cSrcweir     }
614*cdf0e10cSrcweir     else
615*cdf0e10cSrcweir     {
616*cdf0e10cSrcweir         buf.appendAscii(
617*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("> dumping default permissions:") );
618*cdf0e10cSrcweir     }
619*cdf0e10cSrcweir     OString str( ::rtl::OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
620*cdf0e10cSrcweir     OSL_TRACE( str.getStr() );
621*cdf0e10cSrcweir     Sequence< OUString > permissions( collection.toStrings() );
622*cdf0e10cSrcweir     OUString const * p = permissions.getConstArray();
623*cdf0e10cSrcweir     for ( sal_Int32 nPos = 0; nPos < permissions.getLength(); ++nPos )
624*cdf0e10cSrcweir     {
625*cdf0e10cSrcweir         OString str( ::rtl::OUStringToOString( p[ nPos ], RTL_TEXTENCODING_ASCII_US ) );
626*cdf0e10cSrcweir         OSL_TRACE( str.getStr() );
627*cdf0e10cSrcweir     }
628*cdf0e10cSrcweir     OSL_TRACE( "> permission dump done" );
629*cdf0e10cSrcweir }
630*cdf0e10cSrcweir #endif
631*cdf0e10cSrcweir 
632*cdf0e10cSrcweir 
633*cdf0e10cSrcweir //__________________________________________________________________________________________________
634*cdf0e10cSrcweir inline void AccessController::clearPostPoned() SAL_THROW( () )
635*cdf0e10cSrcweir {
636*cdf0e10cSrcweir     delete reinterpret_cast< t_rec_vec * >( m_rec.getData() );
637*cdf0e10cSrcweir     m_rec.setData( 0 );
638*cdf0e10cSrcweir }
639*cdf0e10cSrcweir //__________________________________________________________________________________________________
640*cdf0e10cSrcweir void AccessController::checkAndClearPostPoned() SAL_THROW( (RuntimeException) )
641*cdf0e10cSrcweir {
642*cdf0e10cSrcweir     // check postponed permissions
643*cdf0e10cSrcweir     auto_ptr< t_rec_vec > rec( reinterpret_cast< t_rec_vec * >( m_rec.getData() ) );
644*cdf0e10cSrcweir     m_rec.setData( 0 ); // takeover ownership
645*cdf0e10cSrcweir     OSL_ASSERT( rec.get() );
646*cdf0e10cSrcweir     if (rec.get())
647*cdf0e10cSrcweir     {
648*cdf0e10cSrcweir         t_rec_vec const & vec = *rec.get();
649*cdf0e10cSrcweir         switch (m_mode)
650*cdf0e10cSrcweir         {
651*cdf0e10cSrcweir         case SINGLE_USER:
652*cdf0e10cSrcweir         {
653*cdf0e10cSrcweir             OSL_ASSERT( m_singleUser_init );
654*cdf0e10cSrcweir             for ( size_t nPos = 0; nPos < vec.size(); ++nPos )
655*cdf0e10cSrcweir             {
656*cdf0e10cSrcweir                 pair< OUString, Any > const & p = vec[ nPos ];
657*cdf0e10cSrcweir                 OSL_ASSERT( m_singleUserId.equals( p.first ) );
658*cdf0e10cSrcweir                 m_singleUserPermissions.checkPermission( p.second );
659*cdf0e10cSrcweir             }
660*cdf0e10cSrcweir             break;
661*cdf0e10cSrcweir         }
662*cdf0e10cSrcweir         case SINGLE_DEFAULT_USER:
663*cdf0e10cSrcweir         {
664*cdf0e10cSrcweir             OSL_ASSERT( m_defaultPerm_init );
665*cdf0e10cSrcweir             for ( size_t nPos = 0; nPos < vec.size(); ++nPos )
666*cdf0e10cSrcweir             {
667*cdf0e10cSrcweir                 pair< OUString, Any > const & p = vec[ nPos ];
668*cdf0e10cSrcweir                 OSL_ASSERT( !p.first.getLength() ); // default-user
669*cdf0e10cSrcweir                 m_defaultPermissions.checkPermission( p.second );
670*cdf0e10cSrcweir             }
671*cdf0e10cSrcweir             break;
672*cdf0e10cSrcweir         }
673*cdf0e10cSrcweir         case ON:
674*cdf0e10cSrcweir         {
675*cdf0e10cSrcweir             for ( size_t nPos = 0; nPos < vec.size(); ++nPos )
676*cdf0e10cSrcweir             {
677*cdf0e10cSrcweir                 pair< OUString, Any > const & p = vec[ nPos ];
678*cdf0e10cSrcweir                 PermissionCollection const * pPermissions;
679*cdf0e10cSrcweir                 // lookup policy for user
680*cdf0e10cSrcweir                 {
681*cdf0e10cSrcweir                     MutexGuard guard( m_mutex );
682*cdf0e10cSrcweir                     pPermissions = m_user2permissions.lookup( p.first );
683*cdf0e10cSrcweir                 }
684*cdf0e10cSrcweir                 OSL_ASSERT( pPermissions );
685*cdf0e10cSrcweir                 if (pPermissions)
686*cdf0e10cSrcweir                 {
687*cdf0e10cSrcweir                     pPermissions->checkPermission( p.second );
688*cdf0e10cSrcweir                 }
689*cdf0e10cSrcweir             }
690*cdf0e10cSrcweir             break;
691*cdf0e10cSrcweir         }
692*cdf0e10cSrcweir         default:
693*cdf0e10cSrcweir             OSL_ENSURE( 0, "### this should never be called in this ac mode!" );
694*cdf0e10cSrcweir             break;
695*cdf0e10cSrcweir         }
696*cdf0e10cSrcweir     }
697*cdf0e10cSrcweir }
698*cdf0e10cSrcweir //__________________________________________________________________________________________________
699*cdf0e10cSrcweir /** this is the only function calling the policy singleton and thus has to take care
700*cdf0e10cSrcweir     of recurring calls!
701*cdf0e10cSrcweir 
702*cdf0e10cSrcweir     @param demanded_perm (if not empty) is the demanded permission of a checkPermission() call
703*cdf0e10cSrcweir                          which will be postponed for recurring calls
704*cdf0e10cSrcweir */
705*cdf0e10cSrcweir PermissionCollection AccessController::getEffectivePermissions(
706*cdf0e10cSrcweir     Reference< XCurrentContext > const & xContext,
707*cdf0e10cSrcweir     Any const & demanded_perm )
708*cdf0e10cSrcweir     SAL_THROW( (RuntimeException) )
709*cdf0e10cSrcweir {
710*cdf0e10cSrcweir     OUString userId;
711*cdf0e10cSrcweir 
712*cdf0e10cSrcweir     switch (m_mode)
713*cdf0e10cSrcweir     {
714*cdf0e10cSrcweir     case SINGLE_USER:
715*cdf0e10cSrcweir     {
716*cdf0e10cSrcweir         if (m_singleUser_init)
717*cdf0e10cSrcweir             return m_singleUserPermissions;
718*cdf0e10cSrcweir         userId = m_singleUserId;
719*cdf0e10cSrcweir         break;
720*cdf0e10cSrcweir     }
721*cdf0e10cSrcweir     case SINGLE_DEFAULT_USER:
722*cdf0e10cSrcweir     {
723*cdf0e10cSrcweir         if (m_defaultPerm_init)
724*cdf0e10cSrcweir             return m_defaultPermissions;
725*cdf0e10cSrcweir         break;
726*cdf0e10cSrcweir     }
727*cdf0e10cSrcweir     case ON:
728*cdf0e10cSrcweir     {
729*cdf0e10cSrcweir         if (xContext.is())
730*cdf0e10cSrcweir         {
731*cdf0e10cSrcweir             xContext->getValueByName( OUSTR(USER_CREDS ".id") ) >>= userId;
732*cdf0e10cSrcweir         }
733*cdf0e10cSrcweir         if (! userId.getLength())
734*cdf0e10cSrcweir         {
735*cdf0e10cSrcweir             throw SecurityException(
736*cdf0e10cSrcweir                 OUSTR("cannot determine current user in multi-user ac!"), (OWeakObject *)this );
737*cdf0e10cSrcweir         }
738*cdf0e10cSrcweir 
739*cdf0e10cSrcweir         // lookup policy for user
740*cdf0e10cSrcweir         MutexGuard guard( m_mutex );
741*cdf0e10cSrcweir         PermissionCollection const * pPermissions = m_user2permissions.lookup( userId );
742*cdf0e10cSrcweir         if (pPermissions)
743*cdf0e10cSrcweir             return *pPermissions;
744*cdf0e10cSrcweir         break;
745*cdf0e10cSrcweir     }
746*cdf0e10cSrcweir     default:
747*cdf0e10cSrcweir         OSL_ENSURE( 0, "### this should never be called in this ac mode!" );
748*cdf0e10cSrcweir         return PermissionCollection();
749*cdf0e10cSrcweir     }
750*cdf0e10cSrcweir 
751*cdf0e10cSrcweir     // call on policy
752*cdf0e10cSrcweir     // iff this is a recurring call for the default user, then grant all permissions
753*cdf0e10cSrcweir     t_rec_vec * rec = reinterpret_cast< t_rec_vec * >( m_rec.getData() );
754*cdf0e10cSrcweir     if (rec) // tls entry exists => this is recursive call
755*cdf0e10cSrcweir     {
756*cdf0e10cSrcweir         if (demanded_perm.hasValue())
757*cdf0e10cSrcweir         {
758*cdf0e10cSrcweir             // enqueue
759*cdf0e10cSrcweir             rec->push_back( pair< OUString, Any >( userId, demanded_perm ) );
760*cdf0e10cSrcweir         }
761*cdf0e10cSrcweir #ifdef __DIAGNOSE
762*cdf0e10cSrcweir         OUStringBuffer buf( 48 );
763*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("> info: recurring call of user \"") );
764*cdf0e10cSrcweir         buf.append( userId );
765*cdf0e10cSrcweir         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"") );
766*cdf0e10cSrcweir         OString str(
767*cdf0e10cSrcweir             ::rtl::OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
768*cdf0e10cSrcweir         OSL_TRACE( str.getStr() );
769*cdf0e10cSrcweir #endif
770*cdf0e10cSrcweir         return PermissionCollection( new AllPermission() );
771*cdf0e10cSrcweir     }
772*cdf0e10cSrcweir     else // no tls
773*cdf0e10cSrcweir     {
774*cdf0e10cSrcweir         rec = new t_rec_vec;
775*cdf0e10cSrcweir         m_rec.setData( rec );
776*cdf0e10cSrcweir     }
777*cdf0e10cSrcweir 
778*cdf0e10cSrcweir     try // calls on API
779*cdf0e10cSrcweir     {
780*cdf0e10cSrcweir         // init default permissions
781*cdf0e10cSrcweir         if (! m_defaultPerm_init)
782*cdf0e10cSrcweir         {
783*cdf0e10cSrcweir             PermissionCollection defaultPermissions(
784*cdf0e10cSrcweir                 getPolicy()->getDefaultPermissions() );
785*cdf0e10cSrcweir             // assign
786*cdf0e10cSrcweir             MutexGuard guard( m_mutex );
787*cdf0e10cSrcweir             if (! m_defaultPerm_init)
788*cdf0e10cSrcweir             {
789*cdf0e10cSrcweir                 m_defaultPermissions = defaultPermissions;
790*cdf0e10cSrcweir                 m_defaultPerm_init = true;
791*cdf0e10cSrcweir             }
792*cdf0e10cSrcweir #ifdef __DIAGNOSE
793*cdf0e10cSrcweir             dumpPermissions( m_defaultPermissions );
794*cdf0e10cSrcweir #endif
795*cdf0e10cSrcweir         }
796*cdf0e10cSrcweir 
797*cdf0e10cSrcweir         PermissionCollection ret;
798*cdf0e10cSrcweir 
799*cdf0e10cSrcweir         // init user permissions
800*cdf0e10cSrcweir         switch (m_mode)
801*cdf0e10cSrcweir         {
802*cdf0e10cSrcweir         case SINGLE_USER:
803*cdf0e10cSrcweir         {
804*cdf0e10cSrcweir             ret = PermissionCollection(
805*cdf0e10cSrcweir                 getPolicy()->getPermissions( userId ), m_defaultPermissions );
806*cdf0e10cSrcweir             {
807*cdf0e10cSrcweir             // assign
808*cdf0e10cSrcweir             MutexGuard guard( m_mutex );
809*cdf0e10cSrcweir             if (m_singleUser_init)
810*cdf0e10cSrcweir             {
811*cdf0e10cSrcweir                 ret = m_singleUserPermissions;
812*cdf0e10cSrcweir             }
813*cdf0e10cSrcweir             else
814*cdf0e10cSrcweir             {
815*cdf0e10cSrcweir                 m_singleUserPermissions = ret;
816*cdf0e10cSrcweir                 m_singleUser_init = true;
817*cdf0e10cSrcweir             }
818*cdf0e10cSrcweir             }
819*cdf0e10cSrcweir #ifdef __DIAGNOSE
820*cdf0e10cSrcweir             dumpPermissions( ret, userId );
821*cdf0e10cSrcweir #endif
822*cdf0e10cSrcweir             break;
823*cdf0e10cSrcweir         }
824*cdf0e10cSrcweir         case SINGLE_DEFAULT_USER:
825*cdf0e10cSrcweir         {
826*cdf0e10cSrcweir             ret = m_defaultPermissions;
827*cdf0e10cSrcweir             break;
828*cdf0e10cSrcweir         }
829*cdf0e10cSrcweir         case ON:
830*cdf0e10cSrcweir         {
831*cdf0e10cSrcweir             ret = PermissionCollection(
832*cdf0e10cSrcweir                 getPolicy()->getPermissions( userId ), m_defaultPermissions );
833*cdf0e10cSrcweir             {
834*cdf0e10cSrcweir             // cache
835*cdf0e10cSrcweir             MutexGuard guard( m_mutex );
836*cdf0e10cSrcweir             m_user2permissions.set( userId, ret );
837*cdf0e10cSrcweir             }
838*cdf0e10cSrcweir #ifdef __DIAGNOSE
839*cdf0e10cSrcweir             dumpPermissions( ret, userId );
840*cdf0e10cSrcweir #endif
841*cdf0e10cSrcweir             break;
842*cdf0e10cSrcweir         }
843*cdf0e10cSrcweir         default:
844*cdf0e10cSrcweir             break;
845*cdf0e10cSrcweir         }
846*cdf0e10cSrcweir 
847*cdf0e10cSrcweir         // check postponed
848*cdf0e10cSrcweir         checkAndClearPostPoned();
849*cdf0e10cSrcweir         return ret;
850*cdf0e10cSrcweir     }
851*cdf0e10cSrcweir     catch (security::AccessControlException & exc) // wrapped into DeploymentException
852*cdf0e10cSrcweir     {
853*cdf0e10cSrcweir         clearPostPoned(); // safety: exception could have happened before checking postponed?
854*cdf0e10cSrcweir         OUStringBuffer buf( 64 );
855*cdf0e10cSrcweir         buf.appendAscii(
856*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("deployment error (AccessControlException occured): ") );
857*cdf0e10cSrcweir         buf.append( exc.Message );
858*cdf0e10cSrcweir         throw DeploymentException( buf.makeStringAndClear(), exc.Context );
859*cdf0e10cSrcweir     }
860*cdf0e10cSrcweir     catch (RuntimeException &)
861*cdf0e10cSrcweir     {
862*cdf0e10cSrcweir         // dont check postponed, just cleanup
863*cdf0e10cSrcweir         clearPostPoned();
864*cdf0e10cSrcweir         delete reinterpret_cast< t_rec_vec * >( m_rec.getData() );
865*cdf0e10cSrcweir         m_rec.setData( 0 );
866*cdf0e10cSrcweir         throw;
867*cdf0e10cSrcweir     }
868*cdf0e10cSrcweir     catch (Exception &)
869*cdf0e10cSrcweir     {
870*cdf0e10cSrcweir         // check postponed permissions first
871*cdf0e10cSrcweir         // => AccessControlExceptions are errors, user exceptions not!
872*cdf0e10cSrcweir         checkAndClearPostPoned();
873*cdf0e10cSrcweir         throw;
874*cdf0e10cSrcweir     }
875*cdf0e10cSrcweir     catch (...)
876*cdf0e10cSrcweir     {
877*cdf0e10cSrcweir         // dont check postponed, just cleanup
878*cdf0e10cSrcweir         clearPostPoned();
879*cdf0e10cSrcweir         throw;
880*cdf0e10cSrcweir     }
881*cdf0e10cSrcweir }
882*cdf0e10cSrcweir 
883*cdf0e10cSrcweir // XAccessController impl
884*cdf0e10cSrcweir //__________________________________________________________________________________________________
885*cdf0e10cSrcweir void AccessController::checkPermission(
886*cdf0e10cSrcweir     Any const & perm )
887*cdf0e10cSrcweir     throw (RuntimeException)
888*cdf0e10cSrcweir {
889*cdf0e10cSrcweir     if (rBHelper.bDisposed)
890*cdf0e10cSrcweir     {
891*cdf0e10cSrcweir         throw lang::DisposedException(
892*cdf0e10cSrcweir             OUSTR("checkPermission() call on disposed AccessController!"), (OWeakObject *)this );
893*cdf0e10cSrcweir     }
894*cdf0e10cSrcweir 
895*cdf0e10cSrcweir     if (OFF == m_mode)
896*cdf0e10cSrcweir         return;
897*cdf0e10cSrcweir 
898*cdf0e10cSrcweir     // first dynamic check of ac contexts
899*cdf0e10cSrcweir     Reference< XCurrentContext > xContext;
900*cdf0e10cSrcweir     ::uno_getCurrentContext( (void **)&xContext, s_envType.pData, 0 );
901*cdf0e10cSrcweir     Reference< security::XAccessControlContext > xACC( getDynamicRestriction( xContext ) );
902*cdf0e10cSrcweir     if (xACC.is())
903*cdf0e10cSrcweir     {
904*cdf0e10cSrcweir         xACC->checkPermission( perm );
905*cdf0e10cSrcweir     }
906*cdf0e10cSrcweir 
907*cdf0e10cSrcweir     if (DYNAMIC_ONLY == m_mode)
908*cdf0e10cSrcweir         return;
909*cdf0e10cSrcweir 
910*cdf0e10cSrcweir     // then static check
911*cdf0e10cSrcweir     getEffectivePermissions( xContext, perm ).checkPermission( perm );
912*cdf0e10cSrcweir }
913*cdf0e10cSrcweir //__________________________________________________________________________________________________
914*cdf0e10cSrcweir Any AccessController::doRestricted(
915*cdf0e10cSrcweir     Reference< security::XAction > const & xAction,
916*cdf0e10cSrcweir     Reference< security::XAccessControlContext > const & xRestriction )
917*cdf0e10cSrcweir     throw (Exception)
918*cdf0e10cSrcweir {
919*cdf0e10cSrcweir     if (rBHelper.bDisposed)
920*cdf0e10cSrcweir     {
921*cdf0e10cSrcweir         throw lang::DisposedException(
922*cdf0e10cSrcweir             OUSTR("doRestricted() call on disposed AccessController!"), (OWeakObject *)this );
923*cdf0e10cSrcweir     }
924*cdf0e10cSrcweir 
925*cdf0e10cSrcweir     if (OFF == m_mode) // optimize this way, because no dynamic check will be performed
926*cdf0e10cSrcweir         return xAction->run();
927*cdf0e10cSrcweir 
928*cdf0e10cSrcweir     if (xRestriction.is())
929*cdf0e10cSrcweir     {
930*cdf0e10cSrcweir         Reference< XCurrentContext > xContext;
931*cdf0e10cSrcweir         ::uno_getCurrentContext( (void **)&xContext, s_envType.pData, 0 );
932*cdf0e10cSrcweir 
933*cdf0e10cSrcweir         // override restriction
934*cdf0e10cSrcweir         Reference< XCurrentContext > xNewContext(
935*cdf0e10cSrcweir             new acc_CurrentContext( xContext, acc_Intersection::create(
936*cdf0e10cSrcweir                                         xRestriction, getDynamicRestriction( xContext ) ) ) );
937*cdf0e10cSrcweir         ::uno_setCurrentContext( xNewContext.get(), s_envType.pData, 0 );
938*cdf0e10cSrcweir         cc_reset reset( xContext.get() );
939*cdf0e10cSrcweir         return xAction->run();
940*cdf0e10cSrcweir     }
941*cdf0e10cSrcweir     else
942*cdf0e10cSrcweir     {
943*cdf0e10cSrcweir         return xAction->run();
944*cdf0e10cSrcweir     }
945*cdf0e10cSrcweir }
946*cdf0e10cSrcweir //__________________________________________________________________________________________________
947*cdf0e10cSrcweir Any AccessController::doPrivileged(
948*cdf0e10cSrcweir     Reference< security::XAction > const & xAction,
949*cdf0e10cSrcweir     Reference< security::XAccessControlContext > const & xRestriction )
950*cdf0e10cSrcweir     throw (Exception)
951*cdf0e10cSrcweir {
952*cdf0e10cSrcweir     if (rBHelper.bDisposed)
953*cdf0e10cSrcweir     {
954*cdf0e10cSrcweir         throw lang::DisposedException(
955*cdf0e10cSrcweir             OUSTR("doPrivileged() call on disposed AccessController!"), (OWeakObject *)this );
956*cdf0e10cSrcweir     }
957*cdf0e10cSrcweir 
958*cdf0e10cSrcweir     if (OFF == m_mode) // no dynamic check will be performed
959*cdf0e10cSrcweir     {
960*cdf0e10cSrcweir         return xAction->run();
961*cdf0e10cSrcweir     }
962*cdf0e10cSrcweir 
963*cdf0e10cSrcweir     Reference< XCurrentContext > xContext;
964*cdf0e10cSrcweir     ::uno_getCurrentContext( (void **)&xContext, s_envType.pData, 0 );
965*cdf0e10cSrcweir 
966*cdf0e10cSrcweir     Reference< security::XAccessControlContext > xOldRestr(
967*cdf0e10cSrcweir         getDynamicRestriction( xContext ) );
968*cdf0e10cSrcweir 
969*cdf0e10cSrcweir     if (xOldRestr.is()) // previous restriction
970*cdf0e10cSrcweir     {
971*cdf0e10cSrcweir         // override restriction
972*cdf0e10cSrcweir         Reference< XCurrentContext > xNewContext(
973*cdf0e10cSrcweir             new acc_CurrentContext( xContext, acc_Union::create( xRestriction, xOldRestr ) ) );
974*cdf0e10cSrcweir         ::uno_setCurrentContext( xNewContext.get(), s_envType.pData, 0 );
975*cdf0e10cSrcweir         cc_reset reset( xContext.get() );
976*cdf0e10cSrcweir         return xAction->run();
977*cdf0e10cSrcweir     }
978*cdf0e10cSrcweir     else // no previous restriction => never current restriction
979*cdf0e10cSrcweir     {
980*cdf0e10cSrcweir         return xAction->run();
981*cdf0e10cSrcweir     }
982*cdf0e10cSrcweir }
983*cdf0e10cSrcweir //__________________________________________________________________________________________________
984*cdf0e10cSrcweir Reference< security::XAccessControlContext > AccessController::getContext()
985*cdf0e10cSrcweir     throw (RuntimeException)
986*cdf0e10cSrcweir {
987*cdf0e10cSrcweir     if (rBHelper.bDisposed)
988*cdf0e10cSrcweir     {
989*cdf0e10cSrcweir         throw lang::DisposedException(
990*cdf0e10cSrcweir             OUSTR("getContext() call on disposed AccessController!"), (OWeakObject *)this );
991*cdf0e10cSrcweir     }
992*cdf0e10cSrcweir 
993*cdf0e10cSrcweir     if (OFF == m_mode) // optimize this way, because no dynamic check will be performed
994*cdf0e10cSrcweir     {
995*cdf0e10cSrcweir         return new acc_Policy( PermissionCollection( new AllPermission() ) );
996*cdf0e10cSrcweir     }
997*cdf0e10cSrcweir 
998*cdf0e10cSrcweir     Reference< XCurrentContext > xContext;
999*cdf0e10cSrcweir     ::uno_getCurrentContext( (void **)&xContext, s_envType.pData, 0 );
1000*cdf0e10cSrcweir 
1001*cdf0e10cSrcweir     return acc_Intersection::create(
1002*cdf0e10cSrcweir         getDynamicRestriction( xContext ),
1003*cdf0e10cSrcweir         new acc_Policy( getEffectivePermissions( xContext, Any() ) ) );
1004*cdf0e10cSrcweir }
1005*cdf0e10cSrcweir 
1006*cdf0e10cSrcweir // XServiceInfo impl
1007*cdf0e10cSrcweir //__________________________________________________________________________________________________
1008*cdf0e10cSrcweir OUString AccessController::getImplementationName()
1009*cdf0e10cSrcweir     throw (RuntimeException)
1010*cdf0e10cSrcweir {
1011*cdf0e10cSrcweir     return s_implName;
1012*cdf0e10cSrcweir }
1013*cdf0e10cSrcweir //__________________________________________________________________________________________________
1014*cdf0e10cSrcweir sal_Bool AccessController::supportsService( OUString const & serviceName )
1015*cdf0e10cSrcweir     throw (RuntimeException)
1016*cdf0e10cSrcweir {
1017*cdf0e10cSrcweir     OUString const * pNames = s_serviceNames.getConstArray();
1018*cdf0e10cSrcweir     for ( sal_Int32 nPos = s_serviceNames.getLength(); nPos--; )
1019*cdf0e10cSrcweir     {
1020*cdf0e10cSrcweir         if (serviceName.equals( pNames[ nPos ] ))
1021*cdf0e10cSrcweir         {
1022*cdf0e10cSrcweir             return sal_True;
1023*cdf0e10cSrcweir         }
1024*cdf0e10cSrcweir     }
1025*cdf0e10cSrcweir     return sal_False;
1026*cdf0e10cSrcweir }
1027*cdf0e10cSrcweir //__________________________________________________________________________________________________
1028*cdf0e10cSrcweir Sequence< OUString > AccessController::getSupportedServiceNames()
1029*cdf0e10cSrcweir     throw (RuntimeException)
1030*cdf0e10cSrcweir {
1031*cdf0e10cSrcweir     return s_serviceNames;
1032*cdf0e10cSrcweir }
1033*cdf0e10cSrcweir }
1034*cdf0e10cSrcweir //##################################################################################################
1035*cdf0e10cSrcweir namespace stoc_bootstrap {
1036*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
1037*cdf0e10cSrcweir Reference< XInterface > SAL_CALL ac_create(
1038*cdf0e10cSrcweir     Reference< XComponentContext > const & xComponentContext )
1039*cdf0e10cSrcweir     SAL_THROW( (Exception) )
1040*cdf0e10cSrcweir {
1041*cdf0e10cSrcweir     return (OWeakObject *)new stoc_sec::AccessController( xComponentContext );
1042*cdf0e10cSrcweir }
1043*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
1044*cdf0e10cSrcweir Sequence< OUString > ac_getSupportedServiceNames() SAL_THROW( () )
1045*cdf0e10cSrcweir {
1046*cdf0e10cSrcweir     return stoc_sec::s_serviceNames;
1047*cdf0e10cSrcweir }
1048*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
1049*cdf0e10cSrcweir OUString ac_getImplementationName() SAL_THROW( () )
1050*cdf0e10cSrcweir {
1051*cdf0e10cSrcweir     return stoc_sec::s_implName;
1052*cdf0e10cSrcweir }
1053*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
1054*cdf0e10cSrcweir Reference< XInterface > SAL_CALL filepolicy_create(
1055*cdf0e10cSrcweir     Reference< XComponentContext > const & xComponentContext )
1056*cdf0e10cSrcweir     SAL_THROW( (Exception) );
1057*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
1058*cdf0e10cSrcweir Sequence< OUString > filepolicy_getSupportedServiceNames() SAL_THROW( () );
1059*cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
1060*cdf0e10cSrcweir OUString filepolicy_getImplementationName() SAL_THROW( () );
1061*cdf0e10cSrcweir }
1062