CFStringRef
EAPOLClientItemIDGetProfileID(EAPOLClientItemIDRef itemID)
{
    switch (itemID->type) {
    case kEAPOLClientItemIDTypeProfileID:
	return (itemID->u.profileID);
    case kEAPOLClientItemIDTypeProfile:
	return (EAPOLClientProfileGetID(itemID->u.profile));
    default:
	break;
    }
    return (NULL);
}
/**
 ** Internal SPI
 **/
PRIVATE_EXTERN void
EAPOLClientConfigurationSetProfileForSSID(EAPOLClientConfigurationRef cfg,
					  CFDataRef ssid,
					  EAPOLClientProfileRef profile)
{
    if (profile == NULL) {
	CFDictionaryRemoveValue(cfg->ssids, ssid);
    }
    else {
	CFDictionarySetValue(cfg->ssids, ssid,
			     EAPOLClientProfileGetID(profile));
    }
    return;
}
PRIVATE_EXTERN void
EAPOLClientConfigurationSetProfileForWLANDomain(EAPOLClientConfigurationRef cfg,
						CFStringRef domain,
						EAPOLClientProfileRef profile)
{
    if (profile == NULL) {
	CFDictionaryRemoveValue(cfg->domains, domain);
    }
    else {
	CFDictionarySetValue(cfg->domains, domain,
			     EAPOLClientProfileGetID(profile));
    }
    return;
}
/*
 * Function: EAPOLClientConfigurationRemoveProfile
 *
 * Purpose:
 *   Remove the specified profile from the configuration.
 *
 * Returns:
 *   FALSE if the profile is invalid or not in the configuration,
 *   TRUE otherwise.
 */
Boolean
EAPOLClientConfigurationRemoveProfile(EAPOLClientConfigurationRef cfg,
				      EAPOLClientProfileRef profile)
{
    CFStringRef			profileID = EAPOLClientProfileGetID(profile);
    CFDataRef			ssid;
    
    if (EAPOLClientConfigurationGetProfileWithID(cfg, profileID) != profile) {
	/* trying to remove profile that isn't part of the configuration */
	return (FALSE);
    }
    ssid = EAPOLClientProfileGetWLANSSIDAndSecurityType(profile, NULL);
    if (ssid != NULL) {
	CFDictionaryRemoveValue(cfg->ssids, ssid);
    }
    CFDictionaryRemoveValue(cfg->profiles, profileID);
    return (TRUE);
}
/*
 * Function: EAPOLClientConfigurationAddProfile
 *
 * Purpose:
 *   Add the specified profile to the configuration.
 *
 * Returns:
 *   FALSE if the profile could not be added, either because:
 *   - the profile is already in the configuration, or
 *   - the profile conflicts with an existing profile (profileID or WLAN SSID)
 *   TRUE if the profile was added successfully.
 */
Boolean
EAPOLClientConfigurationAddProfile(EAPOLClientConfigurationRef cfg,
				   EAPOLClientProfileRef profile)
{
    CFStringRef		domain = NULL;
    CFStringRef		profileID = EAPOLClientProfileGetID(profile);
    CFDataRef		ssid;

    if (profile->cfg != NULL) {
	/* profile is already part of the configuration */
	return (FALSE);
    }
    if (EAPOLClientConfigurationGetProfileWithID(cfg, profileID) != NULL) {
	/* profile already present with that profileID */
	return (FALSE);
    }
    ssid = EAPOLClientProfileGetWLANSSIDAndSecurityType(profile, NULL);
    if (ssid != NULL) {
	if (EAPOLClientConfigurationGetProfileWithWLANSSID(cfg, ssid) != NULL) {
	    /* profile already present with that SSID */
	    return (FALSE);
	}
    }
    else {
	domain = EAPOLClientProfileGetWLANDomain(profile);
	if (domain != NULL) {
	    if (EAPOLClientConfigurationGetProfileWithWLANDomain(cfg, domain)
		!= NULL) {
		/* profile already exists with that domain */
		return (FALSE);
	    }
	}
    }
    CFDictionarySetValue(cfg->profiles, profileID, profile);
    if (ssid != NULL) {
	CFDictionarySetValue(cfg->ssids, ssid, profileID);
    }
    else if (domain != NULL) {
	CFDictionarySetValue(cfg->domains, domain, profileID);
    }
    EAPOLClientProfileSetConfiguration(profile, cfg);
    return (TRUE);
}
STATIC CFStringRef
__EAPOLClientItemIDCopyDebugDesc(CFTypeRef cf)
{
    CFAllocatorRef		allocator = CFGetAllocator(cf);
    EAPOLClientItemIDRef	itemID = (EAPOLClientItemIDRef)cf;
    CFStringRef			profileID;
    CFMutableStringRef		result;
    CFStringRef			ssid_str;

    result = CFStringCreateMutable(allocator, 0);
    CFStringAppendFormat(result, NULL, 
			 CFSTR("<EAPOLClientItemID %p [%p]> {"), cf, allocator);
    switch (itemID->type) {
    case kEAPOLClientItemIDTypeWLANSSID:
	ssid_str = my_CFStringCreateWithData(itemID->u.ssid);
	CFStringAppendFormat(result, NULL, CFSTR("WLAN SSID = %@"),
			     ssid_str);
	CFRelease(ssid_str);
	break;
    case kEAPOLClientItemIDTypeWLANDomain:
	CFStringAppendFormat(result, NULL, CFSTR("WLAN domain = %@"),
			     itemID->u.domain);
	break;
    case kEAPOLClientItemIDTypeProfileID:
	CFStringAppendFormat(result, NULL, CFSTR("ProfileID = %@"),
			     itemID->u.profileID);
	break;
    case kEAPOLClientItemIDTypeProfile:
	profileID = EAPOLClientProfileGetID(itemID->u.profile);
	CFStringAppendFormat(result, NULL, CFSTR("Profile = %@"),
			     profileID);
	break;
    case kEAPOLClientItemIDTypeDefault:
	CFStringAppend(result, CFSTR("Default"));
	break;
    default:
	break;
    }
    CFStringAppend(result, CFSTR("}"));
    return result;
}
/*
 * Function: EAPOLClientConfigurationCopyMatchingProfiles
 *
 * Purpose:
 *   Find the profile(s) matching the specified profile.
 *   A profile is matched based on the profileID, the WLAN SSID, and
 *   the WLAN domain, all of which must be unique in the configuration.
 *
 *   Usually invoked after calling 
 *   EAPOLClientProfileCreateWithPropertyList() to instantiate a profile
 *   from an external format.
 *
 * Returns:
 *   NULL if no matching profile is part of the configuration,
 *   non-NULL CFArrayRef of EAPOLClientProfileRef if found.
 */
CFArrayRef /* of EAPOLClientProfileRef */
EAPOLClientConfigurationCopyMatchingProfiles(EAPOLClientConfigurationRef cfg,
					     EAPOLClientProfileRef profile)
{
    int				count;
    EAPOLClientProfileRef	matching_profile;
    CFStringRef			profileID = EAPOLClientProfileGetID(profile);
    CFDataRef			ssid;
    const void *		values[2] = { NULL, NULL };
    
    count = 0;
    matching_profile = EAPOLClientConfigurationGetProfileWithID(cfg, profileID);
    if (matching_profile != NULL) {
	values[count] = matching_profile;
	count++;
    }
    matching_profile = NULL;
    ssid = EAPOLClientProfileGetWLANSSIDAndSecurityType(profile, NULL);
    if (ssid != NULL) {
	matching_profile 
	    = EAPOLClientConfigurationGetProfileWithWLANSSID(cfg, ssid);
    }
    else {
	CFStringRef		domain;
	
	domain = EAPOLClientProfileGetWLANDomain(profile);
	if (domain != NULL) {
	    matching_profile 
		= EAPOLClientConfigurationGetProfileWithWLANDomain(cfg, domain);
	}
    }
    if (matching_profile != NULL && values[0] != matching_profile) {
	values[count] = matching_profile;
	count++;
    }
    if (count == 0) {
	return (NULL);
    }
    return (CFArrayCreate(CFGetAllocator(cfg), values, count,
			  &kCFTypeArrayCallBacks));
}
/*
 * Function: EAPOLClientItemIDSetPasswordItem
 *
 * Purpose:
 *   Set the password item in secure storage for the specified itemID
 *   in the specified domain.
 *
 *   Passing an empty 'username' or 'password' removes the corresponding
 *   attribute.   If both 'username' and 'password' are empty, the item is
 *   also removed.  An empty value is a non-NULL CFDataRef of length 0.
 *
 *   Passing NULL for 'username' or 'password' means that the corresponding
 *   item attribute is left alone.  If both 'username" and 'password' are
 *   NULL, the call has no effect, but TRUE is still returned.
 *
 *   Passing non-NULL, non-empty 'username' or 'password' sets the
 *   corresponding item attribute to the specified value.   If the item
 *   does not exist, it will be created.
 *
 * Returns:
 *   FALSE if the operation did not succeed, TRUE otherwise.
 */
Boolean
EAPOLClientItemIDSetPasswordItem(EAPOLClientItemIDRef itemID,
				 EAPOLClientDomain domain,
				 CFDataRef name, CFDataRef password)
{
    CFMutableDictionaryRef	attrs = NULL;
    CFDataRef			data;
    SecKeychainRef		keychain = NULL;
    CFDataRef			ssid;
    OSStatus			status = errSecParam;
    CFStringRef			unique_string;

    if (name == NULL && password == NULL) {
	return (TRUE);
    }
    switch (domain) {
    case kEAPOLClientDomainUser:
	status = SecKeychainCopyDomainDefault(kSecPreferencesDomainUser,
					      &keychain);
	if (status != noErr) {
	    fprintf(stderr, "EAPOLClientItemIDSetPasswordItem can't get"
		    " User keychain,  %s (%d)\n",
		    EAPSecurityErrorString(status), (int)status);
	    return (FALSE);
	}
	break;
    case kEAPOLClientDomainSystem:
	if (EAPOLClientItemIDGetAuthorizationExternalForm(itemID) != NULL) {
	    return (authEAPOLClientItemIDSetPasswordItem(itemID, name,
							 password));
	}
	status = SecKeychainCopyDomainDefault(kSecPreferencesDomainSystem,
					      &keychain);
	if (status != noErr) {
	    fprintf(stderr, "EAPOLClientItemIDSetPasswordItem can't get"
		    " System keychain,  %s (%d)\n",
		    EAPSecurityErrorString(status), (int)status);
	    return (FALSE);
	}
	break;
    default:
	return (FALSE);
    }

    /* populate an attributes dictionary */
    attrs = CFDictionaryCreateMutable(NULL, 0,
				      &kCFTypeDictionaryKeyCallBacks,
				      &kCFTypeDictionaryValueCallBacks);

    /* Description */
    data = CFDataCreate(NULL, (UInt8 *)kItemDescription,
			kItemDescriptionLength);
    CFDictionarySetValue(attrs, kEAPSecKeychainPropDescription, data);
    CFRelease(data);

    /* Label */
    switch (itemID->type) {
    case kEAPOLClientItemIDTypeWLANSSID:
	CFDictionarySetValue(attrs, kEAPSecKeychainPropLabel,
			     itemID->u.ssid);
	break;
    case kEAPOLClientItemIDTypeWLANDomain: {
	CFDataRef		label_data;

	label_data = my_CFDataCreateWithString(itemID->u.domain);
	CFDictionarySetValue(attrs, kEAPSecKeychainPropLabel,
			     label_data);
	CFRelease(label_data);
	break;
    }
    case kEAPOLClientItemIDTypeProfileID: {
	CFDataRef		label_data;

	label_data = my_CFDataCreateWithString(itemID->u.profileID);
	CFDictionarySetValue(attrs, kEAPSecKeychainPropLabel, label_data);
	CFRelease(label_data);
	break;
    }
    case kEAPOLClientItemIDTypeProfile:
	ssid = EAPOLClientProfileGetWLANSSIDAndSecurityType(itemID->u.profile,
							    NULL);
	if (ssid != NULL) {
	    CFDictionarySetValue(attrs, kEAPSecKeychainPropLabel,
				 ssid);
	}
	else {
	    CFStringRef		label;
	    CFDataRef		label_data;
    
	    label = EAPOLClientProfileGetUserDefinedName(itemID->u.profile);
	    if (label == NULL) {
		label = EAPOLClientProfileGetWLANDomain(itemID->u.profile);
		if (label == NULL) {
		    label = EAPOLClientProfileGetID(itemID->u.profile);
		}
	    }
	    label_data = my_CFDataCreateWithString(label);
	    CFDictionarySetValue(attrs, kEAPSecKeychainPropLabel, label_data);
	    CFRelease(label_data);
	}
	break;
    case kEAPOLClientItemIDTypeDefault: {
	CFDataRef		label_data;

	/* XXX localize? */
	label_data = my_CFDataCreateWithString(CFSTR("Default"));
	CFDictionarySetValue(attrs, kEAPSecKeychainPropLabel, label_data);
	CFRelease(label_data);
	break;
    }
    default:
	goto done;
    }
    
    /* Account */
    if (name != NULL) {
	CFDictionarySetValue(attrs, kEAPSecKeychainPropAccount, name);
    }
    
    /* Password */
    if (password != NULL) {
	CFDictionarySetValue(attrs, kEAPSecKeychainPropPassword, password);
    };

    if (domain == kEAPOLClientDomainUser) {
	CFArrayRef			trusted_apps;

	/* Trusted Applications */
	trusted_apps = copy_trusted_applications(FALSE);
	if (trusted_apps != NULL) {
	    CFDictionarySetValue(attrs,
				 kEAPSecKeychainPropTrustedApplications,
				 trusted_apps);
	    CFRelease(trusted_apps);
	}
    }
    else {
	CFDictionarySetValue(attrs,
			     kEAPSecKeychainPropAllowRootAccess,
			     kCFBooleanTrue);
    }
    unique_string = EAPOLClientItemIDCopyUniqueString(itemID, domain, TRUE);
    status = EAPSecKeychainPasswordItemSet2(keychain, unique_string,
					    attrs);
    if (status == errSecItemNotFound) {
	status = EAPSecKeychainPasswordItemCreate(keychain,
						  unique_string,
						  attrs);
    }
    my_CFRelease(&unique_string);
    if (status != noErr) {
	EAPLOG(LOG_NOTICE,
	       "EAPOLClientItemID: failed to set keychain item, %d",
	       (int)status);
    }

 done:
    my_CFRelease(&attrs);
    my_CFRelease(&keychain);
    return (status == noErr);
}
STATIC CFStringRef
EAPOLClientItemIDCopyUniqueString(EAPOLClientItemIDRef itemID,
				  EAPOLClientDomain domain, bool is_item)
{
    const char *	domain_str;
    CFStringRef		result = NULL;
    CFStringRef		profileID;
    CFDataRef		ssid;
    CFStringRef		ssid_str;
    const char *	type_str;

    type_str = is_item ? "item" : "identity";
    domain_str = (domain == kEAPOLClientDomainSystem) ? "system" : "user";
    switch (itemID->type) {
    case kEAPOLClientItemIDTypeWLANSSID:
	ssid_str = my_CFStringCreateWithData(itemID->u.ssid);
	result = create_item_format(domain_str, type_str, WLAN_SSID_STR,
				    ssid_str);
	if (ssid_str != NULL) {
	    CFRelease(ssid_str);
	}
	break;
    case kEAPOLClientItemIDTypeWLANDomain:
	result = create_item_format(domain_str, type_str,
				    WLAN_DOMAIN_STR, itemID->u.domain);
	break;
    case kEAPOLClientItemIDTypeProfileID:
	result = create_item_format(domain_str, type_str, PROFILEID_STR,
				    itemID->u.profileID);
	break;
    case kEAPOLClientItemIDTypeProfile:
	ssid = EAPOLClientProfileGetWLANSSIDAndSecurityType(itemID->u.profile,
							    NULL);
	if (ssid != NULL) {
	    ssid_str = my_CFStringCreateWithData(ssid);
	    result = create_item_format(domain_str, type_str, WLAN_SSID_STR,
					ssid_str);
	    if (ssid_str != NULL) {
		CFRelease(ssid_str);
	    }
	}
	else {
	    CFStringRef		wlan_domain;

	    wlan_domain = EAPOLClientProfileGetWLANDomain(itemID->u.profile);
	    if (wlan_domain != NULL) {
		result = create_item_format(domain_str, type_str,
					    WLAN_DOMAIN_STR, wlan_domain);
	    }
	    else {
		profileID = EAPOLClientProfileGetID(itemID->u.profile);
		result = create_item_format(domain_str, type_str, PROFILEID_STR,
					    profileID);
	    }
	}
	break;
    case kEAPOLClientItemIDTypeDefault:
	result = create_item_format(domain_str, type_str, DEFAULT_STR, NULL);
	break;
    default:
	break;
    }
    return (result);
}
PRIVATE_EXTERN CFMutableDictionaryRef
EAPOLClientProfileCreateDictAndProfileID(EAPOLClientProfileRef profile,
					 CFStringRef * ret_profileID)
{
    CFArrayRef			accept_types = NULL;
    CFMutableDictionaryRef	dict;

    if (profile->auth_props != NULL) {
	accept_types = CFDictionaryGetValue(profile->auth_props,
					    kEAPClientPropAcceptEAPTypes);
    }
    if (accept_types_valid(accept_types) == FALSE) {
	SCLog(TRUE, LOG_NOTICE, 
	      CFSTR("EAPOLClientConfiguration: profile %@"
		    " missing/invalid AuthenticationProperties"),
	      EAPOLClientProfileGetID(profile));
	return (NULL);
    }
    dict = CFDictionaryCreateMutable(NULL, 0,
				     &kCFTypeDictionaryKeyCallBacks,
				     &kCFTypeDictionaryValueCallBacks);
    if (ret_profileID != NULL) {
	*ret_profileID = CFRetain(profile->uuid);
    }
    CFDictionarySetValue(dict, 
			 kProfileKeyAuthenticationProperties,
			 profile->auth_props);
    if (profile->user_defined_name != NULL) {
	CFDictionarySetValue(dict, 
			     kProfileKeyUserDefinedName,
			     profile->user_defined_name);
    }
    if (profile->information != NULL
	&& CFDictionaryGetCount(profile->information) != 0) {
	CFDictionarySetValue(dict,
			     kProfileKeyInformation,
			     profile->information);
    }
    if (profile->WLAN.ssid != NULL || profile->WLAN.domain != NULL) {
	int			count;
	const void *		keys[2];
	CFDictionaryRef		WLAN;
	const void *		values[2];

	if (profile->WLAN.ssid != NULL) {
	    keys[0] = kProfileKeyWLANSSID;
	    values[0] = profile->WLAN.ssid;
	    keys[1] = kProfileKeyWLANSecurityType;
	    values[1] = profile->WLAN.security_type;
	    count = 2;
	}
	else {
	    keys[0] = kProfileKeyWLANDomain;
	    values[0] = profile->WLAN.domain;
	    count = 1;
	}
	WLAN = CFDictionaryCreate(NULL, keys, values, count, 
				  &kCFTypeDictionaryKeyCallBacks,
				  &kCFTypeDictionaryValueCallBacks);
	CFDictionarySetValue(dict, kProfileKeyWLAN, WLAN);
	CFRelease(WLAN);
    }
    return (dict);
}
/*
 * Function: EAPOLClientConfigurationSetSystemProfile
 *
 * Purpose:
 *   Set the profile configured for System mode on the specified
 *   BSD network interface (e.g. "en0", "en1").
 *
 *   If you pass NULL for the "profile" argument, the System profile
 *   list is cleared.
 */
Boolean
EAPOLClientConfigurationSetSystemProfile(EAPOLClientConfigurationRef cfg,
					 CFStringRef if_name,
					 EAPOLClientProfileRef profile)
{
    CFDictionaryRef		dict;
    CFStringRef			existing_profileID = NULL;
    CFMutableDictionaryRef	new_dict = NULL;
    SCNetworkInterfaceRef	net_if = NULL;
    CFStringRef			profileID = NULL;
    Boolean			ret = FALSE;

    if (profile != NULL) {
	profileID = EAPOLClientProfileGetID(profile);
    }
    dict = get_eapol_configuration(get_sc_prefs(cfg), if_name, &net_if);
    if (net_if == NULL) {
	goto done;
    }
    if (CFEqual(SCNetworkInterfaceGetInterfaceType(net_if),
		kSCNetworkInterfaceTypeIEEE80211)) {
	/* disallow setting static System Mode on AirPort interfaces */
	goto done;
    }

    if (dict != NULL) {
	existing_profileID 
	    = CFDictionaryGetValue(dict, kSystemProfileID);
    }
    if (my_CFEqual(existing_profileID, profileID)) {
	/* nothing to do */
	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 (profileID == NULL) {
	CFDictionaryRemoveValue(new_dict, kSystemProfileID);
	if (CFDictionaryGetCount(new_dict) == 0) {
	    my_CFRelease(&new_dict);
	}
    }
    else {
	CFDictionarySetValue(new_dict, kSystemProfileID, profileID);
    }
    if (setInterfaceEAPOLConfiguration(cfg, net_if, new_dict)
	== FALSE) {
	goto done;
    }
    ret = TRUE;

 done:
    my_CFRelease(&new_dict);
    my_CFRelease(&net_if);
    return (ret);
}
/*
 * 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);
}