/ OSX / libsecurity_mds / lib / mdsapi.cpp
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  }