]> git.saurik.com Git - apple/configd.git/blob - configd.tproj/_configopen.c
configd-42.tar.gz
[apple/configd.git] / configd.tproj / _configopen.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23 /*
24 * Modification History
25 *
26 * June 1, 2001 Allan Nathanson <ajn@apple.com>
27 * - public API conversion
28 *
29 * March 24, 2000 Allan Nathanson <ajn@apple.com>
30 * - initial revision
31 */
32
33 #include "configd.h"
34 #include "configd_server.h"
35 #include "session.h"
36
37 int
38 __SCDynamicStoreOpen(SCDynamicStoreRef *store, CFStringRef name)
39 {
40 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreOpen:"));
41 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" name = %@"), name);
42
43 /*
44 * allocate and initialize a new session
45 */
46 *store = __SCDynamicStoreCreatePrivate(NULL, name, NULL, NULL);
47
48 /*
49 * If necessary, initialize the store and session data dictionaries
50 */
51 if (storeData == NULL) {
52 storeData = CFDictionaryCreateMutable(NULL,
53 0,
54 &kCFTypeDictionaryKeyCallBacks,
55 &kCFTypeDictionaryValueCallBacks);
56 sessionData = CFDictionaryCreateMutable(NULL,
57 0,
58 &kCFTypeDictionaryKeyCallBacks,
59 &kCFTypeDictionaryValueCallBacks);
60 changedKeys = CFSetCreateMutable(NULL,
61 0,
62 &kCFTypeSetCallBacks);
63 deferredRemovals = CFSetCreateMutable(NULL,
64 0,
65 &kCFTypeSetCallBacks);
66 removedSessionKeys = CFSetCreateMutable(NULL,
67 0,
68 &kCFTypeSetCallBacks);
69 }
70
71 return kSCStatusOK;
72 }
73
74
75 kern_return_t
76 _configopen(mach_port_t server,
77 xmlData_t nameRef, /* raw XML bytes */
78 mach_msg_type_number_t nameLen,
79 mach_port_t *newServer,
80 int *sc_status)
81 {
82 kern_return_t status;
83 serverSessionRef mySession, newSession;
84 CFDataRef xmlName; /* name (XML serialized) */
85 CFStringRef name; /* name (un-serialized) */
86 CFStringRef xmlError;
87 mach_port_t oldNotify;
88 CFStringRef sessionKey;
89 CFDictionaryRef info;
90 CFMutableDictionaryRef newInfo;
91 CFMachPortRef mp;
92
93 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Open new session."));
94 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
95
96 /* un-serialize the name */
97 xmlName = CFDataCreate(NULL, nameRef, nameLen);
98 status = vm_deallocate(mach_task_self(), (vm_address_t)nameRef, nameLen);
99 if (status != KERN_SUCCESS) {
100 CFRelease(xmlName);
101 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
102 /* non-fatal???, proceed */
103 }
104 name = CFPropertyListCreateFromXMLData(NULL,
105 xmlName,
106 kCFPropertyListImmutable,
107 &xmlError);
108 CFRelease(xmlName);
109 if (!name) {
110 if (xmlError) {
111 SCLog(_configd_verbose, LOG_DEBUG,
112 CFSTR("CFPropertyListCreateFromXMLData() name: %@"),
113 xmlError);
114 CFRelease(xmlError);
115 }
116 *sc_status = kSCStatusFailed;
117 return KERN_SUCCESS;
118 } else if (!isA_CFString(name)) {
119 CFRelease(name);
120 *sc_status = kSCStatusInvalidArgument;
121 return KERN_SUCCESS;
122 }
123
124 mySession = getSession(server);
125 if (mySession->store) {
126 CFRelease(name);
127 SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" Sorry, this session is already open."));
128 *sc_status = kSCStatusFailed; /* you can't re-open an "open" session */
129 return KERN_SUCCESS;
130 }
131
132 /* Create the server port for this session */
133 mp = CFMachPortCreate(NULL, configdCallback, NULL, NULL);
134
135 /* return the newly allocated port to be used for this session */
136 *newServer = CFMachPortGetPort(mp);
137
138 /*
139 * establish the new session
140 */
141 newSession = addSession(mp);
142
143 /* Create and add a run loop source for the port */
144 newSession->serverRunLoopSource = CFMachPortCreateRunLoopSource(NULL, mp, 0);
145 CFRunLoopAddSource(CFRunLoopGetCurrent(),
146 newSession->serverRunLoopSource,
147 kCFRunLoopDefaultMode);
148
149 /*
150 * save the credentials associated with the caller.
151 */
152 newSession->callerEUID = mySession->callerEUID;
153 newSession->callerEGID = mySession->callerEGID;
154
155 *sc_status = __SCDynamicStoreOpen(&newSession->store, name);
156
157 /*
158 * Make the server port accessible to the framework routines.
159 */
160 ((SCDynamicStorePrivateRef)newSession->store)->server = *newServer;
161
162 /* Request a notification when/if the client dies */
163 status = mach_port_request_notification(mach_task_self(),
164 *newServer,
165 MACH_NOTIFY_NO_SENDERS,
166 1,
167 *newServer,
168 MACH_MSG_TYPE_MAKE_SEND_ONCE,
169 &oldNotify);
170 if (status != KERN_SUCCESS) {
171 SCLog(_configd_verbose, LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status));
172 CFRelease(name);
173 cleanupSession(*newServer);
174 *newServer = MACH_PORT_NULL;
175 *sc_status = kSCStatusFailed;
176 return KERN_SUCCESS;
177 }
178
179 if (oldNotify != MACH_PORT_NULL) {
180 SCLog(_configd_verbose, LOG_ERR, CFSTR("_configopen(): why is oldNotify != MACH_PORT_NULL?"));
181 }
182
183 /*
184 * Save the name of the calling application / plug-in with the session data.
185 */
186 sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), *newServer);
187 info = CFDictionaryGetValue(sessionData, sessionKey);
188 if (info) {
189 newInfo = CFDictionaryCreateMutableCopy(NULL, 0, info);
190 } else {
191 newInfo = CFDictionaryCreateMutable(NULL,
192 0,
193 &kCFTypeDictionaryKeyCallBacks,
194 &kCFTypeDictionaryValueCallBacks);
195 }
196 CFDictionarySetValue(newInfo, kSCDName, name);
197 CFRelease(name);
198 CFDictionarySetValue(sessionData, sessionKey, newInfo);
199 CFRelease(newInfo);
200 CFRelease(sessionKey);
201
202 return KERN_SUCCESS;
203 }