2  * Copyright (c) 2000-2001,2011,2014 Apple 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. 
  23    Contains:  Module Directory Services Data Types and API. 
  25    Copyright (c) 1999,2011,2014 Apple Inc. All Rights Reserved. 
  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 
  33 #include "MDSSession.h" 
  35 #include <security_cdsa_utilities/cssmbridge.h> 
  37 #include <security_utilities/globalizer.h> 
  38 #include <security_utilities/threading.h> 
  40 #define MSApiDebug(args...)     secinfo("MDS_API", ## args) 
  42 /* Protects access to AppleDataBase */ 
  43 ModuleNexus
<Mutex
> adbMutex
; 
  47 static CSSM_RETURN CSSMAPI 
mds_DataGetFirst(CSSM_DL_DB_HANDLE DLDBHandle
, 
  48          const CSSM_QUERY 
*Query
, 
  49          CSSM_HANDLE_PTR ResultsHandle
, 
  50          CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes
, 
  52          CSSM_DB_UNIQUE_RECORD_PTR 
*UniqueId
) 
  55   MSApiDebug("mds_DataGetFirst"); 
  56   StLock
<Mutex
> _(adbMutex()); 
  57   if (!(Required(ResultsHandle
) = HandleObject::find
<MDSSession
>(DLDBHandle
.DLHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).DataGetFirst(DLDBHandle
.DBHandle
, 
  58                         CssmQuery::optional(Query
), 
  60                         CssmData::optional(Data
), 
  62         return CSSMERR_DL_ENDOFDATA
; 
  66 static CSSM_RETURN CSSMAPI 
mds_DataModify(CSSM_DL_DB_HANDLE DLDBHandle
, 
  67          CSSM_DB_RECORDTYPE RecordType
, 
  68          CSSM_DB_UNIQUE_RECORD_PTR UniqueRecordIdentifier
, 
  69          const CSSM_DB_RECORD_ATTRIBUTE_DATA 
*AttributesToBeModified
, 
  70          const CSSM_DATA 
*DataToBeModified
, 
  71          CSSM_DB_MODIFY_MODE ModifyMode
) 
  74   StLock
<Mutex
> _(adbMutex()); 
  75   HandleObject::find
<MDSSession
>(DLDBHandle
.DLHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).DataModify(DLDBHandle
.DBHandle
, 
  77                         Required(UniqueRecordIdentifier
), 
  78                         AttributesToBeModified
, 
  79                         CssmData::optional(DataToBeModified
), 
  84 static CSSM_RETURN CSSMAPI 
mds_GetDbNameFromHandle(CSSM_DL_DB_HANDLE DLDBHandle
, 
  88   StLock
<Mutex
> _(adbMutex()); 
  89   HandleObject::find
<MDSSession
>(DLDBHandle
.DLHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).GetDbNameFromHandle(DLDBHandle
.DBHandle
, 
  94 static CSSM_RETURN CSSMAPI 
mds_DataAbortQuery(CSSM_DL_DB_HANDLE DLDBHandle
, 
  95          CSSM_HANDLE ResultsHandle
) 
  98   MSApiDebug("mds_DataAbortQuery"); 
  99   StLock
<Mutex
> _(adbMutex()); 
 100   HandleObject::find
<MDSSession
>(DLDBHandle
.DLHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).DataAbortQuery(DLDBHandle
.DBHandle
, 
 105 static CSSM_RETURN CSSMAPI 
mds_DestroyRelation(CSSM_DL_DB_HANDLE DLDBHandle
, 
 106          CSSM_DB_RECORDTYPE RelationID
) 
 109   StLock
<Mutex
> _(adbMutex()); 
 110   HandleObject::find
<MDSSession
>(DLDBHandle
.DLHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).DestroyRelation(DLDBHandle
.DBHandle
, 
 115 static CSSM_RETURN CSSMAPI 
mds_DataDelete(CSSM_DL_DB_HANDLE DLDBHandle
, 
 116          const CSSM_DB_UNIQUE_RECORD 
*UniqueRecordIdentifier
) 
 119   StLock
<Mutex
> _(adbMutex()); 
 120   HandleObject::find
<MDSSession
>(DLDBHandle
.DLHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).DataDelete(DLDBHandle
.DBHandle
, 
 121                         Required(UniqueRecordIdentifier
)); 
 125 static CSSM_RETURN CSSMAPI 
mds_DataInsert(CSSM_DL_DB_HANDLE DLDBHandle
, 
 126          CSSM_DB_RECORDTYPE RecordType
, 
 127          const CSSM_DB_RECORD_ATTRIBUTE_DATA 
*Attributes
, 
 128          const CSSM_DATA 
*Data
, 
 129          CSSM_DB_UNIQUE_RECORD_PTR 
*UniqueId
) 
 132   StLock
<Mutex
> _(adbMutex()); 
 133   HandleObject::find
<MDSSession
>(DLDBHandle
.DLHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).DataInsert(DLDBHandle
.DBHandle
, 
 136                         CssmData::optional(Data
), 
 141 static CSSM_RETURN CSSMAPI 
mds_DataGetFromUniqueRecordId(CSSM_DL_DB_HANDLE DLDBHandle
, 
 142          const CSSM_DB_UNIQUE_RECORD 
*UniqueRecord
, 
 143          CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes
, 
 147   StLock
<Mutex
> _(adbMutex()); 
 148   HandleObject::find
<MDSSession
>(DLDBHandle
.DLHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).DataGetFromUniqueRecordId(DLDBHandle
.DBHandle
, 
 149                         Required(UniqueRecord
), 
 151                         CssmData::optional(Data
)); 
 155 static CSSM_RETURN CSSMAPI 
mds_CreateRelation(CSSM_DL_DB_HANDLE DLDBHandle
, 
 156          CSSM_DB_RECORDTYPE RelationID
, 
 157          const char *RelationName
, 
 158          uint32 NumberOfAttributes
, 
 159          const CSSM_DB_SCHEMA_ATTRIBUTE_INFO 
*pAttributeInfo
, 
 160          uint32 NumberOfIndexes
, 
 161          const CSSM_DB_SCHEMA_INDEX_INFO 
*pIndexInfo
) 
 164   StLock
<Mutex
> _(adbMutex()); 
 165   HandleObject::find
<MDSSession
>(DLDBHandle
.DLHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).CreateRelation(DLDBHandle
.DBHandle
, 
 171                         Required(pIndexInfo
)); 
 175 static CSSM_RETURN CSSMAPI 
mds_FreeUniqueRecord(CSSM_DL_DB_HANDLE DLDBHandle
, 
 176          CSSM_DB_UNIQUE_RECORD_PTR UniqueRecord
) 
 179   StLock
<Mutex
> _(adbMutex()); 
 180   HandleObject::find
<MDSSession
>(DLDBHandle
.DLHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).FreeUniqueRecord(DLDBHandle
.DBHandle
, 
 181                         Required(UniqueRecord
)); 
 185 static CSSM_RETURN CSSMAPI 
mds_DbOpen(CSSM_DL_HANDLE DLHandle
, 
 187          const CSSM_NET_ADDRESS 
*DbLocation
, 
 188          CSSM_DB_ACCESS_TYPE AccessRequest
, 
 189          const CSSM_ACCESS_CREDENTIALS 
*AccessCred
, 
 190          const void *OpenParameters
, 
 191          CSSM_DB_HANDLE 
*DbHandle
) 
 194   MSApiDebug("mds_DbOpen %s", DbName
); 
 195   StLock
<Mutex
> _(adbMutex()); 
 196   HandleObject::find
<MDSSession
>(DLHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).DbOpen(DbName
, 
 199                         AccessCredentials::optional(AccessCred
), 
 205 static CSSM_RETURN CSSMAPI 
mds_DataGetNext(CSSM_DL_DB_HANDLE DLDBHandle
, 
 206          CSSM_HANDLE ResultsHandle
, 
 207          CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes
, 
 209          CSSM_DB_UNIQUE_RECORD_PTR 
*UniqueId
) 
 212   MSApiDebug("mds_DataGetNext"); 
 213   StLock
<Mutex
> _(adbMutex()); 
 214   if (!HandleObject::find
<MDSSession
>(DLDBHandle
.DLHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).DataGetNext(DLDBHandle
.DBHandle
, 
 217                         CssmData::optional(Data
), 
 219         return CSSMERR_DL_ENDOFDATA
; 
 223 static CSSM_RETURN CSSMAPI 
mds_GetDbNames(CSSM_DL_HANDLE DLHandle
, 
 224          CSSM_NAME_LIST_PTR 
*NameList
) 
 227   HandleObject::find
<MDSSession
>(DLHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).GetDbNames(Required(NameList
)); 
 231 static CSSM_RETURN CSSMAPI 
mds_DbClose(CSSM_DL_DB_HANDLE DLDBHandle
) 
 234   MSApiDebug("mds_DbClose"); 
 235   StLock
<Mutex
> _(adbMutex()); 
 236   HandleObject::find
<MDSSession
>(DLDBHandle
.DLHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).DbClose(DLDBHandle
.DBHandle
); 
 240 static CSSM_RETURN CSSMAPI 
mds_FreeNameList(CSSM_DL_HANDLE DLHandle
, 
 241          CSSM_NAME_LIST_PTR NameList
) 
 244   HandleObject::find
<MDSSession
>(DLHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).FreeNameList(Required(NameList
)); 
 248 static MDS_FUNCS gMDSFunctionTable 
= 
 253     mds_GetDbNameFromHandle
, 
 261     mds_DataGetFromUniqueRecordId
, 
 262     mds_FreeUniqueRecord
, 
 269 MDS_Initialize (const CSSM_GUID 
*inCallerGuid
, 
 270                 const CSSM_MEMORY_FUNCS 
*inMemoryFunctions
, 
 271                 MDS_FUNCS_PTR outDlFunctions
, 
 272                 MDS_HANDLE 
*outMDSHandle
) 
 275     Required (outDlFunctions
); 
 276     Required (outMDSHandle
) = (new MDSSession (Guid::optional(inCallerGuid
), 
 277                                                Required(inMemoryFunctions
)))->handle (); 
 278     *outDlFunctions 
= gMDSFunctionTable
; 
 283 MDS_Terminate (MDS_HANDLE inMDSHandle
) 
 286     auto_ptr
<MDSSession
> aMDSSession (&HandleObject::findAndKill
<MDSSession
> (inMDSHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
)); 
 287     aMDSSession
->terminate (); // Even if terminate throws the MDSSession object will be deleted. 
 292 MDS_Install (MDS_HANDLE inMDSHandle
) 
 295     HandleObject::find
<MDSSession
> (inMDSHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).install (); 
 300 MDS_Uninstall (MDS_HANDLE inMDSHandle
) 
 303     HandleObject::find
<MDSSession
> (inMDSHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).uninstall (); 
 309 // Private APIs for subsystem registration (called from securityd as root ONLY) 
 312 MDS_InstallFile(MDS_HANDLE inMDSHandle
, const MDS_InstallDefaults 
*defaults
, 
 313         const char *bundlePath
, const char *subdir
, const char *file
)   // file(s) 
 316   HandleObject::find
<MDSSession
>(inMDSHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).installFile(defaults
, bundlePath
, subdir
, file
); 
 324 MDS_RemoveSubservice(MDS_HANDLE inMDSHandle
, const char *guid
, uint32 ssid
) 
 327   HandleObject::find
<MDSSession
>(inMDSHandle
, CSSMERR_CSSM_INVALID_ADDIN_HANDLE
).removeSubservice(guid
, ssid
);