1/*
2 * Copyright (c) 2000, 2001, 2003, 2004, 2006, 2008, 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 * Modification History
26 *
27 * June 1, 2001			Allan Nathanson <ajn@apple.com>
28 * - public API conversion
29 *
30 * March 24, 2000		Allan Nathanson <ajn@apple.com>
31 * - initial revision
32 */
33
34#include "configd.h"
35#include "session.h"
36
37__private_extern__
38int
39__SCDynamicStoreAddValue(SCDynamicStoreRef store, CFStringRef key, CFDataRef value)
40{
41	int				sc_status	= kSCStatusOK;
42	SCDynamicStorePrivateRef	storePrivate	= (SCDynamicStorePrivateRef)store;
43	CFDataRef			tempValue;
44
45	if (_configd_trace) {
46		SCTrace(TRUE, _configd_trace,
47			CFSTR("%s%s : %5d : %@\n"),
48			"add  ",
49			storePrivate->useSessionKeys ? "t " : "  ",
50			storePrivate->server,
51			key);
52	}
53
54	/*
55	 * Ensure that this is a new key.
56	 */
57	sc_status = __SCDynamicStoreCopyValue(store, key, &tempValue, TRUE);
58	switch (sc_status) {
59		case kSCStatusNoKey :
60			/* store key does not exist, proceed */
61			break;
62
63		case kSCStatusOK :
64			/* store key exists, sorry */
65			CFRelease(tempValue);
66			sc_status = kSCStatusKeyExists;
67			goto done;
68
69		default :
70#ifdef	DEBUG
71			SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreAddValue __SCDynamicStoreCopyValue(): %s"), SCErrorString(sc_status));
72#endif	/* DEBUG */
73			goto done;
74	}
75
76	/*
77	 * Save the new key.
78	 */
79	sc_status = __SCDynamicStoreSetValue(store, key, value, TRUE);
80
81	/* push changes */
82	__SCDynamicStorePush();
83
84    done:
85
86	return sc_status;
87}
88
89
90__private_extern__
91kern_return_t
92_configadd(mach_port_t 			server,
93	   xmlData_t			keyRef,		/* raw XML bytes */
94	   mach_msg_type_number_t	keyLen,
95	   xmlData_t			dataRef,	/* raw XML bytes */
96	   mach_msg_type_number_t	dataLen,
97	   int				*newInstance,
98	   int				*sc_status,
99	   audit_token_t		audit_token)
100{
101	CFStringRef		key		= NULL;		/* key  (un-serialized) */
102	CFDataRef		data		= NULL;		/* data (un-serialized) */
103	serverSessionRef	mySession;
104
105	*sc_status = kSCStatusOK;
106
107	/* un-serialize the key */
108	if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
109		*sc_status = kSCStatusFailed;
110		goto done;
111	}
112
113	/* un-serialize the data */
114	if (!_SCUnserializeData(&data, (void *)dataRef, dataLen)) {
115		*sc_status = kSCStatusFailed;
116	}
117
118	if (*sc_status != kSCStatusOK) {
119		goto done;
120	}
121
122	if (!isA_CFString(key)) {
123		*sc_status = kSCStatusInvalidArgument;
124		goto done;
125	}
126
127	mySession = getSession(server);
128	if (mySession == NULL) {
129		mySession = tempSession(server, CFSTR("SCDynamicStoreAddValue"), audit_token);
130		if (mySession == NULL) {
131			/* you must have an open session to play */
132			*sc_status = kSCStatusNoStoreSession;
133			goto done;
134		}
135	}
136
137	if (!hasWriteAccess(mySession, key)) {
138		*sc_status = kSCStatusAccessError;
139		goto done;
140	}
141
142	*sc_status = __SCDynamicStoreAddValue(mySession->store, key, data);
143	if (*sc_status == kSCStatusOK) {
144		*newInstance = 0;
145	}
146
147    done :
148
149	if (key != NULL)	CFRelease(key);
150	if (data != NULL)	CFRelease(data);
151
152	return KERN_SUCCESS;
153}
154
155
156__private_extern__
157kern_return_t
158_configadd_s(mach_port_t 		server,
159	     xmlData_t			keyRef,		/* raw XML bytes */
160	     mach_msg_type_number_t	keyLen,
161	     xmlData_t			dataRef,	/* raw XML bytes */
162	     mach_msg_type_number_t	dataLen,
163	     int			*newInstance,
164	     int			*sc_status)
165{
166	CFDataRef			data		= NULL;		/* data (un-serialized) */
167	CFStringRef			key		= NULL;		/* key  (un-serialized) */
168	serverSessionRef		mySession;
169	SCDynamicStorePrivateRef	storePrivate;
170	Boolean				useSessionKeys;
171
172	*sc_status = kSCStatusOK;
173
174	/* un-serialize the key */
175	if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
176		*sc_status = kSCStatusFailed;
177	}
178
179	/* un-serialize the data */
180	if (!_SCUnserializeData(&data, (void *)dataRef, dataLen)) {
181		*sc_status = kSCStatusFailed;
182	}
183
184	if (*sc_status != kSCStatusOK) {
185		goto done;
186	}
187
188	if (!isA_CFString(key)) {
189		*sc_status = kSCStatusInvalidArgument;
190		goto done;
191	}
192
193	mySession = getSession(server);
194	if (mySession == NULL) {
195		/* you must have an open session to play */
196		*sc_status = kSCStatusNoStoreSession;
197		goto done;
198	}
199
200	if (!hasWriteAccess(mySession, key)) {
201		*sc_status = kSCStatusAccessError;
202		goto done;
203	}
204
205	// force "useSessionKeys"
206	storePrivate = (SCDynamicStorePrivateRef)mySession->store;
207	useSessionKeys = storePrivate->useSessionKeys;
208	storePrivate->useSessionKeys = TRUE;
209
210	*sc_status = __SCDynamicStoreAddValue(mySession->store, key, data);
211	if (*sc_status == kSCStatusOK) {
212		*newInstance = 0;
213	}
214
215	// restore "useSessionKeys"
216	storePrivate->useSessionKeys = useSessionKeys;
217
218    done :
219
220	if (key != NULL)	CFRelease(key);
221	if (data != NULL)	CFRelease(data);
222
223	return KERN_SUCCESS;
224}
225