2 * Copyright (c) 2000-2006, 2009-2011, 2015, 2017 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * Modification History
27 * June 1, 2001 Allan Nathanson <ajn@apple.com>
28 * - public API conversion
30 * April 14, 2000 Allan Nathanson <ajn@apple.com>
39 #include "configd_server.h"
41 #include "plugin_support.h"
44 #define SNAPSHOT_PATH_STATE _PATH_VARTMP "configd-state"
45 #define SNAPSHOT_PATH_STORE _PATH_VARTMP "configd-store.plist"
46 #define SNAPSHOT_PATH_PATTERN _PATH_VARTMP "configd-pattern.plist"
47 #define SNAPSHOT_PATH_SESSION _PATH_VARTMP "configd-session.plist"
52 static CF_RETURNS_RETAINED CFDictionaryRef
53 _expandStore(CFDictionaryRef storeData
)
55 const void * keys_q
[N_QUICK
];
56 const void ** keys
= keys_q
;
58 CFDictionaryRef newStoreData
= NULL
;
59 const void * nValues_q
[N_QUICK
];
60 const void ** nValues
= nValues_q
;
61 const void * oValues_q
[N_QUICK
];
62 const void ** oValues
= oValues_q
;
64 nElements
= CFDictionaryGetCount(storeData
);
68 if (nElements
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) {
69 keys
= CFAllocatorAllocate(NULL
, nElements
* sizeof(CFTypeRef
), 0);
70 oValues
= CFAllocatorAllocate(NULL
, nElements
* sizeof(CFTypeRef
), 0);
71 nValues
= CFAllocatorAllocate(NULL
, nElements
* sizeof(CFTypeRef
), 0);
73 bzero(nValues
, nElements
* sizeof(CFTypeRef
));
75 CFDictionaryGetKeysAndValues(storeData
, keys
, oValues
);
76 for (i
= 0; i
< nElements
; i
++) {
79 data
= CFDictionaryGetValue(oValues
[i
], kSCDData
);
81 CFPropertyListRef plist
;
83 nValues
[i
] = CFDictionaryCreateMutableCopy(NULL
, 0, oValues
[i
]);
85 if (!_SCUnserialize(&plist
, data
, NULL
, 0)) {
86 SC_log(LOG_NOTICE
, "_SCUnserialize() failed, key=%@", keys
[i
]);
90 CFDictionarySetValue((CFMutableDictionaryRef
)nValues
[i
],
95 nValues
[i
] = CFRetain(oValues
[i
]);
100 newStoreData
= CFDictionaryCreate(NULL
,
104 &kCFTypeDictionaryKeyCallBacks
,
105 &kCFTypeDictionaryValueCallBacks
);
110 for (i
= 0; i
< nElements
; i
++) {
111 CFRelease(nValues
[i
]);
114 if (keys
!= keys_q
) {
115 CFAllocatorDeallocate(NULL
, keys
);
116 CFAllocatorDeallocate(NULL
, oValues
);
117 CFAllocatorDeallocate(NULL
, nValues
);
127 __SCDynamicStoreSnapshot(SCDynamicStoreRef store
)
129 #pragma unused(store)
130 CFDictionaryRef expandedStoreData
;
135 /* Save a snapshot of configd's "state" */
137 (void) unlink(SNAPSHOT_PATH_STATE
);
138 fd
= open(SNAPSHOT_PATH_STATE
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_EXCL
, 0644);
140 return kSCStatusFailed
;
144 return kSCStatusFailed
;
146 SCPrint(TRUE
, f
, CFSTR("Main thread :\n\n"));
147 SCPrint(TRUE
, f
, CFSTR("%@\n"), CFRunLoopGetCurrent());
148 if (plugin_runLoop
!= NULL
) {
149 SCPrint(TRUE
, f
, CFSTR("Plug-in thread :\n\n"));
150 SCPrint(TRUE
, f
, CFSTR("%@\n"), plugin_runLoop
);
155 /* Save a snapshot of the "store" data */
157 (void) unlink(SNAPSHOT_PATH_STORE
);
158 fd
= open(SNAPSHOT_PATH_STORE
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_EXCL
, 0644);
160 return kSCStatusFailed
;
163 expandedStoreData
= _expandStore(storeData
);
164 xmlData
= CFPropertyListCreateData(NULL
, expandedStoreData
, kCFPropertyListXMLFormat_v1_0
, 0, NULL
);
165 CFRelease(expandedStoreData
);
166 if (xmlData
== NULL
) {
167 SC_log(LOG_NOTICE
, "CFPropertyListCreateData() failed");
169 return kSCStatusFailed
;
171 (void) write(fd
, CFDataGetBytePtr(xmlData
), CFDataGetLength(xmlData
));
175 /* Save a snapshot of the "pattern" data */
177 (void) unlink(SNAPSHOT_PATH_PATTERN
);
178 fd
= open(SNAPSHOT_PATH_PATTERN
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_EXCL
, 0644);
180 return kSCStatusFailed
;
183 xmlData
= CFPropertyListCreateData(NULL
, patternData
, kCFPropertyListXMLFormat_v1_0
, 0, NULL
);
184 if (xmlData
== NULL
) {
185 SC_log(LOG_NOTICE
, "CFPropertyListCreateData() failed");
187 return kSCStatusFailed
;
189 (void) write(fd
, CFDataGetBytePtr(xmlData
), CFDataGetLength(xmlData
));
193 /* Save a snapshot of the "session" data */
195 (void) unlink(SNAPSHOT_PATH_SESSION
);
196 fd
= open(SNAPSHOT_PATH_SESSION
, O_WRONLY
|O_CREAT
|O_TRUNC
|O_EXCL
, 0644);
198 return kSCStatusFailed
;
201 xmlData
= CFPropertyListCreateData(NULL
, sessionData
, kCFPropertyListXMLFormat_v1_0
, 0, NULL
);
202 if (xmlData
== NULL
) {
203 SC_log(LOG_NOTICE
, "CFPropertyListCreateData() failed");
205 return kSCStatusFailed
;
207 (void) write(fd
, CFDataGetBytePtr(xmlData
), CFDataGetLength(xmlData
));
217 _snapshot(mach_port_t server
, int *sc_status
, audit_token_t audit_token
)
219 serverSessionRef mySession
;
221 mySession
= getSession(server
);
222 if (mySession
== NULL
) {
223 mySession
= tempSession(server
, CFSTR("SCDynamicStoreSnapshot"), audit_token
);
224 if (mySession
== NULL
) {
225 /* you must have an open session to play */
226 return kSCStatusNoStoreSession
;
230 if (!hasRootAccess(mySession
)) {
231 return kSCStatusAccessError
;
234 *sc_status
= __SCDynamicStoreSnapshot(mySession
->store
);