2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
20 // dlclient - client interface to CSSM DLs and their operations
22 #include <Security/dlclient.h>
23 #include <Security/aclclient.h>
24 #include <Security/ssclient.h>
26 using namespace CssmClient
;
30 // Manage DL attachments
32 DLImpl::DLImpl(const Guid
&guid
) : AttachmentImpl(guid
, CSSM_SERVICE_DL
)
36 DLImpl::DLImpl(const Module
&module) : AttachmentImpl(module, CSSM_SERVICE_DL
)
45 DLImpl::getDbNames(char **)
47 CssmError::throwMe(CSSMERR_DL_FUNCTION_NOT_IMPLEMENTED
);
51 DLImpl::freeNameList(char **)
53 CssmError::throwMe(CSSMERR_DL_FUNCTION_NOT_IMPLEMENTED
);
57 DLImpl::newDb(const char *inDbName
, const CSSM_NET_ADDRESS
*inDbLocation
)
59 return new DbImpl(DL(this), inDbName
, inDbLocation
);
66 DbImpl::DbImpl(const DL
&dl
, const char *inDbName
, const CSSM_NET_ADDRESS
*inDbLocation
)
67 : ObjectImpl(dl
), mDbName(inDbName
, inDbLocation
),
68 mAccessRequest(CSSM_DB_ACCESS_READ
), mAccessCredentials(NULL
),
69 mOpenParameters(NULL
), mDbInfo(NULL
), mResourceControlContext(NULL
)
87 assert(mDbInfo
== nil
);
88 mHandle
.DLHandle
= dl()->handle();
89 check(CSSM_DL_DbOpen(mHandle
.DLHandle
, name(), dbLocation(),
90 mAccessRequest
, mAccessCredentials
,
91 mOpenParameters
, &mHandle
.DBHandle
));
100 CssmError::throwMe(CSSMERR_DL_DATASTORE_ALREADY_EXISTS
);
102 if (mDbInfo
== nil
) {
103 // handle a missing (null) mDbInfo as an all-zero one
104 static const CSSM_DBINFO nullDbInfo
= { };
105 mDbInfo
= &nullDbInfo
;
107 mHandle
.DLHandle
= dl()->handle();
109 if (!mResourceControlContext
&& mAccessCredentials
) {
110 AclFactory::AnyResourceContext
ctx(mAccessCredentials
);
111 check(CSSM_DL_DbCreate(mHandle
.DLHandle
, name(), dbLocation(), mDbInfo
,
112 mAccessRequest
, &ctx
,
113 mOpenParameters
, &mHandle
.DBHandle
));
115 check(CSSM_DL_DbCreate(mHandle
.DLHandle
, name(), dbLocation(), mDbInfo
,
116 mAccessRequest
, mResourceControlContext
,
117 mOpenParameters
, &mHandle
.DBHandle
));
125 check(CSSM_DL_DbClose(mHandle
));
153 // Deactivate so the db gets closed if it was open.
155 // This call does not require the receiver to be active.
156 check(CSSM_DL_DbDelete(dl()->handle(), name(), dbLocation(),
157 mAccessCredentials
));
161 DbImpl::rename(const char *newName
)
163 // Deactivate so the db gets closed if it was open.
165 if (::rename(name(), newName
))
166 UnixError::throwMe(errno
);
168 // Change our DbName to reflect this rename.
169 mDbName
= DbName(newName
, mDbName
.dbLocation());
173 DbImpl::authenticate(CSSM_DB_ACCESS_TYPE inAccessRequest
,
174 const CSSM_ACCESS_CREDENTIALS
*inAccessCredentials
)
178 // XXX Could do the same for create but this would require sticking
179 // inAccessCredentials into mResourceControlContext.
182 // We were not yet active. Just do an open.
183 accessRequest(inAccessRequest
);
184 accessCredentials(inAccessCredentials
);
190 check(CSSM_DL_Authenticate(handle(), inAccessRequest
, inAccessCredentials
));
194 DbImpl::name(char *&outDbName
)
196 check(CSSM_DL_GetDbNameFromHandle(handle(), &outDbName
));
200 DbImpl::createRelation(CSSM_DB_RECORDTYPE inRelationID
,
201 const char *inRelationName
,
202 uint32 inNumberOfAttributes
,
203 const CSSM_DB_SCHEMA_ATTRIBUTE_INFO
*pAttributeInfo
,
204 uint32 inNumberOfIndexes
,
205 const CSSM_DB_SCHEMA_INDEX_INFO
*pIndexInfo
)
207 check(CSSM_DL_CreateRelation(handle(), inRelationID
, inRelationName
,
208 inNumberOfAttributes
, pAttributeInfo
,
209 inNumberOfIndexes
, pIndexInfo
));
213 DbImpl::destroyRelation(CSSM_DB_RECORDTYPE inRelationID
)
215 check(CSSM_DL_DestroyRelation(handle(), inRelationID
));
219 DbImpl::insert(CSSM_DB_RECORDTYPE recordType
, const CSSM_DB_RECORD_ATTRIBUTE_DATA
*attributes
,
220 const CSSM_DATA
*data
)
222 DbUniqueRecord
uniqueId(Db(this));
223 check(CSSM_DL_DataInsert(handle(), recordType
,
226 // Activate uniqueId so CSSM_DL_FreeUniqueRecord() gets called when it goes out of scope.
227 uniqueId
->activate();
233 // Generic Passthrough interface
235 void DbImpl::passThrough(uint32 passThroughId
, const void *in
, void **out
)
237 check(CSSM_DL_PassThrough(handle(), passThroughId
, in
, out
));
242 // Passthrough functions (only implemented by AppleCSPDL).
247 check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_LOCK
, NULL
, NULL
));
253 check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_UNLOCK
, NULL
, NULL
));
257 DbImpl::unlock(const CSSM_DATA
&password
)
259 check(CSSM_DL_PassThrough(handle(), CSSM_APPLECSPDL_DB_UNLOCK
, &password
, NULL
));
263 DbImpl::getSettings(uint32
&outIdleTimeout
, bool &outLockOnSleep
)
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
);
274 DbImpl::setSettings(uint32 inIdleTimeout
, bool inLockOnSleep
)
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
));
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 **>(¶ms
)));
288 bool isLocked
= params
->isLocked
;
289 allocator().free(params
);
294 DbImpl::changePassphrase(const CSSM_ACCESS_CREDENTIALS
*cred
)
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
, ¶ms
, NULL
));
302 DbImpl::getUnlockKeyIndex(CssmData
&index
)
305 SecurityServer::DbHandle dbHandle
;
306 if (CSSM_DL_PassThrough(handle(),
307 CSSM_APPLECSPDL_DB_GET_HANDLE
, NULL
, (void **)&dbHandle
))
308 return false; // can't get index
309 SecurityServer::ClientSession
ss(allocator(), allocator());
310 ss
.getDbSuggestedIndex(dbHandle
, index
);
312 } catch (const CssmError
&error
) {
313 if (error
.cssmError() == CSSMERR_DL_DATASTORE_DOESNOT_EXIST
)
324 DbImpl::newDbCursor(const CSSM_QUERY
&query
, CssmAllocator
&allocator
)
326 return new DbDbCursorImpl(Db(this), query
, allocator
);
330 DbImpl::newDbCursor(uint32 capacity
, CssmAllocator
&allocator
)
332 return new DbDbCursorImpl(Db(this), capacity
, allocator
);
336 // DbUniqueRecordMaker
339 DbImpl::newDbUniqueRecord()
341 return new DbUniqueRecordImpl(Db(this));
349 DbImpl::dlDbIdentifier() const
351 return DLDbIdentifier(dl()->subserviceUid(), name(), dbLocation());
358 DbDbCursorImpl::DbDbCursorImpl(const Db
&db
, const CSSM_QUERY
&query
, CssmAllocator
&allocator
)
359 : DbCursorImpl(db
, query
, allocator
), mResultsHandle(CSSM_INVALID_HANDLE
)
363 DbDbCursorImpl::DbDbCursorImpl(const Db
&db
, uint32 capacity
, CssmAllocator
&allocator
)
364 : DbCursorImpl(db
, capacity
, allocator
), mResultsHandle(CSSM_INVALID_HANDLE
)
368 DbDbCursorImpl::~DbDbCursorImpl()
378 DbDbCursorImpl::next(DbAttributes
*attributes
, ::CssmDataContainer
*data
, DbUniqueRecord
&uniqueId
)
381 attributes
->deleteValues();
388 DbUniqueRecord
unique(db
);
391 result
= CSSM_DL_DataGetFirst(db
->handle(),
397 if (result
== CSSM_OK
)
399 else if (data
!= NULL
)
404 result
= CSSM_DL_DataGetNext(db
->handle(),
410 if (result
!= CSSM_OK
&& data
!= NULL
)
416 if (result
== CSSMERR_DL_ENDOFDATA
)
424 // Activate uniqueId so CSSM_DL_FreeUniqueRecord() gets called when it goes out of scope.
431 DbDbCursorImpl::activate()
436 DbDbCursorImpl::deactivate()
441 check(CSSM_DL_DataAbortQuery(database()->handle(), mResultsHandle
));
449 DbCursorImpl::DbCursorImpl(const Object
&parent
, const CSSM_QUERY
&query
, CssmAllocator
&allocator
) :
450 ObjectImpl(parent
), CssmAutoQuery(query
, allocator
)
454 DbCursorImpl::DbCursorImpl(const Object
&parent
, uint32 capacity
, CssmAllocator
&allocator
) :
455 ObjectImpl(parent
), CssmAutoQuery(capacity
, allocator
)
460 DbCursorImpl::allocator() const
462 return ObjectImpl::allocator();
466 DbCursorImpl::allocator(CssmAllocator
&alloc
)
468 ObjectImpl::allocator(alloc
);
475 DbUniqueRecordImpl::DbUniqueRecordImpl(const Db
&db
) : ObjectImpl(db
)
479 DbUniqueRecordImpl::~DbUniqueRecordImpl()
489 DbUniqueRecordImpl::deleteRecord()
491 check(CSSM_DL_DataDelete(database()->handle(), mUniqueId
));
495 DbUniqueRecordImpl::modify(CSSM_DB_RECORDTYPE recordType
,
496 const CSSM_DB_RECORD_ATTRIBUTE_DATA
*attributes
,
497 const CSSM_DATA
*data
,
498 CSSM_DB_MODIFY_MODE modifyMode
)
500 check(CSSM_DL_DataModify(database()->handle(), recordType
, mUniqueId
,
506 DbUniqueRecordImpl::get(DbAttributes
*attributes
,
507 ::CssmDataContainer
*data
)
510 attributes
->deleteValues();
515 // @@@ Fix the allocators for attributes and data.
517 result
= CSSM_DL_DataGetFromUniqueRecordId(database()->handle(), mUniqueId
,
521 if (result
!= CSSM_OK
&& data
!= NULL
) // the data returned is no longer valid
530 DbUniqueRecordImpl::activate()
536 DbUniqueRecordImpl::deactivate()
541 check(CSSM_DL_FreeUniqueRecord(database()->handle(), mUniqueId
));
549 DbAttributes::DbAttributes()
550 : CssmAutoDbRecordAttributeData(0, CssmAllocator::standard(), CssmAllocator::standard())
554 DbAttributes::DbAttributes(const Db
&db
, uint32 capacity
, CssmAllocator
&allocator
)
555 : CssmAutoDbRecordAttributeData(capacity
, db
->allocator(), allocator
)