]> git.saurik.com Git - apple/security.git/blob - Security/libsecurity_cdsa_client/lib/multidldb.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / Security / libsecurity_cdsa_client / lib / 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