예제 #1
0
static CFStringRef
copy_primary_ip(SCDynamicStoreRef store, CFStringRef serviceID)
{
	CFStringRef	address	= NULL;
	CFDictionaryRef	dict;
	CFStringRef	key;

	key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
							  kSCDynamicStoreDomainState,
							  serviceID,
							  kSCEntNetIPv4);
	dict = SCDynamicStoreCopyValue(store, key);
	CFRelease(key);

	if (dict != NULL) {
		if (isA_CFDictionary(dict)) {
			CFArrayRef	addresses;

			addresses = CFDictionaryGetValue(dict, kSCPropNetIPv4Addresses);
			if (isA_CFArray(addresses) && (CFArrayGetCount(addresses) > 0)) {
				address = CFArrayGetValueAtIndex(addresses, 0);
				if (isA_CFString(address)) {
					CFRetain(address);
				} else {
					address = NULL;
				}
			}
		}
		CFRelease(dict);
	}

	return address;
}
static CFArrayRef
copy_supplemental_proxies(CFArrayRef proxies, Boolean skip)
{
	CFIndex			i;
	CFIndex			n_proxies;
	CFMutableArrayRef	supplemental	= NULL;

	// iterate over services

	n_proxies = isA_CFArray(proxies) ? CFArrayGetCount(proxies) : 0;
	for (i = 0; i < n_proxies; i++) {
		CFDictionaryRef		proxy;

		proxy = CFArrayGetValueAtIndex(proxies, i);
		if (!isSupplementalProxy(proxy)) {
			// if not supplemental proxy (i.e. no match domain)
			continue;
		}

		// add [supplemental] proxy entry
		if (supplemental == NULL) {
			supplemental = CFArrayCreateMutable(NULL,
							    0,
							    &kCFTypeArrayCallBacks);
		}
		CFArrayAppendValue(supplemental, proxy);
	}

	return supplemental;
}
static void
add_configured_interface(const void *key, const void *value, void *context)
{
	SCBondInterfaceRef		bond;
	CFStringRef			bond_if		= (CFStringRef)key;
	CFDictionaryRef			bond_info	= (CFDictionaryRef)value;
	CFDictionaryRef			bond_options;
	CFIndex				i;
	CFArrayRef			interfaces;
	SCNetworkInterfacePrivateRef	interfacePrivate;
	CFMutableArrayRef		members		= NULL;
	CFNumberRef			mode;
	addContextRef			myContext	= (addContextRef)context;
	CFStringRef			name;
	CFIndex				n;

	// create the bond interface
	bond = (SCBondInterfaceRef)_SCBondInterfaceCreatePrivate(NULL, bond_if);

	// add member interfaces
	interfaces = CFDictionaryGetValue(bond_info, kSCPropVirtualNetworkInterfacesBondInterfaces);
	n = isA_CFArray(interfaces) ? CFArrayGetCount(interfaces) : 0;
	for (i = 0; i < n; i++) {
		CFStringRef	member;

		member = CFArrayGetValueAtIndex(interfaces, i);
		if (isA_CFString(member)) {
			add_interface(&members, member);
		}
	}
	if (members != NULL) {
		_SCBondInterfaceSetMemberInterfaces(bond, members);
		CFRelease(members);
	}

	// set display name
	name = CFDictionaryGetValue(bond_info, kSCPropUserDefinedName);
	if (isA_CFString(name)) {
		SCBondInterfaceSetLocalizedDisplayName(bond, name);
	}

	// set options
	bond_options = CFDictionaryGetValue(bond_info, kSCPropVirtualNetworkInterfacesBondOptions);
	if (isA_CFDictionary(bond_options)) {
		SCBondInterfaceSetOptions(bond, bond_options);
	}

	// set the mode
	mode = CFDictionaryGetValue(bond_info, kSCPropVirtualNetworkInterfacesBondMode);
	_SCBondInterfaceSetMode(bond, isA_CFNumber(mode));

	// estabish link to the stored configuration
	interfacePrivate = (SCNetworkInterfacePrivateRef)bond;
	interfacePrivate->prefs = CFRetain(myContext->prefs);

	CFArrayAppendValue(myContext->bonds, bond);
	CFRelease(bond);

	return;
}
예제 #4
0
CFArrayRef /* of serviceID CFStringRef's */
SCNetworkSetGetServiceOrder(SCNetworkSetRef set)
{
	CFDictionaryRef		dict;
	CFStringRef		path;
	CFArrayRef		serviceOrder;
	SCNetworkSetPrivateRef	setPrivate	= (SCNetworkSetPrivateRef)set;

	if (!isA_SCNetworkSet(set)) {
		_SCErrorSet(kSCStatusInvalidArgument);
		return NULL;
	}

	path = SCPreferencesPathKeyCreateSetNetworkGlobalEntity(NULL, setPrivate->setID, kSCEntNetIPv4);
	if (path == NULL) {
		return NULL;
	}

	dict = SCPreferencesPathGetValue(setPrivate->prefs, path);
	CFRelease(path);
	if (!isA_CFDictionary(dict)) {
		return NULL;
	}

	serviceOrder = CFDictionaryGetValue(dict, kSCPropNetServiceOrder);
	serviceOrder = isA_CFArray(serviceOrder);

	return serviceOrder;
}
예제 #5
0
__private_extern__
void
link_add(const char *if_name)
{
	CFStringRef		interface;
	CFStringRef		cacheKey;
	CFDictionaryRef		dict;
	CFMutableDictionaryRef	newDict		= NULL;
	CFArrayRef		ifList;
	CFMutableArrayRef	newIFList	= NULL;

	interface = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingMacRoman);
	cacheKey  = SCDynamicStoreKeyCreateNetworkInterface(NULL,
							    kSCDynamicStoreDomainState);

	dict = cache_SCDynamicStoreCopyValue(store, cacheKey);
	if (dict) {
		if (isA_CFDictionary(dict)) {
			newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
			ifList  = CFDictionaryGetValue(newDict, kSCPropNetInterfaces);
			if (isA_CFArray(ifList)) {
				newIFList = CFArrayCreateMutableCopy(NULL, 0, ifList);
			}
		}
		CFRelease(dict);
	}

	if (!newDict) {
		newDict = CFDictionaryCreateMutable(NULL,
						    0,
						    &kCFTypeDictionaryKeyCallBacks,
						    &kCFTypeDictionaryValueCallBacks);
	}

	if (!newIFList) {
		newIFList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
	}

	if (CFArrayContainsValue(newIFList,
				 CFRangeMake(0, CFArrayGetCount(newIFList)),
				 interface) == FALSE) {
		CFArrayAppendValue(newIFList, interface);
		CFDictionarySetValue(newDict, kSCPropNetInterfaces, newIFList);
	}
	cache_SCDynamicStoreSetValue(store, cacheKey, newDict);
	link_update_status(if_name, TRUE);
#ifdef KEV_DL_LINK_QUALITY_METRIC_CHANGED
	link_update_quality_metric(if_name);
#endif /* KEV_DL_LINK_QUALITY_METRIC_CHANGED */
	CFRelease(cacheKey);
	CFRelease(interface);
	if (newDict)	CFRelease(newDict);
	if (newIFList)	CFRelease(newIFList);

	return;
}
예제 #6
0
/* -----------------------------------------------------------------------------
----------------------------------------------------------------------------- */
static Boolean
hasEntitlement(audit_token_t audit_token, CFStringRef entitlement, CFStringRef vpntype)
{
	Boolean		hasEntitlement	= FALSE;
	SecTaskRef	task;

	/* Create the security task from the audit token. */
	task = SecTaskCreateWithAuditToken(NULL, audit_token);
	if (task != NULL) {
		CFErrorRef	error	= NULL;
		CFTypeRef	value;

		/* Get the value for the entitlement. */
		value = SecTaskCopyValueForEntitlement(task, entitlement, &error);
		if (value != NULL) {
			if (isA_CFBoolean(value)) {
				if (CFBooleanGetValue(value)) {
					/* if client DOES have entitlement */
					hasEntitlement = TRUE;
				}
			} else if (isA_CFArray(value)){
				if (vpntype == NULL){
					/* we don't care about subtype */
					hasEntitlement = TRUE;
				}else {
					if (CFArrayContainsValue(value,
											 CFRangeMake(0, CFArrayGetCount(value)),
											 vpntype)) {
						// if client DOES have entitlement
						hasEntitlement = TRUE;
					}
				}
			} else {
				SCLog(TRUE, LOG_ERR,
				      CFSTR("SCNC Controller: entitlement not valid: %@"),
				      entitlement);
			}

			CFRelease(value);
		} else if (error != NULL) {
			SCLog(TRUE, LOG_ERR,
			      CFSTR("SCNC Controller: SecTaskCopyValueForEntitlement() failed, error=%@: %@"),
			      error,
			      entitlement);
			CFRelease(error);
		}

		CFRelease(task);
	} else {
		SCLog(TRUE, LOG_ERR,
		      CFSTR("SCNC Controller: SecTaskCreateWithAuditToken() failed: %@"),
		      entitlement);
	}

	return hasEntitlement;
}
예제 #7
0
static void
nc_listvpn(int argc, char **argv)
{

	CFDictionaryRef		appDict = NULL;
	CFArrayRef		appinfo = NULL;
	int			i, j, count, subtypecount;
	const void * *		keys = NULL;
	CFMutableDictionaryRef optionsDict = NULL;
	const void * *		values = NULL;
	CFStringRef		vpntype = NULL;

	optionsDict = CFDictionaryCreateMutable(NULL, 0,
						&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
	CFDictionarySetValue(optionsDict, kLookupApplicationTypeKey, kApplicationTypeUser);
	CFDictionarySetValue(optionsDict, kLookupAttributeKey, CFSTR("UIVPNPlugin"));

	appDict = MobileInstallationLookup(optionsDict);
	if (!isA_CFDictionary(appDict))
		goto done;

	count = CFDictionaryGetCount(appDict);
	if (count > 0) {
		keys = (const void * *)malloc(sizeof(CFTypeRef) * count);
		values = (const void * *)malloc(sizeof(CFTypeRef) * count);

		CFDictionaryGetKeysAndValues(appDict, keys, values);
		for (i=0; i<count; i++) {
			appinfo = CFDictionaryGetValue(values[i], CFSTR("UIVPNPlugin"));
			if (appinfo) {



				if (isA_CFString(appinfo)) {
					nc_print_VPN_app_info((CFStringRef)appinfo, (CFDictionaryRef)values[i]);
				}
				else if (isA_CFArray(appinfo)) {
					subtypecount = CFArrayGetCount((CFArrayRef)appinfo);
					for(j=0; j<subtypecount; j++) {
						vpntype = (CFStringRef)CFArrayGetValueAtIndex((CFArrayRef)appinfo, j);
						nc_print_VPN_app_info(vpntype, (CFDictionaryRef)values[i]);
					}
				}
			}
		}
	}
done:
	if (keys) free(keys);
	if (values) free(values);
	my_CFRelease(&optionsDict);
	my_CFRelease(&appDict);

	exit(0);
}
예제 #8
0
Boolean
SCNetworkSetSetServiceOrder(SCNetworkSetRef set, CFArrayRef newOrder)
{
	CFDictionaryRef		dict;
	CFMutableDictionaryRef  newDict;
	Boolean			ok;
	CFStringRef		path;
	SCNetworkSetPrivateRef	setPrivate	= (SCNetworkSetPrivateRef)set;

	if (!isA_SCNetworkSet(set)) {
		_SCErrorSet(kSCStatusInvalidArgument);
		return FALSE;
	}

	if (isA_CFArray(newOrder)) {
		CFIndex	i;
		CFIndex	n	= CFArrayGetCount(newOrder);

		for (i = 0; i < n; i++) {
			CFStringRef	serviceID;

			serviceID = CFArrayGetValueAtIndex(newOrder, i);
			if (!isA_CFString(serviceID)) {
				_SCErrorSet(kSCStatusInvalidArgument);
				return FALSE;
			}
		}
	} else {
		_SCErrorSet(kSCStatusInvalidArgument);
		return FALSE;
	}

	path = SCPreferencesPathKeyCreateSetNetworkGlobalEntity(NULL, setPrivate->setID, kSCEntNetIPv4);
	if (path == NULL) {
		return FALSE;
	}

	dict = SCPreferencesPathGetValue(setPrivate->prefs, path);
	if (dict != NULL) {
		newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
	} else {
		newDict = CFDictionaryCreateMutable(NULL,
						    0,
						    &kCFTypeDictionaryKeyCallBacks,
						    &kCFTypeDictionaryValueCallBacks);
	}

	CFDictionarySetValue(newDict, kSCPropNetServiceOrder, newOrder);
	ok = SCPreferencesPathSetValue(setPrivate->prefs, path, newDict);
	CFRelease(newDict);
	CFRelease(path);

	return ok;
}
STATIC bool
load_DUID_info(void)
{
    CFDataRef		duid;
    CFDictionaryRef	duid_ia;
    CFDataRef		host_uuid;
    CFArrayRef		ia_list;

    duid_ia = my_CFPropertyListCreateFromFile(DUID_IA_FILE);
    if (isA_CFDictionary(duid_ia) == NULL) {
	goto done;
    }
    duid = CFDictionaryGetValue(duid_ia, kDUIDKey);
    if (isA_CFData(duid) == NULL) {
	goto done;
    }
    ia_list = CFDictionaryGetValue(duid_ia, kIAIDListKey);
    ia_list = isA_CFArray(ia_list);
    if (ia_list != NULL) {
	int		count;
	int		i;

	count = CFArrayGetCount(ia_list);
	for (i = 0; i < count; i++) {
	    CFStringRef	name = CFArrayGetValueAtIndex(ia_list, i);
	    if (isA_CFString(name) == NULL) {
		/* invalid property */
		ia_list = NULL;
		break;
	    }
	}
    }
    host_uuid = CFDictionaryGetValue(duid_ia, kHostUUIDKey);
    if (isA_CFData(host_uuid) != NULL 
	&& CFDataGetLength(host_uuid) == sizeof(uuid_t)) {
	CFDataRef	our_UUID;

	our_UUID = HostUUIDGet();
	if (our_UUID != NULL && CFEqual(host_uuid, our_UUID) == FALSE) {
	    syslog(LOG_NOTICE,
		   "DHCPDUID: ignoring DUID - host UUID doesn't match");
	    goto done;
	}
    }
    S_DUID = CFRetain(duid);
    if (ia_list != NULL) {
	S_IAIDList = CFArrayCreateMutableCopy(NULL, 0, ia_list);
    }

 done:
    my_CFRelease(&duid_ia);
    return (S_DUID != NULL);
}
예제 #10
0
__private_extern__
void
link_remove(const char *if_name)
{
	CFStringRef		interface;
	CFStringRef		cacheKey;
	CFDictionaryRef		dict;
	CFMutableDictionaryRef	newDict		= NULL;
	CFArrayRef		ifList;
	CFMutableArrayRef	newIFList	= NULL;
	CFIndex			i;

	interface = CFStringCreateWithCString(NULL, if_name, kCFStringEncodingMacRoman);
	cacheKey  = SCDynamicStoreKeyCreateNetworkInterface(NULL,
							    kSCDynamicStoreDomainState);

	dict = cache_SCDynamicStoreCopyValue(store, cacheKey);
	if (dict) {
		if (isA_CFDictionary(dict)) {
			newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
			ifList  = CFDictionaryGetValue(newDict, kSCPropNetInterfaces);
			if (isA_CFArray(ifList)) {
				newIFList = CFArrayCreateMutableCopy(NULL, 0, ifList);
			}
		}
		CFRelease(dict);
	}

	if (!newIFList ||
	    ((i = CFArrayGetFirstIndexOfValue(newIFList,
					     CFRangeMake(0, CFArrayGetCount(newIFList)),
					     interface)) == kCFNotFound)
	   ) {
		/* we're not tracking this interface */
		goto done;
	}

	CFArrayRemoveValueAtIndex(newIFList, i);
	CFDictionarySetValue(newDict, kSCPropNetInterfaces, newIFList);
	cache_SCDynamicStoreSetValue(store, cacheKey, newDict);

	interface_remove(if_name);

    done:

	CFRelease(cacheKey);
	CFRelease(interface);
	if (newDict)	CFRelease(newDict);
	if (newIFList)	CFRelease(newIFList);

	return;
}
static CFArrayRef
service_order_copy_all(CFDictionaryRef services, CFArrayRef service_order)
{
	const void *		keys_q[N_QUICK];
	const void **		keys	= keys_q;
	CFIndex			i;
	CFIndex			n_order;
	CFIndex			n_services;
	CFMutableArrayRef	order;

	// ensure that we process all services in order
	n_services = isA_CFDictionary(services) ? CFDictionaryGetCount(services) : 0;
	if (n_services == 0) {
		// if no services
		return NULL;
	}

	// ensure that we process all services in order

	n_order = isA_CFArray(service_order) ? CFArrayGetCount(service_order) : 0;
	if (n_order > 0) {
		order = CFArrayCreateMutableCopy(NULL, 0, service_order);
	} else {
		order = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
	}

	if (n_services > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) {
		keys = CFAllocatorAllocate(NULL, n_services * sizeof(CFTypeRef), 0);
	}
	CFDictionaryGetKeysAndValues(services, keys, NULL);
	for (i = 0; i < n_services; i++) {
		CFStringRef	serviceID	= (CFStringRef)keys[i];

		if (!CFArrayContainsValue(order, CFRangeMake(0, n_order), serviceID)) {
			CFArrayAppendValue(order, serviceID);
			n_order++;
		}
	}
	if (keys != keys_q) {
		CFAllocatorDeallocate(NULL, keys);
	}

	return order;
}
예제 #12
0
/*
 * Function: EAPOLClientConfigurationCopyLoginWindowProfiles
 *
 * Purpose:
 *   Return the list of profiles configured for LoginWindow mode on the
 *   specified BSD network interface (e.g. "en0", "en1").
 *
 * Returns:
 *   NULL if no profiles are defined, non-NULL non-empty array of profiles
 *   otherwise.
 */
CFArrayRef /* of EAPOLClientProfileRef */
EAPOLClientConfigurationCopyLoginWindowProfiles(EAPOLClientConfigurationRef cfg,
						CFStringRef if_name)
{
    int				count;
    int				i;
    CFDictionaryRef		dict;
    CFArrayRef			profile_ids;
    CFMutableArrayRef		ret_profiles = NULL;

    dict = get_eapol_configuration(get_sc_prefs(cfg), if_name, NULL);
    if (dict == NULL) {
	goto done;
    }
    profile_ids = CFDictionaryGetValue(dict, kLoginWindowProfileIDs);
    if (isA_CFArray(profile_ids) == NULL) {
	goto done;
    }
    count = CFArrayGetCount(profile_ids);
    if (count == 0) {
	goto done;
    }
    ret_profiles = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks);
    for (i = 0; i < count; i++) {
	CFStringRef		profileID;
	EAPOLClientProfileRef	profile;

	profileID = (CFStringRef)CFArrayGetValueAtIndex(profile_ids, i);
	if (isA_CFString(profileID) == NULL) {
	    continue;
	}
	profile = EAPOLClientConfigurationGetProfileWithID(cfg, profileID);
	if (profile != NULL) {
	    CFArrayAppendValue(ret_profiles, profile);
	}
    }
    if (CFArrayGetCount(ret_profiles) == 0) {
	my_CFRelease(&ret_profiles);
    }

 done:
    return (ret_profiles);
}
/* IOPSCopyUPSArray
 *
 * Argument: 
 *	CFTypeRef power_sources: The return value from IOPSCoyPowerSourcesInfo()
 * Return value:
 * 	CFArrayRef: all the UPS's we found
 *			NULL if none are found
 */
 CFArrayRef
IOPSCopyUPSArray(CFTypeRef power_sources)
{
    CFArrayRef			array = isA_CFArray(IOPSCopyPowerSourcesList(power_sources));
    CFMutableArrayRef   ret_arr;
    CFTypeRef			name = NULL;
    CFDictionaryRef		ps;
    CFStringRef			transport_type;
    int				    i, count;

    if(!array) return NULL;
    count = CFArrayGetCount(array);
    name = NULL;

    ret_arr = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
    if(!ret_arr) goto exit;

    // Iterate through power_sources
    for(i=0; i<count; i++) {
        name = CFArrayGetValueAtIndex(array, i);
        ps = isA_CFDictionary(IOPSGetPowerSourceDescription(power_sources, name));
        if(ps) {
            transport_type = isA_CFString(CFDictionaryGetValue(ps, CFSTR(kIOPSTransportTypeKey)));
            if(transport_type && ( CFEqual(transport_type, CFSTR(kIOPSSerialTransportType)) ||
                CFEqual(transport_type, CFSTR(kIOPSUSBTransportType)) ||
                CFEqual(transport_type, CFSTR(kIOPSNetworkTransportType)) ) )
            {
                CFArrayAppendValue(ret_arr, name);
            }
        }
    }

    if(0 == CFArrayGetCount(ret_arr)) {
        CFRelease(ret_arr);
        ret_arr = NULL;
    }

exit:
    CFRelease(array);
    return ret_arr;
}
/*
 *
 * copySchedulePowerChangeArrays
 *
 */
static void
copyScheduledPowerChangeArrays(void)
{
#if !TARGET_OS_EMBEDDED
    CFArrayRef              tmp;
    SCPreferencesRef        prefs;
    PowerEventBehavior      *this_behavior;
    int                     i;
   
    prefs = SCPreferencesCreate(0, 
                                CFSTR("PM-configd-AutoWake"),
                                CFSTR(kIOPMAutoWakePrefsPath));
    if(!prefs) return;

    activeEventCnt = 0;
    // Loop through all sleep, wake, shutdown powerbehaviors
    for(i=0; i<kBehaviorsCount; i++) 
    {
        this_behavior = behaviors[i];

        if(this_behavior->array) {
            CFRelease(this_behavior->array);
            this_behavior->array = NULL;
        }

        tmp = isA_CFArray(SCPreferencesGetValue(prefs, this_behavior->title));
        if(tmp && (0 < CFArrayGetCount(tmp))) {
            this_behavior->array = CFArrayCreateMutableCopy(0, 0, tmp);
            activeEventCnt += CFArrayGetCount(tmp);
        } else {
            this_behavior->array = NULL;
        }
    }



    CFRelease(prefs);

#endif
}
예제 #15
0
PRIVATE_EXTERN Boolean
accept_types_valid(CFArrayRef accept)
{
    int			count;
    int			i;

    if (isA_CFArray(accept) == NULL) {
	return (FALSE);
    }
    count = CFArrayGetCount(accept);
    if (count == 0) {
	return (FALSE);
    }
    for (i = 0; i < count; i++) {
	CFNumberRef		type = CFArrayGetValueAtIndex(accept, i);

	if (isA_CFNumber(type) == NULL) {
	    return (FALSE);
	}
    }
    return (TRUE);
}
static void
add_supplemental(CFMutableArrayRef proxies, CFDictionaryRef proxy, uint32_t defaultOrder)
{
	CFArrayRef	domains;
	CFIndex		i;
	CFIndex		n_domains;
	CFArrayRef	orders;

	domains = CFDictionaryGetValue(proxy, kSCPropNetProxiesSupplementalMatchDomains);
	n_domains = isA_CFArray(domains) ? CFArrayGetCount(domains) : 0;
	if (n_domains == 0) {
		return;
	}

	orders = CFDictionaryGetValue(proxy, kSCPropNetProxiesSupplementalMatchOrders);
	if (orders != NULL) {
		if (!isA_CFArray(orders) || (n_domains != CFArrayGetCount(orders))) {
			return;
		}
	}

	/*
	 * yes, this is a "supplemental" proxy configuration, expand
	 * the match domains and add each to the proxies list.
	 */
	for (i = 0; i < n_domains; i++) {
		CFStringRef		match_domain;
		CFNumberRef		match_order;
		CFMutableDictionaryRef	match_proxy;

		match_domain = CFArrayGetValueAtIndex(domains, i);
		if (!isA_CFString(match_domain)) {
			continue;
		}

		match_proxy = CFDictionaryCreateMutableCopy(NULL, 0, proxy);

		// set supplemental proxy match "domain"
		match_domain = _SC_trimDomain(match_domain);
		if (match_domain != NULL) {
			CFDictionarySetValue(match_proxy, kSCPropNetProxiesSupplementalMatchDomain, match_domain);
			CFRelease(match_domain);
		} else {
			CFDictionaryRemoveValue(match_proxy, kSCPropNetProxiesSupplementalMatchDomain);
		}

		// set supplemental proxy match "order"
		match_order = (orders != NULL) ? CFArrayGetValueAtIndex(orders, i) : NULL;
		if (isA_CFNumber(match_order)) {
			CFDictionarySetValue(match_proxy, PROXY_MATCH_ORDER_KEY, match_order);
		} else {
			CFNumberRef     num;

			num = CFNumberCreate(NULL, kCFNumberIntType, &defaultOrder);
			CFDictionarySetValue(match_proxy, PROXY_MATCH_ORDER_KEY, num);
			CFRelease(num);

			defaultOrder++;		// if multiple domains, maintain ordering
		}

		// remove keys we don't want in a supplemental proxy
		CFDictionaryRemoveValue(match_proxy, kSCPropNetProxiesSupplementalMatchDomains);
		CFDictionaryRemoveValue(match_proxy, kSCPropNetProxiesSupplementalMatchOrders);
		CFDictionaryRemoveValue(match_proxy, kSCPropInterfaceName);

		add_proxy(proxies, match_proxy);
		CFRelease(match_proxy);
	}

	return;
}
static CFDictionaryRef
copy_scoped_proxies(CFDictionaryRef services, CFArrayRef order)
{
	CFIndex			i;
	CFIndex			n_order;
	CFMutableDictionaryRef	scoped	= NULL;

	// iterate over services

	n_order = isA_CFArray(order) ? CFArrayGetCount(order) : 0;
	for (i = 0; i < n_order; i++) {
		char			if_name[IF_NAMESIZE];
		CFStringRef		interface;
		CFMutableDictionaryRef	newProxy;
		CFDictionaryRef		proxy;
		CFDictionaryRef		service;
		CFStringRef		serviceID;

		serviceID = CFArrayGetValueAtIndex(order, i);
		service = CFDictionaryGetValue(services, serviceID);
		if (!isA_CFDictionary(service)) {
			// if no service
			continue;
		}

		proxy = CFDictionaryGetValue(service, kSCEntNetProxies);
		if (!isA_CFDictionary(proxy)) {
			// if no proxy
			continue;
		}

		interface = CFDictionaryGetValue(proxy, kSCPropInterfaceName);
		if (interface == NULL) {
			// if no [scoped] interface
			continue;
		}
		if ((scoped != NULL) &&
		    CFDictionaryContainsKey(scoped, interface)) {
			// if we've already processed this [scoped] interface
			continue;
		}

		if ((_SC_cfstring_to_cstring(interface,
					     if_name,
					     sizeof(if_name),
					     kCFStringEncodingASCII) == NULL) ||
		    ((if_nametoindex(if_name)) == 0)) {
			// if interface index not available
			continue;
		}

		// add [scoped] proxy entry
		// ... and remove keys we don't want in a [scoped] proxy
		CFRetain(interface);
		newProxy = CFDictionaryCreateMutableCopy(NULL, 0, proxy);
		CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesSupplementalMatchDomains);
		CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesSupplementalMatchOrders);
		CFDictionaryRemoveValue(newProxy, kSCPropInterfaceName);
		if (scoped == NULL) {
			scoped = CFDictionaryCreateMutable(NULL,
							   0,
							   &kCFTypeDictionaryKeyCallBacks,
							   &kCFTypeDictionaryValueCallBacks);
		}
		CFDictionarySetValue(scoped, interface, newProxy);
		CFRelease(newProxy);
		CFRelease(interface);
	}

	return scoped;
}
static CFDictionaryRef
copy_app_layer_vpn_proxies(CFDictionaryRef services, CFArrayRef order, CFDictionaryRef services_info)
{
	CFMutableDictionaryRef	app_layer_proxies	= NULL;
	CFIndex			i;
	CFIndex			n_order;

	if (!isA_CFDictionary(services_info)) {
		return NULL;
	}

	// iterate over services

	n_order = isA_CFArray(order) ? CFArrayGetCount(order) : 0;
	for (i = 0; i < n_order; i++) {
		CFMutableDictionaryRef	newProxy;
		CFDictionaryRef		proxy;
		CFDictionaryRef		service;
		CFStringRef		serviceID;
		CFDictionaryRef		vpn;
		CFStringRef		vpn_key;

		serviceID = CFArrayGetValueAtIndex(order, i);
		service = CFDictionaryGetValue(services, serviceID);
		if (!isA_CFDictionary(service)) {
			// if no service
			continue;
		}

		proxy = CFDictionaryGetValue(service, kSCEntNetProxies);
		if (!isA_CFDictionary(proxy)) {
			// if no proxy
			continue;
		}

		vpn_key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
								      kSCDynamicStoreDomainSetup,
								      serviceID,
								      kSCEntNetVPN);
		vpn = CFDictionaryGetValue(services_info, vpn_key);
		CFRelease(vpn_key);

		if (!isA_CFDictionary(vpn) || !CFDictionaryContainsKey(vpn, kSCPropNetVPNAppRules)) {
			// if not app-layer vpn
			continue;
		}

		if ((app_layer_proxies != NULL) &&
		    CFDictionaryContainsKey(app_layer_proxies, serviceID)) {
			// if we've already processed this [app_layer_proxies] interface
			continue;
		}

		// add [app_layer_proxies] proxy entry
		newProxy = CFDictionaryCreateMutableCopy(NULL, 0, proxy);
		CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesSupplementalMatchDomains);
		CFDictionaryRemoveValue(newProxy, kSCPropNetProxiesSupplementalMatchOrders);
		if (app_layer_proxies == NULL) {
			app_layer_proxies = CFDictionaryCreateMutable(NULL,
								      0,
								      &kCFTypeDictionaryKeyCallBacks,
								      &kCFTypeDictionaryValueCallBacks);
		}
		CFDictionarySetValue(app_layer_proxies, serviceID, newProxy);
		CFRelease(newProxy);
	}

	return app_layer_proxies;
}
Boolean
SCBondInterfaceSetMemberInterfaces(SCBondInterfaceRef bond, CFArrayRef members)
{
	SCNetworkInterfacePrivateRef	interfacePrivate	= (SCNetworkInterfacePrivateRef)bond;
	Boolean				ok;
	int				sc_status		= kSCStatusOK;

	if (!isA_SCBondInterface(bond)) {
		_SCErrorSet(kSCStatusInvalidArgument);
		return FALSE;
	}

	if ((members != NULL) && !isA_CFArray(members)) {
		_SCErrorSet(kSCStatusInvalidArgument);
		return FALSE;
	}

	if (interfacePrivate->prefs != NULL) {
		CFArrayRef	available;
		CFArrayRef	current;
		CFIndex		i;
		CFIndex		n_available;
		CFIndex		n_current;
		CFIndex		n_members;
		CFArrayRef	services	= NULL;

		current     = SCBondInterfaceGetMemberInterfaces(bond);
		n_current   = (current != NULL) ? CFArrayGetCount(current) : 0;

		available   = SCBondInterfaceCopyAvailableMemberInterfaces(interfacePrivate->prefs);
		n_available = (available != NULL) ? CFArrayGetCount(available) : 0;

		n_members = (members != NULL) ? CFArrayGetCount(members) : 0;
		for (i = 0; i < n_members; i++) {
			SCNetworkInterfaceRef	member;

			member = CFArrayGetValueAtIndex(members, i);

			if ((current != NULL) &&
			    CFArrayContainsValue(current, CFRangeMake(0, n_current), member)) {
				// current members are allowed
				continue;
			}

			if ((available != NULL) &&
			    CFArrayContainsValue(available, CFRangeMake(0, n_available), member)) {
				// available members are allowed but cannot be associated
				// with any other network services.

				if (services == NULL) {
					services = __SCNetworkServiceCopyAllEnabled(interfacePrivate->prefs);
				}
				if ((services != NULL) &&
				    __SCNetworkServiceExistsForInterface(services, member)) {
					sc_status = kSCStatusKeyExists;
					break;
				}

				// if available
				continue;
			}

			// if member not allowed
			sc_status = kSCStatusInvalidArgument;
			break;
		}

		if (available != NULL) CFRelease(available);
		if (services != NULL) CFRelease(services);
	}

	if (sc_status != kSCStatusOK) {
		_SCErrorSet(sc_status);
		return FALSE;
	}

	ok = _SCBondInterfaceSetMemberInterfaces(bond, members);
	return ok;
}
static void
add_supplemental_proxies(CFMutableArrayRef proxies, CFDictionaryRef services, CFArrayRef service_order)
{
	const void *		keys_q[N_QUICK];
	const void **		keys	= keys_q;
	CFIndex			i;
	CFIndex			n_order;
	CFIndex			n_services;
	const void *		vals_q[N_QUICK];
	const void **		vals	= vals_q;

	n_services = isA_CFDictionary(services) ? CFDictionaryGetCount(services) : 0;
	if (n_services == 0) {
		return;		// if no services
	}

	if (n_services > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) {
		keys = CFAllocatorAllocate(NULL, n_services * sizeof(CFTypeRef), 0);
		vals = CFAllocatorAllocate(NULL, n_services * sizeof(CFTypeRef), 0);
	}

	n_order = isA_CFArray(service_order) ? CFArrayGetCount(service_order) : 0;

	CFDictionaryGetKeysAndValues(services, keys, vals);
	for (i = 0; i < n_services; i++) {
		uint32_t		defaultOrder;
		CFDictionaryRef		proxy;
		CFMutableDictionaryRef	proxyWithDNS	= NULL;
		CFDictionaryRef		service		= (CFDictionaryRef)vals[i];

		if (!isA_CFDictionary(service)) {
			continue;
		}

		proxy = CFDictionaryGetValue(service, kSCEntNetProxies);
		if (!isA_CFDictionary(proxy)) {
			continue;
		}

		if ((G_supplemental_proxies_follow_dns != NULL) && CFBooleanGetValue(G_supplemental_proxies_follow_dns)) {
			CFDictionaryRef	dns;
			CFArrayRef	matchDomains;
			CFArrayRef	matchOrders;

			if (!CFDictionaryContainsKey(proxy, kSCPropNetProxiesSupplementalMatchDomains) &&
			    CFDictionaryGetValueIfPresent(service, kSCEntNetDNS, (const void **)&dns) &&
			    isA_CFDictionary(dns) &&
			    CFDictionaryGetValueIfPresent(dns, kSCPropNetDNSSupplementalMatchDomains, (const void **)&matchDomains) &&
			    isA_CFArray(matchDomains)) {
				proxyWithDNS = CFDictionaryCreateMutableCopy(NULL, 0, proxy);
				CFDictionarySetValue(proxyWithDNS, kSCPropNetProxiesSupplementalMatchDomains, matchDomains);
				if (CFDictionaryGetValueIfPresent(dns, kSCPropNetDNSSupplementalMatchOrders, (const void **)&matchOrders) &&
				    isA_CFArray(matchOrders)) {
					CFDictionarySetValue(proxyWithDNS, kSCPropNetProxiesSupplementalMatchOrders, matchOrders);
				} else {
					CFDictionaryRemoveValue(proxyWithDNS, kSCPropNetProxiesSupplementalMatchOrders);
				}
				proxy = proxyWithDNS;
			}
		}

		defaultOrder = DEFAULT_MATCH_ORDER
			       - (DEFAULT_MATCH_ORDER / 2)
			       + ((DEFAULT_MATCH_ORDER / 1000) * i);
		if ((n_order > 0) &&
		    !CFArrayContainsValue(service_order, CFRangeMake(0, n_order), keys[i])) {
			// push out services not specified in service order
			defaultOrder += (DEFAULT_MATCH_ORDER / 1000) * n_services;
		}

		add_supplemental(proxies, proxy, defaultOrder);
		if (proxyWithDNS != NULL) CFRelease(proxyWithDNS);
	}

	if (keys != keys_q) {
		CFAllocatorDeallocate(NULL, keys);
		CFAllocatorDeallocate(NULL, vals);
	}

	return;
}
예제 #21
0
static CFArrayRef
getTargets(CFBundleRef bundle)
{
	int			fd;
	Boolean			ok;
	struct stat		statBuf;
	CFArrayRef		targets;	/* The array of dictionaries
						   representing targets with
						   a "kick me" sign posted on
						   their backs. */
	char			targetPath[MAXPATHLEN];
	CFURLRef		url;
	CFStringRef		xmlError;
	CFMutableDataRef	xmlTargets;

	/* locate the Kicker targets */
	url = CFBundleCopyResourceURL(bundle, CFSTR("Kicker"), CFSTR("xml"), NULL);
	if (!url) {
		return NULL;
	}

	ok = CFURLGetFileSystemRepresentation(url,
					      TRUE,
					      (UInt8 *)&targetPath,
					      sizeof(targetPath));
	CFRelease(url);
	if (!ok) {
		return NULL;
	}

	/* open the file */
	if ((fd = open(targetPath, O_RDONLY, 0)) == -1) {
		SCLog(TRUE, LOG_NOTICE,
		      CFSTR("%@ load(): %s not found"),
		      CFBundleGetIdentifier(bundle),
		      targetPath);
		return NULL;
	}

	/* get the type and size of the XML data file */
	if (fstat(fd, &statBuf) < 0) {
		(void) close(fd);
		return NULL;
	}

	/* check that its a regular file */
	if ((statBuf.st_mode & S_IFMT) != S_IFREG) {
		(void) close(fd);
		return NULL;
	}

	/* load the file contents */
	xmlTargets = CFDataCreateMutable(NULL, statBuf.st_size);
	CFDataSetLength(xmlTargets, statBuf.st_size);
	if (read(fd, (void *)CFDataGetMutableBytePtr(xmlTargets), statBuf.st_size) != statBuf.st_size) {
		CFRelease(xmlTargets);
		(void) close(fd);
		return NULL;
	}
	(void) close(fd);

	/* convert the XML data into a property list */
	targets = CFPropertyListCreateFromXMLData(NULL,
						  xmlTargets,
						  kCFPropertyListImmutable,
						  &xmlError);
	CFRelease(xmlTargets);
	if (!targets) {
		if (xmlError) {
			SCLog(TRUE, LOG_DEBUG,
			      CFSTR("CFPropertyListCreateFromXMLData() start: %@"),
			      xmlError);
			CFRelease(xmlError);
		}
		return NULL;
	}

	if (!isA_CFArray(targets)) {
		CFRelease(targets);
		targets = NULL;
	}

	return targets;
}
예제 #22
0
/*
 * startKicker()
 *
 * The first argument is a dictionary representing the keys
 * which need to be monitored for a given "target" and what
 * action should be taken if a change in one of those keys
 * is detected.
 */
static void
startKicker(const void *value, void *context)
{
	CFMutableStringRef	name;
	CFArrayRef		keys;
	CFArrayRef		patterns;
	kickeeRef		target		= CFAllocatorAllocate(NULL, sizeof(kickee), 0);
	SCDynamicStoreContext	targetContext	= { 0, (void *)target, NULL, NULL, NULL };

	target->active		= FALSE;
	target->needsKick	= FALSE;
	target->dict		= CFRetain((CFDictionaryRef)value);
	target->store		= NULL;
	target->rl		= NULL;
	target->rls		= NULL;
	target->changedKeys	= NULL;

	name = CFStringCreateMutableCopy(NULL,
					 0,
					 CFDictionaryGetValue(target->dict, CFSTR("name")));
	SCLog(TRUE, LOG_DEBUG, CFSTR("Starting kicker for %@"), name);

	CFStringAppend(name, CFSTR(" \"Kicker\""));
	target->store = SCDynamicStoreCreate(NULL, name, kicker, &targetContext);
	CFRelease(name);
	if (!target->store) {
		SCLog(TRUE,
		      LOG_NOTICE,
		      CFSTR("SCDynamicStoreCreate() failed: %s"),
		      SCErrorString(SCError()));
		goto error;
	}

	keys     = isA_CFArray(CFDictionaryGetValue(target->dict, CFSTR("keys")));
	patterns = isA_CFArray(CFDictionaryGetValue(target->dict, CFSTR("regexKeys")));
	if (!SCDynamicStoreSetNotificationKeys(target->store, keys, patterns)) {
		SCLog(TRUE,
		      LOG_NOTICE,
		      CFSTR("SCDynamicStoreSetNotifications() failed: %s"),
		      SCErrorString(SCError()));
		goto error;
	}

	target->rl  = CFRunLoopGetCurrent();
	target->rls = SCDynamicStoreCreateRunLoopSource(NULL, target->store, 0);
	if (!target->rls) {
		SCLog(TRUE,
		      LOG_NOTICE,
		      CFSTR("SCDynamicStoreCreateRunLoopSource() failed: %s"),
		      SCErrorString(SCError()));
		goto error;
	}

	CFRunLoopAddSource(target->rl, target->rls, kCFRunLoopDefaultMode);
	return;

    error :

	CFRelease(target->dict);
	if (target->store)	CFRelease(target->store);
	CFAllocatorDeallocate(NULL, target);
	return;
}
예제 #23
0
static boolean_t
updateConfiguration(int *newState)
{
	boolean_t		changed			= FALSE;
	CFStringRef		computerName;
	CFStringEncoding	computerNameEncoding;
	CFArrayRef		configuredServices	= NULL;
	CFDictionaryRef		dict;
	CFIndex			i;
	CFIndex			ifCount			= 0;
	CFMutableArrayRef	info			= NULL;
	CFArrayRef		interfaces		= NULL;
	CFStringRef		key;
	CFArrayRef		keys;
	CFIndex			n;
	CFMutableArrayRef	newConfigFile;
	CFMutableDictionaryRef	newDefaults;
	CFMutableDictionaryRef	newDict;
	CFMutableDictionaryRef	newGlobals;
	CFMutableDictionaryRef	newGlobalsX;			/* newGlobals without ServiceID */
	CFMutableDictionaryRef	newStartup;
	CFMutableDictionaryRef	newZones;
	CFNumberRef		num;
	CFMutableDictionaryRef	curGlobalsX;			/* curGlobals without ServiceID */
	CFStringRef		pattern;
	boolean_t		postGlobals		= FALSE;
	CFStringRef		primaryPort		= NULL;	/* primary interface */
	CFStringRef		primaryZone		= NULL;
	CFArrayRef		serviceOrder		= NULL;
	CFDictionaryRef		setGlobals		= NULL;

	cache_open();

	/*
	 * establish the "new" AppleTalk configuration
	 */
	*newState     = curState;
	newConfigFile = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
	newGlobals    = CFDictionaryCreateMutable(NULL,
						  0,
						  &kCFTypeDictionaryKeyCallBacks,
						  &kCFTypeDictionaryValueCallBacks);
	newDefaults   = CFDictionaryCreateMutable(NULL,
						  0,
						  &kCFTypeDictionaryKeyCallBacks,
						  &kCFTypeDictionaryValueCallBacks);
	newStartup    = CFDictionaryCreateMutable(NULL,
						  0,
						  &kCFTypeDictionaryKeyCallBacks,
						  &kCFTypeDictionaryValueCallBacks);
	newZones      = CFDictionaryCreateMutable(NULL,
						  0,
						  &kCFTypeDictionaryKeyCallBacks,
						  &kCFTypeDictionaryValueCallBacks);

	/* initialize overall state */
	CFDictionarySetValue(newStartup, CFSTR("APPLETALK"), CFSTR("-NO-"));

	/*
	 * get the global settings (ServiceOrder, ComputerName, ...)
	 */
	key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
							 kSCDynamicStoreDomainSetup,
							 kSCEntNetAppleTalk);
	setGlobals = cache_SCDynamicStoreCopyValue(store, key);
	CFRelease(key);
	if (setGlobals) {
		if (isA_CFDictionary(setGlobals)) {
			/* get service order */
			serviceOrder = CFDictionaryGetValue(setGlobals,
							    kSCPropNetServiceOrder);
			serviceOrder = isA_CFArray(serviceOrder);
			if (serviceOrder) {
				CFRetain(serviceOrder);
			}
		} else {
			CFRelease(setGlobals);
			setGlobals = NULL;
		}
	}

	/*
	 * if we don't have an AppleTalk ServiceOrder, use IPv4's (if defined)
	 */
	if (!serviceOrder) {
		key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
								 kSCDynamicStoreDomainSetup,
								 kSCEntNetIPv4);
		dict = cache_SCDynamicStoreCopyValue(store, key);
		CFRelease(key);
		if (dict) {
			if (isA_CFDictionary(dict)) {
				serviceOrder = CFDictionaryGetValue(dict,
								    kSCPropNetServiceOrder);
				serviceOrder = isA_CFArray(serviceOrder);
				if (serviceOrder) {
					CFRetain(serviceOrder);
				}
			}
			CFRelease(dict);
		}
	}

	/*
	 * get the list of ALL configured services
	 */
	configuredServices = entity_all(store, kSCEntNetAppleTalk, serviceOrder);
	if (configuredServices) {
		ifCount = CFArrayGetCount(configuredServices);
	}

	if (serviceOrder)	CFRelease(serviceOrder);

	/*
	 * get the list of ALL active interfaces
	 */
	key  = SCDynamicStoreKeyCreateNetworkInterface(NULL, kSCDynamicStoreDomainState);
	dict = cache_SCDynamicStoreCopyValue(store, key);
	CFRelease(key);
	if (dict) {
		if (isA_CFDictionary(dict)) {
			interfaces = CFDictionaryGetValue(dict,
							  kSCDynamicStorePropNetInterfaces);
			interfaces = isA_CFArray(interfaces);
			if (interfaces) {
				CFRetain(interfaces);
			}
		}
		CFRelease(dict);
	}

	/*
	 * get the list of previously configured services
	 */
	pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
							      kSCDynamicStoreDomainState,
							      kSCCompAnyRegex,
							      kSCEntNetAppleTalk);
	keys = SCDynamicStoreCopyKeyList(store, pattern);
	CFRelease(pattern);
	if (keys) {
		info = CFArrayCreateMutableCopy(NULL, 0, keys);
		CFRelease(keys);
	}

	/*
	 * iterate over each configured service to establish the new
	 * configuration.
	 */
	for (i = 0; i < ifCount; i++) {
		CFDictionaryRef		service;
		CFStringRef		ifName;
		CFStringRef		configMethod;
		CFMutableStringRef	portConfig	= NULL;
		CFArrayRef		networkRange;	/* for seed ports, CFArray[2] of CFNumber (lo, hi) */
		int			sNetwork;
		int			eNetwork;
		CFArrayRef		zoneList;	/* for seed ports, CFArray[] of CFString (zones names) */
		CFIndex			zCount;
		CFIndex			j;
		CFMutableDictionaryRef	ifDefaults	= NULL;
		CFNumberRef		defaultNetwork;
		CFNumberRef		defaultNode;
		CFStringRef		defaultZone;

		/* get AppleTalk service dictionary */
		service = CFArrayGetValueAtIndex(configuredServices, i);

		/* get interface name */
		ifName  = CFDictionaryGetValue(service, kSCPropNetInterfaceDeviceName);

		/* check inteface availability */
		if (!interfaces ||
		    !CFArrayContainsValue(interfaces, CFRangeMake(0, CFArrayGetCount(interfaces)), ifName)) {
			/* if interface not available */
			goto nextIF;
		}

		/* check interface link status */
		key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
								    kSCDynamicStoreDomainState,
								    ifName,
								    kSCEntNetLink);
		dict = cache_SCDynamicStoreCopyValue(store, key);
		CFRelease(key);
		if (dict) {
			Boolean	linkStatus	= TRUE;  /* assume the link is "up" */
			Boolean	ifDetaching	= FALSE; /* assume link is not detaching */

			/* the link key for this interface is available */
			if (isA_CFDictionary(dict)) {
				CFBooleanRef	bVal;

				bVal = CFDictionaryGetValue(dict, kSCPropNetLinkActive);
				if (isA_CFBoolean(bVal)) {
					linkStatus = CFBooleanGetValue(bVal);
				}

				/* check if interface is detaching - value
				   doesn't really matter, only that it exists */
				ifDetaching = CFDictionaryContainsKey(dict, kSCPropNetLinkDetaching);
			}
			CFRelease(dict);

			if (!linkStatus || ifDetaching) {
				/* if link status down or the interface is detaching */
				goto nextIF;
			}
		}

		/*
		 * Determine configuration method for this service
		 */
		configMethod = CFDictionaryGetValue(service, kSCPropNetAppleTalkConfigMethod);
		if (!isA_CFString(configMethod)) {
			/* if no ConfigMethod */
			goto nextIF;
		}

		if (!CFEqual(configMethod, kSCValNetAppleTalkConfigMethodNode      ) &&
		    !CFEqual(configMethod, kSCValNetAppleTalkConfigMethodRouter    ) &&
		    !CFEqual(configMethod, kSCValNetAppleTalkConfigMethodSeedRouter)) {
			/* if not one of the expected values, disable */
			SCLog(TRUE, LOG_NOTICE,
			      CFSTR("Unexpected AppleTalk ConfigMethod: %@"),
			      configMethod);
			goto nextIF;
		}

		/*
		 * the first service to be defined will always be "primary"
		 */
		if (CFArrayGetCount(newConfigFile) == 0) {
			CFDictionaryRef	active;

			CFDictionarySetValue(newGlobals,
					     kSCDynamicStorePropNetPrimaryService,
					     CFDictionaryGetValue(service, CFSTR("ServiceID")));
			CFDictionarySetValue(newGlobals,
					     kSCDynamicStorePropNetPrimaryInterface,
					     ifName);

			/* and check if AT newtorking is active on the primary interface */
			key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
									    kSCDynamicStoreDomainState,
									    ifName,
									    kSCEntNetAppleTalk);
			active = cache_SCDynamicStoreCopyValue(store, key);
			CFRelease(key);
			if (active) {
				if (isA_CFDictionary(active)) {
					postGlobals = TRUE;
				}
				CFRelease(active);
			}
		}

		/*
		 * define the port
		 */
		portConfig = CFStringCreateMutable(NULL, 0);
		CFStringAppendFormat(portConfig, NULL, CFSTR("%@:"), ifName);

		if (CFEqual(configMethod, kSCValNetAppleTalkConfigMethodSeedRouter)) {
			CFNumberRef	num;

			/*
			 * we have been asked to configure this interface as a
			 * seed port. Ensure that we have been provided at least
			 * one network number, have been provided with at least
			 * one zonename, ...
			 */

			networkRange = CFDictionaryGetValue(service,
							    kSCPropNetAppleTalkSeedNetworkRange);
			if (!isA_CFArray(networkRange) || (CFArrayGetCount(networkRange) == 0)) {
				SCLog(TRUE, LOG_NOTICE,
				      CFSTR("AppleTalk configuration error (%@)"),
				      kSCPropNetAppleTalkSeedNetworkRange);
				goto nextIF;
			}

			/*
			 * establish the starting and ending network numbers
			 */
			num = CFArrayGetValueAtIndex(networkRange, 0);
			if (!isA_CFNumber(num)) {
				SCLog(TRUE, LOG_NOTICE,
				      CFSTR("AppleTalk configuration error (%@)"),
				      kSCPropNetAppleTalkSeedNetworkRange);
				goto nextIF;
			}
			CFNumberGetValue(num, kCFNumberIntType, &sNetwork);
			eNetwork = sNetwork;

			if (CFArrayGetCount(networkRange) > 1) {
				num = CFArrayGetValueAtIndex(networkRange, 1);
				if (!isA_CFNumber(num)) {
					SCLog(TRUE, LOG_NOTICE,
					      CFSTR("AppleTalk configuration error (%@)"),
					      kSCPropNetAppleTalkSeedNetworkRange);
					goto nextIF;
				}
				CFNumberGetValue(num, kCFNumberIntType, &eNetwork);
			}
			CFStringAppendFormat(portConfig, NULL, CFSTR("%d:%d:"), sNetwork, eNetwork);

			/*
			 * establish the zones associated with this port
			 */
			zoneList = CFDictionaryGetValue(service,
							kSCPropNetAppleTalkSeedZones);
			if (!isA_CFArray(zoneList)) {
				SCLog(TRUE, LOG_NOTICE,
				      CFSTR("AppleTalk configuration error (%@)"),
				      kSCPropNetAppleTalkSeedZones);
				goto nextIF;
			}

			zCount = CFArrayGetCount(zoneList);
			for (j = 0; j < zCount; j++) {
				CFStringRef		zone;
				CFArrayRef		ifList;
				CFMutableArrayRef	newIFList;

				zone = CFArrayGetValueAtIndex(zoneList, j);
				if (!isA_CFString(zone)) {
					continue;
				}

				if (CFDictionaryGetValueIfPresent(newZones, zone, (const void **)&ifList)) {
					/* known zone */
					newIFList = CFArrayCreateMutableCopy(NULL, 0, ifList);
				} else {
					/* new zone */
					newIFList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
				}
				CFArrayAppendValue(newIFList, ifName);
				CFArraySortValues(newIFList,
						  CFRangeMake(0, CFArrayGetCount(newIFList)),
						  (CFComparatorFunction)CFStringCompare,
						  NULL);
				CFDictionarySetValue(newZones, zone, newIFList);
				CFRelease(newIFList);

				/*
				 * flag the default zone
				 */
				if (!primaryZone) {
					primaryZone = CFRetain(zone);
				}
			}
			if (!primaryZone) {
				SCLog(TRUE, LOG_NOTICE,
				      CFSTR("AppleTalk configuration error (%@)"),
				      kSCPropNetAppleTalkSeedZones);
				goto nextIF;
			}
		}

		/* get the (per-interface) "Computer Name" */
		computerName = CFDictionaryGetValue(service,
						    kSCPropNetAppleTalkComputerName);
		if (CFDictionaryGetValueIfPresent(service,
						  kSCPropNetAppleTalkComputerNameEncoding,
						  (const void **)&num) &&
		    isA_CFNumber(num)) {
			CFNumberGetValue(num, kCFNumberIntType, &computerNameEncoding);
		} else {
			computerNameEncoding = CFStringGetSystemEncoding();
		}
		encodeName(computerName, computerNameEncoding, newStartup, newGlobals);

		/*
		 * declare the first configured AppleTalk service / interface
		 * as the "home port".
		 */
		if (CFArrayGetCount(newConfigFile) == 0) {
			CFStringAppend(portConfig, CFSTR("*"));
			primaryPort = CFRetain(ifName);
		}
		CFArrayAppendValue(newConfigFile, portConfig);

		/*
		 * get the per-interface defaults
		 */
		ifDefaults = CFDictionaryCreateMutable(NULL,
						       0,
						       &kCFTypeDictionaryKeyCallBacks,
						       &kCFTypeDictionaryValueCallBacks);

		defaultNetwork = CFDictionaryGetValue(service, kSCPropNetAppleTalkNetworkID);
		defaultNode    = CFDictionaryGetValue(service, kSCPropNetAppleTalkNodeID);
		if (isA_CFNumber(defaultNetwork) && isA_CFNumber(defaultNode)) {
			/*
			 * set the default node and network
			 */
			CFDictionarySetValue(ifDefaults,
					     kSCPropNetAppleTalkNetworkID,
					     defaultNetwork);
			CFDictionarySetValue(ifDefaults,
					     kSCPropNetAppleTalkNodeID,
					     defaultNode);
		}

		if ((CFDictionaryGetValueIfPresent(service,
						   kSCPropNetAppleTalkDefaultZone,
						   (const void **)&defaultZone) == TRUE)) {
			/*
			 * set the default zone for this interface
			 */
			CFDictionarySetValue(ifDefaults,
					     kSCPropNetAppleTalkDefaultZone,
					     defaultZone);
		}

		CFDictionarySetValue(newDefaults, ifName, ifDefaults);
		CFRelease(ifDefaults);

		switch (CFArrayGetCount(newConfigFile)) {
			case 1:
				/*
				 * first AppleTalk interface
				 */
				CFDictionarySetValue(newStartup, CFSTR("APPLETALK"), ifName);
				break;
			case 2:
				/* second AppleTalk interface */
				if (!CFEqual(CFDictionaryGetValue(newStartup, CFSTR("APPLETALK")),
					     CFSTR("-ROUTER-"))) {
					/*
					 * if not routing (yet), configure as multi-home
					 */
					CFDictionarySetValue(newStartup, CFSTR("APPLETALK"), CFSTR("-MULTIHOME-"));
				}
				break;
		}

		if (CFEqual(configMethod, kSCValNetAppleTalkConfigMethodRouter) ||
		    CFEqual(configMethod, kSCValNetAppleTalkConfigMethodSeedRouter)) {
			/* if not a simple node, enable routing */
			CFDictionarySetValue(newStartup, CFSTR("APPLETALK"), CFSTR("-ROUTER-"));
		}

		/*
		 * establish the State:/Network/Service/nnn/AppleTalk key info
		 */
		key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
								  kSCDynamicStoreDomainState,
								  CFDictionaryGetValue(service, CFSTR("ServiceID")),
								  kSCEntNetAppleTalk);
		newDict = CFDictionaryCreateMutable(NULL,
						    0,
						    &kCFTypeDictionaryKeyCallBacks,
						    &kCFTypeDictionaryValueCallBacks);
		CFDictionaryAddValue(newDict, kSCPropInterfaceName, ifName);
		cache_SCDynamicStoreSetValue(store, key, newDict);
		CFRelease(newDict);
		if (info) {
			j = CFArrayGetFirstIndexOfValue(info,
							CFRangeMake(0, CFArrayGetCount(info)),
							key);
			if (j != kCFNotFound) {
				CFArrayRemoveValueAtIndex(info, j);
			}
		}
		CFRelease(key);

	    nextIF :

		if (portConfig)	CFRelease(portConfig);
	}

	if (primaryZone) {
		CFArrayRef		ifList;
		CFMutableArrayRef	newIFList;

		ifList = CFDictionaryGetValue(newZones, primaryZone);
		if (CFArrayContainsValue(ifList,
					 CFRangeMake(0, CFArrayGetCount(ifList)),
					 primaryPort)) {
			newIFList = CFArrayCreateMutableCopy(NULL, 0, ifList);
			CFArrayAppendValue(newIFList, CFSTR("*"));
			CFDictionarySetValue(newZones, primaryZone, newIFList);
			CFRelease(newIFList);
		}
		CFRelease(primaryZone);
	}
	if (primaryPort) {
		CFRelease(primaryPort);
	}

	/* sort the ports */
	i = CFArrayGetCount(newConfigFile);
	CFArraySortValues(newConfigFile,
			  CFRangeMake(0, i),
			  (CFComparatorFunction)CFStringCompare,
			  NULL);

	/* add the zones to the configuration */
	CFDictionaryApplyFunction(newZones, addZoneToPorts, newConfigFile);
	CFRelease(newZones);

	/* sort the zones */
	CFArraySortValues(newConfigFile,
			  CFRangeMake(i, CFArrayGetCount(newConfigFile)-i),
			  (CFComparatorFunction)CFStringCompare,
			  NULL);

	/* ensure that the last line of the configuration file is terminated */
	CFArrayAppendValue(newConfigFile, CFSTR(""));

	/*
	 * Check if we have a "ComputerName" and look elsewhere if we don't have
	 * one yet.
	 */
	if (!CFDictionaryContainsKey(newStartup, CFSTR("APPLETALK_HOSTNAME")) &&
	    (setGlobals != NULL)) {
		computerName = CFDictionaryGetValue(setGlobals,
						    kSCPropNetAppleTalkComputerName);
		if (CFDictionaryGetValueIfPresent(setGlobals,
						  kSCPropNetAppleTalkComputerNameEncoding,
						  (const void **)&num) &&
		    isA_CFNumber(num)) {
			CFNumberGetValue(num, kCFNumberIntType, &computerNameEncoding);
		} else {
			computerNameEncoding = CFStringGetSystemEncoding();
		}
		encodeName(computerName, computerNameEncoding, newStartup, newGlobals);
	}
	if (!CFDictionaryContainsKey(newStartup, CFSTR("APPLETALK_HOSTNAME"))) {
		computerName = SCDynamicStoreCopyComputerName(store, &computerNameEncoding);
		if (computerName) {
			encodeName(computerName, computerNameEncoding, newStartup, newGlobals);
			CFRelease(computerName);
		}
	}
	if (!CFDictionaryContainsKey(newStartup, CFSTR("APPLETALK_HOSTNAME"))) {
		struct utsname	name;

		if (uname(&name) == 0) {
			computerName = CFStringCreateWithCString(NULL, name.nodename, kCFStringEncodingASCII);
			if (computerName) {
				encodeName(computerName, kCFStringEncodingASCII, NULL, newGlobals);
				CFRelease(computerName);
			}
		}
	}

	/* compare the previous and current configurations */

	curGlobalsX = CFDictionaryCreateMutableCopy(NULL, 0, curGlobals);
	CFDictionaryRemoveValue(curGlobalsX, kSCDynamicStorePropNetPrimaryService);

	newGlobalsX = CFDictionaryCreateMutableCopy(NULL, 0, newGlobals);
	CFDictionaryRemoveValue(newGlobalsX, kSCDynamicStorePropNetPrimaryService);

	key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
							 kSCDynamicStoreDomainState,
							 kSCEntNetAppleTalk);

	if (CFEqual(curGlobalsX   , newGlobalsX   ) &&
	    CFEqual(curConfigFile , newConfigFile) &&
	    CFEqual(curDefaults   , newDefaults  ) &&
	    CFEqual(curStartup    , newStartup   )
	    ) {
		/*
		 * the configuration has not changed.
		 */

		if (postGlobals) {
			/*
			 * the requested configuration hasn't changed but we
			 * now need to tell everyone that AppleTalk is active.
			 */
			if (!SCDynamicStoreSetValue(store, key, newGlobals)) {
				SCLog(TRUE,
				      LOG_ERR,
				      CFSTR("SCDynamicStoreSetValue() failed: %s"),
				      SCErrorString(SCError()));
			}
		}

		CFRelease(newGlobals);
		CFRelease(newConfigFile);
		CFRelease(newDefaults);
		CFRelease(newStartup);
	} else if (CFArrayGetCount(newConfigFile) <= 1) {
		/*
		 * the configuration has changed but there are no
		 * longer any interfaces configured for AppleTalk
		 * networking.
		 */

		/*
		 * remove the global (State:/Network/Global/AppleTalk) key.
		 *
		 * Note: it will be restored later after AT networking has
		 *       been activated.
		 */

		/* remove the (/etc/appletalk.cfg) configuration file */
		(void)unlink(AT_CFG_FILE);

		/*
		 * update the per-service (and global) state
		 */
		cache_SCDynamicStoreRemoveValue(store, key);	// remove State:/Network/Global/AppleTalk
		n = CFArrayGetCount(info);
		for (i = 0; i < n; i++) {
			CFStringRef	xKey	= CFArrayGetValueAtIndex(info, i);

			cache_SCDynamicStoreRemoveValue(store, xKey);
		}
		cache_write(store);

		/* flag this as a new configuration */
		*newState = -(abs(curState) + 1);
		changed = TRUE;
	} else {
		/*
		 * the configuration has changed.
		 */

		/* update the (/etc/appletalk.cfg) configuration file */
		configWrite(AT_CFG_FILE, newConfigFile);

		/*
		 * update the per-service (and global) state
		 *
		 * Note: if present, we remove any existing global state key and allow it
		 *       to be restored after the stack has been re-started.
		 */
		CFDictionaryApplyFunction(newDefaults, updateDefaults, NULL);
		cache_SCDynamicStoreRemoveValue(store, key);	// remove State:/Network/Global/AppleTalk
		n = CFArrayGetCount(info);
		for (i = 0; i < n; i++) {
			CFStringRef	xKey	= CFArrayGetValueAtIndex(info, i);

			cache_SCDynamicStoreRemoveValue(store, xKey);
		}
		cache_write(store);

		/* flag this as a new configuration */
		*newState = abs(curState) + 1;
		changed = TRUE;
	}

	CFRelease(curGlobalsX);
	CFRelease(newGlobalsX);
	CFRelease(key);

	if (changed) {
		CFRelease(curGlobals);
		curGlobals    = newGlobals;
		CFRelease(curConfigFile);
		curConfigFile = newConfigFile;
		CFRelease(curDefaults);
		curDefaults   = newDefaults;
		CFRelease(curStartup);
		curStartup    = newStartup;
	}

	if (info)		CFRelease(info);
	if (interfaces)		CFRelease(interfaces);
	if (configuredServices)	CFRelease(configuredServices);
	if (setGlobals)		CFRelease(setGlobals);

	cache_close();

	return changed;
}
예제 #24
0
static void
smb_set_configuration(SCDynamicStoreRef store, CFDictionaryRef dict)
{
	CFArrayRef		array;
	Boolean			changed		= FALSE;
	UInt32			dosCodepage	= 0;
	CFStringEncoding	dosEncoding	= 0;
	CFStringEncoding	macEncoding	= kCFStringEncodingMacRoman;
	uint32_t		macRegion	= 0;
	Boolean			ok;
	SCPreferencesRef	prefs;
	CFStringRef		str;

	prefs = SCPreferencesCreate(NULL, CFSTR("smb-configuration"), CFSTR(kSMBPreferencesAppID));
	if (prefs == NULL) {
		my_log(LOG_ERR,
		       "smb_set_configuration: SCPreferencesCreate() failed: %s",
		       SCErrorString(SCError()));
		return;
	}

	ok = SCPreferencesLock(prefs, TRUE);
	if (!ok) {
		my_log(LOG_ERR,
		       "smb_set_configuration: SCPreferencesLock() failed: %s",
		       SCErrorString(SCError()));
		goto done;
	}

	// Server description
	str = SCDynamicStoreCopyComputerName(store, &macEncoding);
	update_pref(prefs, CFSTR(kSMBPrefServerDescription), str, &changed);

	// DOS code page
	if (str != NULL) {
		if (macEncoding == kCFStringEncodingMacRoman) {
			CFStringRef	key;
			CFDictionaryRef	dict;

			// get region
			key = SCDynamicStoreKeyCreateComputerName(NULL);
			dict = SCDynamicStoreCopyValue(store, key);
			CFRelease(key);
			if (dict != NULL) {
				if (isA_CFDictionary(dict)) {
					CFNumberRef	num;
					SInt32		val;

					num = CFDictionaryGetValue(dict, kSCPropSystemComputerNameRegion);
					if (isA_CFNumber(num) &&
					    CFNumberGetValue(num, kCFNumberSInt32Type, &val)) {
						macRegion = (uint32_t)val;
					}
				}

				CFRelease(dict);
			}
		}

		CFRelease(str);
	} else {
		// Important: must have root acccess (eUID==0) to access the config file!
		__CFStringGetInstallationEncodingAndRegion((uint32_t *)&macEncoding, &macRegion);
	}
	_SC_dos_encoding_and_codepage(macEncoding, macRegion, &dosEncoding, &dosCodepage);
	str = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), (unsigned int)dosCodepage);
	assert(str != NULL);
	update_pref(prefs, CFSTR(kSMBPrefDOSCodePage), str, &changed);
	CFRelease(str);

	// NetBIOS name
	str = CFDictionaryGetValue(dict, kSCPropNetSMBNetBIOSName);
	str = isA_CFString(str);
	update_pref(prefs, CFSTR(kSMBPrefNetBIOSName), str, &changed);

	// NetBIOS node type
	str = CFDictionaryGetValue(dict, kSCPropNetSMBNetBIOSNodeType);
	str = isA_CFString(str);
	if (str != NULL) {
		if (CFEqual(str, kSCValNetSMBNetBIOSNodeTypeBroadcast)) {
			// B-node
			str = CFSTR(kSMBPrefNetBIOSNodeBroadcast);
		} else if (CFEqual(str, kSCValNetSMBNetBIOSNodeTypePeer)) {
			// P-node
			str = CFSTR(kSMBPrefNetBIOSNodePeer);
		} else if (CFEqual(str, kSCValNetSMBNetBIOSNodeTypeMixed)) {
			// M-node
			str = CFSTR(kSMBPrefNetBIOSNodeMixed);
		} else if (CFEqual(str, kSCValNetSMBNetBIOSNodeTypeHybrid)) {
			// H-node
			str = CFSTR(kSMBPrefNetBIOSNodeHybrid);
		} else {
			str = NULL;
		}
	}
	update_pref(prefs, CFSTR(kSMBPrefNetBIOSNodeType), str, &changed);

#ifdef	ADD_NETBIOS_SCOPE
	// NetBIOS scope
	str = CFDictionaryGetValue(dict, kSCPropNetSMBNetBIOSScope);
	str = isA_CFString(str);
	update_pref(prefs, CFSTR(kSMBPrefNetBIOSScope), str, &changed);
#endif	// ADD_NETBIOS_SCOPE

	// WINS addresses
	array = CFDictionaryGetValue(dict, kSCPropNetSMBWINSAddresses);
	array = isA_CFArray(array);
	update_pref(prefs, CFSTR(kSMBPrefWINSServerAddressList), array, &changed);

	// Workgroup (or domain)
	str = CFDictionaryGetValue(dict, kSCPropNetSMBWorkgroup);
	str = isA_CFString(str);
	update_pref(prefs, CFSTR(kSMBPrefWorkgroup), str, &changed);

	if (changed) {
		ok = SCPreferencesCommitChanges(prefs);
		if (!ok) {
			if ((SCError() != EROFS)) {
				my_log(LOG_ERR,
				       "smb_set_configuration: SCPreferencesCommitChanges() failed: %s",
				       SCErrorString(SCError()));
			}
			goto done;
		}

		ok = SCPreferencesApplyChanges(prefs);
		if (!ok) {
			my_log(LOG_ERR,
			       "smb_set_configuration: SCPreferencesApplyChanges() failed: %s",
			       SCErrorString(SCError()));
			goto done;
		}
	}

    done :

	(void) SCPreferencesUnlock(prefs);
	CFRelease(prefs);
	return;
}
예제 #25
0
/*
 * Function: EAPOLClientConfigurationSetLoginWindowProfiles
 *
 * Purpose:
 *   Set the list of profiles configured for LoginWindow mode on the
 *   specified BSD network interface (e.g. "en0", "en1").
 *
 *   If you pass NULL for the "profiles" argument, the LoginWindow profile
 *   list is cleared.
 */
Boolean
EAPOLClientConfigurationSetLoginWindowProfiles(EAPOLClientConfigurationRef cfg,
					       CFStringRef if_name,
					       CFArrayRef profiles)
{
    CFDictionaryRef		dict;
    CFArrayRef			existing_profile_ids = NULL;
    SCNetworkInterfaceRef	net_if = NULL;
    CFMutableDictionaryRef	new_dict = NULL;
    CFMutableArrayRef		profile_ids = NULL;
    Boolean			ret = FALSE;

    dict = get_eapol_configuration(get_sc_prefs(cfg), if_name, &net_if);
    if (net_if == NULL) {
	goto done;
    }
    if (dict != NULL) {
	existing_profile_ids
	    = CFDictionaryGetValue(dict, kLoginWindowProfileIDs);
	existing_profile_ids = isA_CFArray(existing_profile_ids);
    }
    if (profiles == NULL || CFArrayGetCount(profiles) == 0) {
	profile_ids = NULL;
    }
    else {
	int				count;
	int				i;
	CFRange				r = { 0, 0 };

	count = CFArrayGetCount(profiles);
	profile_ids = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks);
	for (i = 0; i < count; i++) {
	    EAPOLClientProfileRef	profile;
	    CFStringRef			profileID;

	    profile = (EAPOLClientProfileRef)
		CFArrayGetValueAtIndex(profiles, i);
	    profileID = EAPOLClientProfileGetID(profile);
	    if (CFArrayContainsValue(profile_ids, r, profileID) == FALSE) {
		CFArrayAppendValue(profile_ids, profileID);
		r.length++;
	    }
	}
    }
    if (my_CFEqual(existing_profile_ids, profile_ids)) {
	ret = TRUE;
	goto done;
    }
    if (dict != NULL) {
	/*
	 * remove the AcceptEAPTypes array to give EAPOLController a way to
	 * know whether we're using new configuration or the old
	 */
	new_dict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
	CFDictionaryRemoveValue(new_dict, kEAPClientPropAcceptEAPTypes);
	CFDictionaryRemoveValue(new_dict, kSCResvInactive);
    }
    else {
	new_dict = CFDictionaryCreateMutable(NULL, 0,
					     &kCFTypeDictionaryKeyCallBacks,
					     &kCFTypeDictionaryValueCallBacks);
    }
    if (profile_ids == NULL) {
	CFDictionaryRemoveValue(new_dict, kLoginWindowProfileIDs);
	if (CFDictionaryGetCount(new_dict) == 0) {
	    my_CFRelease(&new_dict);
	}
    }
    else {
	CFDictionarySetValue(new_dict, kLoginWindowProfileIDs, profile_ids);
    }
    if (setInterfaceEAPOLConfiguration(cfg, net_if, new_dict)
	== FALSE) {
	goto done;
    }
    ret = TRUE;

 done:
    my_CFRelease(&new_dict);
    my_CFRelease(&profile_ids);
    my_CFRelease(&net_if);
    return (ret);
}