]> git.saurik.com Git - apple/security.git/blob - AppleCSPDL/SSDatabase.cpp
31cffa8ac9b717a513272ab5d4208ce00c6236d8
[apple/security.git] / AppleCSPDL / SSDatabase.cpp
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 // SSDatabase.cpp - Security Server database object
21 //
22 #include "SSDatabase.h"
23
24 #include "KeySchema.h"
25
26 using namespace CssmClient;
27 using namespace SecurityServer;
28
29 const char *const SSDatabaseImpl::DBBlobRelationName = "DBBlob";
30
31
32 SSDatabaseImpl::SSDatabaseImpl(ClientSession &inClientSession, const CssmClient::DL &dl,
33 const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation)
34 : Db::Impl(dl, inDbName, inDbLocation), mClientSession(inClientSession), mSSDbHandle(noDb)
35 {
36 }
37
38 SSDatabaseImpl::~SSDatabaseImpl()
39 {
40 if (mSSDbHandle != noDb)
41 mClientSession.releaseDb(mSSDbHandle);
42 }
43
44 SSUniqueRecord
45 SSDatabaseImpl::insert(CSSM_DB_RECORDTYPE recordType,
46 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
47 const CSSM_DATA *data, bool)
48 {
49 SSUniqueRecord uniqueId(SSDatabase(this));
50 check(CSSM_DL_DataInsert(handle(), recordType,
51 attributes,
52 data, uniqueId));
53 // Activate uniqueId so CSSM_DL_FreeUniqueRecord() gets called when it goes out of scope.
54 uniqueId->activate();
55 return uniqueId;
56 }
57
58 void
59 SSDatabaseImpl::authenticate(CSSM_DB_ACCESS_TYPE inAccessRequest,
60 const CSSM_ACCESS_CREDENTIALS *inAccessCredentials)
61 {
62 mClientSession.authenticateDb(dbHandle(), inAccessRequest,
63 AccessCredentials::overlay(inAccessCredentials));
64 }
65
66 void
67 SSDatabaseImpl::lock()
68 {
69 mClientSession.lock(dbHandle());
70
71 }
72
73 void
74 SSDatabaseImpl::unlock()
75 {
76 mClientSession.unlock(dbHandle());
77 }
78
79 void
80 SSDatabaseImpl::unlock(const CSSM_DATA &password)
81 {
82 mClientSession.unlock(dbHandle(), CssmData::overlay(password));
83 }
84
85 void
86 SSDatabaseImpl::getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep)
87 {
88 DBParameters parameters;
89 mClientSession.getDbParameters(dbHandle(), parameters);
90 outIdleTimeout = parameters.idleTimeout;
91 outLockOnSleep = parameters.lockOnSleep;
92 }
93
94 void
95 SSDatabaseImpl::setSettings(uint32 inIdleTimeout, bool inLockOnSleep)
96 {
97 DBParameters parameters;
98 parameters.idleTimeout = inIdleTimeout;
99 parameters.lockOnSleep = inLockOnSleep;
100 mClientSession.setDbParameters(dbHandle(), parameters);
101
102 // Reencode the db blob.
103 CssmDataContainer dbb(allocator());
104 mClientSession.encodeDb(mSSDbHandle, dbb, allocator());
105 getDbBlobId(NULL)->modify(DBBlobRelationID, NULL, &dbb, CSSM_DB_MODIFY_ATTRIBUTE_NONE);
106 }
107
108 bool
109 SSDatabaseImpl::isLocked()
110 {
111 return mClientSession.isLocked(dbHandle());
112 }
113
114 void
115 SSDatabaseImpl::changePassphrase(const CSSM_ACCESS_CREDENTIALS *cred)
116 {
117 mClientSession.changePassphrase(dbHandle(), AccessCredentials::overlay(cred));
118
119 // Reencode the db blob.
120 CssmDataContainer dbb(allocator());
121 mClientSession.encodeDb(mSSDbHandle, dbb, allocator());
122 getDbBlobId(NULL)->modify(DBBlobRelationID, NULL, &dbb, CSSM_DB_MODIFY_ATTRIBUTE_NONE);
123 }
124
125 DbHandle
126 SSDatabaseImpl::dbHandle()
127 {
128 activate();
129 if (mForked()) {
130 // re-establish the dbHandle with the SecurityServer
131 CssmDataContainer dbb(allocator());
132 getDbBlobId(&dbb);
133 mSSDbHandle = mClientSession.decodeDb(mIdentifier,
134 AccessCredentials::overlay(accessCredentials()), dbb);
135 }
136 return mSSDbHandle;
137 }
138
139 void
140 SSDatabaseImpl::create(const DLDbIdentifier &dlDbIdentifier)
141 {
142 mIdentifier = dlDbIdentifier;
143 DbImpl::create();
144
145 try
146 {
147 // @@@ The CSSM_DB_SCHEMA_ATTRIBUTE_INFO and CSSM_DB_SCHEMA_INDEX_INFO
148 // arguments should be optional.
149 createRelation(DBBlobRelationID, DBBlobRelationName,
150 0, (CSSM_DB_SCHEMA_ATTRIBUTE_INFO *)42,
151 0, (CSSM_DB_SCHEMA_INDEX_INFO *)42);
152
153 // @@@ Only iff not already in mDbInfo
154 createRelation(CSSM_DL_DB_RECORD_PUBLIC_KEY, "CSSM_DL_DB_RECORD_PUBLIC_KEY",
155 KeySchema::KeySchemaAttributeCount, KeySchema::KeySchemaAttributeList,
156 KeySchema::KeySchemaIndexCount, KeySchema::KeySchemaIndexList);
157
158 // @@@ Only iff not already in mDbInfo
159 createRelation(CSSM_DL_DB_RECORD_PRIVATE_KEY, "CSSM_DL_DB_RECORD_PRIVATE_KEY",
160 KeySchema::KeySchemaAttributeCount, KeySchema::KeySchemaAttributeList,
161 KeySchema::KeySchemaIndexCount, KeySchema::KeySchemaIndexList);
162
163 // @@@ Only iff not already in mDbInfo
164 createRelation(CSSM_DL_DB_RECORD_SYMMETRIC_KEY, "CSSM_DL_DB_RECORD_SYMMETRIC_KEY",
165 KeySchema::KeySchemaAttributeCount, KeySchema::KeySchemaAttributeList,
166 KeySchema::KeySchemaIndexCount, KeySchema::KeySchemaIndexList);
167
168 DBParameters dbParameters;
169 memset(&dbParameters, 0, sizeof(DBParameters));
170 dbParameters.idleTimeout = kDefaultIdleTimeout;
171 dbParameters.lockOnSleep = kDefaultLockOnSleep;
172
173 const AccessCredentials *cred = NULL;
174 const AclEntryInput *owner = NULL;
175 if (resourceControlContext())
176 {
177 cred = AccessCredentials::overlay(resourceControlContext()->AccessCred);
178 owner = &AclEntryInput::overlay(resourceControlContext()->InitialAclEntry);
179 }
180 mSSDbHandle = mClientSession.createDb(dlDbIdentifier, cred, owner, dbParameters);
181 CssmDataContainer dbb(allocator());
182 mClientSession.encodeDb(mSSDbHandle, dbb, allocator());
183 Db::Impl::insert(DBBlobRelationID, NULL, &dbb);
184 }
185 catch(...)
186 {
187 DbImpl::deleteDb();
188 throw;
189 }
190 }
191
192 void
193 SSDatabaseImpl::open(const DLDbIdentifier &dlDbIdentifier)
194 {
195 mIdentifier = dlDbIdentifier;
196 Db::Impl::open();
197
198 CssmDataContainer dbb(allocator());
199 getDbBlobId(&dbb);
200
201 mSSDbHandle = mClientSession.decodeDb(dlDbIdentifier, AccessCredentials::overlay(accessCredentials()), dbb);
202 }
203
204 DbUniqueRecordImpl *
205 SSDatabaseImpl::newDbUniqueRecord()
206 {
207 return new SSUniqueRecordImpl(SSDatabase(this));
208 }
209
210 CssmClient::DbUniqueRecord
211 SSDatabaseImpl::getDbBlobId(CssmDataContainer *dbb)
212 {
213 CssmClient::DbUniqueRecord dbBlobId;
214
215 DbCursor cursor(SSDatabase(this));
216 cursor->recordType(DBBlobRelationID);
217 if (!cursor->next(NULL, dbb, dbBlobId))
218 CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
219
220 return dbBlobId;
221 }
222
223
224
225 SSUniqueRecordImpl::SSUniqueRecordImpl(const SSDatabase &db)
226 : DbUniqueRecord::Impl(db)
227 {
228 }
229
230 SSUniqueRecordImpl::~SSUniqueRecordImpl()
231 {
232 }
233
234 SSDatabase
235 SSUniqueRecordImpl::database() const
236 {
237 return parent<SSDatabase>();
238 }