1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_stoc.hxx" 30 31 #include <vector> 32 33 #include <osl/process.h> 34 #include <osl/socket.hxx> 35 #include <osl/mutex.hxx> 36 37 #include <rtl/string.hxx> 38 #include <rtl/ustrbuf.hxx> 39 40 #include <com/sun/star/security/RuntimePermission.hpp> 41 #include <com/sun/star/security/AllPermission.hpp> 42 #include <com/sun/star/io/FilePermission.hpp> 43 #include <com/sun/star/connection/SocketPermission.hpp> 44 #include <com/sun/star/security/AccessControlException.hpp> 45 46 #include "permissions.h" 47 48 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) 49 50 51 using namespace ::std; 52 using namespace ::osl; 53 using namespace ::com::sun::star; 54 using namespace ::com::sun::star::uno; 55 using ::rtl::OUString; 56 using ::rtl::OUStringBuffer; 57 58 namespace stoc_sec 59 { 60 61 //-------------------------------------------------------------------------------------------------- 62 static inline sal_Int32 makeMask( 63 OUString const & items, char const * const * strings ) SAL_THROW( () ) 64 { 65 sal_Int32 mask = 0; 66 67 sal_Int32 n = 0; 68 do 69 { 70 OUString item( items.getToken( 0, ',', n ).trim() ); 71 if (! item.getLength()) 72 continue; 73 sal_Int32 nPos = 0; 74 while (strings[ nPos ]) 75 { 76 if (item.equalsAscii( strings[ nPos ] )) 77 { 78 mask |= (0x80000000 >> nPos); 79 break; 80 } 81 ++nPos; 82 } 83 #if OSL_DEBUG_LEVEL > 0 84 if (! strings[ nPos ]) 85 { 86 OUStringBuffer buf( 48 ); 87 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("### ignoring unknown socket action: ") ); 88 buf.append( item ); 89 ::rtl::OString str( ::rtl::OUStringToOString( 90 buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) ); 91 OSL_TRACE( str.getStr() ); 92 } 93 #endif 94 } 95 while (n >= 0); // all items 96 return mask; 97 } 98 //-------------------------------------------------------------------------------------------------- 99 static inline OUString makeStrings( 100 sal_Int32 mask, char const * const * strings ) SAL_THROW( () ) 101 { 102 OUStringBuffer buf( 48 ); 103 while (mask) 104 { 105 if (0x80000000 & mask) 106 { 107 buf.appendAscii( *strings ); 108 if (mask << 1) // more items following 109 buf.append( (sal_Unicode)',' ); 110 } 111 mask = (mask << 1); 112 ++strings; 113 } 114 return buf.makeStringAndClear(); 115 } 116 117 //################################################################################################## 118 119 //================================================================================================== 120 class SocketPermission : public Permission 121 { 122 static char const * s_actions []; 123 sal_Int32 m_actions; 124 125 OUString m_host; 126 sal_Int32 m_lowerPort; 127 sal_Int32 m_upperPort; 128 mutable OUString m_ip; 129 mutable bool m_resolveErr; 130 mutable bool m_resolvedHost; 131 bool m_wildCardHost; 132 133 inline bool resolveHost() const SAL_THROW( () ); 134 135 public: 136 SocketPermission( 137 connection::SocketPermission const & perm, 138 ::rtl::Reference< Permission > const & next = ::rtl::Reference< Permission >() ) 139 SAL_THROW( () ); 140 virtual bool implies( Permission const & perm ) const SAL_THROW( () ); 141 virtual OUString toString() const SAL_THROW( () ); 142 }; 143 //__________________________________________________________________________________________________ 144 char const * SocketPermission::s_actions [] = { "accept", "connect", "listen", "resolve", 0 }; 145 //__________________________________________________________________________________________________ 146 SocketPermission::SocketPermission( 147 connection::SocketPermission const & perm, 148 ::rtl::Reference< Permission > const & next ) 149 SAL_THROW( () ) 150 : Permission( SOCKET, next ) 151 , m_actions( makeMask( perm.Actions, s_actions ) ) 152 , m_host( perm.Host ) 153 , m_lowerPort( 0 ) 154 , m_upperPort( 65535 ) 155 , m_resolveErr( false ) 156 , m_resolvedHost( false ) 157 , m_wildCardHost( perm.Host.getLength() && '*' == perm.Host.pData->buffer[ 0 ] ) 158 { 159 if (0xe0000000 & m_actions) // if any (except resolve) is given => resolve implied 160 m_actions |= 0x10000000; 161 162 // separate host from portrange 163 sal_Int32 colon = m_host.indexOf( ':' ); 164 if (colon >= 0) // port [range] given 165 { 166 sal_Int32 minus = m_host.indexOf( '-', colon +1 ); 167 if (minus < 0) 168 { 169 m_lowerPort = m_upperPort = m_host.copy( colon +1 ).toInt32(); 170 } 171 else if (minus == (colon +1)) // -N 172 { 173 m_upperPort = m_host.copy( minus +1 ).toInt32(); 174 } 175 else if (minus == (m_host.getLength() -1)) // N- 176 { 177 m_lowerPort = m_host.copy( colon +1, m_host.getLength() -1 -colon -1 ).toInt32(); 178 } 179 else // A-B 180 { 181 m_lowerPort = m_host.copy( colon +1, minus - colon -1 ).toInt32(); 182 m_upperPort = m_host.copy( minus +1, m_host.getLength() -minus -1 ).toInt32(); 183 } 184 m_host = m_host.copy( 0, colon ); 185 } 186 } 187 //__________________________________________________________________________________________________ 188 inline bool SocketPermission::resolveHost() const SAL_THROW( () ) 189 { 190 if (m_resolveErr) 191 return false; 192 193 if (! m_resolvedHost) 194 { 195 // dns lookup 196 SocketAddr addr; 197 SocketAddr::resolveHostname( m_host, addr ); 198 OUString ip; 199 m_resolveErr = (::osl_Socket_Ok != ::osl_getDottedInetAddrOfSocketAddr( 200 addr.getHandle(), &ip.pData )); 201 if (m_resolveErr) 202 return false; 203 204 MutexGuard guard( Mutex::getGlobalMutex() ); 205 if (! m_resolvedHost) 206 { 207 m_ip = ip; 208 m_resolvedHost = true; 209 } 210 } 211 return m_resolvedHost; 212 } 213 //__________________________________________________________________________________________________ 214 bool SocketPermission::implies( Permission const & perm ) const SAL_THROW( () ) 215 { 216 // check type 217 if (SOCKET != perm.m_type) 218 return false; 219 SocketPermission const & demanded = static_cast< SocketPermission const & >( perm ); 220 221 // check actions 222 if ((m_actions & demanded.m_actions) != demanded.m_actions) 223 return false; 224 225 // check ports 226 if (demanded.m_lowerPort < m_lowerPort) 227 return false; 228 if (demanded.m_upperPort > m_upperPort) 229 return false; 230 231 // quick check host (DNS names: RFC 1034/1035) 232 if (m_host.equalsIgnoreAsciiCase( demanded.m_host )) 233 return true; 234 // check for host wildcards 235 if (m_wildCardHost) 236 { 237 OUString const & demanded_host = demanded.m_host; 238 if (demanded_host.getLength() <= m_host.getLength()) 239 return false; 240 sal_Int32 len = m_host.getLength() -1; // skip star 241 return (0 == ::rtl_ustr_compareIgnoreAsciiCase_WithLength( 242 demanded_host.getStr() + demanded_host.getLength() - len, len, 243 m_host.pData->buffer + 1, len )); 244 } 245 if (demanded.m_wildCardHost) 246 return false; 247 248 // compare IP addresses 249 if (! resolveHost()) 250 return false; 251 if (! demanded.resolveHost()) 252 return false; 253 return (sal_False != m_ip.equals( demanded.m_ip )); 254 } 255 //__________________________________________________________________________________________________ 256 OUString SocketPermission::toString() const SAL_THROW( () ) 257 { 258 OUStringBuffer buf( 48 ); 259 // host 260 buf.appendAscii( 261 RTL_CONSTASCII_STRINGPARAM("com.sun.star.connection.SocketPermission (host=\"") ); 262 buf.append( m_host ); 263 if (m_resolvedHost) 264 { 265 buf.append( (sal_Unicode)'[' ); 266 buf.append( m_ip ); 267 buf.append( (sal_Unicode)']' ); 268 } 269 // port 270 if (0 != m_lowerPort || 65535 != m_upperPort) 271 { 272 buf.append( (sal_Unicode)':' ); 273 if (m_lowerPort > 0) 274 buf.append( m_lowerPort ); 275 if (m_upperPort > m_lowerPort) 276 { 277 buf.append( (sal_Unicode)'-' ); 278 if (m_upperPort < 65535) 279 buf.append( m_upperPort ); 280 } 281 } 282 // actions 283 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\", actions=\"") ); 284 buf.append( makeStrings( m_actions, s_actions ) ); 285 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\")") ); 286 return buf.makeStringAndClear(); 287 } 288 289 //################################################################################################## 290 291 //================================================================================================== 292 class FilePermission : public Permission 293 { 294 static char const * s_actions []; 295 sal_Int32 m_actions; 296 297 OUString m_url; 298 bool m_allFiles; 299 300 public: 301 FilePermission( 302 io::FilePermission const & perm, 303 ::rtl::Reference< Permission > const & next = ::rtl::Reference< Permission >() ) 304 SAL_THROW( () ); 305 virtual bool implies( Permission const & perm ) const SAL_THROW( () ); 306 virtual OUString toString() const SAL_THROW( () ); 307 }; 308 //__________________________________________________________________________________________________ 309 char const * FilePermission::s_actions [] = { "read", "write", "execute", "delete", 0 }; 310 //-------------------------------------------------------------------------------------------------- 311 static OUString const & getWorkingDir() SAL_THROW( () ) 312 { 313 static OUString * s_workingDir = 0; 314 if (! s_workingDir) 315 { 316 OUString workingDir; 317 ::osl_getProcessWorkingDir( &workingDir.pData ); 318 319 MutexGuard guard( Mutex::getGlobalMutex() ); 320 if (! s_workingDir) 321 { 322 static OUString s_dir( workingDir ); 323 s_workingDir = &s_dir; 324 } 325 } 326 return *s_workingDir; 327 } 328 //__________________________________________________________________________________________________ 329 FilePermission::FilePermission( 330 io::FilePermission const & perm, 331 ::rtl::Reference< Permission > const & next ) 332 SAL_THROW( () ) 333 : Permission( FILE, next ) 334 , m_actions( makeMask( perm.Actions, s_actions ) ) 335 , m_url( perm.URL ) 336 , m_allFiles( sal_False != perm.URL.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("<<ALL FILES>>")) ) 337 { 338 if (! m_allFiles) 339 { 340 if (m_url.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("*") )) 341 { 342 OUStringBuffer buf( 64 ); 343 buf.append( getWorkingDir() ); 344 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/*") ); 345 m_url = buf.makeStringAndClear(); 346 } 347 else if (m_url.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("-") )) 348 { 349 OUStringBuffer buf( 64 ); 350 buf.append( getWorkingDir() ); 351 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/-") ); 352 m_url = buf.makeStringAndClear(); 353 } 354 else if (0 != m_url.compareToAscii( RTL_CONSTASCII_STRINGPARAM("file:///") )) 355 { 356 // relative path 357 OUString out; 358 oslFileError rc = ::osl_getAbsoluteFileURL( 359 getWorkingDir().pData, perm.URL.pData, &out.pData ); 360 m_url = (osl_File_E_None == rc ? out : perm.URL); // fallback 361 } 362 #ifdef SAL_W32 363 // correct win drive letters 364 if (9 < m_url.getLength() && '|' == m_url[ 9 ]) // file:///X| 365 { 366 static OUString s_colon = OUSTR(":"); 367 // common case in API is a ':' (sal), so convert '|' to ':' 368 m_url = m_url.replaceAt( 9, 1, s_colon ); 369 } 370 #endif 371 } 372 } 373 //__________________________________________________________________________________________________ 374 bool FilePermission::implies( Permission const & perm ) const SAL_THROW( () ) 375 { 376 // check type 377 if (FILE != perm.m_type) 378 return false; 379 FilePermission const & demanded = static_cast< FilePermission const & >( perm ); 380 381 // check actions 382 if ((m_actions & demanded.m_actions) != demanded.m_actions) 383 return false; 384 385 // check url 386 if (m_allFiles) 387 return true; 388 if (demanded.m_allFiles) 389 return false; 390 391 #ifdef SAL_W32 392 if (m_url.equalsIgnoreAsciiCase( demanded.m_url )) 393 return true; 394 #else 395 if (m_url.equals( demanded.m_url )) 396 return true; 397 #endif 398 if (m_url.getLength() > demanded.m_url.getLength()) 399 return false; 400 // check /- wildcard: all files and recursive in that path 401 if (1 < m_url.getLength() && 402 0 == ::rtl_ustr_ascii_compare_WithLength( m_url.getStr() + m_url.getLength() - 2, 2, "/-" )) 403 { 404 // demanded url must start with granted path (including path trailing path sep) 405 sal_Int32 len = m_url.getLength() -1; 406 #ifdef SAL_W32 407 return (0 == ::rtl_ustr_compareIgnoreAsciiCase_WithLength( 408 demanded.m_url.pData->buffer, len, m_url.pData->buffer, len )); 409 #else 410 return (0 == ::rtl_ustr_reverseCompare_WithLength( 411 demanded.m_url.pData->buffer, len, m_url.pData->buffer, len )); 412 #endif 413 } 414 // check /* wildcard: all files in that path (not recursive!) 415 if (1 < m_url.getLength() && 416 0 == ::rtl_ustr_ascii_compare_WithLength( m_url.getStr() + m_url.getLength() - 2, 2, "/*" )) 417 { 418 // demanded url must start with granted path (including path trailing path sep) 419 sal_Int32 len = m_url.getLength() -1; 420 #ifdef SAL_W32 421 return ((0 == ::rtl_ustr_compareIgnoreAsciiCase_WithLength( 422 demanded.m_url.pData->buffer, len, m_url.pData->buffer, len )) && 423 (0 > demanded.m_url.indexOf( '/', len ))); // in addition, no deeper pathes 424 #else 425 return ((0 == ::rtl_ustr_reverseCompare_WithLength( 426 demanded.m_url.pData->buffer, len, m_url.pData->buffer, len )) && 427 (0 > demanded.m_url.indexOf( '/', len ))); // in addition, no deeper pathes 428 #endif 429 } 430 return false; 431 } 432 //__________________________________________________________________________________________________ 433 OUString FilePermission::toString() const SAL_THROW( () ) 434 { 435 OUStringBuffer buf( 48 ); 436 // url 437 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("com.sun.star.io.FilePermission (url=\"") ); 438 buf.append( m_url ); 439 // actions 440 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\", actions=\"") ); 441 buf.append( makeStrings( m_actions, s_actions ) ); 442 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\")") ); 443 return buf.makeStringAndClear(); 444 } 445 446 //################################################################################################## 447 448 //================================================================================================== 449 class RuntimePermission : public Permission 450 { 451 OUString m_name; 452 453 public: 454 inline RuntimePermission( 455 security::RuntimePermission const & perm, 456 ::rtl::Reference< Permission > const & next = ::rtl::Reference< Permission >() ) 457 SAL_THROW( () ) 458 : Permission( RUNTIME, next ) 459 , m_name( perm.Name ) 460 {} 461 virtual bool implies( Permission const & perm ) const SAL_THROW( () ); 462 virtual OUString toString() const SAL_THROW( () ); 463 }; 464 //__________________________________________________________________________________________________ 465 bool RuntimePermission::implies( Permission const & perm ) const SAL_THROW( () ) 466 { 467 // check type 468 if (RUNTIME != perm.m_type) 469 return false; 470 RuntimePermission const & demanded = static_cast< RuntimePermission const & >( perm ); 471 472 // check name 473 return (sal_False != m_name.equals( demanded.m_name )); 474 } 475 //__________________________________________________________________________________________________ 476 OUString RuntimePermission::toString() const SAL_THROW( () ) 477 { 478 OUStringBuffer buf( 48 ); 479 buf.appendAscii( 480 RTL_CONSTASCII_STRINGPARAM("com.sun.star.security.RuntimePermission (name=\"") ); 481 buf.append( m_name ); 482 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\")") ); 483 return buf.makeStringAndClear(); 484 } 485 486 //################################################################################################## 487 488 //__________________________________________________________________________________________________ 489 bool AllPermission::implies( Permission const & ) const SAL_THROW( () ) 490 { 491 return true; 492 } 493 //__________________________________________________________________________________________________ 494 OUString AllPermission::toString() const SAL_THROW( () ) 495 { 496 return OUSTR("com.sun.star.security.AllPermission"); 497 } 498 499 //################################################################################################## 500 501 //__________________________________________________________________________________________________ 502 PermissionCollection::PermissionCollection( 503 Sequence< Any > const & permissions, PermissionCollection const & addition ) 504 SAL_THROW( (RuntimeException) ) 505 : m_head( addition.m_head ) 506 { 507 Any const * perms = permissions.getConstArray(); 508 for ( sal_Int32 nPos = permissions.getLength(); nPos--; ) 509 { 510 Any const & perm = perms[ nPos ]; 511 Type const & perm_type = perm.getValueType(); 512 513 // supported permission types 514 if (perm_type.equals( ::getCppuType( (io::FilePermission const *)0 ) )) 515 { 516 m_head = new FilePermission( 517 *reinterpret_cast< io::FilePermission const * >( perm.pData ), m_head ); 518 } 519 else if (perm_type.equals( ::getCppuType( (connection::SocketPermission const *)0 ) )) 520 { 521 m_head = new SocketPermission( 522 *reinterpret_cast< connection::SocketPermission const * >( perm.pData ), m_head ); 523 } 524 else if (perm_type.equals( ::getCppuType( (security::RuntimePermission const *)0 ) )) 525 { 526 m_head = new RuntimePermission( 527 *reinterpret_cast< security::RuntimePermission const * >( perm.pData ), m_head ); 528 } 529 else if (perm_type.equals( ::getCppuType( (security::AllPermission const *)0 ) )) 530 { 531 m_head = new AllPermission( m_head ); 532 } 533 else 534 { 535 OUStringBuffer buf( 48 ); 536 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( 537 "checking for unsupported permission type: ") ); 538 buf.append( perm_type.getTypeName() ); 539 throw RuntimeException( 540 buf.makeStringAndClear(), Reference< XInterface >() ); 541 } 542 } 543 } 544 #ifdef __DIAGNOSE 545 //__________________________________________________________________________________________________ 546 Sequence< OUString > PermissionCollection::toStrings() const SAL_THROW( () ) 547 { 548 vector< OUString > strings; 549 strings.reserve( 8 ); 550 for ( Permission * perm = m_head.get(); perm; perm = perm->m_next.get() ) 551 { 552 strings.push_back( perm->toString() ); 553 } 554 return Sequence< OUString >( 555 strings.empty() ? 0 : &strings[ 0 ], strings.size() ); 556 } 557 #endif 558 //__________________________________________________________________________________________________ 559 inline static bool __implies( 560 ::rtl::Reference< Permission > const & head, Permission const & demanded ) SAL_THROW( () ) 561 { 562 for ( Permission * perm = head.get(); perm; perm = perm->m_next.get() ) 563 { 564 if (perm->implies( demanded )) 565 return true; 566 } 567 return false; 568 } 569 570 #ifdef __DIAGNOSE 571 //-------------------------------------------------------------------------------------------------- 572 static void demanded_diag( 573 Permission const & perm ) 574 SAL_THROW( () ) 575 { 576 OUStringBuffer buf( 48 ); 577 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("demanding ") ); 578 buf.append( perm.toString() ); 579 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" => ok.") ); 580 ::rtl::OString str( 581 ::rtl::OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) ); 582 OSL_TRACE( str.getStr() ); 583 } 584 #endif 585 //-------------------------------------------------------------------------------------------------- 586 static void throwAccessControlException( 587 Permission const & perm, Any const & demanded_perm ) 588 SAL_THROW( (security::AccessControlException) ) 589 { 590 OUStringBuffer buf( 48 ); 591 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("access denied: ") ); 592 buf.append( perm.toString() ); 593 throw security::AccessControlException( 594 buf.makeStringAndClear(), Reference< XInterface >(), demanded_perm ); 595 } 596 //================================================================================================== 597 void PermissionCollection::checkPermission( Any const & perm ) const 598 SAL_THROW( (RuntimeException) ) 599 { 600 Type const & demanded_type = perm.getValueType(); 601 602 // supported permission types 603 // stack object of SimpleReferenceObject are ok, as long as they are not 604 // assigned to a ::rtl::Reference<> (=> delete this) 605 if (demanded_type.equals( ::getCppuType( (io::FilePermission const *)0 ) )) 606 { 607 FilePermission demanded( 608 *reinterpret_cast< io::FilePermission const * >( perm.pData ) ); 609 if (__implies( m_head, demanded )) 610 { 611 #ifdef __DIAGNOSE 612 demanded_diag( demanded ); 613 #endif 614 return; 615 } 616 throwAccessControlException( demanded, perm ); 617 } 618 else if (demanded_type.equals( ::getCppuType( (connection::SocketPermission const *)0 ) )) 619 { 620 SocketPermission demanded( 621 *reinterpret_cast< connection::SocketPermission const * >( perm.pData ) ); 622 if (__implies( m_head, demanded )) 623 { 624 #ifdef __DIAGNOSE 625 demanded_diag( demanded ); 626 #endif 627 return; 628 } 629 throwAccessControlException( demanded, perm ); 630 } 631 else if (demanded_type.equals( ::getCppuType( (security::RuntimePermission const *)0 ) )) 632 { 633 RuntimePermission demanded( 634 *reinterpret_cast< security::RuntimePermission const * >( perm.pData ) ); 635 if (__implies( m_head, demanded )) 636 { 637 #ifdef __DIAGNOSE 638 demanded_diag( demanded ); 639 #endif 640 return; 641 } 642 throwAccessControlException( demanded, perm ); 643 } 644 else if (demanded_type.equals( ::getCppuType( (security::AllPermission const *)0 ) )) 645 { 646 AllPermission demanded; 647 if (__implies( m_head, demanded )) 648 { 649 #ifdef __DIAGNOSE 650 demanded_diag( demanded ); 651 #endif 652 return; 653 } 654 throwAccessControlException( demanded, perm ); 655 } 656 else 657 { 658 OUStringBuffer buf( 48 ); 659 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("checking for unsupported permission type: ") ); 660 buf.append( demanded_type.getTypeName() ); 661 throw RuntimeException( 662 buf.makeStringAndClear(), Reference< XInterface >() ); 663 } 664 } 665 666 } 667