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; }
static Boolean establishNewPreferences() { CFBundleRef bundle; SCNetworkSetRef current = NULL; CFStringRef new_model; Boolean ok = FALSE; int sc_status = kSCStatusFailed; SCNetworkSetRef set = NULL; CFStringRef setName = NULL; Boolean updated = FALSE; while (TRUE) { ok = SCPreferencesLock(prefs, TRUE); if (ok) { break; } sc_status = SCError(); if (sc_status == kSCStatusStale) { SCPreferencesSynchronize(prefs); } else { SCLog(TRUE, LOG_ERR, CFSTR("Could not acquire network configuration lock: %s"), SCErrorString(sc_status)); return FALSE; } } /* Ensure that the preferences has the new model */ new_model = _SC_hw_model(FALSE); /* Need to regenerate the new configuration for new model */ if (new_model != NULL) { CFStringRef old_model; old_model = SCPreferencesGetValue(prefs, MODEL); if ((old_model != NULL) && !_SC_CFEqual(old_model, new_model)) { CFIndex count; CFIndex index; CFArrayRef keys; keys = SCPreferencesCopyKeyList(prefs); count = (keys != NULL) ? CFArrayGetCount(keys) : 0; // if new hardware for (index = 0; index < count; index++) { CFStringRef existing_key; existing_key = CFArrayGetValueAtIndex(keys, index); if (isA_CFString(existing_key) != NULL) { CFStringRef new_key; CFPropertyListRef value; /* If it already contains a Model or if it already contains a MODEL:KEY key skip it*/ if (CFEqual(existing_key, MODEL) || CFStringFind(existing_key, CFSTR(":"), 0).location != kCFNotFound) { continue; } value = SCPreferencesGetValue(prefs, existing_key); /* Create a new key as OLD_MODEL:OLD_KEY */ new_key = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@:%@"), old_model, existing_key); SCPreferencesSetValue(prefs, new_key, value); if (!CFEqual(existing_key, kSCPrefSystem)) { /* preserve existing host names */ SCPreferencesRemoveValue(prefs, existing_key); } CFRelease(new_key); } } if (keys != NULL) { CFRelease(keys); } } /* Set the new model */ SCPreferencesSetValue(prefs, MODEL, new_model); } current = SCNetworkSetCopyCurrent(prefs); if (current != NULL) { set = current; } if (set == NULL) { set = SCNetworkSetCreate(prefs); if (set == NULL) { ok = FALSE; sc_status = SCError(); goto done; } bundle = _SC_CFBundleGet(); if (bundle != NULL) { setName = CFBundleCopyLocalizedString(bundle, CFSTR("DEFAULT_SET_NAME"), CFSTR("Automatic"), NULL); } ok = SCNetworkSetSetName(set, (setName != NULL) ? setName : CFSTR("Automatic")); if (!ok) { sc_status = SCError(); goto done; } ok = SCNetworkSetSetCurrent(set); if (!ok) { sc_status = SCError(); goto done; } } ok = SCNetworkSetEstablishDefaultConfiguration(set); if (!ok) { sc_status = SCError(); goto done; } done : if (ok) { ok = SCPreferencesCommitChanges(prefs); if (ok) { SCLog(TRUE, LOG_NOTICE, CFSTR("New network configuration saved")); updated = TRUE; } else { sc_status = SCError(); if (sc_status == EROFS) { /* a read-only fileysstem is OK */ ok = TRUE; /* ... but we don't want to synchronize */ rofs = TRUE; } } /* apply (committed or temporary/read-only) changes */ (void) SCPreferencesApplyChanges(prefs); } else if ((current == NULL) && (set != NULL)) { (void) SCNetworkSetRemove(set); } if (!ok) { SCLog(TRUE, LOG_ERR, CFSTR("Could not establish network configuration: %s"), SCErrorString(sc_status)); } (void)SCPreferencesUnlock(prefs); if (setName != NULL) CFRelease(setName); if (set != NULL) CFRelease(set); return updated; }