/ OSX / libsecurity_cdsa_client / lib / dlclient.h
dlclient.h
  1  /*
  2   * Copyright (c) 2000-2001,2011-2014 Apple 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() { StLock<Mutex> _(mActivateMutex); 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 stash();
316      virtual void stashCheck();
317  	virtual void getSettings(uint32 &outIdleTimeout, bool &outLockOnSleep);
318  	virtual void setSettings(uint32 inIdleTimeout, bool inLockOnSleep);
319  	virtual bool isLocked();
320  	virtual void changePassphrase(const CSSM_ACCESS_CREDENTIALS *cred);
321  	virtual void recode(const CSSM_DATA &data, const CSSM_DATA &extraData);
322  	virtual void copyBlob(CssmData &data);
323  	virtual void setBatchMode(Boolean mode, Boolean rollback);
324  
325      // Get the version of this database's encoding
326      virtual uint32 dbBlobVersion();
327  
328      // Attempt to recode this database to the new version
329      virtual uint32 recodeDbToVersion(uint32 version);
330  
331      // Declare that the recode operation is complete
332      virtual void recodeFinished();
333  
334      // Try to take or release the file lock on the underlying database.
335      // You _must_ call these as a pair. They start a transaction on the
336      // underlying DL object, and that transaction is only finished when release
337      // is called. Pass success=true if you want the transaction to commit; otherwise
338      // it will roll back.
339      virtual void takeFileLock();
340      virtual void releaseFileLock(bool success);
341  
342      // Make a backup of this database on the filesystem
343      virtual void makeBackup();
344  
345      // Make a copy of this database on the filesystem
346      // Throws a UnixError if anything goes wrong
347      virtual void makeCopy(const char* path);
348  
349      // Make a clone of this database in a new location.
350      // This method handles telling securityd about the clone, and copying the
351      // file over.
352      virtual Db cloneTo(const DLDbIdentifier& dldbidentifier);
353  
354      // Transfer this database to a new location. If the database is open in
355      // securityd, transfer the lock status as well.
356      virtual void transferTo(const DLDbIdentifier& dldbidentifier);
357  
358      // This will attempt to delete the file underlying this database.
359      // Don't call this unless you really, really mean to.
360      virtual void deleteFile();
361  
362  	// Utility methods
363  
364  	// Always use the dbName and dbLocation that were passed in during
365  	// construction.
366  	virtual DLDbIdentifier dlDbIdentifier();
367  
368  	// DbCursorMaker
369  	virtual DbCursorImpl *newDbCursor(const CSSM_QUERY &query, Allocator &allocator);
370  	virtual DbCursorImpl *newDbCursor(uint32 capacity, Allocator &allocator);
371  
372  	// DbUniqueRecordMaker
373  	virtual DbUniqueRecordImpl *newDbUniqueRecord();
374  
375  	// Acl manipulation
376  	void getAcl(AutoAclEntryInfoList &aclInfos, const char *selectionTag = NULL) const;
377  	void changeAcl(const CSSM_ACL_EDIT &aclEdit,
378  		const CSSM_ACCESS_CREDENTIALS *accessCred);
379  
380  	// Acl owner manipulation
381  	void getOwner(AutoAclOwnerPrototype &owner) const;
382  	void changeOwner(const CSSM_ACL_OWNER_PROTOTYPE &newOwner,
383  		const CSSM_ACCESS_CREDENTIALS *accessCred = NULL);
384  	
385  	// default-credential hook
386  	class DefaultCredentialsMaker {
387  	public:
388  		virtual ~DefaultCredentialsMaker();
389  		virtual const AccessCredentials *makeCredentials() = 0;
390  	};
391  	
392  	void defaultCredentials(DefaultCredentialsMaker *maker);	// NULL to turn off
393  
394  	void activate();
395  
396  protected:
397  	void deactivate();
398  
399  private:
400  	CSSM_DL_DB_HANDLE mHandle;			// CSSM DLDB handle
401  
402  	DbName mDbName;
403  	bool mUseNameFromHandle; // false if CSSM_DL_GetDbNameFromHandle failed
404  	char *mNameFromHandle; // Cached CSSM_DL_GetDbNameFromHandle result.
405  	CSSM_DB_ACCESS_TYPE mAccessRequest;
406  	const CSSM_ACCESS_CREDENTIALS *mAccessCredentials;
407  	DefaultCredentialsMaker *mDefaultCredentials;
408  	const void *mOpenParameters;
409  
410  	// Arguments to create
411  	const CSSM_DBINFO *mDbInfo;
412  	const ResourceControlContext *mResourceControlContext;
413  };
414  
415  
416  class Db : public Object, public DLAccess
417  {
418  public:
419  	typedef DbImpl Impl;
420  	typedef Impl::DefaultCredentialsMaker DefaultCredentialsMaker;
421  
422  	explicit Db(Impl *impl) : Object(impl) {}
423  	Db() : Object(NULL) {}
424  	Db(DbMaker &maker, const char *inDbName, const CSSM_NET_ADDRESS *inDbLocation = NULL)
425  	: Object(maker.newDb(inDbName, inDbLocation)) {}
426  
427  	Impl *operator ->() const { return &impl<Impl>(); }
428  	Impl &operator *() const { return impl<Impl>(); }
429  
430  	// Conversion to DbCursorMaker.
431  	operator DbCursorMaker &() const { return impl<Impl>(); }
432  	// Conversion to DbUniqueRecordMaker.
433  	operator DbUniqueRecordMaker &() const { return impl<Impl>(); }
434  
435  	const CSSM_DL_DB_HANDLE &handle() { return impl<Impl>().handle(); }
436  	
437  protected:
438  	// DLAccess adapters
439  	CSSM_HANDLE dlGetFirst(const CSSM_QUERY &query,
440  		CSSM_DB_RECORD_ATTRIBUTE_DATA &attributes, CSSM_DATA *data,
441  		CSSM_DB_UNIQUE_RECORD *&id);
442  	bool dlGetNext(CSSM_HANDLE handle,
443  		CSSM_DB_RECORD_ATTRIBUTE_DATA &attributes, CSSM_DATA *data,
444  		 CSSM_DB_UNIQUE_RECORD *&id);
445  	void dlAbortQuery(CSSM_HANDLE handle);
446  	void dlFreeUniqueId(CSSM_DB_UNIQUE_RECORD *id);
447  	void dlDeleteRecord(CSSM_DB_UNIQUE_RECORD *id);
448  	Allocator &allocator();
449  };
450  
451  //
452  // DbCursor
453  //
454  
455  // This class is still abstract.  You must subclass it in order to be able to instantiate an instance.
456  class DbCursorImpl : public ObjectImpl, public CssmAutoQuery
457  {
458  public:
459  	DbCursorImpl(const Object &parent, const CSSM_QUERY &query, Allocator &allocator);
460  	DbCursorImpl(const Object &parent, uint32 capacity, Allocator &allocator);
461  
462  	virtual Allocator &allocator() const;
463  	virtual void allocator(Allocator &alloc);
464  
465  	virtual bool next(DbAttributes *attributes, ::CssmDataContainer *data, DbUniqueRecord &uniqueId) = 0;
466  	void abort() { deactivate(); }
467  };
468  
469  class DbCursor : public Object
470  {
471  public:
472  	typedef DbCursorImpl Impl;
473  
474  	explicit DbCursor(Impl *impl) : Object(impl) {}
475  	DbCursor() : Object(NULL) {}
476  	DbCursor(DbCursorMaker &maker, const CSSM_QUERY &query,
477  			 Allocator &allocator = Allocator::standard())
478  	: Object(maker.newDbCursor(query, allocator)) {}
479  	DbCursor(DbCursorMaker &maker, uint32 capacity = 0,
480  			 Allocator &allocator = Allocator::standard())
481  	: Object(maker.newDbCursor(capacity, allocator)) {}
482  
483  	Impl *operator ->() const { return &impl<Impl>(); }
484  	Impl &operator *() const { return impl<Impl>(); }
485  };
486  
487  
488  //
489  // DbUniqueRecord
490  //
491  class DbUniqueRecordImpl : public ObjectImpl
492  {
493  public:
494  	DbUniqueRecordImpl(const Db &db);
495  	virtual ~DbUniqueRecordImpl();
496  
497  	virtual void deleteRecord();
498  	virtual void modify(CSSM_DB_RECORDTYPE recordType,
499  						const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
500  						const CSSM_DATA *data,
501  						CSSM_DB_MODIFY_MODE modifyMode);
502  
503  	virtual void modifyWithoutEncryption (CSSM_DB_RECORDTYPE recordType,
504  											const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
505  											const CSSM_DATA *data,
506  											CSSM_DB_MODIFY_MODE modifyMode);
507  											
508  	virtual void get(DbAttributes *attributes, ::CssmDataContainer *data);
509  
510  	virtual void getWithoutEncryption(DbAttributes *attributes, ::CssmDataContainer *data);
511  
512  	Db database() const { return parent<Db>(); }
513  
514  	void free() { deactivate(); }
515  
516  	// Client must call activate() after calling this function if mUniqueId is successfully set.
517  	operator CSSM_DB_UNIQUE_RECORD_PTR *() { if (mActive) free(); return &mUniqueId; }
518  
519  	operator CSSM_DB_UNIQUE_RECORD *() { return mUniqueId; }
520  	operator const CSSM_DB_UNIQUE_RECORD *() const { return mUniqueId; }
521  
522  	void activate();
523  	
524  	void getRecordIdentifier(CSSM_DATA &data);
525  
526  	void setUniqueRecordPtr (CSSM_DB_UNIQUE_RECORD_PTR uniquePtr); // because cast overloading is evil!
527  
528  protected:
529  	void deactivate();
530  
531  	CSSM_DB_UNIQUE_RECORD_PTR mUniqueId;
532  	bool mDestroyID;
533      RecursiveMutex mActivateMutex;
534  };
535  
536  class DbUniqueRecord : public Object
537  {
538  public:
539  	typedef DbUniqueRecordImpl Impl;
540  
541  	explicit DbUniqueRecord(Impl *impl) : Object(impl) {}
542  	DbUniqueRecord() : Object(NULL) {}
543  	DbUniqueRecord(DbUniqueRecordMaker &maker) : Object(maker.newDbUniqueRecord()) {}
544  
545  	Impl *operator ->() { return &impl<Impl>(); }
546  	Impl &operator *() { return impl<Impl>(); }
547  	const Impl &operator *() const { return impl<Impl>(); }
548  
549  	// Conversion operators must be here.
550  
551  	// Client must activate after calling this function if mUniqueId is successfully set.
552  	operator CSSM_DB_UNIQUE_RECORD_PTR *() { return **this; }
553  
554  	operator CSSM_DB_UNIQUE_RECORD *() { return **this; }
555  	operator const CSSM_DB_UNIQUE_RECORD *() const { return **this; }
556  };
557  
558  
559  //
560  // DbAttributes
561  //
562  class DbAttributes : public CssmAutoDbRecordAttributeData
563  {
564  public:
565  	DbAttributes();
566  	DbAttributes(const Db &db, uint32 capacity = 0, Allocator &allocator = Allocator::standard());
567  
568      // Similar to CssmAutoDbRecordAttributeData::updateWith, but a different
569      // signature. Will canonicalize the elements in both this and the newValues dbAttributes.
570      void updateWithDbAttributes(DbAttributes* newValues);
571  
572      // Try to change the infos in this database to a canonicalized form
573      void canonicalize();
574  };
575  
576  
577  //
578  // DbDbCursor -- concrete subclass of DbCursorImpl for querying Db's
579  //
580  class DbDbCursorImpl : public DbCursorImpl
581  {
582  public:
583  	DbDbCursorImpl(const Db &db, const CSSM_QUERY &query, Allocator &allocator);
584  	DbDbCursorImpl(const Db &db, uint32 capacity, Allocator &allocator);
585  	virtual ~DbDbCursorImpl();
586  
587  	bool next(DbAttributes *attributes, ::CssmDataContainer *data, DbUniqueRecord &uniqueId);
588  
589  protected:
590  	Db database() { return parent<Db>(); }
591  
592  	void activate();
593  	void deactivate();
594  
595  private:
596  	CSSM_HANDLE mResultsHandle;
597      RecursiveMutex mActivateMutex;
598  };
599  
600  } // end namespace CssmClient
601  
602  } // end namespace Security
603  
604  #endif // _H_CDSA_CLIENT_DLCLIENT