]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/_confignotify.c
configd-596.12.tar.gz
[apple/configd.git] / configd.tproj / _confignotify.c
1 /*
2 * Copyright (c) 2000-2004, 2006, 2008, 2011, 2012 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 * May 19, 2001 Allan Nathanson <ajn@apple.com>
28 * - initial revision
29 */
30
31 #include "configd.h"
32 #include "session.h"
33
34 __private_extern__
35 int
36 __SCDynamicStoreNotifyValue(SCDynamicStoreRef store, CFStringRef key, Boolean internal)
37 {
38 CFDictionaryRef dict;
39 Boolean newValue = FALSE;
40 SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
41 int sc_status = kSCStatusOK;
42 CFDataRef value;
43
44 if (_configd_trace) {
45 SCTrace(TRUE, _configd_trace,
46 CFSTR("%s : %5d : %@\n"),
47 internal ? "*notify" : "notify ",
48 storePrivate->server,
49 key);
50 }
51
52 /*
53 * Tickle the value in the dynamic store
54 */
55 dict = CFDictionaryGetValue(storeData, key);
56 if (!dict || !CFDictionaryGetValueIfPresent(dict, kSCDData, (const void **)&value)) {
57 /* key doesn't exist (or data never defined) */
58 (void)_SCSerialize(kCFBooleanTrue, &value, NULL, NULL);
59 newValue = TRUE;
60 }
61
62 /* replace or store initial/temporary existing value */
63 __SCDynamicStoreSetValue(store, key, value, TRUE);
64
65 if (newValue) {
66 /* remove the value we just created */
67 __SCDynamicStoreRemoveValue(store, key, TRUE);
68 CFRelease(value);
69 }
70
71 if (!internal) {
72 /* push changes */
73 __SCDynamicStorePush();
74 }
75
76 return sc_status;
77 }
78
79
80 __private_extern__
81 kern_return_t
82 _confignotify(mach_port_t server,
83 xmlData_t keyRef, /* raw XML bytes */
84 mach_msg_type_number_t keyLen,
85 int *sc_status,
86 audit_token_t audit_token)
87 {
88 CFStringRef key = NULL; /* key (un-serialized) */
89 serverSessionRef mySession;
90
91 /* un-serialize the key */
92 if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
93 *sc_status = kSCStatusFailed;
94 goto done;
95 }
96
97 if (!isA_CFString(key)) {
98 *sc_status = kSCStatusInvalidArgument;
99 goto done;
100 }
101
102 mySession = getSession(server);
103 if (mySession == NULL) {
104 mySession = tempSession(server, CFSTR("SCDynamicStoreNotifyValue"), audit_token);
105 if (mySession == NULL) {
106 /* you must have an open session to play */
107 *sc_status = kSCStatusNoStoreSession;
108 goto done;
109 }
110 }
111
112 if (!hasWriteAccess(mySession, key)) {
113 *sc_status = kSCStatusAccessError;
114 goto done;
115 }
116
117 *sc_status = __SCDynamicStoreNotifyValue(mySession->store, key, FALSE);
118
119 done :
120
121 if (key) CFRelease(key);
122 return KERN_SUCCESS;
123 }