multidldb.cpp
1 /* 2 * Copyright (c) 2000-2001,2011-2012,2014 Apple Inc. All Rights Reserved. 3 * 4 * The contents of this file constitute Original Code as defined in and are 5 * subject to the Apple Public Source License Version 1.2 (the 'License'). 6 * You may not use this file except in compliance with the License. Please obtain 7 * a copy of the License at http://www.apple.com/publicsource and read it before 8 * using this file. 9 * 10 * This Original Code and all software distributed under the License are 11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS 12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT 13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the 15 * specific language governing rights and limitations under the License. 16 */ 17 18 19 // 20 // MultiDLDb implementation. 21 // 22 23 #include <security_cdsa_client/multidldb.h> 24 #include <security_cdsa_client/securestorage.h> 25 26 27 28 namespace Security 29 { 30 31 using namespace CssmClient; 32 33 namespace CssmClient 34 { 35 36 // 37 // MultiDLDbDbCursorImpl declaration 38 // 39 class MultiDLDbDbCursorImpl : public DbCursorImpl 40 { 41 public: 42 MultiDLDbDbCursorImpl(const MultiDLDb &parent, const CSSM_QUERY &query, Allocator &allocator); 43 MultiDLDbDbCursorImpl(const MultiDLDb &parent, uint32 capacity, Allocator &allocator); 44 virtual ~MultiDLDbDbCursorImpl(); 45 46 bool next(DbAttributes *attributes, ::CssmDataContainer *data, DbUniqueRecord &uniqueId); 47 private: 48 MultiDLDb multiDLDb() { return parent<MultiDLDb>(); } 49 void activate(); 50 void deactivate(); 51 52 MultiDLDbImpl::ListRef mListRef; 53 MultiDLDbImpl::List::const_iterator mNext; 54 MultiDLDbImpl::List::const_iterator mEnd; 55 DbCursor mCursor; 56 }; 57 58 } // end namespace CssmClient 59 60 } // end namespace Security 61 62 // 63 // MultiDLDbImpl 64 // 65 MultiDLDbImpl::MultiDLDbImpl(const vector<DLDbIdentifier> &list, bool useSecureStorage, const Cssm &cssm) 66 : ObjectImpl(cssm), mListRef(list), mUseSecureStorage(useSecureStorage) 67 { 68 } 69 70 MultiDLDbImpl::MultiDLDbImpl(const vector<DLDbIdentifier> &list, bool useSecureStorage) 71 : ObjectImpl(Cssm::standard()), mListRef(list), mUseSecureStorage(useSecureStorage) 72 { 73 } 74 75 MultiDLDbImpl::~MultiDLDbImpl() 76 { 77 deactivate(); 78 } 79 80 Db 81 MultiDLDbImpl::database(const DLDbIdentifier &dlDbIdentifier) 82 { 83 StLock<Mutex> _(mLock); 84 DbMap::const_iterator it = mDbMap.find(dlDbIdentifier); 85 if (it != mDbMap.end()) 86 return it->second; 87 88 Module module(dlDbIdentifier.ssuid().guid(), cssm()); 89 DL dl; 90 if (dlDbIdentifier.ssuid().subserviceType() & CSSM_SERVICE_CSP) 91 { 92 if (mUseSecureStorage) 93 dl = SSCSPDL(module); 94 else 95 dl = CSPDL(module); 96 } 97 else 98 dl = DL(module); 99 100 dl->subserviceId(dlDbIdentifier.ssuid().subserviceId()); 101 dl->version(dlDbIdentifier.ssuid().version()); 102 Db db(dl, dlDbIdentifier.dbName()); 103 if (find(mListRef->begin(), mListRef->end(), dlDbIdentifier) != mListRef->end()) 104 mDbMap.insert(DbMap::value_type(dlDbIdentifier, db)); 105 106 return db; 107 } 108 109 void 110 MultiDLDbImpl::list(const vector<DLDbIdentifier> &list) 111 { 112 StLock<Mutex> _(mLock); 113 set<DLDbIdentifier> oldList(mListRef->begin(), mListRef->end()); 114 mListRef = ListRef(list); 115 set<DLDbIdentifier> newList(mListRef->begin(), mListRef->end()); 116 vector<DLDbIdentifier> obsolete; 117 back_insert_iterator<vector<DLDbIdentifier> > ii(obsolete); 118 // Remove all db's from the map that were in oldList but are not in mListRef. 119 set_difference(oldList.begin(), oldList.end(), newList.begin(), newList.end(), ii); 120 for (vector<DLDbIdentifier>::const_iterator it = obsolete.begin(); it != obsolete.end(); ++it) 121 mDbMap.erase(*it); 122 } 123 124 DbCursorImpl * 125 MultiDLDbImpl::newDbCursor(const CSSM_QUERY &query, Allocator &allocator) 126 { 127 return new MultiDLDbDbCursorImpl(MultiDLDb(this), query, allocator); 128 } 129 130 DbCursorImpl * 131 MultiDLDbImpl::newDbCursor(uint32 capacity, Allocator &allocator) 132 { 133 return new MultiDLDbDbCursorImpl(MultiDLDb(this), capacity, allocator); 134 } 135 136 void 137 MultiDLDbImpl::activate() 138 { 139 } 140 141 void 142 MultiDLDbImpl::deactivate() 143 { 144 StLock<Mutex> _(mLock); 145 mDbMap.erase(mDbMap.begin(), mDbMap.end()); 146 } 147 148 149 // 150 // MultiDLDbDbCursorImpl 151 // 152 MultiDLDbDbCursorImpl::MultiDLDbDbCursorImpl(const MultiDLDb &parent, 153 const CSSM_QUERY &query, Allocator &allocator) 154 : DbCursorImpl(parent, query, allocator) 155 { 156 } 157 158 MultiDLDbDbCursorImpl::MultiDLDbDbCursorImpl(const MultiDLDb &parent, 159 uint32 capacity, Allocator &allocator) 160 : DbCursorImpl(parent, capacity, allocator) 161 { 162 } 163 164 MultiDLDbDbCursorImpl::~MultiDLDbDbCursorImpl() 165 { 166 try 167 { 168 deactivate(); 169 } 170 catch(...) {} 171 } 172 173 bool 174 MultiDLDbDbCursorImpl::next(DbAttributes *attributes, ::CssmDataContainer *data, DbUniqueRecord &uniqueId) 175 { 176 activate(); 177 for (;;) 178 { 179 if (!mCursor) 180 { 181 if (mNext == mEnd) 182 { 183 // This is how it ends. 184 deactivate(); 185 return false; 186 } 187 188 mCursor = DbCursor(multiDLDb()->database(*mNext++), *this); 189 } 190 191 try 192 { 193 if (mCursor->next(attributes, data, uniqueId)) 194 return true; 195 } 196 197 catch(const CommonError &err) 198 { 199 OSStatus status = err.osStatus(); 200 if(status != CSSMERR_DL_DATASTORE_DOESNOT_EXIST) 201 throw; 202 } 203 204 205 206 mCursor = DbCursor(); 207 } 208 } 209 210 void 211 MultiDLDbDbCursorImpl::activate() 212 { 213 StLock<Mutex> _(mActivateMutex); 214 if (!mActive) 215 { 216 mListRef = multiDLDb()->listRef(); 217 mNext = mListRef->begin(); 218 mEnd = mListRef->end(); 219 mActive = true; 220 } 221 } 222 223 void 224 MultiDLDbDbCursorImpl::deactivate() 225 { 226 StLock<Mutex> _(mActivateMutex); 227 if (mActive) 228 { 229 mActive = false; 230 mListRef = MultiDLDbImpl::ListRef(); 231 mNext = mEnd; 232 mCursor = DbCursor(); 233 } 234 } 235