1/*
2 * Copyright (c) 2000-2001 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
21   File:      mds.h
22
23   Contains:  Module Directory Services Data Types and API.
24
25   Copyright: (c) 1999 Apple Computer, 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
40#define MSApiDebug(args...)	secdebug("MDS_API", ## args)
41
42/* Protects access to AppleDataBase */
43ModuleNexus<Mutex> adbMutex;
44
45using namespace std;
46
47static 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,
51         CSSM_DATA_PTR Data,
52         CSSM_DB_UNIQUE_RECORD_PTR *UniqueId)
53{
54  BEGIN_API
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),
59			Attributes,
60			CssmData::optional(Data),
61			Required(UniqueId))))
62	return CSSMERR_DL_ENDOFDATA;
63  END_API(MDS)
64}
65
66static 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)
72{
73  BEGIN_API
74  StLock<Mutex> _(adbMutex());
75  HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DataModify(DLDBHandle.DBHandle,
76			RecordType,
77			Required(UniqueRecordIdentifier),
78			AttributesToBeModified,
79			CssmData::optional(DataToBeModified),
80			ModifyMode);
81  END_API(MDS)
82}
83
84static CSSM_RETURN CSSMAPI mds_GetDbNameFromHandle(CSSM_DL_DB_HANDLE DLDBHandle,
85         char **DbName)
86{
87  BEGIN_API
88  StLock<Mutex> _(adbMutex());
89  HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).GetDbNameFromHandle(DLDBHandle.DBHandle,
90			DbName);
91  END_API(MDS)
92}
93
94static CSSM_RETURN CSSMAPI mds_DataAbortQuery(CSSM_DL_DB_HANDLE DLDBHandle,
95         CSSM_HANDLE ResultsHandle)
96{
97  BEGIN_API
98  MSApiDebug("mds_DataAbortQuery");
99  StLock<Mutex> _(adbMutex());
100  HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DataAbortQuery(DLDBHandle.DBHandle,
101			ResultsHandle);
102  END_API(MDS)
103}
104
105static CSSM_RETURN CSSMAPI mds_DestroyRelation(CSSM_DL_DB_HANDLE DLDBHandle,
106         CSSM_DB_RECORDTYPE RelationID)
107{
108  BEGIN_API
109  StLock<Mutex> _(adbMutex());
110  HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DestroyRelation(DLDBHandle.DBHandle,
111			RelationID);
112  END_API(MDS)
113}
114
115static CSSM_RETURN CSSMAPI mds_DataDelete(CSSM_DL_DB_HANDLE DLDBHandle,
116         const CSSM_DB_UNIQUE_RECORD *UniqueRecordIdentifier)
117{
118  BEGIN_API
119  StLock<Mutex> _(adbMutex());
120  HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DataDelete(DLDBHandle.DBHandle,
121			Required(UniqueRecordIdentifier));
122  END_API(MDS)
123}
124
125static 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)
130{
131  BEGIN_API
132  StLock<Mutex> _(adbMutex());
133  HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DataInsert(DLDBHandle.DBHandle,
134			RecordType,
135			Attributes,
136			CssmData::optional(Data),
137			Required(UniqueId));
138  END_API(MDS)
139}
140
141static 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,
144         CSSM_DATA_PTR Data)
145{
146  BEGIN_API
147  StLock<Mutex> _(adbMutex());
148  HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DataGetFromUniqueRecordId(DLDBHandle.DBHandle,
149			Required(UniqueRecord),
150            Attributes,
151			CssmData::optional(Data));
152  END_API(MDS)
153}
154
155static 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)
162{
163  BEGIN_API
164  StLock<Mutex> _(adbMutex());
165  HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).CreateRelation(DLDBHandle.DBHandle,
166			RelationID,
167			RelationName,
168			NumberOfAttributes,
169			pAttributeInfo,
170			NumberOfIndexes,
171			Required(pIndexInfo));
172  END_API(MDS)
173}
174
175static CSSM_RETURN CSSMAPI mds_FreeUniqueRecord(CSSM_DL_DB_HANDLE DLDBHandle,
176         CSSM_DB_UNIQUE_RECORD_PTR UniqueRecord)
177{
178  BEGIN_API
179  StLock<Mutex> _(adbMutex());
180  HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).FreeUniqueRecord(DLDBHandle.DBHandle,
181			Required(UniqueRecord));
182  END_API(MDS)
183}
184
185static CSSM_RETURN CSSMAPI mds_DbOpen(CSSM_DL_HANDLE DLHandle,
186         const char *DbName,
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)
192{
193  BEGIN_API
194  MSApiDebug("mds_DbOpen %s", DbName);
195  StLock<Mutex> _(adbMutex());
196  HandleObject::find<MDSSession>(DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DbOpen(DbName,
197			DbLocation,
198			AccessRequest,
199			AccessCredentials::optional(AccessCred),
200			OpenParameters,
201			Required(DbHandle));
202  END_API(MDS)
203}
204
205static CSSM_RETURN CSSMAPI mds_DataGetNext(CSSM_DL_DB_HANDLE DLDBHandle,
206         CSSM_HANDLE ResultsHandle,
207         CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR Attributes,
208         CSSM_DATA_PTR Data,
209         CSSM_DB_UNIQUE_RECORD_PTR *UniqueId)
210{
211  BEGIN_API
212  MSApiDebug("mds_DataGetNext");
213  StLock<Mutex> _(adbMutex());
214  if (!HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DataGetNext(DLDBHandle.DBHandle,
215			ResultsHandle,
216			Attributes,
217			CssmData::optional(Data),
218			Required(UniqueId)))
219	return CSSMERR_DL_ENDOFDATA;
220  END_API(MDS)
221}
222
223static CSSM_RETURN CSSMAPI mds_GetDbNames(CSSM_DL_HANDLE DLHandle,
224         CSSM_NAME_LIST_PTR *NameList)
225{
226  BEGIN_API
227  HandleObject::find<MDSSession>(DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).GetDbNames(Required(NameList));
228  END_API(MDS)
229}
230
231static CSSM_RETURN CSSMAPI mds_DbClose(CSSM_DL_DB_HANDLE DLDBHandle)
232{
233  BEGIN_API
234  MSApiDebug("mds_DbClose");
235  StLock<Mutex> _(adbMutex());
236  HandleObject::find<MDSSession>(DLDBHandle.DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).DbClose(DLDBHandle.DBHandle);
237  END_API(MDS)
238}
239
240static CSSM_RETURN CSSMAPI mds_FreeNameList(CSSM_DL_HANDLE DLHandle,
241         CSSM_NAME_LIST_PTR NameList)
242{
243  BEGIN_API
244  HandleObject::find<MDSSession>(DLHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).FreeNameList(Required(NameList));
245  END_API(MDS)
246}
247
248static MDS_FUNCS gMDSFunctionTable =
249{
250    mds_DbOpen,
251    mds_DbClose,
252    mds_GetDbNames,
253    mds_GetDbNameFromHandle,
254    mds_FreeNameList,
255    mds_DataInsert,
256    mds_DataDelete,
257    mds_DataModify,
258    mds_DataGetFirst,
259    mds_DataGetNext,
260    mds_DataAbortQuery,
261    mds_DataGetFromUniqueRecordId,
262    mds_FreeUniqueRecord,
263    mds_CreateRelation,
264    mds_DestroyRelation,
265};
266
267
268CSSM_RETURN CSSMAPI
269MDS_Initialize (const CSSM_GUID *inCallerGuid,
270                const CSSM_MEMORY_FUNCS *inMemoryFunctions,
271                MDS_FUNCS_PTR outDlFunctions,
272                MDS_HANDLE *outMDSHandle)
273{
274    BEGIN_API
275    Required (outDlFunctions);
276    Required (outMDSHandle) = (new MDSSession (Guid::optional(inCallerGuid),
277                                               Required(inMemoryFunctions)))->handle ();
278    *outDlFunctions = gMDSFunctionTable;
279    END_API(MDS)
280}
281
282CSSM_RETURN CSSMAPI
283MDS_Terminate (MDS_HANDLE inMDSHandle)
284{
285    BEGIN_API
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.
288    END_API(MDS)
289}
290
291CSSM_RETURN CSSMAPI
292MDS_Install (MDS_HANDLE inMDSHandle)
293{
294    BEGIN_API
295    HandleObject::find<MDSSession> (inMDSHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).install ();
296    END_API(MDS)
297}
298
299CSSM_RETURN CSSMAPI
300MDS_Uninstall (MDS_HANDLE inMDSHandle)
301{
302    BEGIN_API
303    HandleObject::find<MDSSession> (inMDSHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).uninstall ();
304    END_API(MDS)
305}
306
307
308//
309// Private APIs for subsystem registration (called from securityd as root ONLY)
310//
311CSSM_RETURN CSSMAPI
312MDS_InstallFile(MDS_HANDLE inMDSHandle, const MDS_InstallDefaults *defaults,
313	const char *bundlePath, const char *subdir, const char *file)	// file(s)
314{
315  BEGIN_API
316  HandleObject::find<MDSSession>(inMDSHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).installFile(defaults, bundlePath, subdir, file);
317  END_API(MDS)
318}
319
320
321//
322// Remove
323CSSM_RETURN CSSMAPI
324MDS_RemoveSubservice(MDS_HANDLE inMDSHandle, const char *guid, uint32 ssid)
325{
326  BEGIN_API
327  HandleObject::find<MDSSession>(inMDSHandle, CSSMERR_CSSM_INVALID_ADDIN_HANDLE).removeSubservice(guid, ssid);
328  END_API(MDS)
329}
330