]> git.saurik.com Git - apple/security.git/blob - libsecurity_cdsa_client/lib/dlclient.h
Security-55179.1.tar.gz
[apple/security.git] / libsecurity_cdsa_client / lib / dlclient.h
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 // dlclient - client interface to CSSM DLs and their operations
21 //
22
23 #ifndef _H_CDSA_CLIENT_DLCLIENT
24 #define _H_CDSA_CLIENT_DLCLIENT 1
25
26 #include <security_cdsa_client/cssmclient.h>
27 #include <security_cdsa_client/dliterators.h>
28 #include <security_cdsa_client/aclclient.h>
29 #include <security_cdsa_client/DLDBList.h>
30 #include <security_cdsa_utilities/cssmacl.h>
31 #include <security_cdsa_utilities/cssmdb.h>
32 #include <security_cdsa_utilities/cssmdata.h>
33
34
35 namespace Security
36 {
37
38 namespace CssmClient
39 {
40
41 #define CSSM_DB_ATTR(ATTR) ATTR
42 #define CSSM_DB_ATTR_SCHEMA(ATTR) ATTR ## Schema
43
44 #define CSSM_DB_INDEX(ATTR) ATTR ## Index
45 #define CSSM_DB_UNIQUE(ATTR) ATTR ## Unique
46
47 //
48 // Helper macro for declaring and defining a Db index unique and non-unique attributes
49 //
50 #define CSSM_DB_INDEX_DECL(ATTR) static const CSSM_DB_INDEX_INFO CSSM_DB_INDEX(ATTR)
51 #define CSSM_DB_UNIQUE_DECL(ATTR) static const CSSM_DB_INDEX_INFO CSSM_DB_UNIQUE(ATTR)
52
53
54 //
55 // Use this macro for defining a non-unique attribute
56 //
57 #define CSSM_DB_INDEX_DEF(ATTR) \
58 const CSSM_DB_INDEX_INFO CSSM_DB_INDEX(ATTR) = \
59 { \
60 CSSM_DB_INDEX_NONUNIQUE, \
61 CSSM_DB_INDEX_ON_ATTRIBUTE, \
62 CSSM_DB_ATTR(ATTR) \
63 }
64
65 //
66 // Use this macro for defining a unique attribute
67
68 //
69 #define CSSM_DB_UNIQUE_DEF(ATTR) \
70 const CSSM_DB_INDEX_INFO CSSM_DB_UNIQUE(ATTR) = \
71 { \
72 CSSM_DB_INDEX_UNIQUE, \
73 CSSM_DB_INDEX_ON_ATTRIBUTE, \
74 CSSM_DB_ATTR(ATTR) \
75 }
76
77
78
79 //
80 // Helper macro for declaring and defining a Db schema attributes
81 // Use this macro in your header to declare each attribute you require.
82 //
83 #define CSSM_DB_ATTR_DECL(ATTR) \
84 static const CSSM_DB_ATTRIBUTE_INFO CSSM_DB_ATTR(ATTR); \
85 static const CSSM_DB_SCHEMA_ATTRIBUTE_INFO CSSM_DB_ATTR_SCHEMA(ATTR)
86
87 //
88 // Don't directly use this macro use one of the below instead.
89 //
90 #define CSSM_DB_ATTR_DEFINE_SCHEMA(ATTR, INTEGER, NAME, OID_LEN, OID_DATA, VALUETYPE) \
91 const CSSM_DB_SCHEMA_ATTRIBUTE_INFO CSSM_DB_ATTR_SCHEMA(ATTR) = \
92 { \
93 INTEGER, \
94 NAME, \
95 { OID_LEN, OID_DATA }, \
96 CSSM_DB_ATTRIBUTE_FORMAT_ ## VALUETYPE \
97 }
98
99
100 //
101 // Use one of the following macros to defined each declared attribute required by your application.
102 //
103 //
104 // Use this macro to define attributes which are looked up by integer AttributeID.
105 //
106 #define CSSM_DB_INTEGER_ATTR(ATTR, INTEGER, NAME, OID_LEN, OID_DATA, VALUETYPE) \
107 const CSSM_DB_ATTRIBUTE_INFO ATTR = \
108 { \
109 CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER, \
110 {(char *)INTEGER}, \
111 CSSM_DB_ATTRIBUTE_FORMAT_ ## VALUETYPE \
112 };\
113 \
114 CSSM_DB_ATTR_DEFINE_SCHEMA(ATTR, INTEGER, NAME, OID_LEN, OID_DATA, VALUETYPE)
115
116 //
117 // Use this macro to define attributes which are looked up by string AttributeName.
118 //
119 #define CSSM_DB_NAME_ATTR(ATTR, INTEGER, NAME, OID_LEN, OID_DATA, VALUETYPE) \
120 const CSSM_DB_ATTRIBUTE_INFO ATTR = \
121 { \
122 CSSM_DB_ATTRIBUTE_NAME_AS_STRING, \
123 {NAME}, \
124 CSSM_DB_ATTRIBUTE_FORMAT_ ## VALUETYPE \
125 };\
126 \
127 CSSM_DB_ATTR_DEFINE_SCHEMA(ATTR, INTEGER, NAME, OID_LEN, OID_DATA, VALUETYPE)
128
129 //
130 // Use this macro to define attributes which are looked up by OID AttributeNameID.
131 // XXX This does not work yet.
132 //
133 #define CSSM_DB_OID_ATTR(ATTR, INTEGER, NAME, OID_LEN, OID_DATA, VALUETYPE) \
134 const CSSM_DB_ATTRIBUTE_INFO ATTR = \
135 { \
136 CSSM_DB_ATTRIBUTE_NAME_AS_OID, \
137 {{OID_LEN, OID_DATA}}, \
138 CSSM_DB_ATTRIBUTE_FORMAT_ ## VALUETYPE \
139 };\
140 \
141 CSSM_DB_ATTR_DEFINE_SCHEMA(ATTR, INTEGER, NAME, OID_LEN, OID_DATA, VALUETYPE)
142
143
144 //
145 // Use this macro to define attributes which are part of the primary key.
146 //
147 #define CSSM_DB_PRIMARKEY_ATTR(ATTR, NAME) \
148 const CSSM_DB_ATTRIBUTE_INFO ATTR = \
149 { \
150 CSSM_DB_INDEX_UNIQUE, \
151 CSSM_DB_INDEX_ON_ATTRIBUTE, \
152 CSSM_DB_ATTRIBUTE_FORMAT_ ## VALUETYPE \
153 };\
154 \
155 CSSM_DB_ATTR_DEFINE_SCHEMA(ATTR, INTEGER, NAME, OID_LEN, OID_DATA, VALUETYPE)
156
157
158
159 //
160 // Maker interfaces used by various Impl objects
161 //
162
163 // DbMaker -- someone who can create a new DbImpl.
164 class DbImpl;
165 class DbMaker
166 {
167 public:
168 virtual ~DbMaker();
169 virtual DbImpl *newDb(const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation) = 0;
170 };
171
172 // DbCursorMaker -- someone who can create a new DbCursorImpl.
173 class DbCursorImpl;
174 class DbCursorMaker
175 {
176 public:
177 virtual ~DbCursorMaker();
178 virtual DbCursorImpl *newDbCursor(const CSSM_QUERY &query, Allocator &allocator) = 0;
179 virtual DbCursorImpl *newDbCursor(uint32 capacity, Allocator &allocator) = 0;
180 };
181
182 // DbUniqueRecordMaker -- someone who can create a new DbUniqueRecordImpl.
183 class DbUniqueRecordImpl;
184 class DbUniqueRecordMaker
185 {
186 public:
187 virtual ~DbUniqueRecordMaker();
188 virtual DbUniqueRecordImpl *newDbUniqueRecord() = 0;
189 };
190
191
192 //
193 // A DL attachment
194 //
195 class DLImpl : public AttachmentImpl, public DbMaker
196 {
197 public:
198 DLImpl(const Guid &guid);
199 DLImpl(const Module &module);
200 virtual ~DLImpl();
201
202 virtual void getDbNames(char **);
203 virtual void freeNameList(char **);
204
205 // DbMaker
206 virtual DbImpl *newDb(const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation);
207 private:
208 };
209
210 class DL : public Attachment
211 {
212 public:
213 typedef DLImpl Impl;
214
215 explicit DL(Impl *impl) : Attachment(impl) {}
216 DL() : Attachment(NULL) {}
217 DL(const Guid &guid) : Attachment(new Impl(guid)) {}
218 DL(const Module &module) : Attachment(new Impl(module)) {}
219
220 Impl *operator ->() const { return &impl<Impl>(); }
221 Impl &operator *() const { return impl<Impl>(); }
222
223 // Conversion to DbMaker.
224 operator DbMaker &() const { return impl<Impl>(); }
225 };
226
227
228 class DbAttributes;
229 class DbUniqueRecord;
230 class Db;
231
232
233 //
234 // A CSSM_DLDB handle.
235 // Dbs always belong to DLs (DL attachments)
236 //
237 class DbImpl : public ObjectImpl, public AclBearer,
238 public DbCursorMaker, public DbUniqueRecordMaker
239 {
240 public:
241 DbImpl(const DL &dl, const char *inDbName = NULL, const CSSM_NET_ADDRESS *inDbLocation = NULL);
242 virtual ~DbImpl();
243
244 DL dl() const { return parent<DL>(); }
245 Module module() const { return dl()->module(); }
246
247 virtual void open();
248 virtual void create();
249 virtual void createWithBlob (CssmData &blob);
250 virtual void close();
251 virtual void deleteDb();
252 virtual void rename(const char *newName);
253 virtual void authenticate(CSSM_DB_ACCESS_TYPE inAccessRequest,
254 const CSSM_ACCESS_CREDENTIALS *inAccessCredentials);
255 virtual void name(char *&outName); // CSSM_DL_GetDbNameFromHandle()
256
257 virtual void createRelation(CSSM_DB_RECORDTYPE inRelationID,
258 const char *inRelationName,
259 uint32 inNumberOfAttributes,
260 const CSSM_DB_SCHEMA_ATTRIBUTE_INFO *pAttributeInfo,
261 uint32 inNumberOfIndexes,
262 const CSSM_DB_SCHEMA_INDEX_INFO *pIndexInfo);
263 virtual void destroyRelation(CSSM_DB_RECORDTYPE inRelationID);
264
265 virtual DbUniqueRecord insert(CSSM_DB_RECORDTYPE recordType,
266 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
267 const CSSM_DATA *data);
268
269 virtual DbUniqueRecord insertWithoutEncryption(CSSM_DB_RECORDTYPE recordType,
270 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
271 CSSM_DATA *data);
272
273 const CSSM_DL_DB_HANDLE &handle() { activate(); return mHandle; }
274
275 const DbName &dbName() { return mDbName; }
276 void dbName(const DbName &dbName) { mDbName = dbName; }
277
278 // Attempt to get a (cached) name from CSSM_DL_GetDbNameFromHandle(), falls
279 // back to the name passed in to the constructor if this fails.
280 const char *name();
281
282 const CSSM_NET_ADDRESS *dbLocation() const { return mDbName.dbLocation(); }
283
284 CSSM_DB_ACCESS_TYPE accessRequest() const { return mAccessRequest; }
285 void accessRequest(CSSM_DB_ACCESS_TYPE inAccessRequest)
286 { mAccessRequest = inAccessRequest; }
287
288 const CSSM_ACCESS_CREDENTIALS *accessCredentials() const
289 { return mAccessCredentials; }
290 void accessCredentials(const CSSM_ACCESS_CREDENTIALS *inAccessCredentials)
291 { mAccessCredentials = inAccessCredentials; }
292
293 const void *openParameters() const { return mOpenParameters; }
294 void openParameters(const void *inOpenParameters)
295 { mOpenParameters = inOpenParameters; }
296
297 const CSSM_DBINFO *dbInfo() const { return mDbInfo; }
298 void dbInfo(const CSSM_DBINFO *inDbInfo) { mDbInfo = inDbInfo; }
299
300 const ResourceControlContext *resourceControlContext() const
301 { return mResourceControlContext; }
302 void resourceControlContext(const CSSM_RESOURCE_CONTROL_CONTEXT *inResourceControlContext)
303 { mResourceControlContext = ResourceControlContext::overlay(inResourceControlContext); }
304
305 void passThrough(uint32 passThroughId, const void *in, void **out = NULL);
306
307 template <class TIn, class TOut>
308 void passThrough(uint32 passThroughId, const TIn *in, TOut *out = NULL)
309 { passThrough(passThroughId, (const void *)in, (void **)out); }
310
311 // Passthrough functions (only implemented by AppleCSPDL).
312 virtual void lock();
313 virtual void unlock();
314 virtual void unlock(const CSSM_DATA &password);
315 virtual void getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep);
316 virtual void setSettings(uint32 inIdleTimeout, bool inLockOnSleep);
317 virtual bool isLocked();
318 virtual void changePassphrase(const CSSM_ACCESS_CREDENTIALS *cred);
319 virtual void recode(const CSSM_DATA &data, const CSSM_DATA &extraData);
320 virtual void copyBlob(CssmData &data);
321 virtual void setBatchMode(Boolean mode, Boolean rollback);
322
323 // Utility methods
324
325 // Always use the dbName and dbLocation that were passed in during
326 // construction.
327 virtual DLDbIdentifier dlDbIdentifier();
328
329 // DbCursorMaker
330 virtual DbCursorImpl *newDbCursor(const CSSM_QUERY &query, Allocator &allocator);
331 virtual DbCursorImpl *newDbCursor(uint32 capacity, Allocator &allocator);
332
333 // DbUniqueRecordMaker
334 virtual DbUniqueRecordImpl *newDbUniqueRecord();
335
336 // Acl manipulation
337 void getAcl(AutoAclEntryInfoList &aclInfos, const char *selectionTag = NULL) const;
338 void changeAcl(const CSSM_ACL_EDIT &aclEdit,
339 const CSSM_ACCESS_CREDENTIALS *accessCred);
340
341 // Acl owner manipulation
342 void getOwner(AutoAclOwnerPrototype &owner) const;
343 void changeOwner(const CSSM_ACL_OWNER_PROTOTYPE &newOwner,
344 const CSSM_ACCESS_CREDENTIALS *accessCred = NULL);
345
346 // default-credential hook
347 class DefaultCredentialsMaker {
348 public:
349 virtual ~DefaultCredentialsMaker();
350 virtual const AccessCredentials *makeCredentials() = 0;
351 };
352
353 void defaultCredentials(DefaultCredentialsMaker *maker); // NULL to turn off
354
355 void activate();
356
357 protected:
358 void deactivate();
359
360 private:
361 CSSM_DL_DB_HANDLE mHandle; // CSSM DLDB handle
362
363 DbName mDbName;
364 bool mUseNameFromHandle; // false if CSSM_DL_GetDbNameFromHandle failed
365 char *mNameFromHandle; // Cached CSSM_DL_GetDbNameFromHandle result.
366 CSSM_DB_ACCESS_TYPE mAccessRequest;
367 const CSSM_ACCESS_CREDENTIALS *mAccessCredentials;
368 DefaultCredentialsMaker *mDefaultCredentials;
369 const void *mOpenParameters;
370
371 // Arguments to create
372 const CSSM_DBINFO *mDbInfo;
373 const ResourceControlContext *mResourceControlContext;
374 };
375
376
377 class Db : public Object, public DLAccess
378 {
379 public:
380 typedef DbImpl Impl;
381 typedef Impl::DefaultCredentialsMaker DefaultCredentialsMaker;
382
383 explicit Db(Impl *impl) : Object(impl) {}
384 Db() : Object(NULL) {}
385 Db(DbMaker &maker, const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation = NULL)
386 : Object(maker.newDb(inDbName, inDbLocation)) {}
387
388 Impl *operator ->() const { return &impl<Impl>(); }
389 Impl &operator *() const { return impl<Impl>(); }
390
391 // Conversion to DbCursorMaker.
392 operator DbCursorMaker &() const { return impl<Impl>(); }
393 // Conversion to DbUniqueRecordMaker.
394 operator DbUniqueRecordMaker &() const { return impl<Impl>(); }
395
396 const CSSM_DL_DB_HANDLE &handle() { return impl<Impl>().handle(); }
397
398 protected:
399 // DLAccess adapters
400 CSSM_HANDLE dlGetFirst(const CSSM_QUERY &query,
401 CSSM_DB_RECORD_ATTRIBUTE_DATA &attributes, CSSM_DATA *data,
402 CSSM_DB_UNIQUE_RECORD *&id);
403 bool dlGetNext(CSSM_HANDLE handle,
404 CSSM_DB_RECORD_ATTRIBUTE_DATA &attributes, CSSM_DATA *data,
405 CSSM_DB_UNIQUE_RECORD *&id);
406 void dlAbortQuery(CSSM_HANDLE handle);
407 void dlFreeUniqueId(CSSM_DB_UNIQUE_RECORD *id);
408 void dlDeleteRecord(CSSM_DB_UNIQUE_RECORD *id);
409 Allocator &allocator();
410 };
411
412 //
413 // DbCursor
414 //
415
416 // This class is still abstract. You must subclass it in order to be able to instantiate an instance.
417 class DbCursorImpl : public ObjectImpl, public CssmAutoQuery
418 {
419 public:
420 DbCursorImpl(const Object &parent, const CSSM_QUERY &query, Allocator &allocator);
421 DbCursorImpl(const Object &parent, uint32 capacity, Allocator &allocator);
422
423 virtual Allocator &allocator() const;
424 virtual void allocator(Allocator &alloc);
425
426 virtual bool next(DbAttributes *attributes, ::CssmDataContainer *data, DbUniqueRecord &uniqueId) = 0;
427 void abort() { deactivate(); }
428 };
429
430 class DbCursor : public Object
431 {
432 public:
433 typedef DbCursorImpl Impl;
434
435 explicit DbCursor(Impl *impl) : Object(impl) {}
436 DbCursor() : Object(NULL) {}
437 DbCursor(DbCursorMaker &maker, const CSSM_QUERY &query,
438 Allocator &allocator = Allocator::standard())
439 : Object(maker.newDbCursor(query, allocator)) {}
440 DbCursor(DbCursorMaker &maker, uint32 capacity = 0,
441 Allocator &allocator = Allocator::standard())
442 : Object(maker.newDbCursor(capacity, allocator)) {}
443
444 Impl *operator ->() const { return &impl<Impl>(); }
445 Impl &operator *() const { return impl<Impl>(); }
446 };
447
448
449 //
450 // DbUniqueRecord
451 //
452 class DbUniqueRecordImpl : public ObjectImpl
453 {
454 public:
455 DbUniqueRecordImpl(const Db &db);
456 virtual ~DbUniqueRecordImpl();
457
458 virtual void deleteRecord();
459 virtual void modify(CSSM_DB_RECORDTYPE recordType,
460 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
461 const CSSM_DATA *data,
462 CSSM_DB_MODIFY_MODE modifyMode);
463
464 virtual void modifyWithoutEncryption (CSSM_DB_RECORDTYPE recordType,
465 const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
466 const CSSM_DATA *data,
467 CSSM_DB_MODIFY_MODE modifyMode);
468
469 virtual void get(DbAttributes *attributes, ::CssmDataContainer *data);
470
471 virtual void getWithoutEncryption(DbAttributes *attributes, ::CssmDataContainer *data);
472
473 Db database() const { return parent<Db>(); }
474
475 void free() { deactivate(); }
476
477 // Client must call activate() after calling this function if mUniqueId is successfully set.
478 operator CSSM_DB_UNIQUE_RECORD_PTR *() { if (mActive) free(); return &mUniqueId; }
479
480 operator CSSM_DB_UNIQUE_RECORD *() { return mUniqueId; }
481 operator const CSSM_DB_UNIQUE_RECORD *() const { return mUniqueId; }
482
483 void activate();
484
485 void getRecordIdentifier(CSSM_DATA &data);
486
487 void setUniqueRecordPtr (CSSM_DB_UNIQUE_RECORD_PTR uniquePtr); // because cast overloading is evil!
488
489 protected:
490 void deactivate();
491
492 CSSM_DB_UNIQUE_RECORD_PTR mUniqueId;
493 bool mDestroyID;
494 RecursiveMutex mActivateMutex;
495 };
496
497 class DbUniqueRecord : public Object
498 {
499 public:
500 typedef DbUniqueRecordImpl Impl;
501
502 explicit DbUniqueRecord(Impl *impl) : Object(impl) {}
503 DbUniqueRecord() : Object(NULL) {}
504 DbUniqueRecord(DbUniqueRecordMaker &maker) : Object(maker.newDbUniqueRecord()) {}
505
506 Impl *operator ->() { return &impl<Impl>(); }
507 Impl &operator *() { return impl<Impl>(); }
508 const Impl &operator *() const { return impl<Impl>(); }
509
510 // Conversion operators must be here.
511
512 // Client must activate after calling this function if mUniqueId is successfully set.
513 operator CSSM_DB_UNIQUE_RECORD_PTR *() { return **this; }
514
515 operator CSSM_DB_UNIQUE_RECORD *() { return **this; }
516 operator const CSSM_DB_UNIQUE_RECORD *() const { return **this; }
517 };
518
519
520 //
521 // DbAttributes
522 //
523 class DbAttributes : public CssmAutoDbRecordAttributeData
524 {
525 public:
526 DbAttributes();
527 DbAttributes(const Db &db, uint32 capacity = 0, Allocator &allocator = Allocator::standard());
528 };
529
530
531 //
532 // DbDbCursor -- concrete subclass of DbCursorImpl for querying Db's
533 //
534 class DbDbCursorImpl : public DbCursorImpl
535 {
536 public:
537 DbDbCursorImpl(const Db &db, const CSSM_QUERY &query, Allocator &allocator);
538 DbDbCursorImpl(const Db &db, uint32 capacity, Allocator &allocator);
539 virtual ~DbDbCursorImpl();
540
541 bool next(DbAttributes *attributes, ::CssmDataContainer *data, DbUniqueRecord &uniqueId);
542
543 protected:
544 Db database() { return parent<Db>(); }
545
546 void activate();
547 void deactivate();
548
549 private:
550 CSSM_HANDLE mResultsHandle;
551 RecursiveMutex mActivateMutex;
552 };
553
554 } // end namespace CssmClient
555
556 } // end namespace Security
557
558 #endif // _H_CDSA_CLIENT_DLCLIENT