mdsapi.cpp
1 /* 2 * Copyright (c) 2000-2001,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 21 File: mds.h 22 23 Contains: Module Directory Services Data Types and API. 24 25 Copyright (c) 1999,2011,2014 Apple Inc. All Rights Reserved. 26 27 This is the C API wrapper for the C++ MDS implementation. Most of this file 28 could also be generated by the same perl script that generates the plugin 29 C wrapper code. 30 31 */ 32 33 #include "MDSSession.h" 34 #include "mdspriv.h" 35 #include <security_cdsa_utilities/cssmbridge.h> 36 #include <memory> 37 #include <security_utilities/globalizer.h> 38 #include <security_utilities/threading.h> 39 #include "LegacyAPICounts.h" 40 41 #define MSApiDebug(args...) secinfo("MDS_API", ## args) 42 43 /* Protects access to AppleDataBase */ 44 ModuleNexus<Mutex> adbMutex; 45 46 using namespace std; 47 48 static CSSM_RETURN CSSMAPI mds_DataGetFirst(CSSM_DL_DB_HANDLE DLDBHandle, 49 const CSSM_QUERY *Query, 50 CSSM_HANDLE_PTR ResultsHandle, 51 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes, 52 CSSM_DATA_PTR Data, 53 CSSM_DB_UNIQUE_RECORD_PTR *UniqueId) 54 { 55 BEGIN_API 56 MSApiDebug("mds_DataGetFirst"); 57 StLock<Mutex> _(adbMutex()); 58 if (!(Required(ResultsHandle) = HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DataGetFirst(DLDBHandle.DBHandle, 59 CssmQuery::optional(Query), 60 Attributes, 61 CssmData::optional(Data), 62 Required(UniqueId)))) 63 return CSSMERR_DL_ENDOFDATA; 64 END_API(MDS) 65 } 66 67 static CSSM_RETURN CSSMAPI mds_DataModify(CSSM_DL_DB_HANDLE DLDBHandle, 68 CSSM_DB_RECORDTYPE RecordType, 69 CSSM_DB_UNIQUE_RECORD_PTR UniqueRecordIdentifier, 70 const CSSM_DB_RECORD_ATTRIBUTE_DATA *AttributesToBeModified, 71 const CSSM_DATA *DataToBeModified, 72 CSSM_DB_MODIFY_MODE ModifyMode) 73 { 74 BEGIN_API 75 StLock<Mutex> _(adbMutex()); 76 HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DataModify(DLDBHandle.DBHandle, 77 RecordType, 78 Required(UniqueRecordIdentifier), 79 AttributesToBeModified, 80 CssmData::optional(DataToBeModified), 81 ModifyMode); 82 END_API(MDS) 83 } 84 85 static CSSM_RETURN CSSMAPI mds_GetDbNameFromHandle(CSSM_DL_DB_HANDLE DLDBHandle, 86 char **DbName) 87 { 88 BEGIN_API 89 StLock<Mutex> _(adbMutex()); 90 HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).GetDbNameFromHandle(DLDBHandle.DBHandle, 91 DbName); 92 END_API(MDS) 93 } 94 95 static CSSM_RETURN CSSMAPI mds_DataAbortQuery(CSSM_DL_DB_HANDLE DLDBHandle, 96 CSSM_HANDLE ResultsHandle) 97 { 98 BEGIN_API 99 MSApiDebug("mds_DataAbortQuery"); 100 StLock<Mutex> _(adbMutex()); 101 HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DataAbortQuery(DLDBHandle.DBHandle, 102 ResultsHandle); 103 END_API(MDS) 104 } 105 106 static CSSM_RETURN CSSMAPI mds_DestroyRelation(CSSM_DL_DB_HANDLE DLDBHandle, 107 CSSM_DB_RECORDTYPE RelationID) 108 { 109 BEGIN_API 110 StLock<Mutex> _(adbMutex()); 111 HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DestroyRelation(DLDBHandle.DBHandle, 112 RelationID); 113 END_API(MDS) 114 } 115 116 static CSSM_RETURN CSSMAPI mds_DataDelete(CSSM_DL_DB_HANDLE DLDBHandle, 117 const CSSM_DB_UNIQUE_RECORD *UniqueRecordIdentifier) 118 { 119 BEGIN_API 120 StLock<Mutex> _(adbMutex()); 121 HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DataDelete(DLDBHandle.DBHandle, 122 Required(UniqueRecordIdentifier)); 123 END_API(MDS) 124 } 125 126 static CSSM_RETURN CSSMAPI mds_DataInsert(CSSM_DL_DB_HANDLE DLDBHandle, 127 CSSM_DB_RECORDTYPE RecordType, 128 const CSSM_DB_RECORD_ATTRIBUTE_DATA *Attributes, 129 const CSSM_DATA *Data, 130 CSSM_DB_UNIQUE_RECORD_PTR *UniqueId) 131 { 132 BEGIN_API 133 StLock<Mutex> _(adbMutex()); 134 HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DataInsert(DLDBHandle.DBHandle, 135 RecordType, 136 Attributes, 137 CssmData::optional(Data), 138 Required(UniqueId)); 139 END_API(MDS) 140 } 141 142 static CSSM_RETURN CSSMAPI mds_DataGetFromUniqueRecordId(CSSM_DL_DB_HANDLE DLDBHandle, 143 const CSSM_DB_UNIQUE_RECORD *UniqueRecord, 144 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes, 145 CSSM_DATA_PTR Data) 146 { 147 BEGIN_API 148 StLock<Mutex> _(adbMutex()); 149 HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DataGetFromUniqueRecordId(DLDBHandle.DBHandle, 150 Required(UniqueRecord), 151 Attributes, 152 CssmData::optional(Data)); 153 END_API(MDS) 154 } 155 156 static CSSM_RETURN CSSMAPI mds_CreateRelation(CSSM_DL_DB_HANDLE DLDBHandle, 157 CSSM_DB_RECORDTYPE RelationID, 158 const char *RelationName, 159 uint32 NumberOfAttributes, 160 const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *pAttributeInfo, 161 uint32 NumberOfIndexes, 162 const CSSM_DB_SCHEMA_INDEX_INFO *pIndexInfo) 163 { 164 BEGIN_API 165 StLock<Mutex> _(adbMutex()); 166 HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).CreateRelation(DLDBHandle.DBHandle, 167 RelationID, 168 RelationName, 169 NumberOfAttributes, 170 pAttributeInfo, 171 NumberOfIndexes, 172 Required(pIndexInfo)); 173 END_API(MDS) 174 } 175 176 static CSSM_RETURN CSSMAPI mds_FreeUniqueRecord(CSSM_DL_DB_HANDLE DLDBHandle, 177 CSSM_DB_UNIQUE_RECORD_PTR UniqueRecord) 178 { 179 BEGIN_API 180 StLock<Mutex> _(adbMutex()); 181 HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).FreeUniqueRecord(DLDBHandle.DBHandle, 182 Required(UniqueRecord)); 183 END_API(MDS) 184 } 185 186 static CSSM_RETURN CSSMAPI mds_DbOpen(CSSM_DL_HANDLE DLHandle, 187 const char *DbName, 188 const CSSM_NET_ADDRESS *DbLocation, 189 CSSM_DB_ACCESS_TYPE AccessRequest, 190 const CSSM_ACCESS_CREDENTIALS *AccessCred, 191 const void *OpenParameters, 192 CSSM_DB_HANDLE *DbHandle) 193 { 194 BEGIN_API 195 MSApiDebug("mds_DbOpen %s", DbName); 196 StLock<Mutex> _(adbMutex()); 197 HandleObject::find<MDSSession>(DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DbOpen(DbName, 198 DbLocation, 199 AccessRequest, 200 AccessCredentials::optional(AccessCred), 201 OpenParameters, 202 Required(DbHandle)); 203 END_API(MDS) 204 } 205 206 static CSSM_RETURN CSSMAPI mds_DataGetNext(CSSM_DL_DB_HANDLE DLDBHandle, 207 CSSM_HANDLE ResultsHandle, 208 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes, 209 CSSM_DATA_PTR Data, 210 CSSM_DB_UNIQUE_RECORD_PTR *UniqueId) 211 { 212 BEGIN_API 213 MSApiDebug("mds_DataGetNext"); 214 StLock<Mutex> _(adbMutex()); 215 if (!HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DataGetNext(DLDBHandle.DBHandle, 216 ResultsHandle, 217 Attributes, 218 CssmData::optional(Data), 219 Required(UniqueId))) 220 return CSSMERR_DL_ENDOFDATA; 221 END_API(MDS) 222 } 223 224 static CSSM_RETURN CSSMAPI mds_GetDbNames(CSSM_DL_HANDLE DLHandle, 225 CSSM_NAME_LIST_PTR *NameList) 226 { 227 BEGIN_API 228 HandleObject::find<MDSSession>(DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).GetDbNames(Required(NameList)); 229 END_API(MDS) 230 } 231 232 static CSSM_RETURN CSSMAPI mds_DbClose(CSSM_DL_DB_HANDLE DLDBHandle) 233 { 234 BEGIN_API 235 MSApiDebug("mds_DbClose"); 236 StLock<Mutex> _(adbMutex()); 237 HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DbClose(DLDBHandle.DBHandle); 238 END_API(MDS) 239 } 240 241 static CSSM_RETURN CSSMAPI mds_FreeNameList(CSSM_DL_HANDLE DLHandle, 242 CSSM_NAME_LIST_PTR NameList) 243 { 244 BEGIN_API 245 HandleObject::find<MDSSession>(DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).FreeNameList(Required(NameList)); 246 END_API(MDS) 247 } 248 249 static MDS_FUNCS gMDSFunctionTable = 250 { 251 mds_DbOpen, 252 mds_DbClose, 253 mds_GetDbNames, 254 mds_GetDbNameFromHandle, 255 mds_FreeNameList, 256 mds_DataInsert, 257 mds_DataDelete, 258 mds_DataModify, 259 mds_DataGetFirst, 260 mds_DataGetNext, 261 mds_DataAbortQuery, 262 mds_DataGetFromUniqueRecordId, 263 mds_FreeUniqueRecord, 264 mds_CreateRelation, 265 mds_DestroyRelation, 266 }; 267 268 269 CSSM_RETURN CSSMAPI 270 MDS_Initialize (const CSSM_GUID *inCallerGuid, 271 const CSSM_MEMORY_FUNCS *inMemoryFunctions, 272 MDS_FUNCS_PTR outDlFunctions, 273 MDS_HANDLE *outMDSHandle) 274 { 275 // The clang analyzer is not a fan of handing handles to your caller and trusting them to release later. 276 #ifndef __clang_analyzer__ 277 BEGIN_API 278 Required (outDlFunctions); 279 Required (outMDSHandle) = (new MDSSession (Guid::optional(inCallerGuid), 280 Required(inMemoryFunctions)))->handle (); 281 *outDlFunctions = gMDSFunctionTable; 282 END_API(MDS) 283 #endif 284 } 285 286 CSSM_RETURN CSSMAPI 287 MDS_Terminate (MDS_HANDLE inMDSHandle) 288 { 289 BEGIN_API 290 unique_ptr<MDSSession> aMDSSession (&HandleObject::findAndKill<MDSSession> (inMDSHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE)); 291 aMDSSession->terminate (); // Even if terminate throws the MDSSession object will be deleted. 292 END_API(MDS) 293 } 294 295 CSSM_RETURN CSSMAPI 296 MDS_Install (MDS_HANDLE inMDSHandle) 297 { 298 BEGIN_API 299 HandleObject::find<MDSSession> (inMDSHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).install (); 300 END_API(MDS) 301 } 302 303 CSSM_RETURN CSSMAPI 304 MDS_Uninstall (MDS_HANDLE inMDSHandle) 305 { 306 BEGIN_API 307 HandleObject::find<MDSSession> (inMDSHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).uninstall (); 308 END_API(MDS) 309 } 310 311 312 // 313 // Private APIs for subsystem registration (called from securityd as root ONLY) 314 // 315 CSSM_RETURN CSSMAPI 316 MDS_InstallFile(MDS_HANDLE inMDSHandle, const MDS_InstallDefaults *defaults, 317 const char *bundlePath, const char *subdir, const char *file) // file(s) 318 { 319 BEGIN_API 320 HandleObject::find<MDSSession>(inMDSHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).installFile(defaults, bundlePath, subdir, file); 321 END_API(MDS) 322 } 323 324 325 // 326 // Remove 327 CSSM_RETURN CSSMAPI 328 MDS_RemoveSubservice(MDS_HANDLE inMDSHandle, const char *guid, uint32 ssid) 329 { 330 BEGIN_API 331 HandleObject::find<MDSSession>(inMDSHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).removeSubservice(guid, ssid); 332 END_API(MDS) 333 }