]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_client/multidldb.cpp
Security-179.tar.gz
[apple/security.git] / cdsa / cdsa_client / multidldb.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, 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/multidldb.h>
24 #include <Security/securestorage.h>
25 #include <Security/cssmerrno.h>
26
27
28
29 namespace Security
30 {
31
32 using namespace CssmClient;
33
34 namespace CssmClient
35 {
36
37 //
38 // MultiDLDbDbCursorImpl declaration
39 //
40 class MultiDLDbDbCursorImpl : public DbCursorImpl
41 {
42 public:
43 MultiDLDbDbCursorImpl(const MultiDLDb &parent, const CSSM_QUERY &query, CssmAllocator &allocator);
44 MultiDLDbDbCursorImpl(const MultiDLDb &parent, uint32 capacity, CssmAllocator &allocator);
45 virtual ~MultiDLDbDbCursorImpl();
46
47 bool next(DbAttributes *attributes, ::CssmDataContainer *data, DbUniqueRecord &uniqueId);
48 private:
49 MultiDLDb multiDLDb() { return parent<MultiDLDb>(); }
50 void activate();
51 void deactivate();
52
53 MultiDLDbImpl::ListRef mListRef;
54 MultiDLDbImpl::List::const_iterator mNext;
55 MultiDLDbImpl::List::const_iterator mEnd;
56 DbCursor mCursor;
57 };
58
59 } // end namespace CssmClient
60
61 } // end namespace Security
62
63 //
64 // MultiDLDbImpl
65 //
66 MultiDLDbImpl::MultiDLDbImpl(const vector<DLDbIdentifier> &list, bool useSecureStorage, const Cssm &cssm)
67 : ObjectImpl(cssm), mListRef(list), mUseSecureStorage(useSecureStorage)
68 {
69 }
70
71 MultiDLDbImpl::MultiDLDbImpl(const vector<DLDbIdentifier> &list, bool useSecureStorage)
72 : ObjectImpl(Cssm::standard()), mListRef(list), mUseSecureStorage(useSecureStorage)
73 {
74 }
75
76 MultiDLDbImpl::~MultiDLDbImpl()
77 {
78 deactivate();
79 }
80
81 Db
82 MultiDLDbImpl::database(const DLDbIdentifier &dlDbIdentifier)
83 {
84 StLock<Mutex> _(mLock);
85 DbMap::const_iterator it = mDbMap.find(dlDbIdentifier);
86 if (it != mDbMap.end())
87 return it->second;
88
89 Module module(dlDbIdentifier.ssuid().guid(), cssm());
90 DL dl;
91 if (dlDbIdentifier.ssuid().subserviceType() & CSSM_SERVICE_CSP)
92 {
93 if (mUseSecureStorage)
94 dl = SSCSPDL(module);
95 else
96 dl = CSPDL(module);
97 }
98 else
99 dl = DL(module);
100
101 dl->subserviceId(dlDbIdentifier.ssuid().subserviceId());
102 dl->version(dlDbIdentifier.ssuid().version());
103 Db db(dl, dlDbIdentifier.dbName());
104 if (find(mListRef->begin(), mListRef->end(), dlDbIdentifier) != mListRef->end())
105 mDbMap.insert(DbMap::value_type(dlDbIdentifier, db));
106
107 return db;
108 }
109
110 void
111 MultiDLDbImpl::list(const vector<DLDbIdentifier> &list)
112 {
113 StLock<Mutex> _(mLock);
114 set<DLDbIdentifier> oldList(mListRef->begin(), mListRef->end());
115 mListRef = ListRef(list);
116 set<DLDbIdentifier> newList(mListRef->begin(), mListRef->end());
117 vector<DLDbIdentifier> obsolete;
118 back_insert_iterator<vector<DLDbIdentifier> > ii(obsolete);
119 // Remove all db's from the map that were in oldList but are not in mListRef.
120 set_difference(oldList.begin(), oldList.end(), newList.begin(), newList.end(), ii);
121 for (vector<DLDbIdentifier>::const_iterator it = obsolete.begin(); it != obsolete.end(); ++it)
122 mDbMap.erase(*it);
123 }
124
125 DbCursorImpl *
126 MultiDLDbImpl::newDbCursor(const CSSM_QUERY &query, CssmAllocator &allocator)
127 {
128 return new MultiDLDbDbCursorImpl(MultiDLDb(this), query, allocator);
129 }
130
131 DbCursorImpl *
132 MultiDLDbImpl::newDbCursor(uint32 capacity, CssmAllocator &allocator)
133 {
134 return new MultiDLDbDbCursorImpl(MultiDLDb(this), capacity, allocator);
135 }
136
137 void
138 MultiDLDbImpl::activate()
139 {
140 }
141
142 void
143 MultiDLDbImpl::deactivate()
144 {
145 StLock<Mutex> _(mLock);
146 mDbMap.erase(mDbMap.begin(), mDbMap.end());
147 }
148
149
150 //
151 // MultiDLDbDbCursorImpl
152 //
153 MultiDLDbDbCursorImpl::MultiDLDbDbCursorImpl(const MultiDLDb &parent,
154 const CSSM_QUERY &query, CssmAllocator &allocator)
155 : DbCursorImpl(parent, query, allocator)
156 {
157 }
158
159 MultiDLDbDbCursorImpl::MultiDLDbDbCursorImpl(const MultiDLDb &parent,
160 uint32 capacity, CssmAllocator &allocator)
161 : DbCursorImpl(parent, capacity, allocator)
162 {
163 }
164
165 MultiDLDbDbCursorImpl::~MultiDLDbDbCursorImpl()
166 {
167 try
168 {
169 deactivate();
170 }
171 catch(...) {}
172 }
173
174 bool
175 MultiDLDbDbCursorImpl::next(DbAttributes *attributes, ::CssmDataContainer *data, DbUniqueRecord &uniqueId)
176 {
177 activate();
178 for (;;)
179 {
180 if (!mCursor)
181 {
182 if (mNext == mEnd)
183 {
184 // This is how it ends.
185 deactivate();
186 return false;
187 }
188
189 mCursor = DbCursor(multiDLDb()->database(*mNext++), *this);
190 }
191
192 try
193 {
194 if (mCursor->next(attributes, data, uniqueId))
195 return true;
196 }
197
198 catch(const CssmCommonError &err)
199 {
200 OSStatus status = err.osStatus();
201 if(status != CSSMERR_DL_DATASTORE_DOESNOT_EXIST)
202 throw;
203 }
204
205
206
207 mCursor = DbCursor();
208 }
209 }
210
211 void
212 MultiDLDbDbCursorImpl::activate()
213 {
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 if (mActive)
227 {
228 mActive = false;
229 mListRef = MultiDLDbImpl::ListRef();
230 mNext = mEnd;
231 mCursor = DbCursor();
232 }
233 }
234