X-Git-Url: https://git.saurik.com/apple/configd.git/blobdiff_plain/0fae82ee9e32dcee00597b75650c675a75eab32e..441dd19beddb71be6edb0b50e19a89e700a89468:/configd.tproj/_configopen.c diff --git a/configd.tproj/_configopen.c b/configd.tproj/_configopen.c index f462ee9..5f70aeb 100644 --- a/configd.tproj/_configopen.c +++ b/configd.tproj/_configopen.c @@ -1,22 +1,23 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2009 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * * @APPLE_LICENSE_HEADER_END@ */ @@ -34,26 +35,32 @@ #include "configd_server.h" #include "session.h" +#include +#include +#include + +__private_extern__ int __SCDynamicStoreOpen(SCDynamicStoreRef *store, CFStringRef name) { - SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreOpen:")); - SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" name = %@"), name); - /* * allocate and initialize a new session */ - *store = __SCDynamicStoreCreatePrivate(NULL, name, NULL, NULL); + *store = (SCDynamicStoreRef)__SCDynamicStoreCreatePrivate(NULL, name, NULL, NULL); /* * If necessary, initialize the store and session data dictionaries */ if (storeData == NULL) { + sessionData = CFDictionaryCreateMutable(NULL, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); storeData = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - sessionData = CFDictionaryCreateMutable(NULL, + patternData = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); @@ -72,92 +79,123 @@ __SCDynamicStoreOpen(SCDynamicStoreRef *store, CFStringRef name) } +static CFStringRef +openMPCopyDescription(const void *info) +{ + return CFStringCreateWithFormat(NULL, NULL, CFSTR("")); +} + + +__private_extern__ kern_return_t _configopen(mach_port_t server, xmlData_t nameRef, /* raw XML bytes */ mach_msg_type_number_t nameLen, + xmlData_t optionsRef, /* raw XML bytes */ + mach_msg_type_number_t optionsLen, mach_port_t *newServer, - int *sc_status) + int *sc_status, + audit_token_t audit_token) { - kern_return_t status; - serverSessionRef mySession, newSession; - CFDataRef xmlName; /* name (XML serialized) */ - CFStringRef name; /* name (un-serialized) */ - CFStringRef xmlError; - mach_port_t oldNotify; - CFStringRef sessionKey; - CFDictionaryRef info; - CFMutableDictionaryRef newInfo; - CFMachPortRef mp; - - SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Open new session.")); - SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server); + CFDictionaryRef info; + serverSessionRef mySession; + CFStringRef name = NULL; /* name (un-serialized) */ + CFMutableDictionaryRef newInfo; + mach_port_t oldNotify; + CFDictionaryRef options = NULL; /* options (un-serialized) */ + CFStringRef sessionKey; + kern_return_t status; + SCDynamicStorePrivateRef storePrivate; + CFBooleanRef useSessionKeys = NULL; + + *sc_status = kSCStatusOK; /* un-serialize the name */ - xmlName = CFDataCreate(NULL, nameRef, nameLen); - status = vm_deallocate(mach_task_self(), (vm_address_t)nameRef, nameLen); - if (status != KERN_SUCCESS) { - CFRelease(xmlName); - SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status)); - /* non-fatal???, proceed */ + if (!_SCUnserializeString(&name, NULL, (void *)nameRef, nameLen)) { + *sc_status = kSCStatusFailed; } - name = CFPropertyListCreateFromXMLData(NULL, - xmlName, - kCFPropertyListImmutable, - &xmlError); - CFRelease(xmlName); - if (!name) { - if (xmlError) { - SCLog(_configd_verbose, LOG_DEBUG, - CFSTR("CFPropertyListCreateFromXMLData() name: %@"), - xmlError); - CFRelease(xmlError); + + if ((optionsRef != NULL) && (optionsLen > 0)) { + /* un-serialize the [session] options */ + if (!_SCUnserialize((CFPropertyListRef *)&options, NULL, (void *)optionsRef, optionsLen)) { + *sc_status = kSCStatusFailed; } - *sc_status = kSCStatusFailed; - return KERN_SUCCESS; - } else if (!isA_CFString(name)) { - CFRelease(name); + } + + if (*sc_status != kSCStatusOK) { + goto done; + } + + if (!isA_CFString(name)) { *sc_status = kSCStatusInvalidArgument; - return KERN_SUCCESS; + goto done; + } + + if (options != NULL) { + if (!isA_CFDictionary(options)) { + *sc_status = kSCStatusInvalidArgument; + goto done; + } + + /* + * [pre-]process any provided options + */ + useSessionKeys = CFDictionaryGetValue(options, kSCDynamicStoreUseSessionKeys); + if (useSessionKeys != NULL) { + if (!isA_CFBoolean(useSessionKeys)) { + *sc_status = kSCStatusInvalidArgument; + goto done; + } + } } mySession = getSession(server); - if (mySession->store) { - CFRelease(name); - SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" Sorry, this session is already open.")); + if ((mySession != NULL) && (mySession->store != NULL)) { +#ifdef DEBUG + SCLog(TRUE, LOG_DEBUG, CFSTR("_configopen(): session is already open.")); +#endif /* DEBUG */ *sc_status = kSCStatusFailed; /* you can't re-open an "open" session */ - return KERN_SUCCESS; + goto done; } - /* Create the server port for this session */ - mp = CFMachPortCreate(NULL, configdCallback, NULL, NULL); - - /* return the newly allocated port to be used for this session */ - *newServer = CFMachPortGetPort(mp); - /* * establish the new session */ - newSession = addSession(mp); + mySession = addSession(MACH_PORT_NULL, openMPCopyDescription); + *newServer = mySession->key; + __MACH_PORT_DEBUG(TRUE, "*** _configopen (after addSession)", *newServer); + + /* save the audit_token in case we need to check the callers credentials */ + mySession->auditToken = audit_token; /* Create and add a run loop source for the port */ - newSession->serverRunLoopSource = CFMachPortCreateRunLoopSource(NULL, mp, 0); + mySession->serverRunLoopSource = CFMachPortCreateRunLoopSource(NULL, mySession->serverPort, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), - newSession->serverRunLoopSource, + mySession->serverRunLoopSource, kCFRunLoopDefaultMode); - /* - * save the credentials associated with the caller. - */ - newSession->callerEUID = mySession->callerEUID; - newSession->callerEGID = mySession->callerEGID; + if (_configd_trace) { + SCTrace(TRUE, _configd_trace, + CFSTR("open : %5d : %@\n"), + *newServer, + name); + } - *sc_status = __SCDynamicStoreOpen(&newSession->store, name); + *sc_status = __SCDynamicStoreOpen(&mySession->store, name); + storePrivate = (SCDynamicStorePrivateRef)mySession->store; /* * Make the server port accessible to the framework routines. + * ... and be sure to clear before calling CFRelease(store) + */ + storePrivate->server = *newServer; + + /* + * Process any provided [session] options */ - ((SCDynamicStorePrivateRef)newSession->store)->server = *newServer; + if (useSessionKeys != NULL) { + storePrivate->useSessionKeys = CFBooleanGetValue(useSessionKeys); + } /* Request a notification when/if the client dies */ status = mach_port_request_notification(mach_task_self(), @@ -168,16 +206,16 @@ _configopen(mach_port_t server, MACH_MSG_TYPE_MAKE_SEND_ONCE, &oldNotify); if (status != KERN_SUCCESS) { - SCLog(_configd_verbose, LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status)); - CFRelease(name); + SCLog(TRUE, LOG_ERR, CFSTR("_configopen() mach_port_request_notification() failed: %s"), mach_error_string(status)); cleanupSession(*newServer); *newServer = MACH_PORT_NULL; *sc_status = kSCStatusFailed; - return KERN_SUCCESS; + goto done; } + __MACH_PORT_DEBUG(TRUE, "*** _configopen (after mach_port_request_notification)", *newServer); if (oldNotify != MACH_PORT_NULL) { - SCLog(_configd_verbose, LOG_ERR, CFSTR("_configopen(): why is oldNotify != MACH_PORT_NULL?")); + SCLog(TRUE, LOG_ERR, CFSTR("_configopen(): oldNotify != MACH_PORT_NULL")); } /* @@ -185,7 +223,7 @@ _configopen(mach_port_t server, */ sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), *newServer); info = CFDictionaryGetValue(sessionData, sessionKey); - if (info) { + if (info != NULL) { newInfo = CFDictionaryCreateMutableCopy(NULL, 0, info); } else { newInfo = CFDictionaryCreateMutable(NULL, @@ -194,10 +232,19 @@ _configopen(mach_port_t server, &kCFTypeDictionaryValueCallBacks); } CFDictionarySetValue(newInfo, kSCDName, name); - CFRelease(name); CFDictionarySetValue(sessionData, sessionKey, newInfo); CFRelease(newInfo); CFRelease(sessionKey); + /* + * Note: at this time we should be holding ONE send right and + * ONE receive right to the server. The send right is + * moved to the caller. + */ + + done : + + if (name != NULL) CFRelease(name); + if (options != NULL) CFRelease(options); return KERN_SUCCESS; }