]> git.saurik.com Git - apple/configd.git/blobdiff - SystemConfiguration.fproj/SCNetworkService.c
configd-1061.40.2.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SCNetworkService.c
index 489ee394d7ba9a71dda0ca3b4966a20a4ae20249..d9c8d4bed15e63048bfd5db122fb49c29fd26b34 100644 (file)
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2004-2014 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2018 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,
@@ -17,7 +17,7 @@
  * 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 <CoreFoundation/CoreFoundation.h>
 #include <CoreFoundation/CFRuntime.h>
-#include <SystemConfiguration/SystemConfiguration.h>
 #include "SCNetworkConfigurationInternal.h"
-#include <SystemConfiguration/SCValidation.h>
-#include <SystemConfiguration/SCPrivate.h>
 #include "SCPreferencesInternal.h"
 
 #include <pthread.h>
@@ -71,10 +68,11 @@ __SCNetworkServiceCopyDescription(CFTypeRef cf)
 {
        CFAllocatorRef                  allocator       = CFGetAllocator(cf);
        CFMutableStringRef              result;
-       SCNetworkServicePrivateRef      servicePrivate  = (SCNetworkServicePrivateRef)cf;
+       SCNetworkServiceRef             service         = (SCNetworkServiceRef)cf;
+       SCNetworkServicePrivateRef      servicePrivate  = (SCNetworkServicePrivateRef)service;
 
        result = CFStringCreateMutable(allocator, 0);
-       CFStringAppendFormat(result, NULL, CFSTR("<SCNetworkService %p [%p]> {"), cf, allocator);
+       CFStringAppendFormat(result, NULL, CFSTR("<SCNetworkService %p [%p]> {"), service, allocator);
        CFStringAppendFormat(result, NULL, CFSTR("id = %@"), servicePrivate->serviceID);
        if (servicePrivate->prefs != NULL) {
                CFStringAppendFormat(result, NULL, CFSTR(", prefs = %p"), servicePrivate->prefs);
@@ -84,6 +82,9 @@ __SCNetworkServiceCopyDescription(CFTypeRef cf)
        if (servicePrivate->name != NULL) {
                CFStringAppendFormat(result, NULL, CFSTR(", name = %@"), servicePrivate->name);
        }
+       if (!__SCNetworkServiceExists(service)) {
+               CFStringAppendFormat(result, NULL, CFSTR(", REMOVED"));
+       }
        CFStringAppendFormat(result, NULL, CFSTR("}"));
 
        return result;
@@ -166,10 +167,10 @@ __SCNetworkServiceCreatePrivate(CFAllocatorRef            allocator,
                return NULL;
        }
 
+       /* initialize non-zero/NULL members */
        servicePrivate->prefs           = (prefs != NULL) ? CFRetain(prefs): NULL;
        servicePrivate->serviceID       = CFStringCreateCopy(NULL, serviceID);
        servicePrivate->interface       = (interface != NULL) ? CFRetain(interface) : NULL;
-       servicePrivate->name            = NULL;
 
        return servicePrivate;
 }
@@ -340,7 +341,7 @@ _protocolTemplate(SCNetworkServiceRef service, CFStringRef protocolType)
                        }
 
                        overrides = __SCNetworkInterfaceGetTemplateOverrides(interface, protocolType);
-                       if (overrides != NULL) {
+                       if (isA_CFDictionary(overrides)) {
                                CFMutableDictionaryRef  newTemplate;
 
                                newTemplate = CFDictionaryCreateMutableCopy(NULL, 0, template);
@@ -368,10 +369,11 @@ Boolean
 SCNetworkServiceAddProtocolType(SCNetworkServiceRef service, CFStringRef protocolType)
 {
        CFDictionaryRef                 entity;
+       Boolean                         newEnabled;
        CFDictionaryRef                 newEntity       = NULL;
        Boolean                         ok              = FALSE;
        CFStringRef                     path;
-       SCNetworkProtocolRef            protocol;
+       SCNetworkProtocolRef            protocol        = NULL;
        SCNetworkServicePrivateRef      servicePrivate  = (SCNetworkServicePrivateRef)service;
 
        if (!isA_SCNetworkService(service) || (servicePrivate->prefs == NULL)) {
@@ -384,6 +386,15 @@ SCNetworkServiceAddProtocolType(SCNetworkServiceRef service, CFStringRef protoco
                return FALSE;
        }
 
+       if (!__SCNetworkServiceExists(service)) {
+               SC_log(LOG_ERR, "SCNetworkServiceAddProtocolType() w/removed service\n  service = %@\n  protocol = %@",
+                      service,
+                      protocolType);
+               _SC_crash_once("SCNetworkServiceAddProtocolType() w/removed service", NULL, NULL);
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
        path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL,                             // allocator
                                                              servicePrivate->serviceID,        // service
                                                              protocolType);                    // entity
@@ -403,6 +414,7 @@ SCNetworkServiceAddProtocolType(SCNetworkServiceRef service, CFStringRef protoco
                                       &kCFTypeDictionaryValueCallBacks);
        ok = SCPreferencesPathSetValue(servicePrivate->prefs, path, newEntity);
        CFRelease(newEntity);
+       newEntity = NULL;
        if (!ok) {
                goto done;
        }
@@ -411,12 +423,30 @@ SCNetworkServiceAddProtocolType(SCNetworkServiceRef service, CFStringRef protoco
        assert(protocol != NULL);
 
        newEntity = _protocolTemplate(service, protocolType);
+       assert(newEntity != NULL);
+       
        ok = SCNetworkProtocolSetConfiguration(protocol, newEntity);
-       CFRelease(newEntity);
-       CFRelease(protocol);
+       if (!ok) {
+               // could not set default configuration
+               goto done;
+       }
+
+       newEnabled = !CFDictionaryContainsKey(newEntity, kSCResvInactive);
+       ok = SCNetworkProtocolSetEnabled(protocol, newEnabled);
+       if (!ok) {
+               // could not enable/disable protocol
+               goto done;
+       }
 
     done :
 
+       if (newEntity != NULL) CFRelease(newEntity);
+       if (protocol != NULL) CFRelease(protocol);
+
+       if (ok) {
+               SC_log(LOG_DEBUG, "SCNetworkServiceAddProtocolType(): %@, %@", service, protocolType);
+       }
+
        CFRelease(path);
        return ok;
 }
@@ -458,21 +488,21 @@ SCNetworkServiceCopyAll(SCPreferencesRef prefs)
                        SCNetworkServicePrivateRef      servicePrivate;
 
                        if (!isA_CFDictionary(vals[i])) {
-                               SCLog(TRUE,
-                                     LOG_INFO,
-                                     CFSTR("SCNetworkServiceCopyAll(): error w/service \"%@\"\n"),
-                                     keys[i]);
+                               SC_log(LOG_INFO, "error w/service \"%@\"", keys[i]);
                                continue;
                        }
 
                        entity = CFDictionaryGetValue(vals[i], kSCEntNetInterface);
                        if (!isA_CFDictionary(entity)) {
                                // if no "interface"
-                               SCLog(TRUE,
-                                     LOG_INFO,
-                                     CFSTR("SCNetworkServiceCopyAll(): no \"%@\" entity for service \"%@\"\n"),
-                                     kSCEntNetInterface,
-                                     keys[i]);
+                               SC_log(LOG_INFO, "no \"%@\" entity for service \"%@\"",
+                                      kSCEntNetInterface,
+                                      keys[i]);
+                               continue;
+                       }
+
+                       if (__SCNetworkInterfaceEntityIsPPTP(entity)) {
+                               SC_log(LOG_INFO, "PPTP services are no longer supported");
                                continue;
                        }
 
@@ -559,13 +589,12 @@ _copyInterfaceEntityTypes(CFDictionaryRef protocols)
                CFStringRef     entities[]      = { kSCPropNetInterfaceType,
                                                    kSCPropNetInterfaceSubType,
                                                    kSCPropNetInterfaceHardware };
-               int             i;
 
                // include the "Interface" entity itself
                CFSetAddValue(interface_entity_types, kSCEntNetInterface);
 
                // include the entities associated with the interface
-               for (i = 0; i < sizeof(entities)/sizeof(entities[0]); i++) {
+               for (size_t i = 0; i < sizeof(entities)/sizeof(entities[0]); i++) {
                        CFStringRef     entity;
 
                        entity = CFDictionaryGetValue(interface, entities[i]);
@@ -610,6 +639,12 @@ SCNetworkServiceCopy(SCPreferencesRef prefs, CFStringRef serviceID)
                return NULL;
        }
 
+       if (__SCNetworkInterfaceEntityIsPPTP(entity)) {
+               SC_log(LOG_INFO, "PPTP services are no longer supported");
+               _SCErrorSet(kSCStatusNoKey);
+               return NULL;
+       }
+
        servicePrivate = __SCNetworkServiceCreatePrivate(NULL, prefs, serviceID, NULL);
        return (SCNetworkServiceRef)servicePrivate;
 }
@@ -873,7 +908,7 @@ SCNetworkServiceCreate(SCPreferencesRef prefs, SCNetworkInterfaceRef interface)
 
                                // a ConnectionScript (and related keys) from the interface
                                // should trump the settings from the configuration template.
-                               if (overrides != NULL) {
+                               if (isA_CFDictionary(overrides)) {
                                        CFMutableDictionaryRef  newConfig;
 
                                        newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
@@ -892,7 +927,7 @@ SCNetworkServiceCreate(SCPreferencesRef prefs, SCNetworkInterfaceRef interface)
                                CFDictionaryRef         overrides;
 
                                overrides = __SCNetworkInterfaceGetTemplateOverrides(interface, kSCNetworkInterfaceTypePPP);
-                               if (overrides != NULL) {
+                               if (isA_CFDictionary(overrides)) {
                                        CFMutableDictionaryRef  newConfig;
 
                                        newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config);
@@ -903,9 +938,8 @@ SCNetworkServiceCreate(SCPreferencesRef prefs, SCNetworkInterfaceRef interface)
                        }
 
                        if (!__SCNetworkInterfaceSetConfiguration(interface, NULL, config, TRUE)) {
-                               SCLog(TRUE, LOG_DEBUG,
-                                     CFSTR("SCNetworkService __SCNetworkInterfaceSetConfiguration failed(), interface=%@, type=NULL"),
-                                     interface);
+                               SC_log(LOG_INFO, "__SCNetworkInterfaceSetConfiguration failed(), interface=%@, type=NULL",
+                                      interface);
                        }
                        CFRelease(config);
                }
@@ -937,6 +971,8 @@ SCNetworkServiceCreate(SCPreferencesRef prefs, SCNetworkInterfaceRef interface)
                                               interface_name);
        }
 
+       SC_log(LOG_DEBUG, "SCNetworkServiceCreate(): %@", servicePrivate);
+
        return (SCNetworkServiceRef)servicePrivate;
 }
 
@@ -947,7 +983,9 @@ SCNetworkServiceEstablishDefaultConfiguration(SCNetworkServiceRef service)
        CFIndex                         i;
        SCNetworkInterfaceRef           interface;
        CFIndex                         n;
+       Boolean                         ok;
        CFArrayRef                      protocolTypes;
+       CFStringRef                     rankStr;
        SCNetworkServicePrivateRef      servicePrivate  = (SCNetworkServicePrivateRef)service;
 
        if (!isA_SCNetworkService(service) || (servicePrivate->prefs == NULL)) {
@@ -963,45 +1001,40 @@ SCNetworkServiceEstablishDefaultConfiguration(SCNetworkServiceRef service)
        protocolTypes = SCNetworkInterfaceGetSupportedProtocolTypes(interface);
        n = (protocolTypes != NULL) ? CFArrayGetCount(protocolTypes) : 0;
        for (i = 0; i < n; i++) {
-               Boolean                 enabled;
-               CFDictionaryRef         newEntity       = NULL;
-               Boolean                 ok;
-               SCNetworkProtocolRef    protocol        = NULL;
-               CFStringRef             protocolType;
+               CFStringRef     protocolType;
 
                protocolType = CFArrayGetValueAtIndex(protocolTypes, i);
                ok = SCNetworkServiceAddProtocolType(service, protocolType);
-               if (!ok && (SCError() != kSCStatusKeyExists)) {
-                       // could not add protocol
-                       goto nextProtocol;
+               if (!ok) {
+                       SC_log(LOG_INFO,
+                              "SCNetworkServiceEstablishDefaultConfiguration(): could not add protocol \"%@\"",
+                              protocolType);
                }
+       }
 
-               protocol = SCNetworkServiceCopyProtocol(service, protocolType);
-               if (protocol == NULL) {
-                       // oops, somethings wrong (should never happen)
-                       goto nextProtocol;
-               }
+       rankStr = __SCNetworkInterfaceGetTemplateOverrides(interface, kSCPropNetServicePrimaryRank);
+       if (isA_CFString(rankStr)) {
+               SCNetworkServicePrimaryRank     rank;
 
-               newEntity = _protocolTemplate(service, protocolType);
-               ok = SCNetworkProtocolSetConfiguration(protocol, newEntity);
+               ok = __str_to_rank(rankStr, &rank);
                if (!ok) {
-                       // could not set default configuration
-                       goto nextProtocol;
+                       SC_log(LOG_INFO,
+                              "SCNetworkServiceEstablishDefaultConfiguration(): unknown rank \"%@\"",
+                              rankStr);
+                       goto done;
                }
 
-               enabled = !CFDictionaryContainsKey(newEntity, kSCResvInactive);
-               ok = SCNetworkProtocolSetEnabled(protocol, enabled);
+               ok = SCNetworkServiceSetPrimaryRank(service, rank);
                if (!ok) {
-                       // could not enable/disable protocol
-                       goto nextProtocol;
+                       SC_log(LOG_INFO,
+                              "SCNetworkServiceEstablishDefaultConfiguration(): could not set rank \"%@\"",
+                              rankStr);
+                       goto done;
                }
-
-           nextProtocol :
-
-               if (newEntity != NULL) CFRelease(newEntity);
-               if (protocol  != NULL) CFRelease(protocol);
        }
 
+    done :
+
        return TRUE;
 }
 
@@ -1083,13 +1116,13 @@ SCNetworkServiceGetName(SCNetworkServiceRef service)
        CFRelease(path);
 
        useSystemInterfaces = ((__SCPreferencesUsingDefaultPrefs(servicePrivate->prefs)) &&
-                              (__SCPreferencesGetLimitSCNetworkConfiguration(servicePrivate->prefs) == FALSE));
-       
+                              !__SCPreferencesGetLimitSCNetworkConfiguration(servicePrivate->prefs));
+
        if (isA_CFDictionary(entity)) {
                name = CFDictionaryGetValue(entity, kSCPropUserDefinedName);
                if (isA_CFString(name)) {
                        servicePrivate->name = CFRetain(name);
-                       if (useSystemInterfaces == FALSE) {
+                       if (!useSystemInterfaces) {
                                return servicePrivate->name;
                        }
                }
@@ -1153,9 +1186,10 @@ SCNetworkServiceGetName(SCNetworkServiceRef service)
                                        // compare the older "Built-in XXX" non-localized name
                                        interface_name = __SCNetworkInterfaceCopyXNonLocalizedDisplayName(interface);
                                        break;
-#endif // !TARGET_OS_IPHONE
+#else  // !TARGET_OS_IPHONE
                                default :
                                        continue;
+#endif // !TARGET_OS_IPHONE
                        }
 
                        if (interface_name != NULL) {
@@ -1243,15 +1277,21 @@ SCNetworkServiceRemove(SCNetworkServiceRef service)
                return FALSE;
        }
 
+       if (!__SCNetworkServiceExists(service)) {
+               SC_log(LOG_ERR, "SCNetworkServiceRemove() w/removed service\n  service = %@", service);
+               _SC_crash_once("SCNetworkServiceRemove() w/removed service", NULL, NULL);
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
        // remove service from all sets
 
        sets = SCNetworkSetCopyAll(servicePrivate->prefs);
        if (sets != NULL) {
-               CFIndex i;
                CFIndex n;
 
                n = CFArrayGetCount(sets);
-               for (i = 0; i < n; i++) {
+               for (CFIndex i = 0; i < n; i++) {
                        SCNetworkSetRef set;
 
                        set = CFArrayGetValueAtIndex(sets, i);
@@ -1272,6 +1312,10 @@ SCNetworkServiceRemove(SCNetworkServiceRef service)
        ok = SCPreferencesPathRemoveValue(servicePrivate->prefs, path);
        CFRelease(path);
 
+       if (ok) {
+               SC_log(LOG_DEBUG, "SCNetworkServiceRemove(): %@", service);
+       }
+
        return ok;
 }
 
@@ -1289,6 +1333,15 @@ SCNetworkServiceRemoveProtocolType(SCNetworkServiceRef service, CFStringRef prot
                return FALSE;
        }
 
+       if (!__SCNetworkServiceExists(service)) {
+               SC_log(LOG_ERR, "SCNetworkServiceRemoveProtocolType() w/removed service\n  service = %@\n  protocol = %@",
+                      service,
+                      protocolType);
+               _SC_crash_once("SCNetworkServiceRemoveProtocolType() w/removed service", NULL, NULL);
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
        if (!__SCNetworkProtocolIsValidType(protocolType)) {
                _SCErrorSet(kSCStatusInvalidArgument);
                return FALSE;
@@ -1309,6 +1362,10 @@ SCNetworkServiceRemoveProtocolType(SCNetworkServiceRef service, CFStringRef prot
 
     done :
 
+       if (ok) {
+               SC_log(LOG_DEBUG, "SCNetworkServiceRemoveProtocolType(): %@, %@", service, protocolType);
+       }
+
        CFRelease(path);
        return ok;
 }
@@ -1326,6 +1383,13 @@ SCNetworkServiceSetEnabled(SCNetworkServiceRef service, Boolean enabled)
                return FALSE;
        }
 
+       if (!__SCNetworkServiceExists(service)) {
+               SC_log(LOG_ERR, "SCNetworkServiceSetEnabled() w/removed service\n  service = %@", service);
+               _SC_crash_once("SCNetworkProtocolSetEnabled() w/removed service", NULL, NULL);
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
        // make sure that we do not enable a network service if the
        // associated interface is a member of a bond or bridge.
        if (enabled) {
@@ -1345,6 +1409,12 @@ SCNetworkServiceSetEnabled(SCNetworkServiceRef service, Boolean enabled)
        ok = __setPrefsEnabled(servicePrivate->prefs, path, enabled);
        CFRelease(path);
 
+       if (ok) {
+               SC_log(LOG_DEBUG, "SCNetworkServiceSetEnabled(): %@ -> %s",
+                      service,
+                      enabled ? "Enabled" : "Disabled");
+       }
+
        return ok;
 }
 
@@ -1363,6 +1433,15 @@ SCNetworkServiceSetName(SCNetworkServiceRef service, CFStringRef name)
                return FALSE;
        }
 
+       if (!__SCNetworkServiceExists(service)) {
+               SC_log(LOG_ERR, "SCNetworkServiceSetName() w/removed service\n  service = %@\n  name = %@",
+                      service,
+                      name != NULL ? name : CFSTR("<NULL>"));
+               _SC_crash_once("SCNetworkServiceSetName() w/removed service", NULL, NULL);
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
        if (name != NULL) {
                if (!isA_CFString(name)) {
                        _SCErrorSet(kSCStatusInvalidArgument);
@@ -1520,6 +1599,10 @@ SCNetworkServiceSetName(SCNetworkServiceRef service, CFStringRef name)
        if (name != NULL) CFRetain(name);
        servicePrivate->name = name;
 
+       if (ok) {
+               SC_log(LOG_DEBUG, "SCNetworkServiceSetName(): %@", service);
+       }
+
        return ok;
 }
 
@@ -1528,6 +1611,34 @@ SCNetworkServiceSetName(SCNetworkServiceRef service, CFStringRef name)
 #pragma mark SCNetworkService SPIs
 
 
+__private_extern__
+Boolean
+__SCNetworkServiceExists(SCNetworkServiceRef service)
+{
+       CFDictionaryRef                 entity;
+       CFStringRef                     path;
+       SCNetworkServicePrivateRef      servicePrivate  = (SCNetworkServicePrivateRef)service;
+
+       if (servicePrivate->prefs == NULL) {
+               // if no prefs
+               return FALSE;
+       }
+
+       path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL,                             // allocator
+                                                             servicePrivate->serviceID,        // service
+                                                             kSCEntNetInterface);               // entity
+       entity = SCPreferencesPathGetValue(servicePrivate->prefs, path);
+       CFRelease(path);
+
+       if (!isA_CFDictionary(entity)) {
+               // a "service" must have an "interface"
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+
 SCNetworkServicePrimaryRank
 SCNetworkServiceGetPrimaryRank(SCNetworkServiceRef service)
 {
@@ -1599,6 +1710,13 @@ SCNetworkServiceSetPrimaryRank(SCNetworkServiceRef               service,
                return FALSE;
        }
 
+       if ((servicePrivate->prefs != NULL) && !__SCNetworkServiceExists(service)) {
+               SC_log(LOG_ERR, "SCNetworkServiceSetPrimaryRank() w/removed\n  service = %@", service);
+               _SC_crash_once("SCNetworkServiceSetPrimaryRank() w/removed service", NULL, NULL);
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
        ok = __rank_to_str(newRank, &rankStr);
        if (!ok) {
                _SCErrorSet(kSCStatusInvalidArgument);
@@ -1715,9 +1833,12 @@ _SCNetworkServiceIsVPN(SCNetworkServiceRef service)
                if (CFEqual(interfaceType, kSCNetworkInterfaceTypeL2TP)) {
                        return TRUE;
                }
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
                if (CFEqual(interfaceType, kSCNetworkInterfaceTypePPTP)) {
                        return TRUE;
                }
+#pragma GCC diagnostic pop
        } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeVPN)) {
                return TRUE;
        } else if (CFEqual(interfaceType, kSCNetworkInterfaceTypeIPSec)) {
@@ -1731,13 +1852,22 @@ _SCNetworkServiceIsVPN(SCNetworkServiceRef service)
 Boolean
 SCNetworkServiceSetExternalID(SCNetworkServiceRef service, CFStringRef identifierDomain, CFStringRef identifier)
 {
-       CFStringRef                                     prefs_path;
-       CFDictionaryRef                         service_dictionary;
-       SCNetworkServicePrivateRef      service_private         = (SCNetworkServicePrivateRef)service;
-       Boolean                                         success                         = FALSE;
-       CFStringRef                                     prefixed_domain;
+       CFStringRef                     prefs_path;
+       CFDictionaryRef                 service_dictionary;
+       SCNetworkServicePrivateRef      servicePrivate          = (SCNetworkServicePrivateRef)service;
+       Boolean                         success                 = FALSE;
+       CFStringRef                     prefixed_domain;
 
-       if (!isA_SCNetworkService(service) || (service_private->prefs == NULL) || !isA_CFString(identifierDomain)) {
+       if (!isA_SCNetworkService(service) || (servicePrivate->prefs == NULL) || !isA_CFString(identifierDomain)) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       if (!__SCNetworkServiceExists(service)) {
+               SC_log(LOG_ERR, "SCNetworkServiceSetExternalID() w/removed\n  service = %@\n  id = %@",
+                      service,
+                      identifier);
+               _SC_crash_once("SCNetworkServiceSetExternalID() w/removed service", NULL, NULL);
                _SCErrorSet(kSCStatusInvalidArgument);
                return FALSE;
        }
@@ -1750,10 +1880,10 @@ SCNetworkServiceSetExternalID(SCNetworkServiceRef service, CFStringRef identifie
        prefixed_domain = CFStringCreateWithFormat(NULL, 0, CFSTR("%s%@"), EXTERNAL_ID_DOMAIN_PREFIX, identifierDomain);
 
        prefs_path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL,
-                                                                   service_private->serviceID,
+                                                                   servicePrivate->serviceID,
                                                                    NULL);
 
-       service_dictionary = SCPreferencesPathGetValue(service_private->prefs, prefs_path);
+       service_dictionary = SCPreferencesPathGetValue(servicePrivate->prefs, prefs_path);
        if (isA_CFDictionary(service_dictionary) || ((service_dictionary == NULL) && (identifier != NULL))) {
                CFMutableDictionaryRef  new_service_dictionary;
 
@@ -1771,22 +1901,22 @@ SCNetworkServiceSetExternalID(SCNetworkServiceRef service, CFStringRef identifie
                } else {
                        CFDictionaryRemoveValue(new_service_dictionary, prefixed_domain);
                }
-               success = SCPreferencesPathSetValue(service_private->prefs, prefs_path, new_service_dictionary);
+               success = SCPreferencesPathSetValue(servicePrivate->prefs, prefs_path, new_service_dictionary);
                CFRelease(new_service_dictionary);
        }
        CFRelease(prefs_path);
 
        if (identifier != NULL) {
-           if (service_private->externalIDs == NULL) {
-                       service_private->externalIDs = CFDictionaryCreateMutable(NULL,
+           if (servicePrivate->externalIDs == NULL) {
+                       servicePrivate->externalIDs = CFDictionaryCreateMutable(NULL,
                                                                                 0,
-                                                                                                                                        &kCFTypeDictionaryKeyCallBacks,
-                                                                                                                                        &kCFTypeDictionaryValueCallBacks);
+                                                                                &kCFTypeDictionaryKeyCallBacks,
+                                                                                &kCFTypeDictionaryValueCallBacks);
            }
-           CFDictionarySetValue(service_private->externalIDs, prefixed_domain, identifier);
+           CFDictionarySetValue(servicePrivate->externalIDs, prefixed_domain, identifier);
        } else {
-           if (service_private->externalIDs != NULL) {
-                       CFDictionaryRemoveValue(service_private->externalIDs, prefixed_domain);
+           if (servicePrivate->externalIDs != NULL) {
+                       CFDictionaryRemoveValue(servicePrivate->externalIDs, prefixed_domain);
            }
        }
 
@@ -1803,9 +1933,9 @@ SCNetworkServiceSetExternalID(SCNetworkServiceRef service, CFStringRef identifie
 CFStringRef
 SCNetworkServiceCopyExternalID(SCNetworkServiceRef service, CFStringRef identifierDomain)
 {
+       CFStringRef                     identifier              = NULL;
+       CFStringRef                     prefixed_domain;
        SCNetworkServicePrivateRef      service_private         = (SCNetworkServicePrivateRef)service;
-       CFStringRef                                     identifier                      = NULL;
-       CFStringRef                                     prefixed_domain;
 
        if (!isA_SCNetworkService(service) || (service_private->prefs == NULL) || !isA_CFString(identifierDomain)) {
                _SCErrorSet(kSCStatusInvalidArgument);
@@ -1822,7 +1952,7 @@ SCNetworkServiceCopyExternalID(SCNetworkServiceRef service, CFStringRef identifi
        }
 
        if (identifier == NULL) {
-               CFStringRef                     prefs_path;
+               CFStringRef             prefs_path;
                CFDictionaryRef         service_dictionary;
 
                prefs_path = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL,
@@ -1877,9 +2007,9 @@ replaceServiceID(const void *value, void *context)
        // update service order
        serviceOrder = SCNetworkSetGetServiceOrder(set);
        if ((isA_CFArray(serviceOrder) != NULL) &&
-           (CFArrayContainsValue(serviceOrder,
+           CFArrayContainsValue(serviceOrder,
                                  CFRangeMake(0, CFArrayGetCount(serviceOrder)),
-                                 service_context->oldServiceID) == TRUE)) {
+                                 service_context->oldServiceID)) {
                CFIndex count;
                CFIndex serviceOrderIndex;
 
@@ -1910,7 +2040,7 @@ replaceServiceID(const void *value, void *context)
        }
 
        // remove link between "set" and old "service"
-       SCPreferencesPathRemoveValue(setPrivate->prefs, path);
+       (void) SCPreferencesPathRemoveValue(setPrivate->prefs, path);
        CFRelease(path);
 
        // create the link between "set" and the "service"
@@ -1921,7 +2051,7 @@ replaceServiceID(const void *value, void *context)
        link = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL,                             // allocator
                                                              service_context->newServiceID,    // service
                                                              NULL);                            // entity
-       SCPreferencesPathSetLink(setPrivate->prefs, path, link);
+       (void) SCPreferencesPathSetLink(setPrivate->prefs, path, link);
 
     done:
 
@@ -1962,6 +2092,15 @@ _SCNetworkServiceSetServiceID(SCNetworkServiceRef service, CFStringRef newServic
                return TRUE;
        }
 
+       if (!__SCNetworkServiceExists(service)) {
+               SC_log(LOG_ERR, "_SCNetworkServiceSetServiceID() w/removed service\n  service = %@\n  serviceID = %@",
+                      service,
+                      newServiceID);
+               _SC_crash_once("_SCNetworkServiceSetServiceID() w/removed service", NULL, NULL);
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
        newPath = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL,                          // allocator
                                                                 newServiceID,                  // service
                                                                 NULL);                         // entity
@@ -2012,6 +2151,8 @@ _SCNetworkServiceSetServiceID(SCNetworkServiceRef service, CFStringRef newServic
                servicePrivate->interface = newInterface;
        }
 
+       SC_log(LOG_DEBUG, "_SCNetworkServiceSetServiceID(): %@ --> %@", service, newServiceID);
+
        // replace serviceID with new one
        CFRetain(newServiceID);
        CFRelease(servicePrivate->serviceID);
@@ -2028,6 +2169,7 @@ _SCNetworkServiceSetServiceID(SCNetworkServiceRef service, CFStringRef newServic
        if (allSets != NULL) {
                CFRelease(allSets);
        }
+
        return ok;
 }
 
@@ -2057,8 +2199,8 @@ copyInterfaceConfiguration(SCNetworkServiceRef oldService, SCNetworkServiceRef n
 
                if ((configuration != NULL) ||
                    (SCError() == kSCStatusOK)) {
-                       if (SCNetworkInterfaceSetConfiguration(newInterface, configuration) == FALSE) {
-                               SCLog(_sc_debug, LOG_DEBUG, CFSTR("problem setting interface configuration"));
+                       if (!SCNetworkInterfaceSetConfiguration(newInterface, configuration)) {
+                               SC_log(LOG_INFO, "problem setting interface configuration");
                        }
 
                }
@@ -2078,8 +2220,8 @@ copyInterfaceConfiguration(SCNetworkServiceRef oldService, SCNetworkServiceRef n
                                        configuration = SCNetworkInterfaceGetExtendedConfiguration(oldInterface, kSCEntNetIPSec);
                                        if ((configuration != NULL) ||
                                            (SCError() == kSCStatusOK)) {
-                                               if (SCNetworkInterfaceSetExtendedConfiguration(newInterface, kSCEntNetIPSec, configuration) == FALSE) {
-                                                       SCLog(_sc_debug, LOG_DEBUG, CFSTR("problem setting child interface configuration"));
+                                               if (!SCNetworkInterfaceSetExtendedConfiguration(newInterface, kSCEntNetIPSec, configuration)) {
+                                                       SC_log(LOG_INFO, "problem setting child interface configuration");
                                                }
                                        }
                                }
@@ -2128,8 +2270,9 @@ copyInterfaceConfiguration(SCNetworkServiceRef oldService, SCNetworkServiceRef n
        return;
 }
 
-static void
-addProtocolToService(SCNetworkServiceRef service, CFStringRef protocolType, CFDictionaryRef configuration, Boolean enabled)
+__private_extern__
+void
+__SCNetworkServiceAddProtocolToService(SCNetworkServiceRef service, CFStringRef protocolType, CFDictionaryRef configuration, Boolean enabled)
 {
        Boolean ok;
        SCNetworkProtocolRef protocol;
@@ -2174,7 +2317,6 @@ __SCNetworkServiceMigrateNew(SCPreferencesRef             prefs,
        SCNetworkServiceRef newService = NULL;
        CFStringRef serviceID = NULL;
        SCNetworkServicePrivateRef servicePrivate = (SCNetworkServicePrivateRef) service;
-       CFMutableDictionaryRef servicesMutable = NULL;
        CFArrayRef setList = NULL;
        Boolean success = FALSE;
        CFStringRef targetDeviceName = NULL;
@@ -2193,18 +2335,17 @@ __SCNetworkServiceMigrateNew(SCPreferencesRef           prefs,
        newService = SCNetworkServiceCopy(prefs, serviceID);
        if (newService != NULL) {
                // Cannot add service if it already exists
-               SCLog(TRUE, LOG_DEBUG, CFSTR("__SCNetworkServiceMigrateNew: Cannot add service if it already exists."));
+               SC_log(LOG_INFO, "Service already exists");
                goto done;
        }
 
        oldInterface = SCNetworkServiceGetInterface(service);
        interfaceEntity = __SCNetworkInterfaceCopyInterfaceEntity(oldInterface);
        if (interfaceEntity == NULL) {
-               SCLog(TRUE, LOG_DEBUG, CFSTR("__SCNetworkServiceMigrateNew: interfaceEntity does not exist"));
+               SC_log(LOG_INFO, "No interface entity");
                goto done;
        }
        interfaceEntityMutable = CFDictionaryCreateMutableCopy(NULL, 0, interfaceEntity);
-       CFRelease(interfaceEntity);
 
        if (isA_CFDictionary(bsdMapping) != NULL) {
                deviceName = CFDictionaryGetValue(interfaceEntityMutable, kSCPropNetInterfaceDeviceName);
@@ -2238,28 +2379,31 @@ __SCNetworkServiceMigrateNew(SCPreferencesRef           prefs,
                }
        }
        newService = SCNetworkServiceCreate(prefs, interface);
-
        if (newService == NULL) {
-               SCLog(TRUE, LOG_DEBUG, CFSTR("__SCNetworkServiceMigrateNew: Could not create new service"));
+               SC_log(LOG_INFO, "SCNetworkServiceCreate() failed");
                goto done;
        }
 
        enabled = SCNetworkServiceGetEnabled(service);
-       SCNetworkServiceSetEnabled(newService, enabled);
-       
-       if (SCNetworkServiceEstablishDefaultConfiguration(newService) == FALSE) {
+       if (!SCNetworkServiceSetEnabled(newService, enabled)) {
                SCNetworkServiceRemove(newService);
-               SCLog(TRUE, LOG_DEBUG, CFSTR("__SCNetworkServiceMigrateNew: SCNetworkServiceEstablishDefaultConfiguration failed"));
+               SC_log(LOG_INFO, "SCNetworkServiceSetEnabled() failed");
                goto done;
        }
-       
+
+       if (!SCNetworkServiceEstablishDefaultConfiguration(newService)) {
+               SCNetworkServiceRemove(newService);
+               SC_log(LOG_INFO, "SCNetworkServiceEstablishDefaultConfiguration() failed");
+               goto done;
+       }
+
        // Set service ID
        _SCNetworkServiceSetServiceID(newService, serviceID);
 
        userDefinedName = SCNetworkServiceGetName(service);
-       if (userDefinedName != NULL &&
-           SCNetworkServiceSetName(newService, userDefinedName) == FALSE) {
-               SCLog(TRUE, LOG_DEBUG, CFSTR("__SCNetworkServiceMigrateNew: Could not set service name to %@"), userDefinedName);
+       if ((userDefinedName != NULL) &&
+           !SCNetworkServiceSetName(newService, userDefinedName)) {
+               SC_log(LOG_INFO, "SCNetworkServiceSetName(, %@) failed", userDefinedName);
        }
 
        // Determine which sets to add service
@@ -2270,18 +2414,17 @@ __SCNetworkServiceMigrateNew(SCPreferencesRef           prefs,
                        for (CFIndex idx = 0; idx < CFArrayGetCount(setList); idx++) {
                                oldSet = CFArrayGetValueAtIndex(setList, idx);
                                newSet = CFDictionaryGetValue(setMapping, oldSet);
-                               
                                if (newSet == NULL) {
                                        continue;
                                }
-                               if (SCNetworkSetAddService(newSet, newService) == FALSE) {
-                                       SCLog(_sc_debug, LOG_DEBUG, CFSTR("__SCNetworkServiceMigrateNew: Could not add service to set: %@"), newSet);
-                                       continue;
+
+                               if (!SCNetworkSetAddService(newSet, newService)) {
+                                       SC_log(LOG_INFO, "SCNetworkSetAddService() failed");
                                }
                        }
                }
        }
-       
+
        protocols = SCNetworkServiceCopyProtocols(service);
        if (protocols != NULL) {
 
@@ -2290,7 +2433,7 @@ __SCNetworkServiceMigrateNew(SCPreferencesRef             prefs,
                        CFDictionaryRef configuration = SCNetworkProtocolGetConfiguration(protocol);
                        CFStringRef protocolType = SCNetworkProtocolGetProtocolType(protocol);
                        enabled = SCNetworkProtocolGetEnabled(protocol);
-                       addProtocolToService(newService, protocolType, configuration, enabled);
+                       __SCNetworkServiceAddProtocolToService(newService, protocolType, configuration, enabled);
                }
                CFRelease(protocols);
        }
@@ -2302,15 +2445,15 @@ done:
        if (interface != NULL) {
                CFRelease(interface);
        }
+       if (interfaceEntity != NULL) {
+               CFRelease(interfaceEntity);
+       }
        if (interfaceEntityMutable != NULL) {
                CFRelease(interfaceEntityMutable);
        }
        if (newService != NULL) {
                CFRelease(newService);
        }
-       if (servicesMutable != NULL) {
-               CFRelease(servicesMutable);
-       }
        if (ni_prefs != NULL) {
                CFRelease(ni_prefs);
        }
@@ -2338,31 +2481,31 @@ __SCNetworkServiceCreate(SCPreferencesRef       prefs,
        if (userDefinedName == NULL) {
                userDefinedName = __SCNetworkInterfaceGetUserDefinedName(interface);
                if (userDefinedName == NULL) {
-                       SCLog(TRUE, LOG_DEBUG, CFSTR("__SCNetworkServiceCreate: userDefinedName is NULL"));
+                       SC_log(LOG_INFO, "No userDefinedName");
                        goto done;
                }
        }
        service = SCNetworkServiceCreate(prefs, interface);
        if (service == NULL) {
-               SCLog(TRUE, LOG_DEBUG, CFSTR("__SCNetworkServiceCreate: Failed to create service: %s"), SCErrorString(SCError()));
+               SC_log(LOG_INFO, "SCNetworkServiceCreate() failed: %s", SCErrorString(SCError()));
        } else {
                ok = SCNetworkServiceSetName(service, userDefinedName);
-               if (ok == FALSE) {
-                       SCLog(TRUE, LOG_DEBUG, CFSTR("__SCNetworkServiceCreate: Failed to set name: %s"), SCErrorString(SCError()));
+               if (!ok) {
+                       SC_log(LOG_INFO, "SCNetworkServiceSetName() failed: %s", SCErrorString(SCError()));
                        SCNetworkServiceRemove(service);
                        goto done;
                }
 
                ok = SCNetworkServiceEstablishDefaultConfiguration(service);
-               if (ok == FALSE) {
-                       SCLog(TRUE, LOG_DEBUG, CFSTR("__SCNetworkServiceCreate: Failed to establish default configuration: %s"), SCErrorString(SCError()));
+               if (!ok) {
+                       SC_log(LOG_INFO, "SCNetworkServiceEstablishDefaultConfiguration() failed: %s", SCErrorString(SCError()));
                        SCNetworkServiceRemove(service);
                        goto done;
                }
        }
        currentSet = SCNetworkSetCopyCurrent(prefs);
        if (currentSet == NULL) {
-               SCLog(TRUE, LOG_DEBUG, CFSTR("__SCNetworkServiceCreate: Could not copy current set"));
+               SC_log(LOG_INFO, "No current set");
                if (service != NULL) {
                        SCNetworkServiceRemove(service);
                }
@@ -2370,8 +2513,8 @@ __SCNetworkServiceCreate(SCPreferencesRef prefs,
        }
        if (service != NULL) {
                ok = SCNetworkSetAddService(currentSet, service);
-               if (ok == FALSE) {
-                       SCLog(TRUE, LOG_DEBUG, CFSTR("__SCNetworkServiceCreate: Could not add service to the current set"));
+               if (!ok) {
+                       SC_log(LOG_INFO, "Could not add service to the current set");
                        SCNetworkServiceRemove(service);
                        goto done;
                }
@@ -2386,3 +2529,28 @@ __SCNetworkServiceCreate(SCPreferencesRef        prefs,
        }
        return ok;
 }
+
+__private_extern__ Boolean
+__SCNetworkServiceIsPPTP(SCNetworkServiceRef   service)
+{
+       CFStringRef intfSubtype;
+       SCNetworkServicePrivateRef servicePrivate = (SCNetworkServicePrivateRef)service;
+
+       if (servicePrivate == NULL || servicePrivate->interface == NULL) {
+               return FALSE;
+       }
+
+       intfSubtype = __SCNetworkInterfaceGetEntitySubType(servicePrivate->interface);
+       if (intfSubtype == NULL) {
+               return FALSE;
+       }
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+       if (CFEqual(intfSubtype, kSCValNetInterfaceSubTypePPTP)) {
+               return TRUE;
+       }
+#pragma GCC diagnostic pop
+
+       return FALSE;
+}