]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 | 1 | /* |
d8f41ccd | 2 | * Copyright (c) 2000-2001,2011-2012,2014 Apple Inc. All Rights Reserved. |
b1ab9ed8 A |
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 | { | |
313fa17b | 213 | StLock<Mutex> _(mActivateMutex); |
b1ab9ed8 A |
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 | { | |
313fa17b | 226 | StLock<Mutex> _(mActivateMutex); |
b1ab9ed8 A |
227 | if (mActive) |
228 | { | |
229 | mActive = false; | |
230 | mListRef = MultiDLDbImpl::ListRef(); | |
231 | mNext = mEnd; | |
232 | mCursor = DbCursor(); | |
233 | } | |
234 | } | |
235 |