]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_client/dlclient.cpp
Security-54.1.tar.gz
[apple/security.git] / cdsa / cdsa_client / dlclient.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 // dlclient - client interface to CSSM DLs and their operations
21 //
22 #include <Security/dlclient.h>
23
24 using namespace CssmClient;
25
26
27 //
28 // Manage DL attachments
29 //
30 DLImpl::DLImpl(const Guid &guid) : AttachmentImpl(guid, CSSM_SERVICE_DL)
31 {
32 }
33
34 DLImpl::DLImpl(const Module &module) : AttachmentImpl(module, CSSM_SERVICE_DL)
35 {
36 }
37
38 DLImpl::~DLImpl()
39 {
40 }
41
42 void
43 DLImpl::getDbNames(char **)
44 {
45 CssmError::throwMe(CSSMERR_DL_FUNCTION_NOT_IMPLEMENTED);
46 }
47
48 void
49 DLImpl::freeNameList(char **)
50 {
51 CssmError::throwMe(CSSMERR_DL_FUNCTION_NOT_IMPLEMENTED);
52 }
53
54 DbImpl *
55 DLImpl::newDb(const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation)
56 {
57 return new DbImpl(DL(this), inDbName, inDbLocation);
58 }
59
60
61 //
62 // Db (database)
63 //
64 DbImpl::DbImpl(const DL &dl, const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation)
65 : ObjectImpl(dl), mDbName(inDbName, inDbLocation),
66 mAccessRequest(CSSM_DB_ACCESS_READ), mAccessCredentials(NULL),
67 mOpenParameters(NULL), mDbInfo(NULL), mResourceControlContext(NULL)
68 {
69 }
70
71 DbImpl::~DbImpl()
72 {
73 try
74 {
75 deactivate();
76 }
77 catch(...) {}
78 }
79
80 void
81 DbImpl::open()
82 {
83 if (!mActive)
84 {
85 assert(mDbInfo == nil);
86 mHandle.DLHandle = dl()->handle();
87 check(CSSM_DL_DbOpen(mHandle.DLHandle, name(), dbLocation(),
88 mAccessRequest, mAccessCredentials,
89 mOpenParameters, &mHandle.DBHandle));
90 mActive = true;
91 }
92 }
93
94 void
95 DbImpl::create()
96 {
97 if (mActive)
98 CssmError::throwMe(CSSMERR_DL_DATASTORE_ALREADY_EXISTS);
99
100 assert(mDbInfo != nil);
101 mHandle.DLHandle = dl()->handle();
102 check(CSSM_DL_DbCreate(mHandle.DLHandle, name(), dbLocation(), mDbInfo,
103 mAccessRequest, mResourceControlContext,
104 mOpenParameters, &mHandle.DBHandle));
105 mActive = true;
106 }
107
108 void
109 DbImpl::close()
110 {
111 check(CSSM_DL_DbClose(mHandle));
112 }
113
114 void
115 DbImpl::activate()
116 {
117 if (!mActive)
118 {
119 if (mDbInfo)
120 create();
121 else
122 open();
123 }
124 }
125
126 void
127 DbImpl::deactivate()
128 {
129 if (mActive)
130 {
131 mActive = false;
132 close();
133 }
134 }
135
136 void
137 DbImpl::deleteDb()
138 {
139 // Deactivate so the db gets closed if it was open.
140 deactivate();
141 // This call does not require the receiver to be active.
142 check(CSSM_DL_DbDelete(dl()->handle(), name(), dbLocation(),
143 mAccessCredentials));
144 }
145
146 void
147 DbImpl::authenticate(CSSM_DB_ACCESS_TYPE inAccessRequest,
148 const CSSM_ACCESS_CREDENTIALS *inAccessCredentials)
149 {
150 if (!mActive)
151 {
152 // XXX Could do the same for create but this would require sticking
153 // inAccessCredentials into mResourceControlContext.
154 if (!mDbInfo)
155 {
156 // We were not yet active. Just do an open.
157 accessRequest(inAccessRequest);
158 accessCredentials(inAccessCredentials);
159 activate();
160 return;
161 }
162 }
163
164 check(CSSM_DL_Authenticate(handle(), inAccessRequest, inAccessCredentials));
165 }
166
167 void
168 DbImpl::name(char *&outDbName)
169 {
170 check(CSSM_DL_GetDbNameFromHandle(handle(), &outDbName));
171 }
172
173 void
174 DbImpl::createRelation(CSSM_DB_RECORDTYPE inRelationID,
175 const char *inRelationName,
176 uint32 inNumberOfAttributes,
177 const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *pAttributeInfo,
178 uint32 inNumberOfIndexes,
179 const CSSM_DB_SCHEMA_INDEX_INFO *pIndexInfo)
180 {
181 check(CSSM_DL_CreateRelation(handle(), inRelationID, inRelationName,
182 inNumberOfAttributes, pAttributeInfo,
183 inNumberOfIndexes, pIndexInfo));
184 }
185
186 void
187 DbImpl::destroyRelation(CSSM_DB_RECORDTYPE inRelationID)
188 {
189 check(CSSM_DL_DestroyRelation(handle(), inRelationID));
190 }
191
192 DbUniqueRecord
193 DbImpl::insert(CSSM_DB_RECORDTYPE recordType, const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
194 const CSSM_DATA *data)
195 {
196 DbUniqueRecord uniqueId(Db(this));
197 check(CSSM_DL_DataInsert(handle(), recordType,
198 attributes,
199 data, uniqueId));
200 // Activate uniqueId so CSSM_DL_FreeUniqueRecord() gets called when it goes out of scope.
201 uniqueId->activate();
202 return uniqueId;
203 }
204
205 #if 0
206 // @@@ These methods have been moved to DbUniqueRecord.
207 void
208 DbImpl::deleteRecord(const DbUniqueRecord &uniqueId)
209 {
210 check(CSSM_DL_DataDelete(handle(), uniqueId));
211 }
212
213 void
214 DbImpl::modify(CSSM_DB_RECORDTYPE recordType, DbUniqueRecord &uniqueId,
215 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
216 const CSSM_DATA *data,
217 CSSM_DB_MODIFY_MODE modifyMode)
218 {
219 check(CSSM_DL_DataModify(handle(), recordType, uniqueId,
220 attributes,
221 data, modifyMode));
222 }
223
224 void
225 DbImpl::get(const DbUniqueRecord &uniqueId, DbAttributes *attributes,
226 ::CssmDataContainer *data)
227 {
228 if (attributes)
229 attributes->deleteValues();
230
231 if (data)
232 data->clear();
233
234 // @@@ Fix the const_cast here.
235 check(CSSM_DL_DataGetFromUniqueRecordId(handle(), uniqueId,
236 attributes,
237 data));
238 }
239 #endif
240
241 //
242 // Passthrough functions (only implemented by AppleCSPDL).
243 //
244 void
245 DbImpl::lock()
246 {
247 check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_LOCK, NULL, NULL));
248 }
249
250 void
251 DbImpl::unlock()
252 {
253 check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_UNLOCK, NULL, NULL));
254 }
255
256 void
257 DbImpl::unlock(const CSSM_DATA &password)
258 {
259 check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_UNLOCK, &password, NULL));
260 }
261
262 void
263 DbImpl::getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep)
264 {
265 CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS_PTR settings;
266 check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_GET_SETTINGS,
267 NULL, reinterpret_cast<void **>(&settings)));
268 outIdleTimeout = settings->idleTimeout;
269 outLockOnSleep = settings->lockOnSleep;
270 allocator().free(settings);
271 }
272
273 void
274 DbImpl::setSettings(uint32 inIdleTimeout, bool inLockOnSleep)
275 {
276 CSSM_APPLECSPDL_DB_SETTINGS_PARAMETERS settings;
277 settings.idleTimeout = inIdleTimeout;
278 settings.lockOnSleep = inLockOnSleep;
279 check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_SET_SETTINGS, &settings, NULL));
280 }
281
282 bool
283 DbImpl::isLocked()
284 {
285 CSSM_APPLECSPDL_DB_IS_LOCKED_PARAMETERS_PTR params;
286 check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_IS_LOCKED,
287 NULL, reinterpret_cast<void **>(&params)));
288 bool isLocked = params->isLocked;
289 allocator().free(params);
290 return isLocked;
291 }
292
293 void
294 DbImpl::changePassphrase(const CSSM_ACCESS_CREDENTIALS *cred)
295 {
296 CSSM_APPLECSPDL_DB_CHANGE_PASSWORD_PARAMETERS params;
297 params.accessCredentials = const_cast<CSSM_ACCESS_CREDENTIALS *>(cred);
298 check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_CHANGE_PASSWORD, &params, NULL));
299 }
300
301
302 //
303 // DbCursorMaker
304 //
305 DbCursorImpl *
306 DbImpl::newDbCursor(const CSSM_QUERY &query, CssmAllocator &allocator)
307 {
308 return new DbDbCursorImpl(Db(this), query, allocator);
309 }
310
311 DbCursorImpl *
312 DbImpl::newDbCursor(uint32 capacity, CssmAllocator &allocator)
313 {
314 return new DbDbCursorImpl(Db(this), capacity, allocator);
315 }
316
317 //
318 // DbUniqueRecordMaker
319 //
320 DbUniqueRecordImpl *
321 DbImpl::newDbUniqueRecord()
322 {
323 return new DbUniqueRecordImpl(Db(this));
324 }
325
326
327 //
328 // Utility methods
329 //
330 DLDbIdentifier
331 DbImpl::dlDbIdentifier() const
332 {
333 return DLDbIdentifier(dl()->subserviceUid(), name(), dbLocation());
334 }
335
336
337 //
338 // DbDbCursorImpl
339 //
340 DbDbCursorImpl::DbDbCursorImpl(const Db &db, const CSSM_QUERY &query, CssmAllocator &allocator)
341 : DbCursorImpl(db, query, allocator), mResultsHandle(CSSM_INVALID_HANDLE)
342 {
343 }
344
345 DbDbCursorImpl::DbDbCursorImpl(const Db &db, uint32 capacity, CssmAllocator &allocator)
346 : DbCursorImpl(db, capacity, allocator), mResultsHandle(CSSM_INVALID_HANDLE)
347 {
348 }
349
350 DbDbCursorImpl::~DbDbCursorImpl()
351 {
352 try
353 {
354 deactivate();
355 }
356 catch(...) {}
357 }
358
359 bool
360 DbDbCursorImpl::next(DbAttributes *attributes, ::CssmDataContainer *data, DbUniqueRecord &uniqueId)
361 {
362 if (attributes)
363 attributes->deleteValues();
364
365 if (data)
366 data->clear();
367
368 CSSM_RETURN result;
369 Db db(database());
370 DbUniqueRecord unique(db);
371 if (!mActive)
372 {
373 result = CSSM_DL_DataGetFirst(db->handle(),
374 this,
375 &mResultsHandle,
376 attributes,
377 data,
378 unique);
379 if (result == CSSM_OK)
380 mActive = true;
381 }
382 else
383 {
384 result = CSSM_DL_DataGetNext(db->handle(),
385 mResultsHandle,
386 attributes,
387 data,
388 unique);
389 }
390
391 if (result == CSSMERR_DL_ENDOFDATA)
392 {
393 mActive = false;
394 return false;
395 }
396
397 check(result);
398
399 // Activate uniqueId so CSSM_DL_FreeUniqueRecord() gets called when it goes out of scope.
400 unique->activate();
401 uniqueId = unique;
402 return true;
403 }
404
405 void
406 DbDbCursorImpl::activate()
407 {
408 }
409
410 void
411 DbDbCursorImpl::deactivate()
412 {
413 if (mActive)
414 {
415 mActive = false;
416 check(CSSM_DL_DataAbortQuery(database()->handle(), mResultsHandle));
417 }
418 }
419
420
421 //
422 // DbCursorImpl
423 //
424 DbCursorImpl::DbCursorImpl(const Object &parent, const CSSM_QUERY &query, CssmAllocator &allocator) :
425 ObjectImpl(parent), CssmAutoQuery(query, allocator)
426 {
427 }
428
429 DbCursorImpl::DbCursorImpl(const Object &parent, uint32 capacity, CssmAllocator &allocator) :
430 ObjectImpl(parent), CssmAutoQuery(capacity, allocator)
431 {
432 }
433
434 CssmAllocator &
435 DbCursorImpl::allocator() const
436 {
437 return ObjectImpl::allocator();
438 }
439
440 void
441 DbCursorImpl::allocator(CssmAllocator &alloc)
442 {
443 ObjectImpl::allocator(alloc);
444 }
445
446
447 //
448 // DbUniqueRecord
449 //
450 DbUniqueRecordImpl::DbUniqueRecordImpl(const Db &db) : ObjectImpl(db)
451 {
452 }
453
454 DbUniqueRecordImpl::~DbUniqueRecordImpl()
455 {
456 try
457 {
458 deactivate();
459 }
460 catch(...) {}
461 }
462
463 void
464 DbUniqueRecordImpl::deleteRecord()
465 {
466 check(CSSM_DL_DataDelete(database()->handle(), mUniqueId));
467 }
468
469 void
470 DbUniqueRecordImpl::modify(CSSM_DB_RECORDTYPE recordType,
471 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
472 const CSSM_DATA *data,
473 CSSM_DB_MODIFY_MODE modifyMode)
474 {
475 check(CSSM_DL_DataModify(database()->handle(), recordType, mUniqueId,
476 attributes,
477 data, modifyMode));
478 }
479
480 void
481 DbUniqueRecordImpl::get(DbAttributes *attributes,
482 ::CssmDataContainer *data)
483 {
484 if (attributes)
485 attributes->deleteValues();
486
487 if (data)
488 data->clear();
489
490 // @@@ Fix the allocators for attributes and data.
491 check(CSSM_DL_DataGetFromUniqueRecordId(database()->handle(), mUniqueId,
492 attributes,
493 data));
494 }
495
496 void
497 DbUniqueRecordImpl::activate()
498 {
499 mActive = true;
500 }
501
502 void
503 DbUniqueRecordImpl::deactivate()
504 {
505 if (mActive)
506 {
507 mActive = false;
508 check(CSSM_DL_FreeUniqueRecord(database()->handle(), mUniqueId));
509 }
510 }
511
512
513 //
514 // DbAttributes
515 //
516 DbAttributes::DbAttributes()
517 : CssmAutoDbRecordAttributeData(0, CssmAllocator::standard(), CssmAllocator::standard())
518 {
519 }
520
521 DbAttributes::DbAttributes(const Db &db, uint32 capacity, CssmAllocator &allocator)
522 : CssmAutoDbRecordAttributeData(capacity, db->allocator(), allocator)
523 {
524 }