![]() |
|
|
Bdb packages | Design docs | Source docs | Guidelines | Recent releases |
|
Main Page Modules Namespace List Class Hierarchy Alphabetical List Compound List File List Compound Members File Members /BdbAccess/BdbAuthFederation.cc
Go to the documentation of this file.00001 //-------------------------------------------------------------------------- 00002 // File and Version Information: 00003 // $Id: BdbAuthFederation.cc,v 1.3 2002/06/21 18:30:19 ryd Exp $ 00004 // 00005 // Description: 00006 // This class provides an access to and management of the BaBar 00007 // Database athorization records for a federation. 00008 // 00009 // Environment: 00010 // Software developed for the BaBar Detector at the SLAC B-Factory. 00011 // 00012 // Author List: 00013 // Igor A. Gaponenko Original Author 00014 // 00015 // History: 00016 // Copyright (C) 2001 Lawrence Berkeley Laboratory 00017 // 00018 //------------------------------------------------------------------------ 00019 ///////////////////////// 00020 // This Class's Header // 00021 ///////////////////////// 00022 00023 #include "BdbAccess/BdbAuthFederation.hh" 00024 00025 /////////////// 00026 // C Headers // 00027 /////////////// 00028 00029 extern "C" { 00030 #include <assert.h> 00031 #include <stdio.h> 00032 #include <stdlib.h> 00033 #include <string.h> 00034 #include <sys/types.h> 00035 #include <time.h> 00036 } 00037 00038 ///////////////// 00039 // C++ Headers // 00040 ///////////////// 00041 00042 #include <iostream.h> 00043 #include <string> 00044 using std::string; 00045 00046 ///////////////////////////////// 00047 // Collaborating Class Headers // 00048 ///////////////////////////////// 00049 00050 #include "BdbApplication/BdbDomain.hh" 00051 #include "BdbAccess/BdbAuthRegistry.hh" 00052 #include "BdbAccess/BdbAuthUser.hh" 00053 #include "BdbAccess/BdbAuthGroup.hh" 00054 #include "BdbAccess/BdbDbAccessMgr.hh" 00055 #include "BdbAccess/BdbAuthCache.hh" 00056 #include "BdbAccess/BdbAuthStatisticsMonitor.hh" 00057 00058 00059 ///////////////////////////////////////////////////////////////////////// 00060 // Local Macros, Typedefs, Structures, Unions and Forward Declarations // 00061 ///////////////////////////////////////////////////////////////////////// 00062 00063 static const char rcsid[] = "$Id: BdbAuthFederation.cc,v 1.3 2002/06/21 18:30:19 ryd Exp $"; 00064 00065 00066 //////////////////////////////////// 00067 // Static Data Member Definitions // 00068 //////////////////////////////////// 00069 00070 const char* 00071 BdbAuthFederation::RegistryNames[] = { "Registry_of_Conditions", 00072 "Registry_of_Events", 00073 "Registry_of_Online", 00074 "Registry_of_Spatial", 00075 "Registry_of_Temporal", 00076 "Registry_of_Configuration", 00077 "Registry_of_Ambient" }; 00078 00079 //////////////// 00080 // Destructor // 00081 //////////////// 00082 00083 BdbAuthFederation::~BdbAuthFederation( ) 00084 { 00085 delete _statMon; 00086 delete _cache; 00087 } 00088 00089 ///////////////// 00090 // Constructor // 00091 ///////////////// 00092 00093 BdbAuthFederation::BdbAuthFederation( const char* theName ) : 00094 _shortTransactionIsDisabled(false), 00095 _shortTransactionIsActive(false), 00096 _cachingIsDisabled(false), 00097 _statMon(0), 00098 _cache(0), 00099 _myName("") 00100 { 00101 if( 0 != theName ) _myName = theName; 00102 00103 _statMon = new BdbAuthStatisticsMonitor( theName ); 00104 00105 // The actual database operations are deffered in order to allow someone else 00106 // to establish the proper context. 00107 00108 _isInitialized = false; 00109 } 00110 00111 bool 00112 BdbAuthFederation::initialize( ) 00113 { 00114 if( _isInitialized ) return _isInitialized; 00115 00116 // Check for availability of short transaction, which is enabled by default. 00117 // This can be changed if the corresponding environment variable is found. 00118 00119 if( 0 != getenv( "BDBAUTH_DISABLE_NESTED_TRANSACTIONS" )) { 00120 _shortTransactionIsDisabled = true; 00121 } 00122 00123 // Check for availability of caching some frequently used information. 00124 // By default it's enabled. 00125 // The default behavior could be changed by defining 00126 // the following environment variable: 00127 // 00128 // "BDBAUTH_DISABLE_CACHING" 00129 // 00130 00131 if( 0 != getenv( "BDBAUTH_DISABLE_CACHING" )) { 00132 _cachingIsDisabled = true; 00133 } 00134 00135 // Invalidate ::isAuthorized( ) cache. 00136 00137 invalidateCache( ); 00138 00139 // Execute the rest of the method withing a short transaction in order to avoid 00140 // leaving the locked persistent objects. 00141 00142 if( ! startShortReadTransaction( )) return _isInitialized; 00143 00144 while( true ) { 00145 00146 // Check if the database is properly configured. 00147 // Then lookup the registries in the authorization container. 00148 00149 BdbHandle(BdbDBObj) theDbH; 00150 BdbDbAccessMgr theAccessMgr; 00151 00152 theAccessMgr.openManagementDb( theDbH, BdbcRead ); 00153 if( BdbIsNull( theDbH )) { 00154 error( BdbDomain::IllegalDomain, "Unable to open/create Management DB." ); 00155 break; 00156 } 00157 00158 // Collect the information about registries for all known domains. 00159 // 00160 // NOTE: We are assuming that there is no holes in the enumeration of 00161 // the domains. 00162 00163 BdbHandle(BdbAuthRegistry) theRegH; 00164 00165 for( int domain = BdbDomain::FirstDomain; domain < BdbDomain::IllegalDomain; domain++ ) { 00166 if( _registry[ domain - BdbDomain::FirstDomain ].isNull( )) { 00167 theRegH.lookupObj( theDbH, RegistryNames[ domain - BdbDomain::FirstDomain ], BdbcRead ); 00168 _registry[ domain - BdbDomain::FirstDomain ] = theRegH; 00169 } 00170 } 00171 00172 // And finally... 00173 00174 bool transactionIsAvailable = true; 00175 if( ! populateCache( transactionIsAvailable )) { 00176 error( BdbDomain::IllegalDomain, "Failed to populate transient cache from the database." ); 00177 break; 00178 } 00179 00180 // Now, its all done. 00181 00182 _isInitialized = true; 00183 00184 break; 00185 } 00186 commitShortTransaction( ); 00187 00188 return _isInitialized; 00189 } 00190 00191 /////////////// 00192 // Utilities // 00193 /////////////// 00194 00195 char* 00196 BdbAuthFederation::current_time( ) 00197 { 00198 time_t tt; 00199 char* buf; 00200 char* str; 00201 int i; 00202 00203 // Obtain current time in ASCII in the following format: 00204 // "Thu Sep 4 22:25:44 1997" 00205 00206 tt = time ( &tt ); 00207 buf = ctime( &tt ); 00208 00209 // Compress the interesting information into: 00210 // "Sep 4 22:25 1997" 00211 00212 str = new char[18]; 00213 00214 // This does not work for unknown reason. 00215 // replaced by a stupid loop. 00216 // 00217 // strncpy( &(str[0]), &(buf[4]), 12 ); 00218 00219 for( i = 0; i < 12; i++ ) 00220 str[0+i] = buf[4+i]; 00221 00222 str[12] = ' '; 00223 00224 // This does not work for unknown reason. 00225 // replaced by a stupid loop. 00226 // 00227 // strncat( &(str[13]), &(buf[20]), 4 ); 00228 00229 for( i = 0; i < 4; i++ ) 00230 str[13+i] = buf[20+i]; 00231 00232 str[17] = '\0'; 00233 00234 // delete [] buf; We didn't do the new so I don't think we should delete it 00235 00236 return str; 00237 } 00238 00239 /////////////////////// 00240 // Selectors (const) // 00241 /////////////////////// 00242 00243 string 00244 BdbAuthFederation::getName( ) 00245 { 00246 return _myName; 00247 } 00248 00249 /////////////// 00250 // Selectors // 00251 /////////////// 00252 00253 d_Boolean 00254 BdbAuthFederation::isInitialized( BdbDomain::Domains theDomain ) 00255 { 00256 assert( BdbDomain::isDomainValid( theDomain )); 00257 00258 if( ! initialize( )) return false; 00259 00260 // The domain is initialized if the corresponding Registry exists. 00261 00262 return ( ! BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )); 00263 } 00264 00265 d_Boolean 00266 BdbAuthFederation::isAuthorized( BdbDomain::Domains theDomain, 00267 BdbDomain::AuthLevels theAuthLevel, 00268 const char* theAuthName ) 00269 { 00270 d_Boolean result = false; 00271 00272 assert( BdbDomain::isDomainValid ( theDomain )); 00273 assert( BdbDomain::isAuthLevelValid( theAuthLevel )); 00274 00275 const char* theUserName = BdbDomain::userName( ); 00276 const char* theGroupName = theAuthName; 00277 00278 _statMon->increment_isAuthorized( ); 00279 00280 if( ! initialize( )) return result; 00281 00282 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 00283 error( theDomain, "Authorization database is not configured." ); 00284 return result; 00285 } 00286 00287 // Make sure the cache is populated (some actions modifying the contents 00288 // of the database may destroy it). 00289 00290 bool transactionIsAvailable = false; 00291 if( ! populateCache( transactionIsAvailable )) { 00292 error( theDomain, "Failed to populate transient cache from the database." ); 00293 return false; 00294 } 00295 00296 // Try to find the record in the cache. 00297 00298 if( tryCache( theDomain, 00299 theAuthLevel, 00300 theAuthName, 00301 theUserName, 00302 result )) return result; 00303 00304 // WARNING: 00305 // ======== 00306 // 00307 // The following piece of code is executed within a short read-mode transaction 00308 // in order to prevent possible locks. 00309 // 00310 // The code is arranged in "exception-like" while-do loop. This is done in order 00311 // to close transaction in the end. 00312 // 00313 // A successfull sequence of execution is indicated by the "result" 00314 // varisble set to "d_True" value. 00315 00316 if( ! startShortReadTransaction( )) return result; 00317 00318 while( true ) { 00319 00320 // Use handles for better efficiency. 00321 00322 BdbHandle(BdbAuthRegistry) theRegH; 00323 BdbHandle(BdbAuthGroup) theGroupH; 00324 BdbHandle(BdbAuthUser) theUserH; 00325 00326 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 00327 00328 // Try to find this user in the database. 00329 00330 theUserH = theRegH->getUser( theUserName ); 00331 if( BdbIsNull( theUserH )) { 00332 error( theDomain, "User does not exist." ); 00333 break; 00334 } 00335 00336 // Make specific checking for the given authorization level. 00337 00338 switch( theAuthLevel ) { 00339 00340 case BdbDomain::System: 00341 00342 // Verify if the user may assume SYSTEM-level rights. 00343 00344 if( theUserH->isSystemManager( )) result = true; 00345 break; 00346 00347 case BdbDomain::Group: 00348 00349 // Verify if the user belongs to specified group (or is system manager) 00350 00351 if( theUserH->isSystemManager( )) { 00352 result = true; 00353 } else { 00354 00355 if( 0 == theGroupName ) { 00356 error( theDomain, "Bad parameters. Group name must be specified." ); 00357 } else { 00358 00359 theGroupH = theUserH->getGroup( theGroupName ); 00360 if( BdbIsNull( theGroupH )) { 00361 00362 char* buf = new char [ 45 + strlen(theGroupName) ]; 00363 sprintf(buf, "User is not a member of the group \"%s\".", theGroupName); 00364 00365 error( theDomain, buf ); 00366 00367 delete [] buf; 00368 00369 } else { 00370 result = true; 00371 } 00372 } 00373 } 00374 break; 00375 00376 case BdbDomain::User: 00377 00378 // Here is nothing more to check, because such a user exists. 00379 00380 result = true; 00381 00382 break; 00383 } 00384 break; 00385 } 00386 00387 // End current short transaction. 00388 00389 commitShortTransaction( ); 00390 00391 // Update the cache. 00392 00393 updateCache( theDomain, 00394 theAuthLevel, 00395 theAuthName, 00396 theUserName, 00397 result ); 00398 00399 return result; 00400 } 00401 00402 d_Boolean 00403 BdbAuthFederation::isSystemManager( BdbDomain::Domains theDomain, 00404 const char* theUserName ) 00405 { 00406 d_Boolean result = false; 00407 00408 assert( BdbDomain::isDomainValid( theDomain )); 00409 assert( 0 != theUserName ); 00410 00411 if( ! initialize( )) return result; 00412 00413 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 00414 error( theDomain, "Authorization database is not configured." ); 00415 return result; 00416 } 00417 00418 // Use handles for better efficiency. 00419 00420 BdbHandle(BdbAuthRegistry) theRegH; 00421 BdbHandle(BdbAuthUser) theUserH; 00422 00423 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 00424 00425 theUserH = theRegH->getUser( theUserName ); 00426 if( BdbIsNull( theUserH )) { 00427 error( theDomain, "User does not exist." ); 00428 return result; 00429 } 00430 00431 // Obtain and return desired information. 00432 00433 return theUserH->isSystemManager( ); 00434 } 00435 00436 d_Boolean 00437 BdbAuthFederation::isGroupManager( BdbDomain::Domains theDomain, 00438 const char* theUserName, 00439 const char* theGroupName ) 00440 { 00441 d_Boolean result = false; 00442 00443 assert( BdbDomain::isDomainValid( theDomain )); 00444 assert( 0 != theUserName ); 00445 assert( 0 != theGroupName ); 00446 00447 if( ! initialize( )) return result; 00448 00449 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 00450 error( theDomain, "Authorization database is not configured." ); 00451 return result; 00452 } 00453 00454 // Use handles for better efficiency. 00455 00456 BdbHandle(BdbAuthRegistry) theRegH; 00457 BdbHandle(BdbAuthUser) theUserH; 00458 BdbHandle(BdbAuthGroup) theGroupH; 00459 00460 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 00461 00462 // Try to find this user in the database. 00463 00464 theUserH = theRegH->getUser( theUserName ); 00465 if( BdbIsNull( theUserH )) { 00466 error( theDomain, "User does not exist." ); 00467 return result; 00468 } 00469 00470 // Try to find the group. 00471 00472 theGroupH = theRegH->getGroup( theGroupName ); 00473 if( BdbIsNull( theGroupH )) { 00474 error( theDomain, "Group does not exist." ); 00475 return result; 00476 } 00477 00478 // Try to find the user in the group in the list of managers. 00479 00480 theUserH = theGroupH->getManager( theUserName ); 00481 00482 return ( ! BdbIsNull( theUserH )); 00483 } 00484 00485 d_Boolean 00486 BdbAuthFederation::isGroupMember( BdbDomain::Domains theDomain, 00487 const char* theUserName, 00488 const char* theGroupName ) 00489 { 00490 d_Boolean result = false; 00491 00492 assert( BdbDomain::isDomainValid( theDomain )); 00493 assert( 0 != theUserName ); 00494 assert( 0 != theGroupName ); 00495 00496 if( ! initialize( )) return result; 00497 00498 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 00499 error( theDomain, "Authorization database is not configured." ); 00500 return result; 00501 } 00502 00503 // Use handles for better efficiency. 00504 00505 BdbHandle(BdbAuthRegistry) theRegH; 00506 BdbHandle(BdbAuthUser) theUserH; 00507 BdbHandle(BdbAuthGroup) theGroupH; 00508 00509 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 00510 00511 // Try to find this user in the database. 00512 00513 theUserH = theRegH->getUser( theUserName ); 00514 if( BdbIsNull( theUserH )) { 00515 error( theDomain, "User does not exist." ); 00516 return result; 00517 } 00518 00519 // Try to find the group in the database. 00520 00521 theGroupH = theRegH->getGroup( theGroupName ); 00522 if( BdbIsNull( theGroupH )) { 00523 error( theDomain, "Group does not exist." ); 00524 return result; 00525 } 00526 00527 // Try to find the user in the group. 00528 00529 theUserH = theGroupH->getUser( theUserName ); 00530 00531 return ( ! BdbIsNull( theUserH )); 00532 } 00533 00534 d_Boolean 00535 BdbAuthFederation::isDomainMember( BdbDomain::Domains theDomain, 00536 const char* theUserName ) 00537 { 00538 d_Boolean result = false; 00539 00540 assert( BdbDomain::isDomainValid( theDomain )); 00541 assert( 0 != theUserName ); 00542 00543 if( ! initialize( )) return result; 00544 00545 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 00546 error( theDomain, "Authorization database is not configured." ); 00547 return result; 00548 } 00549 00550 // Use handles for better efficiency. 00551 00552 BdbHandle(BdbAuthRegistry) theRegH; 00553 BdbHandle(BdbAuthUser) theUserH; 00554 00555 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 00556 00557 // Try to find this user in the database. 00558 00559 theUserH = theRegH->getUser( theUserName ); 00560 00561 return ( ! BdbIsNull( theUserH )); 00562 } 00563 00564 d_Boolean 00565 BdbAuthFederation::isAccessAllowed( BdbDomain::Domains theDomain, 00566 const char* theUserName ) 00567 { 00568 d_Boolean result = isDomainMember( theDomain, theUserName ); 00569 if( ! result ) { 00570 result = ( ! isDomainMember( theDomain, "registered_only" )); 00571 } 00572 return result; 00573 } 00574 00575 const char* 00576 BdbAuthFederation::getUserDescription( BdbDomain::Domains theDomain, 00577 const char* theUserName ) 00578 { 00579 assert( BdbDomain::isDomainValid( theDomain )); 00580 assert( 0 != theUserName ); 00581 00582 if( ! initialize( )) return 0; 00583 00584 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 00585 error( theDomain, "Authorization database is not configured." ); 00586 return 0; 00587 } 00588 00589 // Use handles for better efficiency. 00590 00591 BdbHandle(BdbAuthRegistry) theRegH; 00592 BdbHandle(BdbAuthUser) theUserH; 00593 00594 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 00595 00596 // Try to find this user in the database. 00597 00598 theUserH = theRegH->getUser( theUserName ); 00599 if( BdbIsNull( theUserH )) { 00600 error( theDomain, "User does not exist." ); 00601 return 0; 00602 } 00603 00604 return theUserH->getDescription( ); 00605 } 00606 00607 const char* 00608 BdbAuthFederation::getUserCreated( BdbDomain::Domains theDomain, 00609 const char* theUserName ) 00610 { 00611 assert( BdbDomain::isDomainValid( theDomain )); 00612 assert( 0 != theUserName ); 00613 00614 if( ! initialize( )) return 0; 00615 00616 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 00617 error( theDomain, "Authorization database is not configured." ); 00618 return 0; 00619 } 00620 00621 // Use handles for better efficiency. 00622 00623 BdbHandle(BdbAuthRegistry) theRegH; 00624 BdbHandle(BdbAuthUser) theUserH; 00625 00626 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 00627 00628 // Try to find this user in the database. 00629 00630 theUserH = theRegH->getUser( theUserName ); 00631 if( BdbIsNull( theUserH )) { 00632 error( theDomain, "User does not exist." ); 00633 return 0; 00634 } 00635 00636 return theUserH->getCreated( ); 00637 } 00638 00639 const char* 00640 BdbAuthFederation::getGroupDescription( BdbDomain::Domains theDomain, 00641 const char* theGroupName ) 00642 { 00643 assert( BdbDomain::isDomainValid( theDomain )); 00644 assert( 0 != theGroupName ); 00645 00646 if( ! initialize( )) return 0; 00647 00648 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 00649 error( theDomain, "Authorization database is not configured." ); 00650 return 0; 00651 } 00652 00653 // Use handles for better efficiency. 00654 00655 BdbHandle(BdbAuthRegistry) theRegH; 00656 BdbHandle(BdbAuthGroup) theGroupH; 00657 00658 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 00659 00660 // Try to find this group in the database. 00661 00662 theGroupH = theRegH->getGroup( theGroupName ); 00663 if( BdbIsNull( theGroupH )) { 00664 error( theDomain, "Group does not exist." ); 00665 return 0; 00666 } 00667 00668 return theGroupH->getDescription( ); 00669 } 00670 00671 const char* 00672 BdbAuthFederation::getGroupCreated( BdbDomain::Domains theDomain, 00673 const char* theGroupName ) 00674 { 00675 assert( BdbDomain::isDomainValid( theDomain )); 00676 assert( 0 != theGroupName ); 00677 00678 if( ! initialize( )) return 0; 00679 00680 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 00681 error( theDomain, "Authorization database is not configured." ); 00682 return 0; 00683 } 00684 00685 // Use handles for better efficiency. 00686 00687 BdbHandle(BdbAuthRegistry) theRegH; 00688 BdbHandle(BdbAuthGroup) theGroupH; 00689 00690 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 00691 00692 // Try to find this group in the database. 00693 00694 theGroupH = theRegH->getGroup( theGroupName ); 00695 if( BdbIsNull( theGroupH )) { 00696 error( theDomain, "Group does not exist." ); 00697 return 0; 00698 } 00699 00700 return theGroupH->getCreated( ); 00701 } 00702 00703 //////////////// 00704 // Operations // 00705 //////////////// 00706 00707 d_Boolean 00708 BdbAuthFederation::initialize( BdbDomain::Domains theDomain ) 00709 { 00710 d_Boolean result = false; 00711 00712 assert( BdbDomain::isDomainValid( theDomain )); 00713 00714 d_ULong status; 00715 00716 if( ! initialize( )) return result; 00717 00718 // Invalidate ::isAuthorized( ) cache, for now we are going 00719 // to modify the contents of the database which eventually could 00720 // lead to the cache inconsistancy. 00721 00722 invalidateCache( ); 00723 00724 // Use handles for better efficiency. 00725 00726 BdbHandle(BdbAuthRegistry) theRegH; 00727 00728 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 00729 00730 // Delete domain information if it still exists (only a System Manager can do this). 00731 00732 if( ! BdbIsNull( theRegH )) { 00733 00734 if( ! isSystemManager( theDomain, BdbDomain::userName( ))) { 00735 error( theDomain, "No privileges for this operation." ); 00736 return result; 00737 } 00738 BdbDelete( theRegH ); 00739 } 00740 00741 // Open the management database. 00742 00743 BdbHandle(BdbDBObj) theDbH; 00744 BdbDbAccessMgr theAccessMgr; 00745 00746 theAccessMgr.openManagementDb( theDbH, BdbcRead ); 00747 if( BdbIsNull( theDbH )) { 00748 error( theDomain, "Unable to open/create Management DB." ); 00749 return result; 00750 } 00751 00752 // Create the authorization container if it doesn't exist 00753 00754 const char* authContName = "authorization"; 00755 00756 BdbHandle(BdbContObj) theContH; 00757 00758 if( BdbcSuccess != theContH.exist( theDbH, authContName, BdbcRead )) { 00759 theContH = new( authContName, 0, 1, 1, theDbH ) BdbContObj; 00760 if( BdbIsNull( theContH )) { 00761 error( theDomain, "Unable to create authorization container" ); 00762 } 00763 } 00764 00765 // Create the registry object and give it a name. 00766 00767 theRegH = new( theContH ) BdbAuthRegistry; 00768 if( BdbIsNull( theRegH )) { 00769 error( theDomain, "Unable to create a registry." ); 00770 return result; 00771 } 00772 status = theRegH.nameObj( theDbH, RegistryNames[ theDomain - BdbDomain::FirstDomain ] ); 00773 if( BdbcSuccess != status ) { 00774 error( theDomain, "Unable to give a name to the registry." ); 00775 return result; 00776 } 00777 00778 // Create default group. Then add it to the registry. 00779 00780 BdbHandle(BdbAuthGroup) theGroupH; 00781 00782 theGroupH = new( theContH ) BdbAuthGroup( "Global", current_time( ), "default group" ); 00783 if( BdbIsNull( theGroupH )) { 00784 error( theDomain, "Unable to create default group." ); 00785 return result; 00786 } 00787 status = theRegH->addGroup( theGroupH ); 00788 if( BdbcSuccess != status ) { 00789 error( theDomain, "Unable to add default group to the registry." ); 00790 return result; 00791 } 00792 00793 // Create initial user. Make him a system manager. 00794 // Then add his record to the registry and to default group. 00795 00796 BdbHandle(BdbAuthUser) theUserH; 00797 00798 theUserH = new( theContH ) BdbAuthUser( BdbDomain::userName( ), current_time( ), "initial system manager" ); 00799 if( BdbIsNull( theUserH )) { 00800 error( theDomain, "Unable to create initial user." ); 00801 return result; 00802 } 00803 theUserH->setSystemManager( true ); 00804 00805 status = theRegH->addUser( theUserH ); 00806 if( BdbcSuccess != status ) { 00807 error( theDomain, "Unable to add the user to the registry." ); 00808 return result; 00809 } 00810 status = theGroupH->addMember( theUserH ); 00811 if( BdbcSuccess != status ) { 00812 error( theDomain, "Unable to add a member to the group." ); 00813 return result; 00814 } 00815 00816 // Create lock container used during db creation. 00817 00818 BdbHandle(BdbContObj) lockCont; 00819 const char* lockContName = "dbLock"; 00820 00821 if( BdbcSuccess != lockCont.exist( theDbH, lockContName, BdbcNoOpen )) { 00822 new( lockContName, 0, 1, 1, theDbH ) BdbContObj; 00823 } 00824 00825 // Make the registry reference available. 00826 00827 _registry[ theDomain - BdbDomain::FirstDomain ] = theRegH; 00828 00829 return true; 00830 } 00831 00832 d_Boolean 00833 BdbAuthFederation::createUser( BdbDomain::Domains theDomain, 00834 BdbDomain::AuthLevels theAuthLevel, 00835 const char* theUserName, 00836 const char* theGroupName, 00837 const char* theDescription ) 00838 { 00839 d_Boolean result = false; 00840 00841 assert( BdbDomain::isDomainValid( theDomain )); 00842 assert( BdbDomain::isAuthLevelValid( theAuthLevel )); 00843 assert( 0 != theUserName ); 00844 00845 d_ULong status; 00846 00847 if( ! initialize( )) return result; 00848 00849 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 00850 error( theDomain, "Authorization database is not configured." ); 00851 return result; 00852 } 00853 00854 // Use handles for better efficiency. 00855 00856 BdbHandle(BdbAuthRegistry) theRegH; 00857 BdbHandle(BdbAuthUser) theUserH; 00858 BdbHandle(BdbAuthGroup) theGroupH; 00859 00860 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 00861 00862 // Invalidate ::isAuthorized( ) cache, for now we are going 00863 // to modify the contents of the database which eventually could 00864 // lead to the cache inconsistancy. 00865 00866 invalidateCache( ); 00867 00868 // Check for the user rights to perform this operation. 00869 00870 if( ! isSystemManager( theDomain, BdbDomain::userName( ))) { 00871 error( theDomain, "No privileges for this operation." ); 00872 return result; 00873 } 00874 00875 // Try to find this user in the database. 00876 00877 theUserH = theRegH->getUser( theUserName ); 00878 if( ! BdbIsNull( theUserH )) { 00879 error( theDomain, "User already exists." ); 00880 return result; 00881 } 00882 00883 // Create new user record. Tune it. 00884 // Then add the record to the registry. 00885 00886 theUserH = new( theRegH ) BdbAuthUser( theUserName, current_time( ), theDescription ); 00887 00888 if( BdbIsNull( theUserH )) { 00889 error( theDomain, "Unable to create the user." ); 00890 return result; 00891 } 00892 if( BdbDomain::System == theAuthLevel ) { 00893 theUserH->setSystemManager( true ); 00894 } 00895 00896 status = theRegH->addUser( theUserH ); 00897 if( BdbcSuccess != status ) { 00898 error( theDomain, "Unable to add the user to the registry." ); 00899 return result; 00900 } 00901 00902 // Obtain the default group. 00903 // Then add user record to the default group. 00904 00905 theGroupH = theRegH->getGroup( "Global" ); 00906 if( BdbIsNull( theGroupH )) { 00907 error( theDomain, "Default group does not exist." ); 00908 BdbDelete( theUserH ); 00909 return result; 00910 } 00911 00912 status = theGroupH->addMember( theUserH ); 00913 if( BdbcSuccess != status ) { 00914 error( theDomain, "Unable to add a member to the group." ); 00915 return result; 00916 } 00917 00918 // If running on Group authorization level - try to find specified 00919 // group. Then add user there, if it is not the default group. 00920 00921 if( BdbDomain::Group == theAuthLevel ) { 00922 00923 if( 0 == theGroupName ) { 00924 error( theDomain, "Illegal parameters. Group name must be specified." ); 00925 BdbDelete( theUserH ); 00926 return result; 00927 } 00928 if( 0 == strcmp( "Global", theGroupName )) { 00929 error( theDomain, "Can not include the user into default group." ); 00930 BdbDelete( theUserH ); 00931 return result; 00932 } 00933 00934 theGroupH = theRegH->getGroup( theGroupName ); 00935 if( BdbIsNull( theGroupH )) { 00936 error( theDomain, "The group does not exist." ); 00937 BdbDelete( theUserH ); 00938 return result; 00939 } 00940 00941 status = theGroupH->addMember( theUserH ); 00942 if( BdbcSuccess != status ) { 00943 error( theDomain, "Unable to add a member to the group." ); 00944 BdbDelete( theUserH ); 00945 return result; 00946 } 00947 } 00948 00949 return true; 00950 } 00951 00952 d_Boolean 00953 BdbAuthFederation::deleteUser( BdbDomain::Domains theDomain, 00954 const char* theUserName ) 00955 { 00956 d_Boolean result = false; 00957 00958 assert( BdbDomain::isDomainValid( theDomain )); 00959 assert( 0 != theUserName ); 00960 00961 if( ! initialize( )) return result; 00962 00963 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 00964 error( theDomain, "Authorization database is not configured." ); 00965 return result; 00966 } 00967 00968 // Use handles for better efficiency. 00969 00970 BdbHandle(BdbAuthRegistry) theRegH; 00971 BdbHandle(BdbAuthUser) theUserH; 00972 00973 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 00974 00975 // Invalidate ::isAuthorized( ) cache, for now we are going 00976 // to modify the contents of the database which eventually could 00977 // lead to the cache inconsistancy. 00978 00979 invalidateCache( ); 00980 00981 // Check for the user rights to perform this operation. 00982 00983 if( ! isSystemManager( theDomain, BdbDomain::userName( ))) { 00984 error( theDomain, "No privileges for this operation." ); 00985 return result; 00986 } 00987 00988 // Try to find specified user in the database. Then delete it 00989 // if exists. The user will be atomatically excluded from 00990 // all the groups it belongs to. 00991 00992 theUserH = theRegH->getUser( theUserName ); 00993 if( BdbIsNull( theUserH )) { 00994 error( theDomain, "User does not exist." ); 00995 return result; 00996 } 00997 BdbDelete( theUserH ); 00998 00999 return true; 01000 } 01001 01002 d_Boolean 01003 BdbAuthFederation::createGroup( BdbDomain::Domains theDomain, 01004 const char* theGroupName, 01005 const char* theDescription ) 01006 { 01007 d_Boolean result = false; 01008 01009 d_ULong status; 01010 01011 assert( BdbDomain::isDomainValid( theDomain )); 01012 assert( 0 != theGroupName ); 01013 assert( 0 != theDescription ); 01014 01015 if( ! initialize( )) return result; 01016 01017 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 01018 error( theDomain, "Authorization database is not configured." ); 01019 return result; 01020 } 01021 01022 // Use handles for better efficiency. 01023 01024 BdbHandle(BdbAuthRegistry) theRegH; 01025 BdbHandle(BdbAuthGroup) theGroupH; 01026 01027 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 01028 01029 // Invalidate ::isAuthorized( ) cache, for now we are going 01030 // to modify the contents of the database which eventually could 01031 // lead to the cache inconsistancy. 01032 01033 invalidateCache( ); 01034 01035 // Check for the user rights to perform this operation. 01036 01037 if( ! isSystemManager( theDomain, BdbDomain::userName( ))) { 01038 error( theDomain, "No privileges for this operation." ); 01039 return result; 01040 } 01041 01042 // Do not create the default group. 01043 01044 if( 0 == strcmp( "Global", theGroupName )) { 01045 error( theDomain, "Default group can not be created." ); 01046 return result; 01047 } 01048 01049 // Try to find this group in the database. 01050 01051 theGroupH = theRegH->getGroup( theGroupName ); 01052 if( ! BdbIsNull( theGroupH )) { 01053 error( theDomain, "Group already exists." ); 01054 return result; 01055 } 01056 01057 // Make new group record then add it to registry. 01058 01059 theGroupH = new( theRegH ) BdbAuthGroup( theGroupName, current_time( ), theDescription ); 01060 if( BdbIsNull( theGroupH )) { 01061 error( theDomain, "Unable to create the group." ); 01062 return result; 01063 } 01064 01065 status = theRegH->addGroup( theGroupH ); 01066 if( BdbcSuccess != status ) { 01067 error( theDomain, "Unable to add the group to the registry." ); 01068 BdbDelete( theGroupH ); 01069 return result; 01070 } 01071 01072 return true; 01073 } 01074 01075 d_Boolean 01076 BdbAuthFederation::deleteGroup( BdbDomain::Domains theDomain, 01077 const char* theGroupName ) 01078 { 01079 d_Boolean result = false; 01080 01081 assert( BdbDomain::isDomainValid( theDomain )); 01082 assert( 0 != theGroupName ); 01083 01084 if( ! initialize( )) return result; 01085 01086 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 01087 error( theDomain, "Authorization database is not configured." ); 01088 return result; 01089 } 01090 01091 // Use handles for better efficiency. 01092 01093 BdbHandle(BdbAuthRegistry) theRegH; 01094 BdbHandle(BdbAuthGroup) theGroupH; 01095 01096 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 01097 01098 // Invalidate ::isAuthorized( ) cache, for now we are going 01099 // to modify the contents of the database which eventually could 01100 // lead to the cache inconsistancy. 01101 01102 invalidateCache( ); 01103 01104 // Check for the user rights to perform this operation. 01105 01106 if( ! isSystemManager( theDomain, BdbDomain::userName( ))) { 01107 error( theDomain, "No privileges for this operation." ); 01108 return result; 01109 } 01110 01111 // Do not delete the default group. 01112 01113 if( 0 == strcmp( "Global", theGroupName )) { 01114 error( theDomain, "Default group can not be deleted." ); 01115 return result; 01116 } 01117 01118 // Try to find specified group in the database. Then delete it 01119 // if exists. 01120 // All the existing group members will be automatically disconnected 01121 // from the group. 01122 01123 theGroupH = theRegH->getGroup( theGroupName ); 01124 if( BdbIsNull( theGroupH )) { 01125 error( theDomain, "Group does not exist." ); 01126 return result; 01127 } 01128 BdbDelete( theGroupH ); 01129 01130 return true; 01131 } 01132 01133 d_Boolean 01134 BdbAuthFederation::includeUser( BdbDomain::Domains theDomain, 01135 const char* theUserName, 01136 const char* theGroupName ) 01137 { 01138 d_Boolean result = false; 01139 01140 d_ULong status; 01141 01142 assert( BdbDomain::isDomainValid( theDomain )); 01143 assert( 0 != theUserName ); 01144 assert( 0 != theGroupName ); 01145 01146 if( ! initialize( )) return result; 01147 01148 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 01149 error( theDomain, "Authorization database is not configured." ); 01150 return result; 01151 } 01152 01153 // Use handles for better efficiency. 01154 01155 BdbHandle(BdbAuthRegistry) theRegH; 01156 BdbHandle(BdbAuthUser) theUserH; 01157 BdbHandle(BdbAuthGroup) theGroupH; 01158 01159 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 01160 01161 // Invalidate ::isAuthorized( ) cache, for now we are going 01162 // to modify the contents of the database which eventually could 01163 // lead to the cache inconsistancy. 01164 01165 invalidateCache( ); 01166 01167 // Check for the user rights to perform this operation. 01168 01169 if( ! isSystemManager( theDomain, BdbDomain::userName( ))) { 01170 if( ! isGroupManager( theDomain, BdbDomain::userName( ), theGroupName )) { 01171 error( theDomain, "No privileges for this operation." ); 01172 return result; 01173 } 01174 } 01175 01176 // Do not include into default group. 01177 01178 if( 0 == strcmp( "Global", theGroupName )) { 01179 error( theDomain, "Cannot include into default group." ); 01180 return result; 01181 } 01182 01183 // Try to find specified group in the databongs 01184 01185 theGroupH = theRegH->getGroup( theGroupName ); 01186 if( BdbIsNull( theGroupH )) { 01187 error( theDomain, "The group does not exist." ); 01188 return result; 01189 } 01190 01191 // Try to find the user in this group. 01192 01193 theUserH = theGroupH->getUser( theUserName ); 01194 if( ! BdbIsNull( theUserH )) { 01195 warning( theDomain, "The user is already a member of this group." ); 01196 return true; 01197 } 01198 01199 // Try to find specified user in all the database. 01200 01201 theUserH = theRegH->getUser( theUserName ); 01202 if( BdbIsNull( theUserH )) { 01203 error( theDomain, "The user does not exist." ); 01204 return result; 01205 } 01206 01207 // Include user into the group. 01208 01209 status = theGroupH->addMember( theUserH ); 01210 if( BdbcSuccess != status ) { 01211 error( theDomain, "Unable to add new member to the group." ); 01212 return result; 01213 } 01214 01215 return true; 01216 } 01217 01218 d_Boolean 01219 BdbAuthFederation::excludeUser( BdbDomain::Domains theDomain, 01220 const char* theUserName, 01221 const char* theGroupName ) 01222 { 01223 d_Boolean result = false; 01224 01225 d_ULong status; 01226 01227 assert( BdbDomain::isDomainValid( theDomain )); 01228 assert( 0 != theUserName ); 01229 assert( 0 != theGroupName ); 01230 01231 if( ! initialize( )) return result; 01232 01233 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 01234 error( theDomain, "Authorization database is not configured." ); 01235 return result; 01236 } 01237 01238 // Use handles for better efficiency. 01239 01240 BdbHandle(BdbAuthRegistry) theRegH; 01241 BdbHandle(BdbAuthUser) theUserH; 01242 BdbHandle(BdbAuthGroup) theGroupH; 01243 01244 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 01245 01246 // Invalidate ::isAuthorized( ) cache, for now we are going 01247 // to modify the contents of the database which eventually could 01248 // lead to the cache inconsistancy. 01249 01250 invalidateCache( ); 01251 01252 // Check for the user rights to perform this operation. 01253 01254 if( ! isSystemManager( theDomain, BdbDomain::userName( ))) { 01255 if( ! isGroupManager( theDomain, BdbDomain::userName( ), theGroupName )) { 01256 error( theDomain, "No privileges for this operation." ); 01257 return result; 01258 } 01259 } 01260 01261 // Do not exclude from default group. 01262 01263 if( 0 == strcmp( "Global", theGroupName )) { 01264 error( theDomain, "Cannot exclude from default group." ); 01265 return result; 01266 } 01267 01268 // Try to find specified group in the database. 01269 01270 theGroupH = theRegH->getGroup( theGroupName ); 01271 if( BdbIsNull( theGroupH )) { 01272 error( theDomain, "Group does not exist." ); 01273 return result; 01274 } 01275 01276 // Try to find the user in this group. 01277 01278 theUserH = theGroupH->getUser( theUserName ); 01279 if( BdbIsNull( theUserH )) { 01280 warning( theDomain, "User is not a member of this group." ); 01281 return true; 01282 } 01283 01284 // Exclude user from the group. 01285 01286 status = theUserH->excludeFromGroup( theGroupH ); 01287 if( BdbcSuccess != status ) { 01288 error( theDomain, "Unable to remove user from the group." ); 01289 return result; 01290 } 01291 01292 return true; 01293 } 01294 01295 d_Boolean 01296 BdbAuthFederation::deleteDomain( BdbDomain::Domains theDomain ) 01297 { 01298 d_Boolean result = false; 01299 01300 assert( BdbDomain::isDomainValid( theDomain )); 01301 01302 if( ! initialize( )) return result; 01303 01304 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 01305 error( theDomain, "Authorization database is not configured." ); 01306 return result; 01307 } 01308 01309 // Use handles for better efficiency. 01310 01311 BdbHandle(BdbAuthRegistry) theRegH; 01312 01313 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 01314 01315 // Invalidate ::isAuthorized( ) cache, for now we are going 01316 // to modify the contents of the database which eventually could 01317 // lead to the cache inconsistancy. 01318 01319 invalidateCache( ); 01320 01321 // Check for the user rights to perform this operation. 01322 01323 if( ! isSystemManager( theDomain, BdbDomain::userName( ))) { 01324 error( theDomain, "No privileges for this operation." ); 01325 return result; 01326 } 01327 01328 // Delete specified registry as a composite object. 01329 01330 BdbDelete( theRegH ); 01331 01332 // Update information in the persistent cache. 01333 01334 _registry[ theDomain - BdbDomain::FirstDomain ] = 0; 01335 01336 return true; 01337 } 01338 01339 d_Boolean 01340 BdbAuthFederation::setSystemManager( BdbDomain::Domains theDomain, 01341 const char* theUserName, 01342 d_Boolean onOff ) 01343 { 01344 d_Boolean result = false; 01345 01346 assert( BdbDomain::isDomainValid( theDomain )); 01347 assert( 0 != theUserName ); 01348 01349 if( ! initialize( )) return result; 01350 01351 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 01352 error( theDomain, "Authorization database is not configured." ); 01353 return result; 01354 } 01355 01356 // Use handles for better efficiency. 01357 01358 BdbHandle(BdbAuthRegistry) theRegH; 01359 BdbHandle(BdbAuthUser) theUserH; 01360 01361 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 01362 01363 // Invalidate ::isAuthorized( ) cache, for now we are going 01364 // to modify the contents of the database which eventually could 01365 // lead to the cache inconsistancy. 01366 01367 invalidateCache( ); 01368 01369 // Check for the user rights to perform this operation. 01370 01371 if( ! isSystemManager( theDomain, BdbDomain::userName( ))) { 01372 error( theDomain, "No privileges for this operation." ); 01373 return result; 01374 } 01375 01376 // Try to find this user in the database. 01377 // Then set/reset his system management right. 01378 01379 theUserH = theRegH->getUser( theUserName ); 01380 if( BdbIsNull( theUserH )) { 01381 error( theDomain, "User does not exist." ); 01382 return result; 01383 } 01384 theUserH->setSystemManager( onOff ); 01385 01386 return true; 01387 } 01388 01389 d_Boolean 01390 BdbAuthFederation::setGroupManager( BdbDomain::Domains theDomain, 01391 const char* theUserName, 01392 const char* theGroupName, 01393 d_Boolean onOff ) 01394 { 01395 d_Boolean result = false; 01396 01397 d_ULong status; 01398 01399 assert( BdbDomain::isDomainValid( theDomain )); 01400 assert( 0 != theUserName ); 01401 assert( 0 != theGroupName ); 01402 01403 if( ! initialize( )) return result; 01404 01405 if( BdbIsNull( _registry[ theDomain - BdbDomain::FirstDomain ] )) { 01406 error( theDomain, "Authorization database is not configured." ); 01407 return result; 01408 } 01409 01410 // Use handles for better efficiency. 01411 01412 BdbHandle(BdbAuthRegistry) theRegH; 01413 BdbHandle(BdbAuthUser) theUserH; 01414 BdbHandle(BdbAuthGroup) theGroupH; 01415 01416 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 01417 01418 // Invalidate ::isAuthorized( ) cache, for now we are going 01419 // to modify the contents of the database which eventually could 01420 // lead to the cache inconsistancy. 01421 01422 invalidateCache( ); 01423 01424 // Check for the user rights to perform this operation. 01425 01426 if( ! isSystemManager( theDomain, BdbDomain::userName( ))) { 01427 error( theDomain, "No privileges for this operation." ); 01428 return result; 01429 } 01430 01431 // This operation is not allowed for the default group. 01432 01433 if( 0 == strcmp( "Global", theGroupName )) { 01434 error( theDomain, "The operation is not allowed for the default group." ); 01435 return result; 01436 } 01437 // Try to find this user in the database. 01438 01439 theUserH = theRegH->getUser( theUserName ); 01440 if( BdbIsNull( theUserH )) { 01441 error( theDomain, "User does not exist." ); 01442 return result; 01443 } 01444 01445 // Try to find the group in the database. 01446 01447 theGroupH = theRegH->getGroup( theGroupName ); 01448 if( BdbIsNull( theGroupH )) { 01449 error( theDomain, "Group does not exist." ); 01450 return result; 01451 } 01452 01453 // Add/remove user as a manager of the group. 01454 01455 if( onOff ) { 01456 status = theGroupH->addManager( theUserH ); 01457 } else { 01458 status = theGroupH->removeManager( theUserH ); 01459 } 01460 if( BdbcSuccess != status ) { 01461 error( theDomain, "Unable to add/remove user as a group manager." ); 01462 return result; 01463 } 01464 01465 return true; 01466 } 01467 01468 ////////////////////////////////// 01469 // Short transaction management // 01470 ////////////////////////////////// 01471 01472 d_Boolean 01473 BdbAuthFederation::startShortReadTransaction( ) 01474 { 01475 // Avoid using short transactions if it's not required. 01476 01477 if( _shortTransactionIsDisabled ) return true; 01478 01479 // We allow one more level of nested transactions only. 01480 01481 if( _shortTransactionIsActive ) { 01482 error( BdbDomain::IllegalDomain, "Short transaction is already active. Internal bug." ); 01483 return false; 01484 } 01485 01486 // Start a transaction in another context. 01487 01488 BdbApplicationOrDomain* theApp = BdbApplicationOrDomain::activeInstance( ); 01489 BdbStatus status; 01490 01491 status = theApp->startNestedRead( ); 01492 if( BdbcSuccess != status ) { 01493 error( BdbDomain::IllegalDomain, "Failed to start nested transaction." ); 01494 return false; 01495 } 01496 _shortTransactionIsActive = true; 01497 01498 return true; 01499 } 01500 01501 d_Boolean 01502 BdbAuthFederation::commitShortTransaction( ) 01503 { 01504 // Avoid using short transactions if it's not required. 01505 01506 if( _shortTransactionIsDisabled ) return true; 01507 01508 // We allow one more level of nested transactions only. At this point this transaction 01509 // should be actiaved. 01510 01511 if( ! _shortTransactionIsActive ) { 01512 error( BdbDomain::IllegalDomain, "Short transaction is not active. Internal bug." ); 01513 return false; 01514 } 01515 01516 // Commit current transaction. 01517 01518 BdbApplicationOrDomain* theApp = BdbApplicationOrDomain::activeInstance( ); 01519 BdbStatus status; 01520 01521 status = theApp->commitNested( ); 01522 if( BdbcSuccess != status ) { 01523 error( BdbDomain::IllegalDomain, "Failed to commit nested transaction." ); 01524 return false; 01525 } 01526 _shortTransactionIsActive = false; 01527 01528 // Done. 01529 01530 return true; 01531 } 01532 01533 /////////////////////////////////////// 01534 // ::isAuthorized( ) cache management // 01535 /////////////////////////////////////// 01536 01537 bool 01538 BdbAuthFederation::tryCache( BdbDomain::Domains theDomain, 01539 BdbDomain::AuthLevels theAuthLevel, 01540 const char* theAuthName, 01541 const char* theUserName, 01542 d_Boolean& isAuthorizedFlag ) 01543 { 01544 // The cache is always empty if caching is disabled. 01545 01546 if( _cachingIsDisabled ) return false; 01547 if( 0 == _cache ) return false; 01548 01549 return _cache->tryCache( theDomain, 01550 theAuthLevel, 01551 theAuthName, 01552 theUserName, 01553 isAuthorizedFlag ); 01554 } 01555 01556 void 01557 BdbAuthFederation::updateCache( BdbDomain::Domains theDomain, 01558 BdbDomain::AuthLevels theAuthLevel, 01559 const char* theAuthName, 01560 const char* theUserName, 01561 d_Boolean isAuthorizedFlag ) 01562 { 01563 // The cache is never updated if caching is disabled. 01564 01565 if( _cachingIsDisabled ) return; 01566 if( 0 == _cache ) _cache = new BdbAuthCache( ); 01567 01568 _cache->updateCache( theDomain, 01569 theAuthLevel, 01570 theAuthName, 01571 theUserName, 01572 isAuthorizedFlag ); 01573 01574 // Update statistics. 01575 01576 _statMon->increment_reloadCache( ); 01577 } 01578 01579 void 01580 BdbAuthFederation::invalidateCache( ) 01581 { 01582 // The cache is never touched if caching is disabled. 01583 01584 if( _cachingIsDisabled ) return; 01585 01586 delete _cache; 01587 _cache = 0; 01588 } 01589 01590 bool 01591 BdbAuthFederation::populateCache( bool transactionIsAvailable ) 01592 { 01593 // NOTE: The cache is never touched if caching is disabled 01594 // or if it's already loaded. 01595 01596 if( _cachingIsDisabled ) return true; 01597 if( 0 != _cache ) return true; 01598 01599 // Do cache loading in a kind of exception loop to provide the flawless 01600 // transaction management logic (if the one is needed) and cleanup seqeunce 01601 // if the loading will fail. 01602 01603 bool failed = false; 01604 01605 if( ! transactionIsAvailable ) { 01606 if( ! startShortReadTransaction( )) return false; 01607 } 01608 _cache = new BdbAuthCache( ); 01609 01610 while( true ) { 01611 01612 // Use handles for better efficiency. 01613 01614 BdbHandle(BdbAuthRegistry) theRegH; 01615 BdbHandle(BdbAuthGroup) theGroupH; 01616 BdbHandle(BdbAuthUser) theUserH; 01617 01618 const char* theUserName = BdbDomain::userName( ); 01619 const char* theGroupName; 01620 01621 for( int theDomain = BdbDomain::FirstDomain; 01622 theDomain < BdbDomain::IllegalDomain; 01623 theDomain++ ) { 01624 01625 // Just ignore non-initialized domain. There will be no information 01626 // in the cache about this domain. 01627 01628 theRegH = _registry[ theDomain - BdbDomain::FirstDomain ]; 01629 if( BdbIsNull( theRegH )) continue; 01630 01631 // Just ignore non-existing user. There will be no information 01632 // in the cache about this domain. 01633 01634 theUserH = theRegH->getUser( theUserName ); 01635 if( BdbIsNull( theUserH )) continue; 01636 01637 // System 01638 01639 d_Boolean resultForSystem = theUserH->isSystemManager( ); 01640 01641 updateCache( static_cast<BdbDomain::Domains>( theDomain ), 01642 BdbDomain::System, 01643 0, 01644 theUserName, 01645 resultForSystem ); 01646 01647 // Group 01648 // 01649 // NOTE: If a user is a System Manager then he/she is authorized 01650 // for all the known groups, if not then only for those 01651 // ones he/she is explicitly registered in. 01652 01653 BdbItr(BdbAuthGroup) theItr; 01654 01655 if( resultForSystem ) { 01656 theRegH->setGroupsItr( theItr ); 01657 } else { 01658 theUserH->setGroupsItr( theItr ); 01659 } 01660 while( theItr.next( )) { 01661 01662 theGroupH = (const BdbHandle(BdbAuthGroup)&) theItr; 01663 if( BdbIsNull( theGroupH )) { 01664 BdbAuthFederation::error( static_cast<BdbDomain::Domains>( theDomain ), "Inconsistency in the Authorization database." ); 01665 failed = true; 01666 break; 01667 } 01668 updateCache( static_cast<BdbDomain::Domains>( theDomain ), 01669 BdbDomain::Group, 01670 theGroupH->getName( ), 01671 theUserName, 01672 d_True ); 01673 } 01674 if( failed ) break; 01675 01676 // User 01677 // 01678 // NOTE: There is nothing to check - the user already exist. 01679 01680 updateCache( static_cast<BdbDomain::Domains>( theDomain ), 01681 BdbDomain::User, 01682 0, 01683 theUserName, 01684 d_True ); 01685 } 01686 break; 01687 } 01688 if( failed ) { 01689 invalidateCache( ); 01690 } 01691 if( ! transactionIsAvailable ) { 01692 commitShortTransaction( ); 01693 } 01694 01695 return ! failed; 01696 } 01697 01698 //////////////////////// 01699 // Messages reporting // 01700 //////////////////////// 01701 01702 void 01703 BdbAuthFederation::message( BdbDomain::Domains theDomain, 01704 const char* theMessage ) 01705 { 01706 cout << "BdbAuthFederation::message() " << theMessage << endl 01707 << " FEDERATION: " << _myName << endl 01708 << " DOMAIN: " << BdbDomain::domainName( theDomain ) << endl; 01709 } 01710 01711 void 01712 BdbAuthFederation::warning( BdbDomain::Domains theDomain, 01713 const char* theMessage ) 01714 { 01715 cout << "BdbAuthFederation::warning() " << theMessage << endl 01716 << " FEDERATION: " << _myName << endl 01717 << " DOMAIN: " << BdbDomain::domainName( theDomain ) << endl; 01718 } 01719 01720 void 01721 BdbAuthFederation::error( BdbDomain::Domains theDomain, 01722 const char* theMessage ) 01723 { 01724 cout << "BdbAuthFederation::error() " << theMessage << endl 01725 << " FEDERATION: " << _myName << endl 01726 << " DOMAIN: " << BdbDomain::domainName( theDomain ) << endl; 01727 } 01728 01729 void 01730 BdbAuthFederation::fatal( BdbDomain::Domains theDomain, 01731 const char* theMessage, 01732 int exitCode ) 01733 { 01734 cout << "BdbAuthFederation::fatal() " << theMessage << endl 01735 << " FEDERATION: " << _myName << endl 01736 << " DOMAIN: " << BdbDomain::domainName( theDomain ) << endl; 01737 01738 exit( exitCode ); 01739 } 01740 01741 ///////////////// 01742 // End Of File // 01743 /////////////////
BaBar Public Site | SLAC | News | Links | Who's Who | Contact Us
Page Owner: Jacek Becla
Last Update: October 04, 2002