2 * Copyright (c) 2000-2008, 2011, 2013-2020 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * Modification History
27 * June 1, 2001 Allan Nathanson <ajn@apple.com>
28 * - public API conversion
30 * January 8, 2001 Allan Nathanson <ajn@apple.com>
35 #include <CoreFoundation/CoreFoundation.h>
36 #include <CoreFoundation/CFStringDefaultEncoding.h> // for __CFStringGetUserDefaultEncoding
37 #include "SCPreferencesInternal.h"
38 #include "SCNetworkConfigurationInternal.h"
39 #include "dy_framework.h"
49 static Boolean keepPrivate
= FALSE
;
50 static dispatch_once_t once
;
52 dispatch_once(&once
, ^{
53 SecTaskRef current_task
;
55 current_task
= SecTaskCreateFromSelf(NULL
);
56 if (current_task
!= NULL
) {
57 CFBooleanRef entitlement
;
59 entitlement
= SecTaskCopyValueForEntitlement(current_task
,
60 CFSTR("com.apple.security.on-demand-install-capable"),
62 if (entitlement
!= NULL
) {
63 if (isA_CFBoolean(entitlement
)) {
64 keepPrivate
= CFBooleanGetValue(entitlement
);
66 CFRelease(entitlement
);
68 CFRelease(current_task
);
74 #endif // __OPEN_SOURCE
77 #pragma mark ComputerName
80 static CFStringEncoding
81 getNameEncoding(CFDictionaryRef dict
)
83 CFStringEncoding encoding
;
86 if (!CFDictionaryGetValueIfPresent(dict
,
87 kSCPropSystemComputerNameEncoding
,
88 (const void **)&num
) ||
90 !CFNumberGetValue(num
, kCFNumberSInt32Type
, &encoding
)) {
91 encoding
= CFStringGetSystemEncoding();
99 _SCPreferencesCopyComputerName(SCPreferencesRef prefs
,
100 CFStringEncoding
*nameEncoding
)
102 CFDictionaryRef dict
;
103 CFStringRef name
= NULL
;
105 Boolean tempPrefs
= FALSE
;
108 prefs
= SCPreferencesCreate(NULL
, CFSTR("_SCPreferencesCopyComputerName"), NULL
);
115 path
= CFStringCreateWithFormat(NULL
,
120 dict
= SCPreferencesPathGetValue(prefs
, path
);
124 if (isA_CFDictionary(dict
)) {
125 name
= CFDictionaryGetValue(dict
, kSCPropSystemComputerName
);
126 name
= isA_CFString(name
);
132 if (nameEncoding
!= NULL
) {
133 *nameEncoding
= getNameEncoding(dict
);
137 if (tempPrefs
) CFRelease(prefs
);
138 _SCErrorSet(name
!= NULL
? kSCStatusOK
: kSCStatusNoKey
);
144 SCDynamicStoreKeyCreateComputerName(CFAllocatorRef allocator
)
146 return SCDynamicStoreKeyCreate(allocator
,
148 kSCDynamicStoreDomainSetup
,
154 SCDynamicStoreCopyComputerName(SCDynamicStoreRef store
,
155 CFStringEncoding
*nameEncoding
)
157 CFDictionaryRef dict
= NULL
;
159 CFStringRef name
= NULL
;
161 #ifndef __OPEN_SOURCE
165 #endif // __OPEN_SOURCE
167 key
= SCDynamicStoreKeyCreateComputerName(NULL
);
168 dict
= SCDynamicStoreCopyValue(store
, key
);
172 * Let's try looking in the preferences.plist file until
173 * (a) we add an API to retrieve the name regardless of
174 * where it is stored and
175 * (b) this API is deprecated
177 name
= _SCPreferencesCopyComputerName(NULL
, nameEncoding
);
180 if (!isA_CFDictionary(dict
)) {
181 _SCErrorSet(kSCStatusNoKey
);
185 name
= isA_CFString(CFDictionaryGetValue(dict
, kSCPropSystemComputerName
));
187 _SCErrorSet(kSCStatusNoKey
);
192 if (nameEncoding
!= NULL
) {
193 *nameEncoding
= getNameEncoding(dict
);
196 _SCErrorSet(kSCStatusOK
);
201 if (dict
!= NULL
) CFRelease(dict
);
207 SCPreferencesSetComputerName(SCPreferencesRef prefs
,
209 CFStringEncoding encoding
)
211 CFDictionaryRef dict
;
212 CFMutableDictionaryRef newDict
;
220 if (!isA_CFString(name
)) {
221 _SCErrorSet(kSCStatusInvalidArgument
);
225 len
= CFStringGetLength(name
);
231 path
= CFStringCreateWithFormat(NULL
,
237 dict
= SCPreferencesPathGetValue(prefs
, path
);
239 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
241 newDict
= CFDictionaryCreateMutable(NULL
,
243 &kCFTypeDictionaryKeyCallBacks
,
244 &kCFTypeDictionaryValueCallBacks
);
247 if ((name
!= NULL
) && (CFStringGetLength(name
) > 0)) {
248 CFDictionarySetValue(newDict
, kSCPropSystemComputerName
, name
);
250 num
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &encoding
);
251 CFDictionarySetValue(newDict
, kSCPropSystemComputerNameEncoding
, num
);
254 CFDictionaryRemoveValue(newDict
, kSCPropSystemComputerNameRegion
);
255 if (encoding
== kCFStringEncodingMacRoman
) {
256 UInt32 userEncoding
= 0;
257 UInt32 userRegion
= 0;
259 __CFStringGetUserDefaultEncoding(&userEncoding
, &userRegion
);
260 if ((userEncoding
== kCFStringEncodingMacRoman
) && (userRegion
!= 0)) {
261 num
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &userRegion
);
262 CFDictionarySetValue(newDict
, kSCPropSystemComputerNameRegion
, num
);
267 CFDictionaryRemoveValue(newDict
, kSCPropSystemComputerName
);
268 CFDictionaryRemoveValue(newDict
, kSCPropSystemComputerNameEncoding
);
269 CFDictionaryRemoveValue(newDict
, kSCPropSystemComputerNameRegion
);
272 ok
= __SCNetworkConfigurationSetValue(prefs
, path
, newDict
, FALSE
);
273 if (ok
&& __SCPreferencesUsingDefaultPrefs(prefs
)) {
275 SC_log(LOG_NOTICE
, "attempting to set the computer name to \"%@\"", name
);
277 SC_log(LOG_NOTICE
, "attempting to reset the computer name");
289 #pragma mark HostName
293 SCPreferencesGetHostName(SCPreferencesRef prefs
)
295 CFDictionaryRef dict
;
299 #ifndef __OPEN_SOURCE
303 #endif // __OPEN_SOURCE
305 path
= CFStringCreateWithFormat(NULL
,
310 dict
= SCPreferencesPathGetValue(prefs
, path
);
313 if (!isA_CFDictionary(dict
)) {
314 _SCErrorSet(kSCStatusNoKey
);
318 name
= isA_CFString(CFDictionaryGetValue(dict
, kSCPropSystemHostName
));
320 _SCErrorSet(kSCStatusNoKey
);
329 SCPreferencesSetHostName(SCPreferencesRef prefs
,
332 CFDictionaryRef dict
;
333 CFMutableDictionaryRef newDict
;
340 if (!isA_CFString(name
)) {
341 _SCErrorSet(kSCStatusInvalidArgument
);
345 len
= CFStringGetLength(name
);
351 path
= CFStringCreateWithFormat(NULL
,
357 dict
= SCPreferencesPathGetValue(prefs
, path
);
359 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
361 newDict
= CFDictionaryCreateMutable(NULL
,
363 &kCFTypeDictionaryKeyCallBacks
,
364 &kCFTypeDictionaryValueCallBacks
);
368 CFDictionarySetValue(newDict
, kSCPropSystemHostName
, name
);
370 CFDictionaryRemoveValue(newDict
, kSCPropSystemHostName
);
373 ok
= __SCNetworkConfigurationSetValue(prefs
, path
, newDict
, FALSE
);
374 if (ok
&& __SCPreferencesUsingDefaultPrefs(prefs
)) {
376 SC_log(LOG_NOTICE
, "attempting to set the host name to \"%@\"", name
);
378 SC_log(LOG_NOTICE
, "attempting to reset the host name");
390 #pragma mark LocalHostName
394 _SCPreferencesCopyLocalHostName(SCPreferencesRef prefs
)
396 CFDictionaryRef dict
;
397 CFStringRef name
= NULL
;
399 Boolean tempPrefs
= FALSE
;
402 prefs
= SCPreferencesCreate(NULL
, CFSTR("_SCPreferencesCopyLocalHostName"), NULL
);
409 path
= CFStringCreateWithFormat(NULL
,
415 dict
= SCPreferencesPathGetValue(prefs
, path
);
419 if (isA_CFDictionary(dict
)) {
420 name
= CFDictionaryGetValue(dict
, kSCPropNetLocalHostName
);
421 name
= isA_CFString(name
);
428 if (tempPrefs
) CFRelease(prefs
);
429 _SCErrorSet(name
!= NULL
? kSCStatusOK
: kSCStatusNoKey
);
435 SCDynamicStoreKeyCreateHostNames(CFAllocatorRef allocator
)
437 return SCDynamicStoreKeyCreate(allocator
,
439 kSCDynamicStoreDomainSetup
,
446 SCDynamicStoreCopyLocalHostName(SCDynamicStoreRef store
)
448 CFDictionaryRef dict
= NULL
;
450 CFStringRef name
= NULL
;
452 #ifndef __OPEN_SOURCE
456 #endif // __OPEN_SOURCE
458 key
= SCDynamicStoreKeyCreateHostNames(NULL
);
459 dict
= SCDynamicStoreCopyValue(store
, key
);
463 * Let's try looking in the preferences.plist file until
464 * (a) we add an API to retrieve the name regardless of
465 * where it is stored and
466 * (b) this API is deprecated
468 name
= _SCPreferencesCopyLocalHostName(NULL
);
471 if (!isA_CFDictionary(dict
)) {
472 _SCErrorSet(kSCStatusNoKey
);
476 name
= isA_CFString(CFDictionaryGetValue(dict
, kSCPropNetLocalHostName
));
478 _SCErrorSet(kSCStatusNoKey
);
483 _SCErrorSet(kSCStatusOK
);
488 if (dict
!= NULL
) CFRelease(dict
);
494 _SC_stringIsValidDNSName(const char *name
)
497 size_t len
= strlen(name
);
505 for (scan
= name
, i
= 0; i
< len
; i
++, scan
++) {
507 char next
= *(scan
+ 1);
509 if (prev
== '.' || prev
== '\0') {
510 if (isalnum(ch
) == 0) {
511 /* a label must begin with a letter or digit */
514 } else if (next
== '\0' || next
== '.') {
515 if (isalnum(ch
) == 0) {
516 /* a label must end with a letter or digit */
519 } else if (isalnum(ch
) == 0) {
522 /* a label separator */
525 /* hyphens are OK within a label */
528 /* an invalid character */
541 _SC_CFStringIsValidDNSName(CFStringRef name
)
543 Boolean clean
= FALSE
;
546 if (!isA_CFString(name
)) {
550 str
= _SC_cfstring_to_cstring(name
, NULL
, 0, kCFStringEncodingASCII
);
555 clean
= _SC_stringIsValidDNSName(str
);
557 if (str
!= NULL
) CFAllocatorDeallocate(NULL
, str
);
563 SCPreferencesSetLocalHostName(SCPreferencesRef prefs
,
566 CFDictionaryRef dict
;
567 CFMutableDictionaryRef newDict
;
574 if (!isA_CFString(name
)) {
575 _SCErrorSet(kSCStatusInvalidArgument
);
579 len
= CFStringGetLength(name
);
581 if (!_SC_CFStringIsValidDNSName(name
)) {
582 _SCErrorSet(kSCStatusInvalidArgument
);
586 if (CFStringFindWithOptions(name
, CFSTR("."), CFRangeMake(0, len
), 0, NULL
)) {
587 _SCErrorSet(kSCStatusInvalidArgument
);
595 path
= CFStringCreateWithFormat(NULL
,
602 dict
= SCPreferencesPathGetValue(prefs
, path
);
604 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
606 newDict
= CFDictionaryCreateMutable(NULL
,
608 &kCFTypeDictionaryKeyCallBacks
,
609 &kCFTypeDictionaryValueCallBacks
);
613 CFDictionarySetValue(newDict
, kSCPropNetLocalHostName
, name
);
615 CFDictionaryRemoveValue(newDict
, kSCPropNetLocalHostName
);
618 ok
= __SCNetworkConfigurationSetValue(prefs
, path
, newDict
, FALSE
);
619 if (ok
&& __SCPreferencesUsingDefaultPrefs(prefs
)) {
621 SC_log(LOG_NOTICE
, "attempting to set the local host name to \"%@\"", name
);
623 SC_log(LOG_NOTICE
, "attempting to reset the local host name");
635 _SC_CFStringIsValidNetBIOSName(CFStringRef name
)
637 if (!isA_CFString(name
)) {
641 if (CFStringGetLength(name
) > 15) {