CFDictionaryRef dict,
CFNumberRef rank_assertion)
{
+ boolean_t add_broadcast = FALSE;
boolean_t add_default = FALSE;
boolean_t add_router_subnet = FALSE;
boolean_t add_subnet = FALSE;
n++;
}
- if (ifindex != lo0_ifindex() && router.s_addr != 0) {
- add_default = TRUE;
+ if (ifindex != lo0_ifindex()) {
+ if (router.s_addr != 0) {
+ add_default = TRUE;
+ n++;
+ }
+ /* allow traffic to 255.255.255.255 (rdar://problem/22794309) */
+ add_broadcast = TRUE;
n++;
}
if (allow_additional_routes) {
r->rank = primary_rank;
r++;
}
+ if (add_broadcast) {
+ /* add the broadcast route */
+ if ((flags & kRouteFlagsIsNULL) != 0) {
+ r->flags |= kRouteFlagsIsNULL;
+ }
+ r->dest.s_addr = INADDR_BROADCAST;
+ r->mask.s_addr = INADDR_BROADCAST;
+ r->prefix_length = IPV4_ROUTE_ALL_BITS_SET;
+ r->ifindex = ifindex;
+ r->ifa = addr;
+ r->rank = primary_rank;
+ r++;
+ }
/* add the subnet route */
if (add_subnet) {
}
+static CFMutableDictionaryRef
+copy_mutable_dictionary(CFDictionaryRef dict)
+{
+ CFMutableDictionaryRef newDict;
+
+ if (isA_CFDictionary(dict) != NULL) {
+ newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
+ }
+ else {
+ newDict = CFDictionaryCreateMutable(NULL,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ }
+ return (newDict);
+}
+
static CFMutableDictionaryRef
copy_entity(CFStringRef key)
{
CFMutableDictionaryRef newDict = NULL;
dict = cache_SCDynamicStoreCopyValue(store, key);
+ newDict = copy_mutable_dictionary(dict);
if (dict != NULL) {
- if (isA_CFDictionary(dict) != NULL) {
- newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
- }
CFRelease(dict);
}
- if (newDict == NULL) {
- newDict = CFDictionaryCreateMutable(NULL,
- 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- }
return (newDict);
}
static void
interface_update_status(const char *if_name,
CFBooleanRef active, boolean_t attach,
- CFBooleanRef expensive)
+ CFBooleanRef expensive, boolean_t only_if_different)
{
CFStringRef key = NULL;
- CFMutableDictionaryRef newDict = NULL;
+ CFMutableDictionaryRef newDict;
+ CFDictionaryRef oldDict;
key = create_interface_key(if_name);
- newDict = copy_entity(key);
+ oldDict = cache_SCDynamicStoreCopyValue(store, key);
+ if (oldDict != NULL && isA_CFDictionary(oldDict) == NULL) {
+ CFRelease(oldDict);
+ oldDict = NULL;
+ }
+ newDict = copy_mutable_dictionary(oldDict);
+
/* if new status available, update cache */
if (active != NULL) {
CFDictionarySetValue(newDict, kSCPropNetLinkActive, active);
CFDictionaryRemoveValue(newDict, kSCPropNetLinkExpensive);
}
- /* update status */
+ /* update the SCDynamicStore */
if (CFDictionaryGetCount(newDict) > 0) {
- SC_log(LOG_DEBUG, "Update interface link status: %s: %@", if_name, newDict);
- cache_SCDynamicStoreSetValue(store, key, newDict);
+ /* set the value */
+ if (!only_if_different
+ || oldDict == NULL
+ || !CFEqual(oldDict, newDict)) {
+ SC_log(LOG_DEBUG, "Update interface link status: %s: %@", if_name, newDict);
+ cache_SCDynamicStoreSetValue(store, key, newDict);
+ }
} else {
+ /* remove the value */
SC_log(LOG_DEBUG, "Update interface link status: %s: <removed>", if_name);
cache_SCDynamicStoreRemoveValue(store, key);
}
CFRelease(key);
CFRelease(newDict);
+ if (oldDict != NULL) {
+ CFRelease(oldDict);
+ }
return;
}
__private_extern__
void
-link_update_status(const char *if_name, boolean_t attach)
+link_update_status(const char *if_name, boolean_t attach, boolean_t only_if_different)
{
CFBooleanRef active = NULL;
CFBooleanRef expensive;
expensive = interface_update_expensive(if_name);
/* update status */
- interface_update_status(if_name, active, attach, expensive);
+ interface_update_status(if_name, active, attach, expensive, only_if_different);
close(sock);
return;
}
+__private_extern__
+void
+link_update_status_if_missing(const char * if_name)
+{
+ CFStringRef key;
+ CFDictionaryRef dict;
+
+ key = create_interface_key(if_name);
+ dict = cache_SCDynamicStoreCopyValue(store, key);
+ if (dict != NULL) {
+ /* it's already present, don't update */
+ CFRelease(dict);
+ goto done;
+ }
+ link_update_status(if_name, FALSE, FALSE);
+ dict = cache_SCDynamicStoreCopyValue(store, key);
+ if (dict != NULL) {
+ /* our action made it appear */
+ messages_add_msg_with_arg("added missing link status", if_name);
+ CFRelease(dict);
+ }
+ done:
+ CFRelease(key);
+ return;
+}
+
__private_extern__
CFMutableArrayRef
interfaceListCopy(void)
/* interface was added, prime the link-specific values */
added = TRUE;
CFArrayAppendValue(ifList, interface);
- link_update_status(if_name, TRUE);
+ link_update_status(if_name, TRUE, FALSE);
#ifdef KEV_DL_LINK_QUALITY_METRIC_CHANGED
link_update_quality_metric(if_name);
#endif /* KEV_DL_LINK_QUALITY_METRIC_CHANGED */
}
+ else {
+ /* only update the link status if it is different */
+ link_update_status(if_name, FALSE, TRUE);
+ }
CFRelease(interface);
return (added);
}
void link_remove (const char *if_name);
-void link_update_status (const char *if_name, boolean_t attach);
+void link_update_status (const char *if_name, boolean_t attach, boolean_t only_if_different);
+
+void link_update_status_if_missing (const char * if_name);
CFMutableArrayRef
interfaceListCopy(void);
#include "ev_ipv4.h"
#include "ev_ipv6.h"
#include <notify.h>
+#include <sys/sysctl.h>
+#include <sys/kern_event.h>
// from ip_fw2.c
#define KEV_LOG_SUBCLASS 10
return;
}
+static void
+check_interface_link_status(const char * if_name)
+{
+ if (S_messages == NULL) {
+ return; /* we're not in early boot of system */
+ }
+ link_update_status_if_missing(if_name);
+ return;
+}
+
__private_extern__
int
dgram_socket(int domain)
copy_if_name(&ev->link_data, ifr_name, sizeof(ifr_name));
SC_log(LOG_INFO, "Process IPv4 address change: %s: %d", (char *)ifr_name, ev_msg->event_code);
ipv4_interface_update(NULL, ifr_name);
+ if (ev_msg->event_code
+ != KEV_INET_ADDR_DELETED) {
+ check_interface_link_status(ifr_name);
+ }
break;
}
case KEV_INET_ARPCOLLISION : {
ETHER_ADDR_LEN,
&ev->ia_mac);
}
+ if (ev_msg->event_code
+ != KEV_INET6_ADDR_DELETED) {
+ check_interface_link_status(ifr_name);
+ }
break;
default :
SC_log(LOG_INFO, "Process interface link %s: %s",
(ev_msg->event_code == KEV_DL_LINK_ON) ? "up" : "down",
(char *)ifr_name);
- link_update_status(ifr_name, FALSE);
+ link_update_status(ifr_name, FALSE, FALSE);
break;
#ifdef KEV_DL_LINK_QUALITY_METRIC_CHANGED
return;
}
+static boolean_t
+kernel_events_lost(void)
+{
+ boolean_t events_lost = FALSE;
+ struct kevtstat kevtstat;
+ size_t len = sizeof(kevtstat);
+ const char * mibvar = "net.systm.kevt.stats";
+ static u_int64_t old_kes_nomem;
+
+ if (sysctlbyname(mibvar, &kevtstat, &len, 0, 0) < 0) {
+ SC_log(LOG_NOTICE, "sysctl(%s) failed, %s",
+ mibvar, strerror(errno));
+ }
+ else if (old_kes_nomem != kevtstat.kes_nomem) {
+ SC_log(LOG_NOTICE, "KernelEventMonitor: lost kernel event");
+ old_kes_nomem = kevtstat.kes_nomem;
+ events_lost = TRUE;
+ }
+ return (events_lost);
+}
+
static void
check_for_new_interfaces(void * context)
{
static int count;
- char msg[32];
count++;
- snprintf(msg, sizeof(msg), "timeout %d (of %d)", count, MAX_TIMER_COUNT);
- cache_open();
- update_interfaces(msg, FALSE);
- cache_write(store);
- cache_close();
- messages_post();
+ if (kernel_events_lost()) {
+ char msg[32];
+
+ snprintf(msg, sizeof(msg), "timeout %d (of %d)", count, MAX_TIMER_COUNT);
+ cache_open();
+ update_interfaces(msg, FALSE);
+ cache_write(store);
+ cache_close();
+ messages_post();
+ }
/* schedule the next timer, if needed */
if (count < MAX_TIMER_COUNT) {
Boolean
SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef store,
- int32_t identifier,
- int *fd)
+ int32_t identifier,
+ int *fd)
{
- size_t n;
+ int fildes[2] = { -1, -1 };
+ fileport_t fileport = MACH_PORT_NULL;
+ int ret;
int sc_status;
- int sock;
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
kern_return_t status;
- char tmpdir[PATH_MAX];
- struct sockaddr_un un;
if (store == NULL) {
/* sorry, you must provide a session */
return FALSE;
}
- if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ ret = pipe(fildes);
+ if (ret == -1) {
_SCErrorSet(errno);
- SC_log(LOG_ERR, "socket() failed: %s", strerror(errno));
- return FALSE;
+ SC_log(LOG_ERR, "pipe() failed: %s", strerror(errno));
+ goto fail;
}
- /* establish a UNIX domain socket for server->client notification */
-
- n = confstr(_CS_DARWIN_USER_TEMP_DIR, tmpdir, sizeof(tmpdir));
- if ((n <= 0) || (n >= sizeof(tmpdir))) {
- (void) strlcpy(tmpdir, _PATH_TMP, sizeof(tmpdir));
- }
-
- bzero(&un, sizeof(un));
- un.sun_family = AF_UNIX;
- snprintf(un.sun_path,
- sizeof(un.sun_path)-1,
- "%s%s-%d-%d",
- tmpdir,
- "SCDynamicStoreNotifyFileDescriptor",
- getpid(),
- storePrivate->server);
-
- /* ensure that the path does not already exist */
- (void) unlink(un.sun_path);
+ /*
+ * send fildes[1], the sender's fd, to configd using a fileport and
+ * return fildes[0] to the caller.
+ */
- if (bind(sock, (struct sockaddr *)&un, sizeof(un)) == -1) {
+ fileport = MACH_PORT_NULL;
+ ret = fileport_makeport(fildes[1], &fileport);
+ if (ret < 0) {
_SCErrorSet(errno);
- SC_log(LOG_ERR, "bind() failed: %s", strerror(errno));
- (void) unlink(un.sun_path);
- (void) close(sock);
- return FALSE;
- }
-
- if (listen(sock, 0) == -1) {
- _SCErrorSet(errno);
- SC_log(LOG_ERR, "listen() failed: %s", strerror(errno));
- (void) unlink(un.sun_path);
- (void) close(sock);
- return FALSE;
+ SC_log(LOG_ERR, "fileport_makeport() failed: %s", strerror(errno));
+ goto fail;
}
retry :
status = notifyviafd(storePrivate->server,
- un.sun_path,
- (mach_msg_type_number_t)strlen(un.sun_path),
+ fileport,
identifier,
(int *)&sc_status);
if (status != KERN_SUCCESS) {
_SCErrorSet(status);
- return FALSE;
+ goto fail;
}
- (void) unlink(un.sun_path);
-
if (sc_status != kSCStatusOK) {
_SCErrorSet(sc_status);
- SC_log(LOG_NOTICE, "SCDynamicStoreNotifyFileDescriptor server error: %s", SCErrorString(sc_status));
- (void) close(sock);
- return FALSE;
+ goto fail;
}
- *fd = accept(sock, 0, 0);
- if (*fd == -1) {
- _SCErrorSet(errno);
- SC_log(LOG_ERR, "accept() failed: %s", strerror(errno));
- (void) close(sock);
- return FALSE;
- }
- (void) close(sock);
+ /* the SCDynamicStore server now has a copy of the write side, close our reference */
+ (void) close(fildes[1]);
+
+ /* and keep the read side */
+ *fd = fildes[0];
/* set notifier active */
storePrivate->notifyStatus = Using_NotifierInformViaFD;
return TRUE;
+
+ fail :
+
+ if (fildes[0] != -1) close(fildes[0]);
+ if (fildes[1] != -1) close(fildes[1]);
+ return FALSE;
}
* Copyright (c) 2000-2004, 2006-2013 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* 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,
* 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@
*/
#include <SystemConfiguration/VPNAppLayerPrivate.h>
#include <netdb.h>
+#if !TARGET_OS_SIMULATOR
+#include <ne_session.h>
+#endif // !TARGET_OS_SIMULATOR
{
Boolean bypass = FALSE;
CFStringRef key;
- CFDictionaryRef proxies;
+ CFDictionaryRef proxies = NULL;
if (options != NULL) {
CFBooleanRef bypassGlobalOption;
- if (isA_CFDictionary(options) == NULL) {
+ if (!isA_CFDictionary(options)) {
_SCErrorSet(kSCStatusInvalidArgument);
return NULL;
}
proxies = SCDynamicStoreCopyValue(store, key);
CFRelease(key);
+ if (isA_CFDictionary(proxies) &&
+ CFDictionaryContainsKey(proxies, kSCPropNetProxiesBypassAllowed)) {
+ CFMutableDictionaryRef newProxies;
+
+ newProxies = CFDictionaryCreateMutableCopy(NULL, 0, proxies);
+ CFRelease(proxies);
+
+ /*
+ * Remove kSCPropNetProxiesBypassAllowed property from network
+ * service based configurations.
+ */
+ CFDictionaryRemoveValue(newProxies, kSCPropNetProxiesBypassAllowed);
+ proxies = newProxies;
+ }
+
if (proxies != NULL) {
CFDictionaryRef base = proxies;
scoped = CFDictionaryGetValue(globalConfiguration, kSCPropNetProxiesScoped);
if (scoped == NULL) {
+#if !TARGET_OS_SIMULATOR
+ if (CFDictionaryContainsKey(globalConfiguration, kSCPropNetProxiesBypassAllowed) &&
+ ne_session_always_on_vpn_configs_present()) {
+ /*
+ * The kSCPropNetProxiesBypassAllowed key will be present
+ * for managed proxy configurations where bypassing is *not*
+ * allowed.
+ *
+ * Also (for now), forcing the use of the managed proxy
+ * configurations will only be done with AOVPN present.
+ */
+ goto useDefault;
+ }
+#endif // !TARGET_OS_SIMULATOR
+
// if no scoped proxy configurations
_SCErrorSet(kSCStatusOK);
return NULL;
// no matches, return "global" proxy configuration
+#if !TARGET_OS_SIMULATOR
+ useDefault :
+#endif // !TARGET_OS_SIMULATOR
+
newProxy = CFDictionaryCreateMutableCopy(NULL, 0, globalConfiguration);
CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesScoped);
CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesServices);
/*
- * Copyright (c) 2000, 2001, 2003-2005, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003-2005, 2011, 2012, 2015 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* 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,
* 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@
*/
*/
+/*
+ * CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
+ *
+ * Be very careful when adding, removing, or changing any
+ * of the MiG routes below. Everything tends to work fine
+ * when the SCDynamicStore client code (in the framework)
+ * and SCDynamicStore server code (in configd) are in sync.
+ * But, when the two are NOT in sync as is often the
+ * case when running the iOS Simulator, the conflict can
+ * be problematic.
+ *
+ * CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION
+ */
+
+
/*
* Connection management API's
*/
routine notifyviaport ( server : mach_port_t;
port : mach_port_move_send_t;
- msgid : mach_msg_id_t;
+ msgid : mach_msg_id_t; /* must be zero */
out status : int);
-routine notifyviafd ( server : mach_port_t;
- path : xmlData;
- identifier : int;
- out status : int);
+ skip; /* was notifyviafd (passing UNIX domain socket filename) */
routine notifyviasignal ( server : mach_port_t;
task : task_t /*task_move_send_t*/;
patterns : xmlData;
out status : int);
- skip; /* reserved for future use */
+routine notifyviafd ( server : mach_port_t;
+ fileport : mach_port_move_send_t;
+ identifier : int;
+ out status : int);
+
skip; /* reserved for future use */
skip; /* reserved for future use */
/*
* Post notification as mach message
*/
- SC_trace(_configd_trace, "%s : %5d : port = %d, msgid = %d\n",
+ SC_trace(_configd_trace, "%s : %5d : port = %d\n",
"-->port",
storePrivate->server,
- storePrivate->notifyPort,
- storePrivate->notifyPortIdentifier);
+ storePrivate->notifyPort);
+
+ /* use a random (and non-zero) identifier */
+ while (storePrivate->notifyPortIdentifier == 0) {
+ storePrivate->notifyPortIdentifier = (mach_msg_id_t)random();
+ }
_SC_sendMachMessage(storePrivate->notifyPort, storePrivate->notifyPortIdentifier);
}
/*
- * Copyright (c) 2000, 2001, 2003, 2004, 2006, 2009, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003, 2004, 2006, 2009, 2011, 2015 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* 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,
* 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@
*/
mach_port_t port);
int
-__SCDynamicStoreNotifyFileDescriptor (SCDynamicStoreRef store,
- int32_t identifier,
- int *fd);
+__SCDynamicStoreNotifyFileDescriptor (SCDynamicStoreRef store);
int
__SCDynamicStoreNotifySignal (SCDynamicStoreRef store,
*/
#include <unistd.h>
+#include <sys/fileport.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
__private_extern__
int
-__SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef store,
- int32_t identifier,
- int *fd)
+__SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef store)
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
- int sock;
CFStringRef sessionKey;
CFDictionaryRef info;
return kSCStatusNotifierActive;
}
- if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
- SC_log(LOG_ERR, "socket() failed: %s", strerror(errno));
- return kSCStatusFailed;
- }
-
- *fd = sock;
-
/* push out a notification if any changes are pending */
sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server);
info = CFDictionaryGetValue(sessionData, sessionKey);
__private_extern__
kern_return_t
-_notifyviafd(mach_port_t server,
- xmlData_t pathRef,
- mach_msg_type_number_t pathLen,
- int identifier,
- int *sc_status
+_notifyviafd(mach_port_t server,
+ fileport_t fileport,
+ int identifier,
+ int *sc_status
)
{
- int bufSiz;
+ int fd = -1;
+ int flags;
serverSessionRef mySession = getSession(server);
- int nbioYes;
- int sock;
SCDynamicStorePrivateRef storePrivate;
- struct sockaddr_un un;
-
- /*
- * if socket currently open, close it!
- */
- /* validate the UNIX domain socket path */
- if (pathLen > (sizeof(un.sun_path) - 1)) {
- SC_log(LOG_INFO, "domain socket path length too long!");
- (void) vm_deallocate(mach_task_self(), (vm_address_t)pathRef, pathLen);
- *sc_status = kSCStatusFailed;
+
+ /* get notification file descriptor */
+ fd = fileport_makefd(fileport);
+ mach_port_deallocate(mach_task_self(), fileport);
+ if (fd < 0) {
+ *sc_status = errno;
return KERN_SUCCESS;
}
- /* un-serialize the UNIX domain socket path */
- un.sun_family = AF_UNIX;
- bcopy(pathRef, un.sun_path, pathLen);
- un.sun_path[pathLen] = '\0';
- (void) vm_deallocate(mach_task_self(), (vm_address_t)pathRef, pathLen);
-
- if (mySession == NULL) {
- *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
- return KERN_SUCCESS;
+ flags = fcntl(fd, F_GETFL, 0);
+ if (flags == -1) {
+ *sc_status = errno;
+ goto fail;
}
- storePrivate = (SCDynamicStorePrivateRef)mySession->store;
- /* check permissions */
- if (!hasRootAccess(mySession)) {
- struct stat statbuf;
-
- bzero(&statbuf, sizeof(statbuf));
- if (stat(un.sun_path, &statbuf) == -1) {
- *sc_status = errno;
- SC_log(LOG_INFO, "stat() failed: %s", strerror(errno));
- return KERN_SUCCESS;
- }
- if (mySession->callerEUID != statbuf.st_uid) {
- *sc_status = kSCStatusAccessError;
- SC_log(LOG_INFO, "permissions error [eUID]");
- return KERN_SUCCESS;
- }
+ flags |= O_NONBLOCK;
+ if (fcntl(fd, F_SETFL, flags) == -1) {
+ *sc_status = errno;
+ goto fail;
}
- if (!hasPathAccess(mySession, un.sun_path)) {
- *sc_status = kSCStatusAccessError;
- SC_log(LOG_INFO, "permissions error [path]");
- return KERN_SUCCESS;
+ if (mySession == NULL) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
+ goto fail;
}
+ storePrivate = (SCDynamicStorePrivateRef)mySession->store;
- /* do common sanity checks, get socket */
- *sc_status = __SCDynamicStoreNotifyFileDescriptor(mySession->store, identifier, &sock);
+ /* do common sanity checks */
+ *sc_status = __SCDynamicStoreNotifyFileDescriptor(mySession->store);
/* check status of __SCDynamicStoreNotifyFileDescriptor() */
if (*sc_status != kSCStatusOK) {
- return KERN_SUCCESS;
- }
-
- /* establish the connection, get ready for a read() */
- if (connect(sock, (struct sockaddr *)&un, sizeof(un)) == -1) {
- *sc_status = errno;
- SC_log(LOG_INFO, "connect() failed: %s", strerror(errno));
- (void) close(sock);
- return KERN_SUCCESS;
- }
-
- bufSiz = sizeof(storePrivate->notifyFileIdentifier);
- if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &bufSiz, sizeof(bufSiz)) == -1) {
- *sc_status = errno;
- SC_log(LOG_INFO, "setsockopt() failed: %s", strerror(errno));
- (void) close(sock);
- return KERN_SUCCESS;
- }
-
- nbioYes = 1;
- if (ioctl(sock, FIONBIO, &nbioYes) == -1) {
- *sc_status = errno;
- SC_log(LOG_INFO, "ioctl(,FIONBIO,) failed: %s", strerror(errno));
- (void) close(sock);
- return KERN_SUCCESS;
+ goto fail;
}
/* set notifier active */
storePrivate->notifyStatus = Using_NotifierInformViaFD;
- storePrivate->notifyFile = sock;
+ storePrivate->notifyFile = fd;
storePrivate->notifyFileIdentifier = identifier;
return KERN_SUCCESS;
+
+ fail :
+
+ if (fd >= 0) close(fd);
+ return KERN_SUCCESS;
}
/*
- * Copyright (c) 2000, 2001, 2003, 2004, 2006, 2009, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003, 2004, 2006, 2009, 2011, 2015 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* 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,
* 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@
*/
return kSCStatusNotifierActive;
}
+ if (identifier != 0) {
+ /* sorry, the message ID (never used, no longer supported) must be zero */
+ return kSCStatusInvalidArgument;
+ }
+
if (port == MACH_PORT_NULL) {
/* sorry, you must specify a valid mach port */
return kSCStatusInvalidArgument;
__MACH_PORT_DEBUG(TRUE, "*** _notifyviaport", port);
storePrivate->notifyStatus = Using_NotifierInformViaMachPort;
storePrivate->notifyPort = port;
- storePrivate->notifyPortIdentifier = identifier;
return KERN_SUCCESS;
}
/*
- * Copyright (c) 2000-2006, 2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2006, 2008, 2011. 2015 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* 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,
* 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@
*/
#define _S_CONFIGD_SERVER_H
#include <sys/cdefs.h>
+#include <sys/fileport.h>
#include <mach/mach.h>
#include <CoreFoundation/CoreFoundation.h>
int *status);
kern_return_t _notifyviafd (mach_port_t server,
- xmlData_t pathRef,
- mach_msg_type_number_t pathLen,
+ fileport_t fileport,
int identifier,
int *status);
buildSettings = {
FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
GCC_DYNAMIC_NO_PIC = NO;
+ HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
INSTALL_PATH = /usr/libexec;
LIBRARY_SEARCH_PATHS = (
"$(SYMROOT)",
buildSettings = {
FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
GCC_DYNAMIC_NO_PIC = NO;
+ HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
INSTALL_PATH = /usr/libexec;
LIBRARY_SEARCH_PATHS = (
"$(SYMROOT)",
buildSettings = {
APPLY_RULES_IN_COPY_FILES = YES;
FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
+ HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
INSTALL_PATH = /usr/libexec;
LIBRARY_SEARCH_PATHS = (
"$(SYMROOT)",
buildSettings = {
APPLY_RULES_IN_COPY_FILES = YES;
FRAMEWORK_SEARCH_PATHS = "$(SYMROOT)";
+ HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
INSTALL_PATH = /usr/libexec;
LIBRARY_SEARCH_PATHS = (
"$(SYMROOT)",
"$(SYMROOT)",
"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
);
+ HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
INSTALL_PATH = /usr/libexec;
LIBRARY_SEARCH_PATHS = (
"$(SYMROOT)",
"$(SYMROOT)",
"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
);
+ HEADER_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/Frameworks/System.framework/PrivateHeaders";
INSTALL_PATH = /usr/libexec;
LIBRARY_SEARCH_PATHS = (
"$(SYMROOT)",