/* ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- */ __private_extern__ kern_return_t _pppcontroller_start(mach_port_t session, xmlData_t dataRef, /* raw XML bytes */ mach_msg_type_number_t dataLen, int linger, int * result) { struct client *client; struct service *serv = 0; CFDictionaryRef optRef = 0; int err; client = client_findbymachport(session); if (!client ) { *result = kSCStatusInvalidArgument; goto failed; } if ((serv = findbyserviceID(client->serviceID)) == 0) { *result = kSCStatusConnectionNoService; goto failed; } /* un-serialize the user options */ if (dataLen) { if (!_SCUnserialize((CFPropertyListRef *)&optRef, NULL, (void *)dataRef, dataLen)) { *result = kSCStatusFailed; goto failed; } if (!isA_CFDictionary(optRef)) { *result = kSCStatusInvalidArgument; goto failed; } } err = scnc_start(serv, optRef, client, linger ? 0 : 1, client->uid, client->gid, client->pid, client->bootstrap_port); if (err) { *result = kSCStatusFailed; goto failed; } my_CFRelease(&optRef); *result = kSCStatusOK; return (KERN_SUCCESS); failed: my_CFRelease(&optRef); return (KERN_SUCCESS); }
static Boolean __SCPreferencesAccess_helper(SCPreferencesRef prefs) { Boolean ok; SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; CFDictionaryRef serverDict = NULL; CFDictionaryRef serverPrefs = NULL; CFDictionaryRef serverSignature = NULL; uint32_t status = kSCStatusOK; CFDataRef reply = NULL; if (prefsPrivate->helper_port == MACH_PORT_NULL) { ok = __SCPreferencesCreate_helper(prefs); if (!ok) { return FALSE; } } // have the helper "access" the prefs ok = _SCHelperExec(prefsPrivate->helper_port, SCHELPER_MSG_PREFS_ACCESS, NULL, &status, &reply); if (!ok) { goto fail; } if (status != kSCStatusOK) { goto error; } if (reply == NULL) { goto fail; } ok = _SCUnserialize((CFPropertyListRef *)&serverDict, reply, NULL, 0); CFRelease(reply); if (!ok) { goto fail; } if (isA_CFDictionary(serverDict)) { serverPrefs = CFDictionaryGetValue(serverDict, CFSTR("preferences")); serverPrefs = isA_CFDictionary(serverPrefs); serverSignature = CFDictionaryGetValue(serverDict, CFSTR("signature")); serverSignature = isA_CFData(serverSignature); } if ((serverPrefs == NULL) || (serverSignature == NULL)) { if (serverDict != NULL) CFRelease(serverDict); goto fail; } prefsPrivate->prefs = CFDictionaryCreateMutableCopy(NULL, 0, serverPrefs); prefsPrivate->signature = CFRetain(serverSignature); prefsPrivate->accessed = TRUE; CFRelease(serverDict); return TRUE; fail : // close helper if (prefsPrivate->helper_port != MACH_PORT_NULL) { _SCHelperClose(&prefsPrivate->helper_port); } status = kSCStatusAccessError; error : // return error _SCErrorSet(status); return FALSE; }
__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, audit_token_t audit_token) { 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 */ if (!_SCUnserializeString(&name, NULL, (void *)nameRef, nameLen)) { *sc_status = kSCStatusFailed; } if ((optionsRef != NULL) && (optionsLen > 0)) { /* un-serialize the [session] options */ if (!_SCUnserialize((CFPropertyListRef *)&options, NULL, (void *)optionsRef, optionsLen)) { *sc_status = kSCStatusFailed; } } if (*sc_status != kSCStatusOK) { goto done; } if (!isA_CFString(name)) { *sc_status = kSCStatusInvalidArgument; 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; } } } /* * establish the new session */ mySession = addSession(server, openMPCopyDescription); if (mySession == 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 */ goto done; } *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 */ mySession->serverRunLoopSource = CFMachPortCreateRunLoopSource(NULL, mySession->serverPort, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), mySession->serverRunLoopSource, kCFRunLoopDefaultMode); if (_configd_trace) { SCTrace(TRUE, _configd_trace, CFSTR("open : %5d : %@\n"), *newServer, 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 */ if (useSessionKeys != NULL) { storePrivate->useSessionKeys = CFBooleanGetValue(useSessionKeys); } /* Request a notification when/if the client dies */ status = mach_port_request_notification(mach_task_self(), *newServer, MACH_NOTIFY_NO_SENDERS, 1, *newServer, MACH_MSG_TYPE_MAKE_SEND_ONCE, &oldNotify); if (status != KERN_SUCCESS) { 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; goto done; } __MACH_PORT_DEBUG(TRUE, "*** _configopen (after mach_port_request_notification)", *newServer); if (oldNotify != MACH_PORT_NULL) { SCLog(TRUE, LOG_ERR, CFSTR("_configopen(): oldNotify != MACH_PORT_NULL")); } /* * Save the name of the calling application / plug-in with the session data. */ sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), *newServer); info = CFDictionaryGetValue(sessionData, sessionKey); if (info != NULL) { newInfo = CFDictionaryCreateMutableCopy(NULL, 0, info); } else { newInfo = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } CFDictionarySetValue(newInfo, kSCDName, 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; }