]> git.saurik.com Git - apple/configd.git/blame - SystemConfiguration.fproj/SCDHostName.c
configd-699.1.5.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SCDHostName.c
CommitLineData
5958d7c0 1/*
78403150 2 * Copyright (c) 2000-2008, 2011, 2013, 2014 Apple Inc. All rights reserved.
5958d7c0
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
78403150 5 *
009ee3c6
A
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
11 * file.
78403150 12 *
009ee3c6
A
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
5958d7c0
A
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
009ee3c6
A
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.
78403150 20 *
5958d7c0
A
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
0fae82ee
A
24/*
25 * Modification History
26 *
27 * June 1, 2001 Allan Nathanson <ajn@apple.com>
28 * - public API conversion
29 *
30 * January 8, 2001 Allan Nathanson <ajn@apple.com>
31 * - initial revision
32 */
5958d7c0 33
edebe297
A
34
35#include <CoreFoundation/CoreFoundation.h>
36#include <CoreFoundation/CFStringDefaultEncoding.h> // for __CFStringGetUserDefaultEncoding
0fae82ee
A
37#include <SystemConfiguration/SystemConfiguration.h>
38#include <SystemConfiguration/SCValidation.h>
39#include <SystemConfiguration/SCPrivate.h>
78403150 40#include "dy_framework.h"
5958d7c0 41
edebe297
A
42
43#pragma mark ComputerName
44
45
78403150 46__private_extern__ CFStringRef
be997540
A
47_SCPreferencesCopyComputerName(SCPreferencesRef prefs,
48 CFStringEncoding *nameEncoding)
49{
50 CFDictionaryRef dict;
51 CFStringRef name = NULL;
52 CFStringRef path;
53 Boolean tempPrefs = FALSE;
54
55 if (prefs == NULL) {
56 prefs = SCPreferencesCreate(NULL, CFSTR("_SCPreferencesCopyComputerName"), NULL);
57 if (prefs == NULL) {
58 return NULL;
59 }
60 tempPrefs = TRUE;
61 }
62
63 path = CFStringCreateWithFormat(NULL,
64 NULL,
65 CFSTR("/%@/%@"),
66 kSCPrefSystem,
67 kSCCompSystem);
68 dict = SCPreferencesPathGetValue(prefs, path);
69 CFRelease(path);
70
71 if (dict != NULL) {
72 if (isA_CFDictionary(dict)) {
73 name = CFDictionaryGetValue(dict, kSCPropSystemComputerName);
74 name = isA_CFString(name);
75 if (name != NULL) {
76 CFRetain(name);
77 }
78 }
79
80 if (nameEncoding != NULL) {
81 CFNumberRef num;
82
83 num = CFDictionaryGetValue(dict,
84 kSCPropSystemComputerNameEncoding);
85 if (isA_CFNumber(num)) {
86 CFNumberGetValue(num, kCFNumberIntType, nameEncoding);
87 } else {
88 *nameEncoding = CFStringGetSystemEncoding();
89 }
90 }
91 }
92
93 if (tempPrefs) CFRelease(prefs);
78403150 94 _SCErrorSet(name != NULL ? kSCStatusOK : kSCStatusNoKey);
be997540
A
95 return name;
96}
97
98
5958d7c0 99CFStringRef
0fae82ee 100SCDynamicStoreKeyCreateComputerName(CFAllocatorRef allocator)
5958d7c0 101{
0fae82ee
A
102 return SCDynamicStoreKeyCreate(allocator,
103 CFSTR("%@/%@"),
104 kSCDynamicStoreDomainSetup,
105 kSCCompSystem);
5958d7c0
A
106}
107
108
0fae82ee
A
109CFStringRef
110SCDynamicStoreCopyComputerName(SCDynamicStoreRef store,
111 CFStringEncoding *nameEncoding)
5958d7c0 112{
17d3ee29 113 CFDictionaryRef dict = NULL;
0fae82ee
A
114 CFStringRef key;
115 CFStringRef name = NULL;
5958d7c0 116
0fae82ee 117 key = SCDynamicStoreKeyCreateComputerName(NULL);
a5f60add 118 dict = SCDynamicStoreCopyValue(store, key);
5958d7c0 119 CFRelease(key);
dbf6a266 120 if (dict == NULL) {
be997540
A
121 /*
122 * Let's try looking in the preferences.plist file until
123 * (a) we add an API to retrieve the name regardless of
124 * where it is stored and
125 * (b) this API is deprecated
126 */
127 name = _SCPreferencesCopyComputerName(NULL, nameEncoding);
0fae82ee
A
128 goto done;
129 }
130 if (!isA_CFDictionary(dict)) {
131 _SCErrorSet(kSCStatusNoKey);
5958d7c0
A
132 goto done;
133 }
134
0fae82ee 135 name = isA_CFString(CFDictionaryGetValue(dict, kSCPropSystemComputerName));
dbf6a266 136 if (name == NULL) {
0fae82ee 137 _SCErrorSet(kSCStatusNoKey);
5958d7c0
A
138 goto done;
139 }
0fae82ee 140 CFRetain(name);
5958d7c0 141
dbf6a266 142 if (nameEncoding != NULL) {
5958d7c0
A
143 CFNumberRef num;
144
145 num = CFDictionaryGetValue(dict,
146 kSCPropSystemComputerNameEncoding);
0fae82ee 147 if (isA_CFNumber(num)) {
5958d7c0
A
148 CFNumberGetValue(num, kCFNumberIntType, nameEncoding);
149 } else {
150 *nameEncoding = CFStringGetSystemEncoding();
151 }
152 }
153
78403150
A
154 _SCErrorSet(kSCStatusOK);
155
5958d7c0
A
156 done :
157
78403150 158
dbf6a266 159 if (dict != NULL) CFRelease(dict);
0fae82ee
A
160 return name;
161}
162
163
164Boolean
dbf6a266 165SCPreferencesSetComputerName(SCPreferencesRef prefs,
0fae82ee
A
166 CFStringRef name,
167 CFStringEncoding encoding)
168{
169 CFDictionaryRef dict;
dbf6a266 170 CFMutableDictionaryRef newDict;
0fae82ee 171 CFNumberRef num;
dbf6a266
A
172 Boolean ok;
173 CFStringRef path;
0fae82ee 174
be997540
A
175 if (name != NULL) {
176 CFIndex len;
177
178 if (!isA_CFString(name)) {
179 _SCErrorSet(kSCStatusInvalidArgument);
180 return FALSE;
181 }
182
183 len = CFStringGetLength(name);
184 if (len == 0) {
185 name = NULL;
186 }
0fae82ee
A
187 }
188
189 path = CFStringCreateWithFormat(NULL,
190 NULL,
191 CFSTR("/%@/%@"),
192 kSCPrefSystem,
193 kSCCompSystem);
194
dbf6a266
A
195 dict = SCPreferencesPathGetValue(prefs, path);
196 if (dict != NULL) {
0fae82ee
A
197 newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
198 } else {
199 newDict = CFDictionaryCreateMutable(NULL,
200 0,
201 &kCFTypeDictionaryKeyCallBacks,
202 &kCFTypeDictionaryValueCallBacks);
203 }
204
be997540
A
205 if ((name != NULL) && (CFStringGetLength(name) > 0)) {
206 CFDictionarySetValue(newDict, kSCPropSystemComputerName, name);
0fae82ee 207
be997540
A
208 num = CFNumberCreate(NULL, kCFNumberSInt32Type, &encoding);
209 CFDictionarySetValue(newDict, kSCPropSystemComputerNameEncoding, num);
210 CFRelease(num);
0fae82ee 211
be997540
A
212 CFDictionaryRemoveValue(newDict, kSCPropSystemComputerNameRegion);
213 if (encoding == kCFStringEncodingMacRoman) {
214 UInt32 userEncoding = 0;
215 UInt32 userRegion = 0;
edebe297 216
be997540
A
217 __CFStringGetUserDefaultEncoding(&userEncoding, &userRegion);
218 if ((userEncoding == kCFStringEncodingMacRoman) && (userRegion != 0)) {
219 num = CFNumberCreate(NULL, kCFNumberSInt32Type, &userRegion);
220 CFDictionarySetValue(newDict, kSCPropSystemComputerNameRegion, num);
221 CFRelease(num);
222 }
edebe297 223 }
be997540
A
224 } else {
225 CFDictionaryRemoveValue(newDict, kSCPropSystemComputerName);
226 CFDictionaryRemoveValue(newDict, kSCPropSystemComputerNameEncoding);
227 CFDictionaryRemoveValue(newDict, kSCPropSystemComputerNameRegion);
edebe297
A
228 }
229
be997540
A
230 if (CFDictionaryGetCount(newDict) > 0) {
231 ok = SCPreferencesPathSetValue(prefs, path, newDict);
232 } else {
233 ok = SCPreferencesPathRemoveValue(prefs, path);
234 }
dbf6a266
A
235
236 CFRelease(path);
237 CFRelease(newDict);
238
239 return ok;
240}
241
242
edebe297
A
243#pragma mark -
244#pragma mark HostName
dbf6a266
A
245
246
247CFStringRef
248SCPreferencesGetHostName(SCPreferencesRef prefs)
249{
250 CFDictionaryRef dict;
251 CFStringRef name;
252 CFStringRef path;
253
254 path = CFStringCreateWithFormat(NULL,
255 NULL,
256 CFSTR("/%@/%@"),
257 kSCPrefSystem,
258 kSCCompSystem);
259 dict = SCPreferencesPathGetValue(prefs, path);
260 CFRelease(path);
261
262 if (!isA_CFDictionary(dict)) {
263 _SCErrorSet(kSCStatusNoKey);
264 return NULL;
0fae82ee
A
265 }
266
edebe297 267 name = isA_CFString(CFDictionaryGetValue(dict, kSCPropSystemHostName));
dbf6a266
A
268 if (name == NULL) {
269 _SCErrorSet(kSCStatusNoKey);
270 return NULL;
271 }
272
273 return name;
274}
275
276
277Boolean
278SCPreferencesSetHostName(SCPreferencesRef prefs,
279 CFStringRef name)
280{
281 CFDictionaryRef dict;
282 CFMutableDictionaryRef newDict;
283 Boolean ok;
284 CFStringRef path;
285
286 if (name != NULL) {
287 CFIndex len;
288
289 if (!isA_CFString(name)) {
290 _SCErrorSet(kSCStatusInvalidArgument);
291 return FALSE;
292 }
293
294 len = CFStringGetLength(name);
295 if (len == 0) {
296 name = NULL;
297 }
298 }
299
300 path = CFStringCreateWithFormat(NULL,
301 NULL,
302 CFSTR("/%@/%@"),
303 kSCPrefSystem,
304 kSCCompSystem);
305
306 dict = SCPreferencesPathGetValue(prefs, path);
307 if (dict != NULL) {
308 newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
309 } else {
310 newDict = CFDictionaryCreateMutable(NULL,
311 0,
312 &kCFTypeDictionaryKeyCallBacks,
313 &kCFTypeDictionaryValueCallBacks);
314 }
315
316 if (name != NULL) {
edebe297 317 CFDictionarySetValue(newDict, kSCPropSystemHostName, name);
dbf6a266 318 } else {
edebe297 319 CFDictionaryRemoveValue(newDict, kSCPropSystemHostName);
dbf6a266
A
320 }
321
322 if (CFDictionaryGetCount(newDict) > 0) {
323 ok = SCPreferencesPathSetValue(prefs, path, newDict);
324 } else {
325 ok = SCPreferencesPathRemoveValue(prefs, path);
326 }
327
328 CFRelease(path);
329 CFRelease(newDict);
0fae82ee
A
330
331 return ok;
5958d7c0 332}
a5f60add
A
333
334
edebe297
A
335#pragma mark -
336#pragma mark LocalHostName
337
338
78403150 339__private_extern__ CFStringRef
be997540
A
340_SCPreferencesCopyLocalHostName(SCPreferencesRef prefs)
341{
342 CFDictionaryRef dict;
343 CFStringRef name = NULL;
344 CFStringRef path;
345 Boolean tempPrefs = FALSE;
346
347 if (prefs == NULL) {
348 prefs = SCPreferencesCreate(NULL, CFSTR("_SCPreferencesCopyLocalHostName"), NULL);
349 if (prefs == NULL) {
350 return NULL;
351 }
352 tempPrefs = TRUE;
353 }
354
355 path = CFStringCreateWithFormat(NULL,
356 NULL,
357 CFSTR("/%@/%@/%@"),
358 kSCPrefSystem,
359 kSCCompNetwork,
360 kSCCompHostNames);
361 dict = SCPreferencesPathGetValue(prefs, path);
362 CFRelease(path);
363
364 if (dict != NULL) {
365 if (isA_CFDictionary(dict)) {
366 name = CFDictionaryGetValue(dict, kSCPropNetLocalHostName);
367 name = isA_CFString(name);
368 if (name != NULL) {
369 CFRetain(name);
370 }
371 }
372 }
373
374 if (tempPrefs) CFRelease(prefs);
78403150 375 _SCErrorSet(name != NULL ? kSCStatusOK : kSCStatusNoKey);
be997540
A
376 return name;
377}
378
379
a5f60add
A
380CFStringRef
381SCDynamicStoreKeyCreateHostNames(CFAllocatorRef allocator)
382{
383 return SCDynamicStoreKeyCreate(allocator,
384 CFSTR("%@/%@/%@"),
385 kSCDynamicStoreDomainSetup,
386 kSCCompNetwork,
387 kSCCompHostNames);
388}
389
390
391CFStringRef
392SCDynamicStoreCopyLocalHostName(SCDynamicStoreRef store)
393{
17d3ee29 394 CFDictionaryRef dict = NULL;
a5f60add
A
395 CFStringRef key;
396 CFStringRef name = NULL;
a5f60add
A
397
398 key = SCDynamicStoreKeyCreateHostNames(NULL);
399 dict = SCDynamicStoreCopyValue(store, key);
400 CFRelease(key);
dbf6a266 401 if (dict == NULL) {
be997540
A
402 /*
403 * Let's try looking in the preferences.plist file until
404 * (a) we add an API to retrieve the name regardless of
405 * where it is stored and
406 * (b) this API is deprecated
407 */
408 name = _SCPreferencesCopyLocalHostName(NULL);
a5f60add
A
409 goto done;
410 }
411 if (!isA_CFDictionary(dict)) {
412 _SCErrorSet(kSCStatusNoKey);
413 goto done;
414 }
415
416 name = isA_CFString(CFDictionaryGetValue(dict, kSCPropNetLocalHostName));
dbf6a266 417 if (name == NULL) {
a5f60add
A
418 _SCErrorSet(kSCStatusNoKey);
419 goto done;
420 }
421 CFRetain(name);
422
78403150
A
423 _SCErrorSet(kSCStatusOK);
424
a5f60add
A
425 done :
426
78403150 427
dbf6a266 428 if (dict != NULL) CFRelease(dict);
a5f60add
A
429 return name;
430}
431
432
433Boolean
434_SC_stringIsValidDNSName(const char *name)
435{
436 int i;
78403150 437 size_t len = strlen(name);
a5f60add
A
438 char prev = '\0';
439 const char *scan;
440
441 if (len == 0) {
442 return FALSE;
443 }
444
445 for (scan = name, i = 0; i < len; i++, scan++) {
446 char ch = *scan;
447 char next = *(scan + 1);
448
449 if (prev == '.' || prev == '\0') {
009ee3c6
A
450 if (isalnum(ch) == 0) {
451 /* a label must begin with a letter or digit */
a5f60add
A
452 return FALSE;
453 }
454 } else if (next == '\0' || next == '.') {
455 if (isalnum(ch) == 0) {
009ee3c6 456 /* a label must end with a letter or digit */
a5f60add
A
457 return FALSE;
458 }
459 } else if (isalnum(ch) == 0) {
460 switch (ch) {
461 case '.':
a40a14f8
A
462 if (prev == '.') {
463 /* no empty labels */
a5f60add
A
464 return FALSE;
465 }
466 break;
a40a14f8
A
467 case '-':
468 /* hyphens are OK within a label */
469 break;
a5f60add 470 default:
009ee3c6 471 /* an invalid character */
a5f60add
A
472 return FALSE;
473 break;
474 }
475 }
476 prev = ch;
477 }
478
479 return TRUE;
480}
481
edebe297 482
a5f60add
A
483Boolean
484_SC_CFStringIsValidDNSName(CFStringRef name)
485{
486 Boolean clean = FALSE;
a5f60add
A
487 char *str = NULL;
488
489 if (!isA_CFString(name)) {
009ee3c6 490 return FALSE;
a5f60add
A
491 }
492
009ee3c6 493 str = _SC_cfstring_to_cstring(name, NULL, 0, kCFStringEncodingASCII);
a5f60add 494 if (str == NULL) {
009ee3c6 495 return FALSE;
a5f60add
A
496 }
497
498 clean = _SC_stringIsValidDNSName(str);
499
dbf6a266 500 if (str != NULL) CFAllocatorDeallocate(NULL, str);
a5f60add
A
501 return clean;
502}
503
504
505Boolean
dbf6a266 506SCPreferencesSetLocalHostName(SCPreferencesRef prefs,
009ee3c6 507 CFStringRef name)
a5f60add
A
508{
509 CFDictionaryRef dict;
dbf6a266
A
510 CFMutableDictionaryRef newDict;
511 Boolean ok;
512 CFStringRef path;
a5f60add 513
dbf6a266 514 if (name != NULL) {
009ee3c6
A
515 CFIndex len;
516
a5f60add
A
517 if (!isA_CFString(name)) {
518 _SCErrorSet(kSCStatusInvalidArgument);
519 return FALSE;
520 }
521
009ee3c6
A
522 len = CFStringGetLength(name);
523 if (len > 0) {
524 if (!_SC_CFStringIsValidDNSName(name)) {
525 _SCErrorSet(kSCStatusInvalidArgument);
526 return FALSE;
527 }
528
529 if (CFStringFindWithOptions(name, CFSTR("."), CFRangeMake(0, len), 0, NULL)) {
530 _SCErrorSet(kSCStatusInvalidArgument);
531 return FALSE;
532 }
533 } else {
a5f60add
A
534 name = NULL;
535 }
536 }
537
a5f60add
A
538 path = CFStringCreateWithFormat(NULL,
539 NULL,
540 CFSTR("/%@/%@/%@"),
541 kSCPrefSystem,
542 kSCCompNetwork,
543 kSCCompHostNames);
544
dbf6a266
A
545 dict = SCPreferencesPathGetValue(prefs, path);
546 if (dict != NULL) {
a5f60add
A
547 newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
548 } else {
549 newDict = CFDictionaryCreateMutable(NULL,
550 0,
551 &kCFTypeDictionaryKeyCallBacks,
552 &kCFTypeDictionaryValueCallBacks);
553 }
554
dbf6a266 555 if (name != NULL) {
a5f60add
A
556 CFDictionarySetValue(newDict, kSCPropNetLocalHostName, name);
557 } else {
558 CFDictionaryRemoveValue(newDict, kSCPropNetLocalHostName);
559 }
560
561 if (CFDictionaryGetCount(newDict) > 0) {
dbf6a266 562 ok = SCPreferencesPathSetValue(prefs, path, newDict);
a5f60add 563 } else {
dbf6a266 564 ok = SCPreferencesPathRemoveValue(prefs, path);
a5f60add
A
565 }
566
dbf6a266
A
567 CFRelease(path);
568 CFRelease(newDict);
a5f60add
A
569
570 return ok;
571}
edebe297
A
572
573
574Boolean
575_SC_CFStringIsValidNetBIOSName(CFStringRef name)
576{
577 if (!isA_CFString(name)) {
578 return FALSE;
579 }
580
581 if (CFStringGetLength(name) > 15) {
582 return FALSE;
583 }
584
585 return TRUE;
586}