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