]> git.saurik.com Git - apple/security.git/blob - AppleCSPDL/SSDatabase.cpp
Security-54.1.3.tar.gz
[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::lock()
60 {
61 mClientSession.lock(dbHandle());
62
63 }
64
65 void
66 SSDatabaseImpl::unlock()
67 {
68 mClientSession.unlock(dbHandle());
69 }
70
71 void
72 SSDatabaseImpl::unlock(const CSSM_DATA &password)
73 {
74 mClientSession.unlock(dbHandle(), CssmData::overlay(password));
75 }
76
77 void
78 SSDatabaseImpl::getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep)
79 {
80 DBParameters parameters;
81 mClientSession.getDbParameters(dbHandle(), parameters);
82 outIdleTimeout = parameters.idleTimeout;
83 outLockOnSleep = parameters.lockOnSleep;
84 }
85
86 void
87 SSDatabaseImpl::setSettings(uint32 inIdleTimeout, bool inLockOnSleep)
88 {
89 DBParameters parameters;
90 parameters.idleTimeout = inIdleTimeout;
91 parameters.lockOnSleep = inLockOnSleep;
92 mClientSession.setDbParameters(dbHandle(), parameters);
93
94 // Reencode the db blob.
95 CssmDataContainer dbb(allocator());
96 mClientSession.encodeDb(mSSDbHandle, dbb, allocator());
97 mDbBlobId->modify(DBBlobRelationID, NULL, &dbb, CSSM_DB_MODIFY_ATTRIBUTE_NONE);
98 }
99
100 bool
101 SSDatabaseImpl::isLocked()
102 {
103 return mClientSession.isLocked(dbHandle());
104 }
105
106 void
107 SSDatabaseImpl::changePassphrase(const CSSM_ACCESS_CREDENTIALS *cred)
108 {
109 mClientSession.changePassphrase(dbHandle(), AccessCredentials::overlay(cred));
110
111 // Reencode the db blob.
112 CssmDataContainer dbb(allocator());
113 mClientSession.encodeDb(mSSDbHandle, dbb, allocator());
114 mDbBlobId->modify(DBBlobRelationID, NULL, &dbb, CSSM_DB_MODIFY_ATTRIBUTE_NONE);
115 }
116
117 DbHandle
118 SSDatabaseImpl::dbHandle()
119 {
120 activate();
121 if (mForked()) {
122 // re-establish the dbHandle with the SecurityServer
123 CssmDataContainer dbb(allocator());
124 mDbBlobId->get(NULL, &dbb);
125 mSSDbHandle = mClientSession.decodeDb(mIdentifier,
126 AccessCredentials::overlay(accessCredentials()), dbb);
127 }
128 return mSSDbHandle;
129 }
130
131 void
132 SSDatabaseImpl::create(const DLDbIdentifier &dlDbIdentifier)
133 {
134 mIdentifier = dlDbIdentifier;
135 DbImpl::create();
136
137 try
138 {
139 // @@@ The CSSM_DB_SCHEMA_ATTRIBUTE_INFO and CSSM_DB_SCHEMA_INDEX_INFO
140 // arguments should be optional.
141 createRelation(DBBlobRelationID, DBBlobRelationName,
142 0, (CSSM_DB_SCHEMA_ATTRIBUTE_INFO *)42,
143 0, (CSSM_DB_SCHEMA_INDEX_INFO *)42);
144
145 // @@@ Only iff not already in mDbInfo
146 createRelation(CSSM_DL_DB_RECORD_PUBLIC_KEY, "CSSM_DL_DB_RECORD_PUBLIC_KEY",
147 KeySchema::KeySchemaAttributeCount, KeySchema::KeySchemaAttributeList,
148 KeySchema::KeySchemaIndexCount, KeySchema::KeySchemaIndexList);
149
150 // @@@ Only iff not already in mDbInfo
151 createRelation(CSSM_DL_DB_RECORD_PRIVATE_KEY, "CSSM_DL_DB_RECORD_PRIVATE_KEY",
152 KeySchema::KeySchemaAttributeCount, KeySchema::KeySchemaAttributeList,
153 KeySchema::KeySchemaIndexCount, KeySchema::KeySchemaIndexList);
154
155 // @@@ Only iff not already in mDbInfo
156 createRelation(CSSM_DL_DB_RECORD_SYMMETRIC_KEY, "CSSM_DL_DB_RECORD_SYMMETRIC_KEY",
157 KeySchema::KeySchemaAttributeCount, KeySchema::KeySchemaAttributeList,
158 KeySchema::KeySchemaIndexCount, KeySchema::KeySchemaIndexList);
159
160 DBParameters dbParameters;
161 memset(&dbParameters, 0, sizeof(DBParameters));
162 dbParameters.idleTimeout = kDefaultIdleTimeout;
163 dbParameters.lockOnSleep = kDefaultLockOnSleep;
164
165 const AccessCredentials *cred = NULL;
166 const AclEntryInput *owner = NULL;
167 if (resourceControlContext())
168 {
169 cred = AccessCredentials::overlay(resourceControlContext()->AccessCred);
170 owner = &AclEntryInput::overlay(resourceControlContext()->InitialAclEntry);
171 }
172 mSSDbHandle = mClientSession.createDb(dlDbIdentifier, cred, owner, dbParameters);
173 CssmDataContainer dbb(allocator());
174 mClientSession.encodeDb(mSSDbHandle, dbb, allocator());
175 mDbBlobId = Db::Impl::insert(DBBlobRelationID, NULL, &dbb);
176 }
177 catch(...)
178 {
179 DbImpl::deleteDb();
180 throw;
181 }
182 }
183
184 void
185 SSDatabaseImpl::open(const DLDbIdentifier &dlDbIdentifier)
186 {
187 mIdentifier = dlDbIdentifier;
188 Db::Impl::open();
189
190 DbCursor cursor(SSDatabase(this));
191 cursor->recordType(DBBlobRelationID);
192 CssmDataContainer dbb(allocator());
193 if (!cursor->next(NULL, &dbb, mDbBlobId))
194 CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT);
195
196 mSSDbHandle = mClientSession.decodeDb(dlDbIdentifier, AccessCredentials::overlay(accessCredentials()), dbb);
197 }
198
199 DbUniqueRecordImpl *
200 SSDatabaseImpl::newDbUniqueRecord()
201 {
202 return new SSUniqueRecordImpl(SSDatabase(this));
203 }
204
205
206 SSUniqueRecordImpl::SSUniqueRecordImpl(const SSDatabase &db)
207 : DbUniqueRecord::Impl(db)
208 {
209 }
210
211 SSUniqueRecordImpl::~SSUniqueRecordImpl()
212 {
213 }
214
215 SSDatabase
216 SSUniqueRecordImpl::database() const
217 {
218 return parent<SSDatabase>();
219 }
220