1/*
2 * Copyright (c) 2000-2004 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#ifndef _DATABASE_H_
20#define _DATABASE_H_  1
21
22#include <security_cdsa_utilities/cssmacl.h>
23#include <security_utilities/threading.h>
24#include <security_cdsa_utilities/cssmdb.h>
25#include <list>
26#include <map>
27#include <set>
28
29
30// @@@ Should not use using in headers.
31using namespace std;
32
33namespace Security
34{
35
36class Database;
37class DatabaseFactory;
38class DatabaseSession;
39class DbContext;
40
41/* DatabaseManager class.  */
42class DatabaseManager
43{
44	NOCOPY(DatabaseManager)
45public:
46    DatabaseManager ();
47    virtual ~DatabaseManager ();
48
49    // Create and return a new DbContext instance which is owned by us and must be discared by calling dbClose.
50    virtual DbContext &dbOpen(DatabaseSession &inDatabaseSession,
51                              const DbName &inDbName,
52                              CSSM_DB_ACCESS_TYPE inAccessRequest,
53                              const AccessCredentials *inAccessCred,
54                              const void *inOpenParameters);
55    virtual DbContext &dbCreate(DatabaseSession &inDatabaseSession,
56                                const DbName &inDbName,
57                                const CSSM_DBINFO &inDBInfo,
58                                CSSM_DB_ACCESS_TYPE inAccessRequest,
59                                const CSSM_RESOURCE_CONTROL_CONTEXT *inCredAndAclEntry,
60                                const void *inOpenParameters);
61
62    // Delete a DbContext instance created by calling dbOpen or dbCreate.
63    virtual void dbClose(DbContext &inDbContext);
64
65    // Delete a database.
66    virtual void dbDelete(DatabaseSession &inDatabaseSession,
67                          const DbName &inDbName,
68                          const AccessCredentials *inAccessCred);
69
70    // List all available databases.
71    virtual CSSM_NAME_LIST_PTR getDbNames(DatabaseSession &inDatabaseSession);
72    virtual void freeNameList(DatabaseSession &inDatabaseSession,
73                              CSSM_NAME_LIST &inNameList);
74protected:
75    virtual void removeIfUnused(Database &inDatabase);
76    virtual Database *get (const DbName &inDbName); // Get existing instance or make a new one.
77    virtual Database *make (const DbName &inDbName) = 0; // Create a new database instance subclass must implement.
78private:
79    typedef map<DbName, Database *> DatabaseMap;
80    DatabaseMap mDatabaseMap;
81    Mutex mDatabaseMapLock;
82};
83
84
85/* Database is an abstract class.  Each Database subclass should implement all the
86   pure virtual methods listed below.  The constructor for a particular Database
87   subclass should create the Database object.  A subsequent call to dBOpen or
88   dBCreate should be is made.  This returns a DbContext.  All other methods take
89   a DbContext as an argument.
90 */
91class Database
92{
93public:
94    virtual void
95    dbCreate (DbContext &inDbContext, const CSSM_DBINFO &inDBInfo,
96              const CSSM_ACL_ENTRY_INPUT *inInitialAclEntry) = 0;
97
98    // Don't override this method in subclasses.
99    virtual DbContext &
100    _dbCreate(DatabaseSession &inDatabaseSession,
101             const CSSM_DBINFO &inDBInfo,
102             CSSM_DB_ACCESS_TYPE inAccessRequest,
103             const CSSM_RESOURCE_CONTROL_CONTEXT *inCredAndAclEntry,
104             const void *inOpenParameters);
105
106    virtual void
107    dbOpen (DbContext &inDbContext) = 0;
108
109    // Don't override this method in subclasses.
110    virtual DbContext &
111    _dbOpen (DatabaseSession &inDatabaseSession,
112            CSSM_DB_ACCESS_TYPE inAccessRequest,
113            const AccessCredentials *inAccessCred,
114            const void *inOpenParameters);
115
116    virtual void
117    dbClose () = 0;
118
119    // Don't override this method in subclasses.
120    virtual void
121    _dbClose (DbContext &dbContext);
122
123    virtual void
124    dbDelete(DatabaseSession &inDatabaseSession,
125             const AccessCredentials *inAccessCred) = 0;
126
127    virtual void
128    createRelation (DbContext &dbContext,
129                    CSSM_DB_RECORDTYPE inRelationID,
130                    const char *inRelationName,
131                    uint32 inNumberOfAttributes,
132                    const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *inAttributeInfo,
133                    uint32 inNumberOfIndexes,
134                    const CSSM_DB_SCHEMA_INDEX_INFO &inIndexInfo) = 0;
135
136    virtual void
137    destroyRelation (DbContext &dbContext,
138                     CSSM_DB_RECORDTYPE inRelationID) = 0;
139
140    virtual void
141    authenticate(DbContext &dbContext,
142                 CSSM_DB_ACCESS_TYPE inAccessRequest,
143                 const AccessCredentials &inAccessCred) = 0;
144
145    virtual void
146    getDbAcl(DbContext &dbContext,
147             const CSSM_STRING *inSelectionTag,
148             uint32 &outNumberOfAclInfos,
149             CSSM_ACL_ENTRY_INFO_PTR &outAclInfos) = 0;
150
151    virtual void
152    changeDbAcl(DbContext &dbContext,
153                const AccessCredentials &inAccessCred,
154                const CSSM_ACL_EDIT &inAclEdit) = 0;
155
156    virtual void
157    getDbOwner(DbContext &dbContext, CSSM_ACL_OWNER_PROTOTYPE &outOwner) = 0;
158
159    virtual void
160    changeDbOwner(DbContext &dbContext,
161                  const AccessCredentials &inAccessCred,
162                  const CSSM_ACL_OWNER_PROTOTYPE &inNewOwner) = 0;
163
164    virtual char *
165    getDbNameFromHandle (const DbContext &dbContext) const = 0;
166
167    virtual CSSM_DB_UNIQUE_RECORD_PTR
168    dataInsert (DbContext &dbContext,
169                CSSM_DB_RECORDTYPE RecordType,
170                const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributes,
171                const CssmData *inData) = 0;
172
173    virtual void
174    dataDelete (DbContext &dbContext,
175                const CSSM_DB_UNIQUE_RECORD &inUniqueRecordIdentifier) = 0;
176
177    virtual void
178    dataModify (DbContext &dbContext,
179                CSSM_DB_RECORDTYPE RecordType,
180                CSSM_DB_UNIQUE_RECORD &inoutUniqueRecordIdentifier,
181                const CSSM_DB_RECORD_ATTRIBUTE_DATA *inAttributesToBeModified,
182                const CssmData *inDataToBeModified,
183                CSSM_DB_MODIFY_MODE ModifyMode) = 0;
184
185    virtual CSSM_HANDLE
186    dataGetFirst (DbContext &dbContext,
187                  const CssmQuery *inQuery,
188                  CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
189                  CssmData *inoutData,
190                  CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord) = 0;
191
192    virtual bool
193    dataGetNext (DbContext &dbContext,
194                 CSSM_HANDLE inResultsHandle,
195                 CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
196                 CssmData *inoutData,
197                 CSSM_DB_UNIQUE_RECORD_PTR &outUniqueRecord) = 0;
198
199    virtual void
200    dataAbortQuery (DbContext &dbContext,
201                    CSSM_HANDLE inResultsHandle) = 0;
202
203    virtual void
204    dataGetFromUniqueRecordId (DbContext &dbContext,
205                               const CSSM_DB_UNIQUE_RECORD &inUniqueRecord,
206                               CSSM_DB_RECORD_ATTRIBUTE_DATA_PTR inoutAttributes,
207                               CssmData *inoutData) = 0;
208
209    virtual void
210    freeUniqueRecord (DbContext &dbContext,
211                      CSSM_DB_UNIQUE_RECORD &inUniqueRecord) = 0;
212
213	virtual void
214	passThrough(DbContext &dbContext,
215				uint32 passThroughId,
216				const void *inputParams,
217				void **outputParams) = 0;
218
219    Database (const DbName &inDbName);
220    virtual ~Database ();
221
222    virtual bool hasDbContexts();
223
224    // XXX @@@ Think about consequences of race conditions between DbOpen/DbCreate/DbDelete/DbClose
225    // on databases with the same name at the same time.
226    //virtual DbContext &insertDbContext();
227    //virtual void removeDbContext(DbContext &inDbContext);
228
229    const DbName mDbName;
230protected:
231    // Subclasses must implement this method.
232    virtual DbContext *makeDbContext(DatabaseSession &inDatabaseSession,
233                                     CSSM_DB_ACCESS_TYPE inAccessRequest,
234                                     const AccessCredentials *inAccessCred,
235                                     const void *inOpenParameters) = 0;
236private:
237    typedef set<DbContext *> DbContextSet;
238    DbContextSet mDbContextSet;
239    Mutex mDbContextSetLock;
240};
241
242} // end namespace Security
243
244#ifdef _CPP_DATABASE
245# pragma export off
246#endif
247
248#endif //_DATABASE_H_
249