]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cdsa_utilities/lib/cssmdb.h
Security-59754.41.1.tar.gz
[apple/security.git] / OSX / libsecurity_cdsa_utilities / lib / cssmdb.h
1 /*
2 * Copyright (c) 2000-2006,2011-2012,2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 // cssmdb.h
26 //
27 // classes for the DL related data structures
28 //
29
30 #ifndef _H_CDSA_UTILITIES_CSSMDB
31 #define _H_CDSA_UTILITIES_CSSMDB
32
33 #include <security_cdsa_utilities/cssmdata.h>
34 #include <security_cdsa_utilities/cssmpods.h>
35 #include <security_cdsa_utilities/cssmalloc.h>
36 #include <security_cdsa_utilities/cssmwalkers.h>
37 #include <security_cdsa_utilities/cssmdbname.h>
38
39
40 namespace Security {
41
42
43 //
44 // Template class to build and maintain external arrays.
45 // Feel free to add and vector<> member functions and behaviours as needed.
46 //
47 // This class differs from vector mainly because it does not construct or
48 // destruct any of the elements it contains. Rather it zero fills the
49 // storage and returns references to elements.
50 // Also it does not implement insert(), erase() or assign(). It does implement
51 // which is equivalent to calling *insert(end()) on a vector.
52 //
53 template <class _Tp>
54 class ArrayBuilder {
55 public:
56 typedef _Tp value_type;
57 typedef value_type* pointer;
58 typedef const value_type* const_pointer;
59 typedef value_type* iterator;
60 typedef const value_type* const_iterator;
61 typedef value_type& reference;
62 typedef const value_type& const_reference;
63 typedef uint32 size_type;
64 typedef ptrdiff_t difference_type;
65
66 typedef reverse_iterator<const_iterator> const_reverse_iterator;
67 typedef reverse_iterator<iterator> reverse_iterator;
68
69 protected:
70 void insert_aux(iterator __position, const _Tp& __x);
71 void insert_aux(iterator __position);
72
73 public:
74 iterator begin() { return mArray; }
75 const_iterator begin() const { return mArray; }
76 iterator end() { return &mArray[mSize]; }
77 const_iterator end() const { return &mArray[mSize]; }
78
79 reverse_iterator rbegin()
80 { return reverse_iterator(end()); }
81 const_reverse_iterator rbegin() const
82 { return const_reverse_iterator(end()); }
83 reverse_iterator rend()
84 { return reverse_iterator(begin()); }
85 const_reverse_iterator rend() const
86 { return const_reverse_iterator(begin()); }
87
88 // Must be defined in base class.
89 //size_type size() const
90 //{ return mSize; }
91 size_type max_size() const
92 { return size_type(-1) / sizeof(_Tp); }
93 size_type capacity() const
94 { return mCapacity; }
95 bool empty() const
96 { return begin() == end(); }
97
98 ArrayBuilder(pointer &array, size_type &size, size_type capacity = 0, Allocator &allocator = Allocator::standard()) :
99 mArray(array), mSize(size), mCapacity(capacity), mAllocator(allocator)
100 {
101 #if BUG_GCC
102 mArray = reinterpret_cast<pointer>(mAllocator.malloc(sizeof(value_type) * mCapacity));
103 #else
104 mArray = reinterpret_cast<pointer>(mAllocator.malloc(sizeof(value_type) * mCapacity));
105 //mArray = mAllocator.alloc(mCapacity);
106 #endif
107 memset(mArray, 0, sizeof(value_type) * mCapacity);
108 mSize = 0;
109 }
110 ~ArrayBuilder() { mAllocator.free(mArray); }
111
112 reference front() { return *begin(); }
113 const_reference front() const { return *begin(); }
114 reference back() { return *(end() - 1); }
115 const_reference back() const { return *(end() - 1); }
116
117 void reserve(size_type newCapacity)
118 {
119 if (newCapacity > mCapacity)
120 {
121 #if BUG_GCC
122 mArray = reinterpret_cast<pointer>(mAllocator.realloc(mArray, sizeof(value_type) * newCapacity));
123 #else
124 mArray = reinterpret_cast<pointer>(mAllocator.realloc(mArray, sizeof(value_type) * newCapacity));
125 //mArray = mAllocator.realloc<value_type>(mArray, newCapacity));
126 #endif
127 memset(&mArray[mCapacity], 0, sizeof(value_type) * (newCapacity - mCapacity));
128 mCapacity = newCapacity;
129 }
130 }
131
132 // XXX Replace by push_back and insert.
133 reference add()
134 {
135 if (mSize >= mCapacity)
136 reserve(max(mSize + 1, mCapacity ? 2 * mCapacity : 1));
137
138 return mArray[mSize++];
139 }
140
141 const_pointer get() const { return mArray; }
142 pointer release() { const_pointer array = mArray; mArray = NULL; return array; }
143 void clear() { if (mSize) { memset(mArray, 0, sizeof(value_type) * mSize); } mSize = 0; }
144
145 // Must be defined in base class.
146 //reference at(size_type ix) { return mArray[ix]; }
147 //const_reference at(size_type ix) const { return mArray[ix]; }
148 //reference operator[] (size_type ix) { assert(ix < size()); return at(ix); }
149 //const_reference operator[] (size_type ix) const { assert(ix < size()); return at(ix); }
150 protected:
151 Allocator &allocator() const { return mAllocator; }
152
153 private:
154
155 pointer &mArray;
156 size_type &mSize;
157 size_type mCapacity;
158 Allocator &mAllocator;
159 };
160
161
162 //
163 // A CSSM_DL_DB_LIST wrapper.
164 // Note that there is a DLDBList class elsewhere that is quite
165 // unrelated to this structure.
166 //
167 class CssmDlDbHandle : public PodWrapper<CssmDlDbHandle, CSSM_DL_DB_HANDLE> {
168 public:
169 CssmDlDbHandle() { clearPod(); }
170 CssmDlDbHandle(CSSM_DL_HANDLE dl, CSSM_DB_HANDLE db) { DLHandle = dl; DBHandle = db; }
171
172 CSSM_DL_HANDLE dl() const { return DLHandle; }
173 CSSM_DB_HANDLE db() const { return DBHandle; }
174
175 operator bool() const { return DLHandle && DBHandle; }
176 };
177
178 inline bool operator < (const CSSM_DL_DB_HANDLE &h1, const CSSM_DL_DB_HANDLE &h2)
179 {
180 return h1.DLHandle < h2.DLHandle
181 || (h1.DLHandle == h2.DLHandle && h1.DBHandle < h2.DBHandle);
182 }
183
184 inline bool operator == (const CSSM_DL_DB_HANDLE &h1, const CSSM_DL_DB_HANDLE &h2)
185 {
186 return h1.DLHandle == h2.DLHandle && h1.DBHandle == h2.DBHandle;
187 }
188
189 inline bool operator != (const CSSM_DL_DB_HANDLE &h1, const CSSM_DL_DB_HANDLE &h2)
190 {
191 return h1.DLHandle != h2.DLHandle || h1.DBHandle != h2.DBHandle;
192 }
193
194
195 class CssmDlDbList : public PodWrapper<CssmDlDbList, CSSM_DL_DB_LIST> {
196 public:
197 uint32 count() const { return NumHandles; }
198 uint32 &count() { return NumHandles; }
199 CssmDlDbHandle *handles() const { return CssmDlDbHandle::overlay(DLDBHandle); }
200 CssmDlDbHandle * &handles() { return CssmDlDbHandle::overlayVar(DLDBHandle); }
201
202 CssmDlDbHandle &operator [] (uint32 ix) const {
203 if (ix >= count()) {
204 secemergency("CssmDlDbList: attempt to index beyond bounds");
205 abort();
206 }
207 return CssmDlDbHandle::overlay(DLDBHandle[ix]);
208 }
209
210 void setDlDbList(uint32 n, CSSM_DL_DB_HANDLE *list)
211 { count() = n; handles() = CssmDlDbHandle::overlay(list); }
212 };
213
214
215 //
216 // CssmDLPolyData
217 //
218 class CssmDLPolyData
219 {
220 public:
221 CssmDLPolyData(const CSSM_DATA &data, CSSM_DB_ATTRIBUTE_FORMAT format)
222 : mData(CssmData::overlay(data))
223 , mFormat(format)
224 {}
225
226 // @@@ Don't use assert, but throw an exception.
227 // @@@ Do a size check on mData as well.
228
229 // @@@ This method is dangerous since the returned string is not guaranteed to be zero terminated.
230 operator const char *() const
231 {
232 assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_STRING
233 || mFormat == CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE);
234 return reinterpret_cast<const char *>(mData.Data);
235 }
236 operator bool() const
237 {
238 assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_UINT32 || mFormat == CSSM_DB_ATTRIBUTE_FORMAT_SINT32);
239 return *reinterpret_cast<uint32 *>(mData.Data);
240 }
241 operator uint32() const
242 {
243 assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_UINT32);
244 return *reinterpret_cast<uint32 *>(mData.Data);
245 }
246 operator const uint32 *() const
247 {
248 assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32);
249 return reinterpret_cast<const uint32 *>(mData.Data);
250 }
251 operator sint32() const
252 {
253 assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_SINT32);
254 return *reinterpret_cast<sint32 *>(mData.Data);
255 }
256 operator double() const
257 {
258 assert(mFormat == CSSM_DB_ATTRIBUTE_FORMAT_REAL);
259 return *reinterpret_cast<double *>(mData.Data);
260 }
261 operator CSSM_DATE () const;
262 operator Guid () const;
263 operator const CssmData &() const
264 {
265 return mData;
266 }
267
268 private:
269 const CssmData &mData;
270 CSSM_DB_ATTRIBUTE_FORMAT mFormat;
271 };
272
273
274 //
275 // CssmDbAttributeInfo pod wrapper for CSSM_DB_ATTRIBUTE_INFO
276 //
277 class CssmDbAttributeInfo : public PodWrapper<CssmDbAttributeInfo, CSSM_DB_ATTRIBUTE_INFO>
278 {
279 public:
280 CssmDbAttributeInfo(const CSSM_DB_ATTRIBUTE_INFO &attr)
281 { assignPod(attr); }
282
283 CssmDbAttributeInfo(const char *name,
284 CSSM_DB_ATTRIBUTE_FORMAT vFormat = CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX);
285 CssmDbAttributeInfo(const CSSM_OID &oid,
286 CSSM_DB_ATTRIBUTE_FORMAT vFormat = CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX);
287 CssmDbAttributeInfo(uint32 id,
288 CSSM_DB_ATTRIBUTE_FORMAT vFormat = CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX);
289
290 CSSM_DB_ATTRIBUTE_NAME_FORMAT nameFormat() const { return AttributeNameFormat; }
291 void nameFormat(CSSM_DB_ATTRIBUTE_NAME_FORMAT nameFormat) { AttributeNameFormat = nameFormat; }
292
293 CSSM_DB_ATTRIBUTE_FORMAT format() const { return AttributeFormat; }
294 void format(CSSM_DB_ATTRIBUTE_FORMAT format) { AttributeFormat = format; }
295
296 const char *stringName() const
297 {
298 assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_STRING);
299 return Label.AttributeName;
300 }
301 const CssmOid &oidName() const
302 {
303 assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_OID);
304 return CssmOid::overlay(Label.AttributeOID);
305 }
306 uint32 intName() const
307 {
308 assert(nameFormat() == CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER);
309 return Label.AttributeID;
310 }
311
312 operator const char *() const { return stringName(); }
313 operator const CssmOid &() const { return oidName(); }
314 operator uint32() const { return intName(); }
315
316 bool operator <(const CssmDbAttributeInfo& other) const;
317 bool operator ==(const CssmDbAttributeInfo& other) const;
318 bool operator !=(const CssmDbAttributeInfo& other) const
319 { return !(*this == other); }
320 };
321
322 //
323 // CssmDbRecordAttributeInfo pod wrapper for CSSM_DB_RECORD_ATTRIBUTE_INFO
324 //
325 class CssmDbRecordAttributeInfo : public PodWrapper<CssmDbRecordAttributeInfo, CSSM_DB_RECORD_ATTRIBUTE_INFO>
326 {
327 public:
328 CssmDbRecordAttributeInfo()
329 { DataRecordType = CSSM_DL_DB_RECORD_ANY; }
330
331 CssmDbRecordAttributeInfo(CSSM_DB_RECORDTYPE recordType, uint32 numberOfAttributes,
332 CSSM_DB_ATTRIBUTE_INFO_PTR attributeInfo)
333 {
334 DataRecordType = recordType;
335 NumberOfAttributes = numberOfAttributes;
336 AttributeInfo = attributeInfo;
337 }
338
339 CSSM_DB_RECORDTYPE recordType() const { return DataRecordType; }
340 void recordType(CSSM_DB_RECORDTYPE recordType) { DataRecordType = recordType; }
341
342 uint32 size() const { return NumberOfAttributes; }
343
344 // attribute access
345 CssmDbAttributeInfo *&attributes()
346 { return CssmDbAttributeInfo::overlayVar(AttributeInfo); }
347 CssmDbAttributeInfo *attributes() const
348 { return CssmDbAttributeInfo::overlay(AttributeInfo); }
349 CssmDbAttributeInfo &at(uint32 ix) const {
350 if (ix >= size()) {
351 secemergency("CssmDbRecordAttributeInfo: attempt to index beyond bounds");
352 abort();
353 }
354 return attributes()[ix];
355 }
356
357 CssmDbAttributeInfo &operator [] (uint32 ix) const { return at(ix); }
358 };
359
360 //
361 // CssmAutoDbRecordAttributeInfo pod wrapper for CSSM_DB_RECORD_ATTRIBUTE_INFO
362 //
363 class CssmAutoDbRecordAttributeInfo: public CssmDbRecordAttributeInfo, public ArrayBuilder<CssmDbAttributeInfo>
364 {
365 public:
366 CssmAutoDbRecordAttributeInfo(uint32 capacity = 0, Allocator &allocator = Allocator::standard()) :
367 CssmDbRecordAttributeInfo(),
368 ArrayBuilder<CssmDbAttributeInfo>(CssmDbAttributeInfo::overlayVar(AttributeInfo),
369 NumberOfAttributes, capacity, allocator) {}
370 };
371
372
373 //
374 // CssmDbAttributeData pod wrapper for CSSM_DB_ATTRIBUTE_DATA
375 //
376 class CssmDbAttributeData : public PodWrapper<CssmDbAttributeData, CSSM_DB_ATTRIBUTE_DATA>
377 {
378 public:
379 CssmDbAttributeData() { NumberOfValues = 0; Value = NULL; }
380 CssmDbAttributeData(const CSSM_DB_ATTRIBUTE_DATA &attr)
381 { assignPod(attr); }
382 CssmDbAttributeData(const CSSM_DB_ATTRIBUTE_INFO &info)
383 { Info = info; NumberOfValues = 0; Value = NULL; }
384
385 CssmDbAttributeInfo &info() { return CssmDbAttributeInfo::overlay(Info); }
386 const CssmDbAttributeInfo &info() const { return CssmDbAttributeInfo::overlay(Info); }
387 void info (const CSSM_DB_ATTRIBUTE_INFO &inInfo) { Info = inInfo; }
388
389 CSSM_DB_ATTRIBUTE_FORMAT format() const { return info().format(); }
390 void format(CSSM_DB_ATTRIBUTE_FORMAT f) { info().format(f); }
391
392 uint32 size() const { return NumberOfValues; }
393 CssmData *&values() { return CssmData::overlayVar(Value); }
394 CssmData *values() const { return CssmData::overlay(Value); }
395
396 CssmData &at(unsigned int ix) const
397 {
398 if (ix >= size()) CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
399 return values()[ix];
400 }
401
402 CssmData &operator [] (unsigned int ix) const { return at(ix); }
403
404 template <class T>
405 T at(unsigned int ix) const { return CssmDLPolyData(Value[ix], format()); }
406
407 // this is intentionally unspecified since it could lead to bugs; the
408 // data is not guaranteed to be NULL-terminated
409 // operator const char *() const;
410
411 operator string() const;
412 operator const Guid &() const;
413 operator bool() const;
414 operator uint32() const;
415 operator const uint32 *() const;
416 operator sint32() const;
417 operator double() const;
418 operator const CssmData &() const;
419
420 // set values without allocation (caller owns the data contents)
421 void set(CssmData &data) { set(1, &data); }
422 void set(uint32 count, CssmData *datas) { NumberOfValues = count; Value = datas; }
423
424 // Set the value of this Attr (assuming it was not set before).
425 void set(const CSSM_DB_ATTRIBUTE_INFO &inInfo, const CssmPolyData &inValue,
426 Allocator &inAllocator);
427
428 // copy (just) the return-value part from another AttributeData to this one
429 void copyValues(const CssmDbAttributeData &source, Allocator &alloc);
430
431 // Set the value of this Attr (which must be unset so far)
432 void set(const CSSM_DB_ATTRIBUTE_DATA &source, Allocator &alloc)
433 {
434 info(source.Info);
435 copyValues(source, alloc);
436 }
437
438 // Add a value to this attribute.
439 void add(const CssmPolyData &inValue, Allocator &inAllocator);
440
441 void add(const char *value, Allocator &alloc)
442 { format(CSSM_DB_ATTRIBUTE_FORMAT_STRING); add(CssmPolyData(value), alloc); }
443
444 void add(const std::string &value, Allocator &alloc)
445 { format(CSSM_DB_ATTRIBUTE_FORMAT_STRING); add(CssmPolyData(value), alloc); }
446
447 void add(uint32 value, Allocator &alloc)
448 { format(CSSM_DB_ATTRIBUTE_FORMAT_UINT32); add(CssmPolyData(value), alloc); }
449
450 void add(sint32 value, Allocator &alloc)
451 { format(CSSM_DB_ATTRIBUTE_FORMAT_SINT32); add(CssmPolyData(value), alloc); }
452
453 void add(const CssmData &value, Allocator &alloc)
454 { format(CSSM_DB_ATTRIBUTE_FORMAT_BLOB); add(CssmPolyData(value), alloc); }
455
456 void add(const CssmDbAttributeData &src, Allocator &inAllocator);
457
458 // delete specific values if they are present in this attribute data
459 bool deleteValue(const CssmData &src, Allocator &inAllocator);
460 void deleteValues(const CssmDbAttributeData &src, Allocator &inAllocator);
461
462 void deleteValues(Allocator &inAllocator);
463
464 bool operator <(const CssmDbAttributeData& other) const;
465 };
466
467
468 //
469 // CssmDbRecordAttributeData pod wrapper for CSSM_DB_RECORD_ATTRIBUTE_DATA
470 //
471 class CssmDbRecordAttributeData : public PodWrapper<CssmDbRecordAttributeData, CSSM_DB_RECORD_ATTRIBUTE_DATA>
472 {
473 public:
474 CssmDbRecordAttributeData()
475 { clearPod(); DataRecordType = CSSM_DL_DB_RECORD_ANY; }
476
477 CSSM_DB_RECORDTYPE recordType() const { return DataRecordType; }
478 void recordType(CSSM_DB_RECORDTYPE recordType) { DataRecordType = recordType; }
479
480 uint32 semanticInformation() const { return SemanticInformation; }
481 void semanticInformation(uint32 semanticInformation) { SemanticInformation = semanticInformation; }
482
483 uint32 size() const { return NumberOfAttributes; }
484 CssmDbAttributeData *&attributes()
485 { return CssmDbAttributeData::overlayVar(AttributeData); }
486 CssmDbAttributeData *attributes() const
487 { return CssmDbAttributeData::overlay(AttributeData); }
488
489 // Attributes by position
490 CssmDbAttributeData &at(unsigned int ix) const {
491 if (ix >= size()) {
492 secemergency("CssmDbRecordAttributeData: attempt to index beyond bounds");
493 abort();
494 }
495 return attributes()[ix];
496 }
497
498 CssmDbAttributeData &operator [] (unsigned int ix) const { return at(ix); }
499
500 void deleteValues(Allocator &allocator)
501 { for (uint32 ix = 0; ix < size(); ++ix) at(ix).deleteValues(allocator); }
502
503 CssmDbAttributeData *find(const CSSM_DB_ATTRIBUTE_INFO &inInfo);
504
505 bool operator <(const CssmDbRecordAttributeData& other) const;
506 };
507
508
509 //
510 // CssmAutoDbRecordAttributeData
511 //
512 class CssmAutoDbRecordAttributeData : public CssmDbRecordAttributeData, public ArrayBuilder<CssmDbAttributeData>
513 {
514 public:
515 CssmAutoDbRecordAttributeData(uint32 capacity = 0,
516 Allocator &valueAllocator = Allocator::standard(),
517 Allocator &dataAllocator = Allocator::standard()) :
518 CssmDbRecordAttributeData(),
519 ArrayBuilder<CssmDbAttributeData>(CssmDbAttributeData::overlayVar(AttributeData),
520 NumberOfAttributes, capacity, dataAllocator),
521 mValueAllocator(valueAllocator) {}
522 ~CssmAutoDbRecordAttributeData();
523
524 void clear();
525 void deleteValues() { CssmDbRecordAttributeData::deleteValues(mValueAllocator); }
526 void invalidate();
527
528 CssmDbAttributeData &add() { return ArrayBuilder<CssmDbAttributeData>::add(); } // XXX using doesn't work here.
529 CssmDbAttributeData &add(const CSSM_DB_ATTRIBUTE_INFO &info);
530 CssmDbAttributeData &add(const CSSM_DB_ATTRIBUTE_INFO &info, const CssmPolyData &value);
531
532 // Take the attributes from the object, and overlay them onto this one
533 void updateWith(const CssmAutoDbRecordAttributeData* newValues);
534
535 // So clients can pass this as the allocator argument to add()
536 operator Allocator &() const { return mValueAllocator; }
537
538 CssmDbAttributeData* findAttribute (const CSSM_DB_ATTRIBUTE_INFO &info);
539 private:
540 Allocator &mValueAllocator;
541
542 CssmDbAttributeData& getAttributeReference (const CSSM_DB_ATTRIBUTE_INFO &info);
543 };
544
545
546 //
547 // CssmSelectionPredicate a PodWrapper for CSSM_SELECTION_PREDICATE
548 //
549 class CssmSelectionPredicate : public PodWrapper<CssmSelectionPredicate, CSSM_SELECTION_PREDICATE> {
550 public:
551 CssmSelectionPredicate() { clearPod(); }
552
553 CSSM_DB_OPERATOR dbOperator() const { return DbOperator; }
554 void dbOperator(CSSM_DB_OPERATOR dbOperator) { DbOperator = dbOperator; }
555
556 CssmSelectionPredicate(CSSM_DB_OPERATOR inDbOperator)
557 { dbOperator(inDbOperator); Attribute.NumberOfValues = 0; Attribute.Value = NULL; }
558
559 CssmDbAttributeData &attribute() { return CssmDbAttributeData::overlay(Attribute); }
560 const CssmDbAttributeData &attribute() const { return CssmDbAttributeData::overlay(Attribute); }
561
562 // Set the value of this CssmSelectionPredicate (assuming it was not set before).
563 void set(const CSSM_DB_ATTRIBUTE_INFO &inInfo,
564 const CssmPolyData &inValue, Allocator &inAllocator)
565 { attribute().set(inInfo, inValue, inAllocator); }
566
567 // Set the value of this CssmSelectionPredicate using another CssmSelectionPredicate's value.
568 void set(const CSSM_SELECTION_PREDICATE &other, Allocator &inAllocator)
569 { DbOperator = other.DbOperator; attribute().set(other.Attribute, inAllocator); }
570
571 // Add a value to the list of values for this CssmSelectionPredicate.
572 void add(const CssmPolyData &inValue, Allocator &inAllocator)
573 { attribute().add(inValue, inAllocator); }
574
575 void deleteValues(Allocator &inAllocator) { attribute().deleteValues(inAllocator); }
576 };
577
578 class CssmQuery : public PodWrapper<CssmQuery, CSSM_QUERY> {
579 public:
580 CssmQuery(CSSM_DB_RECORDTYPE type = CSSM_DL_DB_RECORD_ANY)
581 { clearPod(); RecordType = type; }
582
583 // copy or assign flat from CSSM_QUERY
584 CssmQuery(const CSSM_QUERY &q) { assignPod(q); }
585 CssmQuery &operator = (const CSSM_QUERY &q) { assignPod(q); return *this; }
586
587 // flat copy and change record type
588 CssmQuery(const CssmQuery &q, CSSM_DB_RECORDTYPE type)
589 { *this = q; RecordType = type; }
590
591 CSSM_DB_RECORDTYPE recordType() const { return RecordType; }
592 void recordType(CSSM_DB_RECORDTYPE recordType) { RecordType = recordType; }
593
594 CSSM_DB_CONJUNCTIVE conjunctive() const { return Conjunctive; }
595 void conjunctive(CSSM_DB_CONJUNCTIVE conjunctive) { Conjunctive = conjunctive; }
596
597 CSSM_QUERY_LIMITS queryLimits() const { return QueryLimits; }
598 void queryLimits(CSSM_QUERY_LIMITS queryLimits) { QueryLimits = queryLimits; }
599
600 CSSM_QUERY_FLAGS queryFlags() const { return QueryFlags; }
601 void queryFlags(CSSM_QUERY_FLAGS queryFlags) { QueryFlags = queryFlags; }
602
603 uint32 size() const { return NumSelectionPredicates; }
604
605 CssmSelectionPredicate *&predicates()
606 { return CssmSelectionPredicate::overlayVar(SelectionPredicate); }
607 CssmSelectionPredicate *predicates() const
608 { return CssmSelectionPredicate::overlay(SelectionPredicate); }
609
610 CssmSelectionPredicate &at(uint32 ix) const {
611 if (ix >= size()) {
612 secemergency("CssmDbRecordAttributeData: attempt to index beyond bounds");
613 abort();
614 }
615 return predicates()[ix];
616 }
617
618 CssmSelectionPredicate &operator[] (uint32 ix) const { return at(ix); }
619
620 void set(uint32 count, CSSM_SELECTION_PREDICATE *preds)
621 { NumSelectionPredicates = count; SelectionPredicate = preds; }
622
623 void deleteValues(Allocator &allocator)
624 { for (uint32 ix = 0; ix < size(); ++ix) at(ix).deleteValues(allocator); }
625 };
626
627
628 class CssmAutoQuery : public CssmQuery, public ArrayBuilder<CssmSelectionPredicate> {
629 public:
630 CssmAutoQuery(const CSSM_QUERY &query, Allocator &allocator = Allocator::standard());
631 CssmAutoQuery(uint32 capacity = 0, Allocator &allocator = Allocator::standard()) :
632 ArrayBuilder<CssmSelectionPredicate>(CssmSelectionPredicate::overlayVar(SelectionPredicate),
633 NumSelectionPredicates,
634 capacity, allocator) {}
635 ~CssmAutoQuery();
636 void clear();
637 void deleteValues() { CssmQuery::deleteValues(allocator()); }
638
639 CssmSelectionPredicate &add() { return ArrayBuilder<CssmSelectionPredicate>::add(); }
640 CssmSelectionPredicate &add(CSSM_DB_OPERATOR dbOperator, const CSSM_DB_ATTRIBUTE_INFO &info, const CssmPolyData &value);
641
642 // So clients can pass this as the allocator argument to add()
643 operator Allocator &() const { return allocator(); }
644 };
645
646
647 //
648 // DLDbIdentifier
649 //
650 class DLDbIdentifier
651 {
652 protected:
653 class Impl : public RefCount
654 {
655 NOCOPY(Impl)
656 public:
657 Impl(const CSSM_SUBSERVICE_UID &ssuid,const char *DbName,const CSSM_NET_ADDRESS *DbLocation) :
658 mCssmSubserviceUid(ssuid),mDbName(DbName,DbLocation) {}
659
660 ~Impl() {} // Must be public since RefPointer uses it.
661
662 // Accessors
663 const CssmSubserviceUid &ssuid() const { return mCssmSubserviceUid; }
664 const char *dbName() const { return mDbName.dbName(); }
665 const CssmNetAddress *dbLocation() const { return mDbName.dbLocation(); }
666
667 // comparison (simple lexicographic)
668 bool operator < (const Impl &other) const;
669 bool operator == (const Impl &other) const;
670 private:
671 // Private member variables
672 CssmSubserviceUid mCssmSubserviceUid;
673 DbName mDbName;
674 };
675
676 public:
677 // Constructors
678 DLDbIdentifier() {}
679 DLDbIdentifier(const CSSM_SUBSERVICE_UID &ssuid, const char *DbName, const CSSM_NET_ADDRESS *DbLocation)
680 : mImpl(new Impl(ssuid, DbName, DbLocation)) {}
681 DLDbIdentifier(const char *name, const Guid &guid, uint32 ssid, uint32 sstype,
682 const CSSM_NET_ADDRESS *location = NULL)
683 : mImpl(new Impl(CssmSubserviceUid(guid, NULL, ssid, sstype), name, location)) { }
684
685 DLDbIdentifier(const DLDbIdentifier& i) : mImpl(i.mImpl) {}
686
687 // Conversion Operators
688 bool operator !() const { return !mImpl; }
689 operator bool() const { return mImpl; }
690
691 // Operators
692 bool operator <(const DLDbIdentifier &other) const
693 { return mImpl && other.mImpl ? *mImpl < *other.mImpl : mImpl.get() < other.mImpl.get(); }
694 bool operator ==(const DLDbIdentifier &other) const
695 { return mImpl && other.mImpl ? *mImpl == *other.mImpl : mImpl.get() == other.mImpl.get(); }
696 DLDbIdentifier &operator =(const DLDbIdentifier &other)
697 { mImpl = other.mImpl; return *this; }
698
699 // Accessors
700 const CssmSubserviceUid &ssuid() const { return mImpl->ssuid(); }
701 const char *dbName() const { return mImpl->dbName(); }
702 const CssmNetAddress *dbLocation() const { return mImpl->dbLocation(); }
703 bool IsImplEmpty() const {return mImpl == NULL;}
704
705 RefPointer<Impl> mImpl;
706 };
707
708 // Wrappers for index-related CSSM objects.
709
710 class CssmDbIndexInfo : public PodWrapper<CssmDbIndexInfo, CSSM_DB_INDEX_INFO>
711 {
712 public:
713 CssmDbIndexInfo(const CSSM_DB_INDEX_INFO &attr)
714 { (CSSM_DB_INDEX_INFO &)*this = attr; }
715
716 CSSM_DB_INDEX_TYPE indexType() const { return IndexType; }
717 void indexType(CSSM_DB_INDEX_TYPE indexType) { IndexType = indexType; }
718
719 CSSM_DB_INDEXED_DATA_LOCATION dataLocation() const { return IndexedDataLocation; }
720 void dataLocation(CSSM_DB_INDEXED_DATA_LOCATION dataLocation)
721 {
722 IndexedDataLocation = dataLocation;
723 }
724
725 const CssmDbAttributeInfo &attributeInfo() const
726 {
727 return CssmDbAttributeInfo::overlay(Info);
728 }
729 };
730
731
732 namespace DataWalkers {
733
734
735 //
736 // DLDbIdentifiers don't walk directly because they have Impl structure and use strings.
737 // Happily, they are easily transcribed into a walkable form.
738 //
739 struct DLDbFlatIdentifier {
740 CssmSubserviceUid *uid; // module reference
741 char *name; // string name
742 CssmNetAddress *address; // optional network address
743
744 DLDbFlatIdentifier(const DLDbIdentifier &ident) :
745 uid(const_cast<CssmSubserviceUid *>(&ident.ssuid())),
746 name(const_cast<char *>(ident.dbName())),
747 address(const_cast<CssmNetAddress *>(ident.dbLocation()))
748 { }
749
750 operator DLDbIdentifier () {
751 DLDbIdentifier db(*uid, name, address);
752 return db;
753 }
754 };
755
756 template<class Action>
757 DLDbFlatIdentifier *walk(Action &operate, DLDbFlatIdentifier * &ident)
758 {
759 operate(ident);
760 if (ident->uid)
761 walk(operate, ident->uid);
762 walk(operate, ident->name);
763 if (ident->address)
764 walk(operate, ident->address);
765 return ident;
766 }
767
768
769 //
770 // Walkers for the byzantine data structures of the DL universe.
771 // Geez, what WERE they smoking when they invented this?
772 //
773
774 // DbAttributeInfos
775 template<class Action>
776 void enumerate(Action &operate, CssmDbAttributeInfo &info)
777 {
778 switch (info.nameFormat()) {
779 case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
780 walk(operate, info.Label.AttributeName);
781 break;
782 case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
783 walk(operate, info.Label.AttributeOID);
784 break;
785 default:
786 break;
787 }
788 }
789
790 template <class Action>
791 void walk(Action &operate, CssmDbAttributeInfo &info)
792 {
793 operate(info);
794 enumerate(operate, info);
795 }
796
797 template <class Action>
798 CssmDbAttributeInfo *walk(Action &operate, CssmDbAttributeInfo * &info)
799 {
800 operate(info);
801 enumerate(operate, *info);
802 return info;
803 }
804
805 // DbRecordAttributeInfo
806 template <class Action>
807 void walk(Action &operate, CssmDbRecordAttributeInfo &info)
808 {
809 operate(info);
810 enumerateArray(operate, info, &CssmDbRecordAttributeInfo::attributes);
811 }
812
813 template <class Action>
814 CssmDbRecordAttributeInfo *walk(Action &operate, CssmDbRecordAttributeInfo * &info)
815 {
816 operate(info);
817 enumerateArray(operate, *info, &CssmDbRecordAttributeInfo::attributes);
818 return info;
819 }
820
821 // DbAttributeData (Info + value vector)
822 template <class Action>
823 void walk(Action &operate, CssmDbAttributeData &data)
824 {
825 operate(data);
826 walk(operate, data.info());
827 enumerateArray(operate, data, &CssmDbAttributeData::values);
828 }
829
830 template <class Action>
831 CssmDbAttributeData *walk(Action &operate, CssmDbAttributeData * &data)
832 {
833 operate(data);
834 walk(operate, data->info());
835 enumerateArray(operate, *data, &CssmDbAttributeData::values);
836 return data;
837 }
838
839 // DbRecordAttributeData (array of ...datas)
840 template <class Action>
841 void walk(Action &operate, CssmDbRecordAttributeData &data)
842 {
843 operate(data);
844 enumerateArray(operate, data, &CssmDbRecordAttributeData::attributes);
845 }
846
847 template <class Action>
848 CssmDbRecordAttributeData *walk(Action &operate, CssmDbRecordAttributeData * &data)
849 {
850 operate(data);
851 enumerateArray(operate, *data, &CssmDbRecordAttributeData::attributes);
852 return data;
853 }
854
855 // SelectionPredicates
856 template <class Action>
857 CssmSelectionPredicate *walk(Action &operate, CssmSelectionPredicate * &predicate)
858 {
859 operate(predicate);
860 walk(operate, predicate->attribute());
861 return predicate;
862 }
863
864 template<class Action>
865 void walk(Action &operate, CssmSelectionPredicate &predicate)
866 {
867 operate(predicate);
868 walk(operate, predicate.attribute());
869 }
870
871 // Queries
872 template <class Action>
873 void walk(Action &operate, CssmQuery &query)
874 {
875 operate(query);
876 enumerateArray(operate, query, &CssmQuery::predicates);
877 }
878
879 template <class Action>
880 CssmQuery *walk(Action &operate, CssmQuery * &query)
881 {
882 operate(query);
883 enumerateArray(operate, *query, &CssmQuery::predicates);
884 return query;
885 }
886
887 template <class Action>
888 CSSM_QUERY *walk(Action &operate, CSSM_QUERY * &query)
889 {
890 return walk(operate, CssmQuery::overlayVar(query));
891 }
892
893
894 } // end namespace DataWalkers
895 } // end namespace Security
896
897
898 #endif // _H_CDSA_UTILITIES_CSSMDB