1/* 2 * Copyright (c) 2000-2004 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// mdsclient - friendly interface to CDSA MDS API 21// 22#include <security_cdsa_client/mdsclient.h> 23#include <Security/mdspriv.h> 24 25 26namespace Security { 27namespace MDSClient { 28 29 30// 31// The MDS access object singleton 32// 33ModuleNexus<Directory> mds; 34 35 36// 37// Directory construction initializes MDS and opens the "CDSA" database 38// 39Directory::Directory() 40 : mMemoryFunctions(Allocator::standard()) 41{ 42 StLock<Mutex> _(mInitLock); 43 CssmError::check(MDS_Initialize(&mCallerGuid, &mMemoryFunctions, 44 this, &mCDSA.DLHandle)); 45 mCDSA.DBHandle = CSSM_INVALID_HANDLE; 46} 47 48 49// 50// Cleanup (only called if the ModuleNexus is explicitly reset) 51// 52Directory::~Directory() 53{ 54 if (mCDSA.DBHandle) 55 CssmError::check(DbClose(mCDSA)); 56 CssmError::check(MDS_Terminate(mds())); 57} 58 59 60// 61// Open MDS database if needed 62// 63const MDS_DB_HANDLE &Directory::cdsa() const 64{ 65 if (mCDSA.DBHandle == CSSM_INVALID_HANDLE) { 66 StLock<Mutex> _(mInitLock); 67 if (mCDSA.DBHandle == CSSM_INVALID_HANDLE) 68 CssmError::check(DbOpen(mCDSA.DLHandle, MDS_CDSA_DIRECTORY_NAME, NULL, 69 CSSM_DB_ACCESS_READ, // access mode 70 NULL, // credentials 71 NULL, // OpenParameters 72 &mCDSA.DBHandle)); 73 } 74 return mCDSA; 75} 76 77 78// 79// The DLAccess implementation for MDS. 80// We don't ever return record data, of course; we just zero it out. 81// 82CSSM_HANDLE Directory::dlGetFirst(const CSSM_QUERY &query, CSSM_DB_RECORD_ATTRIBUTE_DATA &attributes, 83 CSSM_DATA *data, CSSM_DB_UNIQUE_RECORD *&id) 84{ 85 CSSM_HANDLE result; 86 switch (CSSM_RETURN rc = DataGetFirst(cdsa(), &query, &result, &attributes, NULL, &id)) { 87 case CSSM_OK: 88 if (data) 89 *data = CssmData(); 90 return result; 91 case CSSMERR_DL_ENDOFDATA: 92 return CSSM_INVALID_HANDLE; 93 default: 94 CssmError::throwMe(rc); 95 return CSSM_INVALID_HANDLE; // placebo 96 } 97} 98 99bool Directory::dlGetNext(CSSM_HANDLE handle, CSSM_DB_RECORD_ATTRIBUTE_DATA &attributes, 100 CSSM_DATA *data, CSSM_DB_UNIQUE_RECORD *&id) 101{ 102 CSSM_RETURN rc = DataGetNext(cdsa(), handle, &attributes, NULL, &id); 103 switch (rc) { 104 case CSSM_OK: 105 if (data) 106 *data = CssmData(); 107 return true; 108 case CSSMERR_DL_ENDOFDATA: 109 return false; 110 default: 111 CssmError::throwMe(rc); 112 return false; // placebo 113 } 114} 115 116void Directory::dlAbortQuery(CSSM_HANDLE handle) 117{ 118 CssmError::check(DataAbortQuery(cdsa(), handle)); 119} 120 121void Directory::dlFreeUniqueId(CSSM_DB_UNIQUE_RECORD *id) 122{ 123 CssmError::check(FreeUniqueRecord(cdsa(), id)); 124} 125 126void Directory::dlDeleteRecord(CSSM_DB_UNIQUE_RECORD *id) 127{ 128 CssmError::check(DataDelete(cdsa(), id)); 129} 130 131Allocator &Directory::allocator() 132{ 133 return Allocator::standard(); 134} 135 136 137// 138// Public MDS operations 139// 140void Directory::install() 141{ 142 CssmError::check(MDS_Install(this->mds())); 143} 144 145void Directory::install(const MDS_InstallDefaults *defaults, 146 const char *path, const char *subdir, const char *file) 147{ 148 CssmError::check(MDS_InstallFile(this->mds(), defaults, path, subdir, file)); 149} 150 151void Directory::uninstall(const char *guid, uint32 ssid) 152{ 153 CssmError::check(MDS_RemoveSubservice(this->mds(), guid, ssid)); 154} 155 156 157} // end namespace MDSClient 158} // end namespace Security 159