]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/_configget.c
configd-963.270.3.tar.gz
[apple/configd.git] / configd.tproj / _configget.c
1 /*
2 * Copyright (c) 2000-2006, 2008, 2011, 2013-2016, 2019 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__
38 int
39 __SCDynamicStoreCopyValue(SCDynamicStoreRef store, CFStringRef key, CFDataRef *value, Boolean internal)
40 {
41 SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
42 CFDictionaryRef dict;
43
44 SC_trace("%s : %5d : %@",
45 internal ? "*copy " : "copy ",
46 storePrivate->server,
47 key);
48
49 dict = CFDictionaryGetValue(storeData, key);
50 if ((dict == NULL) || !CFDictionaryContainsKey(dict, kSCDData)) {
51 /* key doesn't exist (or data never defined) */
52 return kSCStatusNoKey;
53 }
54
55 /* Return the data associated with the key */
56 *value = CFRetain(CFDictionaryGetValue(dict, kSCDData));
57
58 return kSCStatusOK;
59 }
60
61 __private_extern__
62 kern_return_t
63 _configget(mach_port_t server,
64 xmlData_t keyRef, /* raw XML bytes */
65 mach_msg_type_number_t keyLen,
66 xmlDataOut_t *dataRef, /* raw XML bytes */
67 mach_msg_type_number_t *dataLen,
68 int *newInstance,
69 int *sc_status,
70 audit_token_t audit_token)
71 {
72 CFStringRef key = NULL; /* key (un-serialized) */
73 CFIndex len;
74 serverSessionRef mySession;
75 Boolean ok;
76 CFDataRef value;
77
78 *dataRef = NULL;
79 *dataLen = 0;
80 *newInstance = 0;
81
82 /* un-serialize the key */
83 if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
84 *sc_status = kSCStatusFailed;
85 goto done;
86 }
87
88 if (!isA_CFString(key)) {
89 *sc_status = kSCStatusInvalidArgument;
90 goto done;
91 }
92
93 mySession = getSession(server);
94 if (mySession == NULL) {
95 mySession = tempSession(server, CFSTR("SCDynamicStoreCopyValue"), audit_token);
96 if (mySession == NULL) {
97 /* you must have an open session to play */
98 *sc_status = kSCStatusNoStoreSession;
99 goto done;
100 }
101 }
102
103 *sc_status = __SCDynamicStoreCopyValue(mySession->store, key, &value, FALSE);
104 if (*sc_status != kSCStatusOK) {
105 goto done;
106 }
107
108 /* serialize the data */
109 ok = _SCSerializeData(value, (void **)dataRef, &len);
110 *dataLen = (mach_msg_type_number_t)len;
111 CFRelease(value);
112 if (!ok) {
113 *sc_status = kSCStatusFailed;
114 goto done;
115 }
116
117 done :
118
119 if (key != NULL) CFRelease(key);
120 return KERN_SUCCESS;
121 }
122
123 /*
124 * "context" argument for addSpecificKey() and addSpecificPattern()
125 */
126 typedef struct {
127 SCDynamicStoreRef store;
128 CFMutableDictionaryRef dict;
129 } addSpecific, *addSpecificRef;
130
131 static void
132 addSpecificKey(const void *value, void *context)
133 {
134 CFDataRef data;
135 CFStringRef key = (CFStringRef)value;
136 addSpecificRef myContextRef = (addSpecificRef)context;
137 int sc_status;
138
139 if (!isA_CFString(key)) {
140 return;
141 }
142
143 sc_status = __SCDynamicStoreCopyValue(myContextRef->store, key, &data, TRUE);
144 if (sc_status == kSCStatusOK) {
145 CFDictionaryAddValue(myContextRef->dict, key, data);
146 CFRelease(data);
147 }
148
149 return;
150 }
151
152 static void
153 addSpecificPattern(const void *value, void *context)
154 {
155 CFStringRef pattern = (CFStringRef)value;
156 addSpecificRef myContextRef = (addSpecificRef)context;
157 int sc_status;
158 CFArrayRef keys;
159
160 if (!isA_CFString(pattern)) {
161 return;
162 }
163
164 sc_status = __SCDynamicStoreCopyKeyList(myContextRef->store, pattern, TRUE, &keys);
165 if (sc_status == kSCStatusOK) {
166 CFArrayApplyFunction(keys,
167 CFRangeMake(0, CFArrayGetCount(keys)),
168 addSpecificKey,
169 context);
170 CFRelease(keys);
171 }
172
173 return;
174 }
175
176 __private_extern__
177 int
178 __SCDynamicStoreCopyMultiple(SCDynamicStoreRef store, CFArrayRef keys, CFArrayRef patterns, CFDictionaryRef *values)
179 {
180 SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
181 addSpecific myContext;
182
183 SC_trace("copy m : %5d : %ld keys, %ld patterns",
184 storePrivate->server,
185 keys ? CFArrayGetCount(keys) : 0,
186 patterns ? CFArrayGetCount(patterns) : 0);
187
188 myContext.store = store;
189 myContext.dict = CFDictionaryCreateMutable(NULL,
190 0,
191 &kCFTypeDictionaryKeyCallBacks,
192 &kCFTypeDictionaryValueCallBacks);
193
194 if (keys) {
195 CFArrayApplyFunction(keys,
196 CFRangeMake(0, CFArrayGetCount(keys)),
197 addSpecificKey,
198 &myContext);
199 }
200
201 if (patterns) {
202 CFArrayApplyFunction(patterns,
203 CFRangeMake(0, CFArrayGetCount(patterns)),
204 addSpecificPattern,
205 &myContext);
206 }
207
208 /* Return the keys/values associated with the key */
209 *values = myContext.dict;
210
211 return kSCStatusOK;
212 }
213
214 __private_extern__
215 kern_return_t
216 _configget_m(mach_port_t server,
217 xmlData_t keysRef,
218 mach_msg_type_number_t keysLen,
219 xmlData_t patternsRef,
220 mach_msg_type_number_t patternsLen,
221 xmlDataOut_t *dataRef,
222 mach_msg_type_number_t *dataLen,
223 int *sc_status,
224 audit_token_t audit_token)
225 {
226 CFDictionaryRef dict = NULL; /* keys/values (un-serialized) */
227 CFArrayRef keys = NULL; /* keys (un-serialized) */
228 CFIndex len;
229 serverSessionRef mySession;
230 Boolean ok;
231 CFArrayRef patterns = NULL; /* patterns (un-serialized) */
232
233 *dataRef = NULL;
234 *dataLen = 0;
235
236 *sc_status = kSCStatusOK;
237
238 if (keysRef && (keysLen > 0)) {
239 /* un-serialize the keys */
240 if (!_SCUnserialize((CFPropertyListRef *)&keys, NULL, (void *)keysRef, keysLen)) {
241 *sc_status = kSCStatusFailed;
242 }
243 }
244
245 if (patternsRef && (patternsLen > 0)) {
246 /* un-serialize the patterns */
247 if (!_SCUnserialize((CFPropertyListRef *)&patterns, NULL, (void *)patternsRef, patternsLen)) {
248 *sc_status = kSCStatusFailed;
249 }
250 }
251
252 if (*sc_status != kSCStatusOK) {
253 goto done;
254 }
255
256 if ((keys != NULL) && !isA_CFArray(keys)) {
257 *sc_status = kSCStatusInvalidArgument;
258 goto done;
259 }
260
261 if ((patterns != NULL) && !isA_CFArray(patterns)) {
262 *sc_status = kSCStatusInvalidArgument;
263 goto done;
264 }
265
266 mySession = getSession(server);
267 if (mySession == NULL) {
268 mySession = tempSession(server, CFSTR("SCDynamicStoreCopyMultiple"), audit_token);
269 if (mySession == NULL) {
270 /* you must have an open session to play */
271 *sc_status = kSCStatusNoStoreSession;
272 goto done;
273 }
274 }
275
276 /* fetch the requested information */
277 *sc_status = __SCDynamicStoreCopyMultiple(mySession->store, keys, patterns, &dict);
278
279 /* serialize the dictionary of matching keys/patterns */
280 ok = _SCSerialize(dict, NULL, (void **)dataRef, &len);
281 *dataLen = (mach_msg_type_number_t)len;
282 CFRelease(dict);
283 if (!ok) {
284 *sc_status = kSCStatusFailed;
285 }
286
287 done :
288
289 if (keys) CFRelease(keys);
290 if (patterns) CFRelease(patterns);
291 return KERN_SUCCESS;
292 }