1/*
2 * Copyright (c) 2005 Apple Computer, 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 * 01DL_CreateReleation.c
24 */
25
26#include <stdlib.h>
27#include <unistd.h>
28#include <Security/cssmapi.h>
29#include <Security/cssmapple.h>
30
31#include "testmore.h"
32#include "testenv.h"
33#include "testcssm.h"
34
35#define DBNAME "testdl"
36
37CSSM_APPLEDL_OPEN_PARAMETERS openParameters =
38{
39	sizeof(CSSM_APPLEDL_OPEN_PARAMETERS),
40	CSSM_APPLEDL_OPEN_PARAMETERS_VERSION,
41	CSSM_FALSE,
42	kCSSM_APPLEDL_MASK_MODE,
43	0600
44};
45CSSM_DBINFO dbInfo =
46{
47	0 /* NumberOfRecordTypes */,
48	NULL,
49	NULL,
50	NULL,
51	CSSM_TRUE /* IsLocal */,
52	NULL, /* AccessPath - URL, dir path, etc. */
53	NULL /* reserved */
54};
55CSSM_DB_SCHEMA_ATTRIBUTE_INFO attributeInfo[] =
56{
57	{
58		1,
59		"One",
60		{},
61		CSSM_DB_ATTRIBUTE_FORMAT_STRING
62	},
63	{
64		2,
65		"Two",
66		{},
67		CSSM_DB_ATTRIBUTE_FORMAT_STRING
68	}
69};
70CSSM_DB_SCHEMA_INDEX_INFO indexInfo[] =
71{
72	{
73		1,
74		0,
75		CSSM_DB_INDEX_UNIQUE,
76		CSSM_DB_INDEX_ON_ATTRIBUTE
77	},
78	{
79		1,
80		1,
81		CSSM_DB_INDEX_NONUNIQUE,
82		CSSM_DB_INDEX_ON_ATTRIBUTE
83	},
84	{
85		2,
86		2,
87		CSSM_DB_INDEX_NONUNIQUE,
88		CSSM_DB_INDEX_ON_ATTRIBUTE
89	}
90};
91CSSM_DATA values[] =
92{
93	{ 5, (uint8 *)"value" }
94};
95CSSM_DB_ATTRIBUTE_DATA attributeData[] =
96{
97	{
98		{
99			CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
100			{ "One" },
101			CSSM_DB_ATTRIBUTE_FORMAT_STRING
102		},
103		sizeof(values) / sizeof(CSSM_DATA),
104		values
105	},
106	{
107		{
108			CSSM_DB_ATTRIBUTE_NAME_AS_STRING,
109			{ "Two" },
110			CSSM_DB_ATTRIBUTE_FORMAT_STRING
111		},
112		sizeof(values) / sizeof(CSSM_DATA),
113		values
114	}
115};
116CSSM_DB_RECORD_ATTRIBUTE_DATA attributes =
117{
118	42,
119	0,
120	sizeof(attributeData) / sizeof(CSSM_DB_ATTRIBUTE_DATA),
121	attributeData
122};
123
124int
125static test1(CSSM_DL_HANDLE dl)
126{
127    int pass = 1;
128    CSSM_DL_DB_HANDLE dldb = { dl };
129    CSSM_DB_UNIQUE_RECORD_PTR uniqueId;
130
131    pass &= ok_status(CSSM_DL_DbCreate(dl, DBNAME, NULL /* DbLocation */,
132                  &dbInfo,
133                  CSSM_DB_ACCESS_READ | CSSM_DB_ACCESS_WRITE,
134                  NULL /* CredAndAclEntry */,
135                  &openParameters,
136                  &dldb.DBHandle),
137        "CSSM_DL_DbCreate");
138
139    pass &= is_status(CSSM_DL_DataInsert(dldb,
140        attributes.DataRecordType,
141        &attributes,
142        NULL,
143        &uniqueId),
144        CSSMERR_DL_INVALID_RECORDTYPE, "CSSM_DL_DataInsert no table");
145
146    pass &= ok_status(CSSM_DL_CreateRelation(dldb,
147        42,
148        "Fourty Two",
149        sizeof(attributeInfo) / sizeof(CSSM_DB_SCHEMA_ATTRIBUTE_INFO),
150        attributeInfo,
151        sizeof(indexInfo) / sizeof(CSSM_DB_SCHEMA_INDEX_INFO),
152        indexInfo), "CSSM_DL_CreateRelation");
153
154    pass &= ok_status(CSSM_DL_DataInsert(dldb,
155        attributes.DataRecordType,
156        &attributes,
157        NULL,
158        &uniqueId), "CSSM_DL_DataInsert");
159
160    pass &= is_status(CSSM_DL_DataInsert(dldb,
161        attributes.DataRecordType,
162        &attributes,
163        NULL,
164        &uniqueId),
165        CSSMERR_DL_INVALID_UNIQUE_INDEX_DATA, "CSSM_DL_DataInsert dupe");
166
167    pass &= ok_status(CSSM_DL_FreeUniqueRecord(dldb, uniqueId),
168        "CSSM_DL_FreeUniqueRecord");
169
170    pass &= ok_status(CSSM_DL_DbClose(dldb),
171        "CSSM_DL_DbClose");
172
173    return pass;
174}
175
176int
177static test2(CSSM_DL_HANDLE dl)
178{
179	int pass = 1;
180	CSSM_DL_DB_HANDLE dldb = { dl };
181	CSSM_DB_UNIQUE_RECORD_PTR uniqueId;
182
183    pass &= ok_status(CSSM_DL_DbCreate(dl, DBNAME, NULL /* DbLocation */,
184                  &dbInfo,
185                  CSSM_DB_ACCESS_READ | CSSM_DB_ACCESS_WRITE,
186                  NULL /* CredAndAclEntry */,
187                  NULL,
188                  &dldb.DBHandle),
189        "CSSM_DL_DbCreate");
190
191    pass &= ok_status(CSSM_DL_DbClose(dldb),
192        "CSSM_DL_DbClose");
193
194	pass &= ok_status(CSSM_DL_DbOpen(dl, DBNAME, NULL /* DbLocation */,
195                  CSSM_DB_ACCESS_READ | CSSM_DB_ACCESS_WRITE,
196                  NULL /* CredAndAclEntry */,
197                  &openParameters,
198                  &dldb.DBHandle),
199		"CSSM_DL_DbOpen");
200
201	pass &= is_status(CSSM_DL_DataInsert(dldb,
202		attributes.DataRecordType,
203		&attributes,
204		NULL,
205		&uniqueId),
206		CSSMERR_DL_INVALID_RECORDTYPE, "CSSM_DL_DataInsert no table");
207
208	pass &= ok_status(CSSM_DL_CreateRelation(dldb,
209		42,
210		"Fourty Two",
211		sizeof(attributeInfo) / sizeof(CSSM_DB_SCHEMA_ATTRIBUTE_INFO),
212		attributeInfo,
213		sizeof(indexInfo) / sizeof(CSSM_DB_SCHEMA_INDEX_INFO),
214		indexInfo), "CSSM_DL_CreateRelation");
215
216	pass &= ok_status(CSSM_DL_DataInsert(dldb,
217		attributes.DataRecordType,
218		&attributes,
219		NULL,
220		&uniqueId), "CSSM_DL_DataInsert fails unless 4039735 is fixed");
221
222	pass &= is_status(CSSM_DL_DataInsert(dldb,
223		attributes.DataRecordType,
224		&attributes,
225		NULL,
226		&uniqueId),
227		CSSMERR_DL_INVALID_UNIQUE_INDEX_DATA,
228		"CSSM_DL_DataInsert dupe");
229
230	pass &= ok_status(CSSM_DL_FreeUniqueRecord(dldb, uniqueId),
231		"CSSM_DL_FreeUniqueRecord");
232
233	pass &= ok_status(CSSM_DL_DbClose(dldb),
234		"CSSM_DL_DbDelete");
235
236	return pass;
237}
238
239int
240main(int argc, char * const *argv)
241{
242        int guid_alt = argc > 1 && !strcmp(argv[1], "-g");
243        /* {2cb56191-ee6f-432d-a377-853d3c6b949e} */
244        CSSM_GUID s3dl_guid =
245        {
246                0x2cb56191, 0xee6f, 0x432d,
247                { 0xa3, 0x77, 0x85, 0x3d, 0x3c, 0x6b, 0x94, 0x9e }
248        };
249        const CSSM_GUID *guid = guid_alt ? & s3dl_guid : &gGuidAppleFileDL;
250
251	int pass = 1;
252
253	plan_tests(23);
254
255	CSSM_DL_HANDLE dl;
256	pass &= ok(cssm_attach(guid, &dl), "cssm_attach");
257	pass &= ok(tests_begin(argc, argv), "tests_begin");
258
259	pass &= ok(test1(dl), "insert record in new table with ac off");
260	pass &= ok_status(CSSM_DL_DbDelete(dl, DBNAME, NULL /* DbLocation */,
261		NULL /* AccessCred */), "CSSM_DL_DbDelete");
262	pass &= ok(test2(dl),
263		"insert record in existing db in new table with ac off");
264	pass &= ok_status(CSSM_DL_DbDelete(dl, DBNAME, NULL /* DbLocation */,
265		NULL /* AccessCred */), "CSSM_DL_DbDelete");
266	pass &= ok(cssm_detach(guid, dl), "cssm_detach");
267
268	return !tests_end(pass);
269}
270