2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
20 File: MDSAttrUtils.cpp
22 Contains: Stateless functions used by MDSAttrParser.
24 Copyright: (c) 2001 Apple Computer, Inc., all rights reserved.
27 #include "MDSAttrUtils.h"
28 #include <Security/cssmerrno.h>
35 * Fill in one CSSM_DB_ATTRIBUTE_DATA with specified data, type and attribute name.
36 * CSSM_DB_ATTRIBUTE_DATA.Value and its referent are new[]'d and copied.
38 * -- AttributeNameFormat = CSSM_DB_ATTRIBUTE_NAME_AS_STRING
39 * -- NumberOfValues = 1
41 void MDSRawValueToDbAttr(
44 CSSM_DB_ATTRIBUTE_FORMAT attrFormat
, // CSSM_DB_ATTRIBUTE_FORMAT_STRING, etc.
46 CSSM_DB_ATTRIBUTE_DATA
&attr
,
49 CSSM_DB_ATTRIBUTE_INFO_PTR attrInfo
= &attr
.Info
;
50 attrInfo
->AttributeNameFormat
= CSSM_DB_ATTRIBUTE_NAME_AS_STRING
;
51 attrInfo
->Label
.AttributeName
= const_cast<char *>(attrName
);
52 attrInfo
->AttributeFormat
= attrFormat
;
53 attr
.NumberOfValues
= numValues
;
54 attr
.Value
= new CSSM_DATA
[1];
55 attr
.Value
->Data
= new uint8
[len
];
56 attr
.Value
->Length
= len
;
57 memcpy(attr
.Value
->Data
, value
, len
);
62 * Free data new[]'d in the above function.
64 void MDSFreeDbRecordAttrs(
65 CSSM_DB_ATTRIBUTE_DATA
*attrs
,
69 for(i
=0; i
<numAttrs
; i
++) {
70 assert(attrs
->Value
!= NULL
);
71 delete [] attrs
->Value
->Data
;
72 attrs
->Value
->Data
= NULL
;
73 attrs
->Value
->Length
= 0;
74 delete [] attrs
->Value
;
80 /* safely get a new[]'d C string from a CFString */
81 char *MDSCFStringToCString(
85 unsigned len
= CFStringGetLength(cfStr
) + 1;
88 CFStringGetCString(cfStr
, rtn
, len
, CFStringGetSystemEncoding());
93 /* copy a new[]'d C string from a C string */
97 char *outStr
= new char[::strlen(inStr
) + 1];
98 strcpy(outStr
, inStr
);
103 * Given a CFTypeRef which is either a CFString, a CFNumber, or a CFBoolean,
104 * do our best to convert it to a uint32. If it's a CFString, we'll use a
105 * MDSNameValuePair to convert it. CFStrings expressed as decimal numbers
106 * are also converted properly. (MAYBE we'll convert hex strings too...TBD...)
107 * Returns true if conversion was successful.
111 const MDSNameValuePair
*nameValues
, // optional for converting strings to numbers
112 const char *key
, // for debug logging only
113 uint32
&iValue
) // RETURNED
115 assert(cfValue
!= NULL
);
116 CFTypeID valueType
= CFGetTypeID(cfValue
);
117 if(valueType
== CFStringGetTypeID()) {
118 CSSM_RETURN crtn
= MDSStringToUint32((CFStringRef
)cfValue
,
121 MPDebug("cfTypeToInt: key %s uint32 form, string data (%s), "
123 CFStringGetCStringPtr((CFStringRef
)cfValue
,
124 CFStringGetSystemEncoding()));
128 } /* stored as string */
129 else if(valueType
== CFNumberGetTypeID()) {
130 /* be paranoid - there is no unsigned type for CFNumber */
131 CFNumberRef cfNum
= (CFNumberRef
)cfValue
;
132 CFNumberType numType
= CFNumberGetType(cfNum
);
134 case kCFNumberSInt8Type
:
135 case kCFNumberSInt16Type
:
136 case kCFNumberSInt32Type
:
137 case kCFNumberCharType
:
138 case kCFNumberShortType
:
139 case kCFNumberIntType
:
140 case kCFNumberLongType
:
141 case kCFNumberSInt64Type
: // apparently the default
145 MPDebug("MDS cfTypeToInt: Bad CFNumber type (%d) key %s", numType
, key
);
148 Boolean brtn
= CFNumberGetValue(cfNum
, kCFNumberLongType
, &iValue
);
150 MPDebug("MDS cfTypeToInt: Bad CFNumber conversion");
154 } /* stored as number */
155 else if(valueType
== CFBooleanGetTypeID()) {
156 Boolean b
= CFBooleanGetValue((CFBooleanRef
)cfValue
);
161 MPDebug("MDS cfTypeToInt: key %s, uint32 form, bad CF type (%d)",
162 key
, (int)valueType
);
168 * Insert a record, defined by a CSSM_DB_ATTRIBUTE_DATA array, into specified
169 * DL and DB. Returns true on success.
171 bool MDSInsertRecord(
172 const CSSM_DB_ATTRIBUTE_DATA
*inAttr
,
174 CSSM_DB_RECORDTYPE recordType
,
176 CSSM_DB_HANDLE dbHand
)
178 CSSM_DB_RECORD_ATTRIBUTE_DATA recordAttrData
;
179 CSSM_DB_UNIQUE_RECORD_PTR uid
= NULL
;
182 recordAttrData
.DataRecordType
= recordType
;
183 recordAttrData
.SemanticInformation
= 0;
184 recordAttrData
.NumberOfAttributes
= numAttrs
;
185 recordAttrData
.AttributeData
=
186 const_cast<CSSM_DB_ATTRIBUTE_DATA_PTR
>(inAttr
);
189 dl
.DataInsert(dbHand
,
195 catch (const CssmError
&cerr
) {
196 MPDebug("MDSInsertRecord: DataInsert: %s",
197 cssmErrorString(cerr
).c_str());
201 MPDebug("MDSInsertRecord: DataInsert: unknown exception");
205 dl
.FreeUniqueRecord(dbHand
, *uid
);
211 * Convert a number expressed as a CFString to a uint32 using the specified
212 * name/value conversion table. The string may have multiple fields from that
213 * table, ORd together in normal C syntax. Like
215 * CSSM_SERVICE_CSP | CSSM_SERVICE_DL
217 * Individual tokens can also be expressed numerically, either in decimal or
218 * (if prefaced by "0x" hex. Numeric tokens and symbolic string tokens can
219 * be intermixed in the same incoming string.
221 * Individual tokens can be prefixed with "<<" indicating that the indicated
222 * value is to be shifted 16 bits. Cf. CL Primary Relation, {Cert,Crl}TypeFormat.
223 * This applies to both numeric and string tokens.
225 CSSM_RETURN
MDSStringToUint32(
227 const MDSNameValuePair
*table
, // optional, string must be decimal
230 char *cstr
= MDSCFStringToCString(str
);
232 /* should "never" happen...right? */
233 MPDebug("MDSStringToUint32: CFString conversion error");
234 return CSSMERR_CSSM_MDS_ERROR
;
239 char *dst
= tokenStr
;
241 CSSM_RETURN crtn
= CSSM_OK
;
244 while(*src
!= '\0') {
245 /* Get one token from src --> tokenStr[] */
246 /* First skip whitespace and '|' */
247 for( ; *src
!= '\0'; src
++) {
249 if(!isspace(c
) && (c
!= '|')) {
250 /* first char of token */
256 if((*src
== '\0') && (dst
== tokenStr
)) {
261 /* dst[-1] is the first good character of token; copy until
263 for( ; *src
!= '\0'; src
++) {
265 if(isspace(c
) || (c
== '|')) {
273 /* NULL terminate token string, convert to numeric value */
276 CSSM_RETURN crtn
= MDSAttrNameToValue(tokenStr
, table
, tokenVal
);
290 } // end namespace Security