mdsclient.cpp
1 /* 2 * Copyright (c) 2000-2004,2011,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 // mdsclient - friendly interface to CDSA MDS API 21 // 22 #include <security_cdsa_client/mdsclient.h> 23 #include <Security/mdspriv.h> 24 25 26 namespace Security { 27 namespace MDSClient { 28 29 30 // 31 // The MDS access object singleton 32 // 33 ModuleNexus<Directory> mds; 34 35 36 // 37 // Directory construction initializes MDS and opens the "CDSA" database 38 // 39 Directory::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 // 52 Directory::~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 // 63 const 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 // 82 CSSM_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 } 96 } 97 98 bool Directory::dlGetNext(CSSM_HANDLE handle, CSSM_DB_RECORD_ATTRIBUTE_DATA &attributes, 99 CSSM_DATA *data, CSSM_DB_UNIQUE_RECORD *&id) 100 { 101 CSSM_RETURN rc = DataGetNext(cdsa(), handle, &attributes, NULL, &id); 102 switch (rc) { 103 case CSSM_OK: 104 if (data) 105 *data = CssmData(); 106 return true; 107 case CSSMERR_DL_ENDOFDATA: 108 return false; 109 default: 110 CssmError::throwMe(rc); 111 } 112 } 113 114 void Directory::dlAbortQuery(CSSM_HANDLE handle) 115 { 116 CssmError::check(DataAbortQuery(cdsa(), handle)); 117 } 118 119 void Directory::dlFreeUniqueId(CSSM_DB_UNIQUE_RECORD *id) 120 { 121 CssmError::check(FreeUniqueRecord(cdsa(), id)); 122 } 123 124 void Directory::dlDeleteRecord(CSSM_DB_UNIQUE_RECORD *id) 125 { 126 CssmError::check(DataDelete(cdsa(), id)); 127 } 128 129 Allocator &Directory::allocator() 130 { 131 return Allocator::standard(); 132 } 133 134 135 // 136 // Public MDS operations 137 // 138 void Directory::install() 139 { 140 CssmError::check(MDS_Install(this->mds())); 141 } 142 143 void Directory::install(const MDS_InstallDefaults *defaults, 144 const char *path, const char *subdir, const char *file) 145 { 146 CssmError::check(MDS_InstallFile(this->mds(), defaults, path, subdir, file)); 147 } 148 149 void Directory::uninstall(const char *guid, uint32 ssid) 150 { 151 CssmError::check(MDS_RemoveSubservice(this->mds(), guid, ssid)); 152 } 153 154 155 } // end namespace MDSClient 156 } // end namespace Security