]> git.saurik.com Git - apple/configd.git/blame - SystemConfiguration.fproj/SCDHostName.c
configd-210.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SCDHostName.c
CommitLineData
5958d7c0 1/*
edebe297 2 * Copyright (c) 2000-2007 Apple Inc. All rights reserved.
5958d7c0
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
009ee3c6 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.
12 *
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.
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>
5958d7c0 40
edebe297
A
41
42#pragma mark ComputerName
43
44
5958d7c0 45CFStringRef
0fae82ee 46SCDynamicStoreKeyCreateComputerName(CFAllocatorRef allocator)
5958d7c0 47{
0fae82ee
A
48 return SCDynamicStoreKeyCreate(allocator,
49 CFSTR("%@/%@"),
50 kSCDynamicStoreDomainSetup,
51 kSCCompSystem);
5958d7c0
A
52}
53
54
0fae82ee
A
55CFStringRef
56SCDynamicStoreCopyComputerName(SCDynamicStoreRef store,
57 CFStringEncoding *nameEncoding)
5958d7c0 58{
dbf6a266 59 CFDictionaryRef dict;
0fae82ee
A
60 CFStringRef key;
61 CFStringRef name = NULL;
a5f60add 62 Boolean tempSession = FALSE;
5958d7c0 63
dbf6a266 64 if (store == NULL) {
a5f60add
A
65 store = SCDynamicStoreCreate(NULL,
66 CFSTR("SCDynamicStoreCopyComputerName"),
67 NULL,
68 NULL);
dbf6a266 69 if (store == NULL) {
0fae82ee
A
70 return NULL;
71 }
a5f60add 72 tempSession = TRUE;
5958d7c0
A
73 }
74
0fae82ee 75 key = SCDynamicStoreKeyCreateComputerName(NULL);
a5f60add 76 dict = SCDynamicStoreCopyValue(store, key);
5958d7c0 77 CFRelease(key);
dbf6a266 78 if (dict == NULL) {
0fae82ee
A
79 goto done;
80 }
81 if (!isA_CFDictionary(dict)) {
82 _SCErrorSet(kSCStatusNoKey);
5958d7c0
A
83 goto done;
84 }
85
0fae82ee 86 name = isA_CFString(CFDictionaryGetValue(dict, kSCPropSystemComputerName));
dbf6a266 87 if (name == NULL) {
0fae82ee 88 _SCErrorSet(kSCStatusNoKey);
5958d7c0
A
89 goto done;
90 }
0fae82ee 91 CFRetain(name);
5958d7c0 92
dbf6a266 93 if (nameEncoding != NULL) {
5958d7c0
A
94 CFNumberRef num;
95
96 num = CFDictionaryGetValue(dict,
97 kSCPropSystemComputerNameEncoding);
0fae82ee 98 if (isA_CFNumber(num)) {
5958d7c0
A
99 CFNumberGetValue(num, kCFNumberIntType, nameEncoding);
100 } else {
101 *nameEncoding = CFStringGetSystemEncoding();
102 }
103 }
104
105 done :
106
a5f60add 107 if (tempSession) CFRelease(store);
dbf6a266 108 if (dict != NULL) CFRelease(dict);
0fae82ee
A
109 return name;
110}
111
112
113Boolean
dbf6a266 114SCPreferencesSetComputerName(SCPreferencesRef prefs,
0fae82ee
A
115 CFStringRef name,
116 CFStringEncoding encoding)
117{
118 CFDictionaryRef dict;
dbf6a266 119 CFMutableDictionaryRef newDict;
0fae82ee 120 CFNumberRef num;
dbf6a266
A
121 Boolean ok;
122 CFStringRef path;
0fae82ee 123
a5f60add 124 if (!isA_CFString(name)) {
0fae82ee
A
125 _SCErrorSet(kSCStatusInvalidArgument);
126 return FALSE;
127 }
128
129 path = CFStringCreateWithFormat(NULL,
130 NULL,
131 CFSTR("/%@/%@"),
132 kSCPrefSystem,
133 kSCCompSystem);
134
dbf6a266
A
135 dict = SCPreferencesPathGetValue(prefs, path);
136 if (dict != NULL) {
0fae82ee
A
137 newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
138 } else {
139 newDict = CFDictionaryCreateMutable(NULL,
140 0,
141 &kCFTypeDictionaryKeyCallBacks,
142 &kCFTypeDictionaryValueCallBacks);
143 }
144
145 CFDictionarySetValue(newDict, kSCPropSystemComputerName, name);
146
edebe297 147 num = CFNumberCreate(NULL, kCFNumberSInt32Type, &encoding);
0fae82ee
A
148 CFDictionarySetValue(newDict, kSCPropSystemComputerNameEncoding, num);
149 CFRelease(num);
150
edebe297
A
151 CFDictionaryRemoveValue(newDict, kSCPropSystemComputerNameRegion);
152 if (encoding == kCFStringEncodingMacRoman) {
153 UInt32 userEncoding = 0;
154 UInt32 userRegion = 0;
155
156 __CFStringGetUserDefaultEncoding(&userEncoding, &userRegion);
157 if ((userEncoding == kCFStringEncodingMacRoman) && (userRegion != 0)) {
158 num = CFNumberCreate(NULL, kCFNumberSInt32Type, &userRegion);
159 CFDictionarySetValue(newDict, kSCPropSystemComputerNameRegion, num);
160 CFRelease(num);
161 }
162 }
163
dbf6a266
A
164 ok = SCPreferencesPathSetValue(prefs, path, newDict);
165
166 CFRelease(path);
167 CFRelease(newDict);
168
169 return ok;
170}
171
172
edebe297
A
173#pragma mark -
174#pragma mark HostName
dbf6a266
A
175
176
177CFStringRef
178SCPreferencesGetHostName(SCPreferencesRef prefs)
179{
180 CFDictionaryRef dict;
181 CFStringRef name;
182 CFStringRef path;
183
184 path = CFStringCreateWithFormat(NULL,
185 NULL,
186 CFSTR("/%@/%@"),
187 kSCPrefSystem,
188 kSCCompSystem);
189 dict = SCPreferencesPathGetValue(prefs, path);
190 CFRelease(path);
191
192 if (!isA_CFDictionary(dict)) {
193 _SCErrorSet(kSCStatusNoKey);
194 return NULL;
0fae82ee
A
195 }
196
edebe297 197 name = isA_CFString(CFDictionaryGetValue(dict, kSCPropSystemHostName));
dbf6a266
A
198 if (name == NULL) {
199 _SCErrorSet(kSCStatusNoKey);
200 return NULL;
201 }
202
203 return name;
204}
205
206
207Boolean
208SCPreferencesSetHostName(SCPreferencesRef prefs,
209 CFStringRef name)
210{
211 CFDictionaryRef dict;
212 CFMutableDictionaryRef newDict;
213 Boolean ok;
214 CFStringRef path;
215
216 if (name != NULL) {
217 CFIndex len;
218
219 if (!isA_CFString(name)) {
220 _SCErrorSet(kSCStatusInvalidArgument);
221 return FALSE;
222 }
223
224 len = CFStringGetLength(name);
225 if (len == 0) {
226 name = NULL;
227 }
228 }
229
230 path = CFStringCreateWithFormat(NULL,
231 NULL,
232 CFSTR("/%@/%@"),
233 kSCPrefSystem,
234 kSCCompSystem);
235
236 dict = SCPreferencesPathGetValue(prefs, path);
237 if (dict != NULL) {
238 newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
239 } else {
240 newDict = CFDictionaryCreateMutable(NULL,
241 0,
242 &kCFTypeDictionaryKeyCallBacks,
243 &kCFTypeDictionaryValueCallBacks);
244 }
245
246 if (name != NULL) {
edebe297 247 CFDictionarySetValue(newDict, kSCPropSystemHostName, name);
dbf6a266 248 } else {
edebe297 249 CFDictionaryRemoveValue(newDict, kSCPropSystemHostName);
dbf6a266
A
250 }
251
252 if (CFDictionaryGetCount(newDict) > 0) {
253 ok = SCPreferencesPathSetValue(prefs, path, newDict);
254 } else {
255 ok = SCPreferencesPathRemoveValue(prefs, path);
256 }
257
258 CFRelease(path);
259 CFRelease(newDict);
0fae82ee
A
260
261 return ok;
5958d7c0 262}
a5f60add
A
263
264
edebe297
A
265#pragma mark -
266#pragma mark LocalHostName
267
268
a5f60add
A
269CFStringRef
270SCDynamicStoreKeyCreateHostNames(CFAllocatorRef allocator)
271{
272 return SCDynamicStoreKeyCreate(allocator,
273 CFSTR("%@/%@/%@"),
274 kSCDynamicStoreDomainSetup,
275 kSCCompNetwork,
276 kSCCompHostNames);
277}
278
279
280CFStringRef
281SCDynamicStoreCopyLocalHostName(SCDynamicStoreRef store)
282{
dbf6a266 283 CFDictionaryRef dict;
a5f60add
A
284 CFStringRef key;
285 CFStringRef name = NULL;
286 Boolean tempSession = FALSE;
287
dbf6a266 288 if (store == NULL) {
a5f60add
A
289 store = SCDynamicStoreCreate(NULL,
290 CFSTR("SCDynamicStoreCopyLocalHostName"),
291 NULL,
292 NULL);
dbf6a266 293 if (store == NULL) {
a5f60add
A
294 return NULL;
295 }
296 tempSession = TRUE;
297 }
298
299 key = SCDynamicStoreKeyCreateHostNames(NULL);
300 dict = SCDynamicStoreCopyValue(store, key);
301 CFRelease(key);
dbf6a266 302 if (dict == NULL) {
a5f60add
A
303 goto done;
304 }
305 if (!isA_CFDictionary(dict)) {
306 _SCErrorSet(kSCStatusNoKey);
307 goto done;
308 }
309
310 name = isA_CFString(CFDictionaryGetValue(dict, kSCPropNetLocalHostName));
dbf6a266 311 if (name == NULL) {
a5f60add
A
312 _SCErrorSet(kSCStatusNoKey);
313 goto done;
314 }
315 CFRetain(name);
316
317 done :
318
319 if (tempSession) CFRelease(store);
dbf6a266 320 if (dict != NULL) CFRelease(dict);
a5f60add
A
321 return name;
322}
323
324
325Boolean
326_SC_stringIsValidDNSName(const char *name)
327{
328 int i;
329 int len = strlen(name);
330 char prev = '\0';
331 const char *scan;
332
333 if (len == 0) {
334 return FALSE;
335 }
336
337 for (scan = name, i = 0; i < len; i++, scan++) {
338 char ch = *scan;
339 char next = *(scan + 1);
340
341 if (prev == '.' || prev == '\0') {
009ee3c6
A
342 if (isalnum(ch) == 0) {
343 /* a label must begin with a letter or digit */
a5f60add
A
344 return FALSE;
345 }
346 } else if (next == '\0' || next == '.') {
347 if (isalnum(ch) == 0) {
009ee3c6 348 /* a label must end with a letter or digit */
a5f60add
A
349 return FALSE;
350 }
351 } else if (isalnum(ch) == 0) {
352 switch (ch) {
353 case '.':
354 case '-':
355 if (prev == '.' || prev == '-') {
009ee3c6 356 /* a label cannot begin or end with a hyphen */
a5f60add
A
357 return FALSE;
358 }
359 break;
360 default:
009ee3c6 361 /* an invalid character */
a5f60add
A
362 return FALSE;
363 break;
364 }
365 }
366 prev = ch;
367 }
368
369 return TRUE;
370}
371
edebe297 372
a5f60add
A
373Boolean
374_SC_CFStringIsValidDNSName(CFStringRef name)
375{
376 Boolean clean = FALSE;
a5f60add
A
377 char *str = NULL;
378
379 if (!isA_CFString(name)) {
009ee3c6 380 return FALSE;
a5f60add
A
381 }
382
009ee3c6 383 str = _SC_cfstring_to_cstring(name, NULL, 0, kCFStringEncodingASCII);
a5f60add 384 if (str == NULL) {
009ee3c6 385 return FALSE;
a5f60add
A
386 }
387
388 clean = _SC_stringIsValidDNSName(str);
389
dbf6a266 390 if (str != NULL) CFAllocatorDeallocate(NULL, str);
a5f60add
A
391 return clean;
392}
393
394
395Boolean
dbf6a266 396SCPreferencesSetLocalHostName(SCPreferencesRef prefs,
009ee3c6 397 CFStringRef name)
a5f60add
A
398{
399 CFDictionaryRef dict;
dbf6a266
A
400 CFMutableDictionaryRef newDict;
401 Boolean ok;
402 CFStringRef path;
a5f60add 403
dbf6a266 404 if (name != NULL) {
009ee3c6
A
405 CFIndex len;
406
a5f60add
A
407 if (!isA_CFString(name)) {
408 _SCErrorSet(kSCStatusInvalidArgument);
409 return FALSE;
410 }
411
009ee3c6
A
412 len = CFStringGetLength(name);
413 if (len > 0) {
414 if (!_SC_CFStringIsValidDNSName(name)) {
415 _SCErrorSet(kSCStatusInvalidArgument);
416 return FALSE;
417 }
418
419 if (CFStringFindWithOptions(name, CFSTR("."), CFRangeMake(0, len), 0, NULL)) {
420 _SCErrorSet(kSCStatusInvalidArgument);
421 return FALSE;
422 }
423 } else {
a5f60add
A
424 name = NULL;
425 }
426 }
427
a5f60add
A
428 path = CFStringCreateWithFormat(NULL,
429 NULL,
430 CFSTR("/%@/%@/%@"),
431 kSCPrefSystem,
432 kSCCompNetwork,
433 kSCCompHostNames);
434
dbf6a266
A
435 dict = SCPreferencesPathGetValue(prefs, path);
436 if (dict != NULL) {
a5f60add
A
437 newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
438 } else {
439 newDict = CFDictionaryCreateMutable(NULL,
440 0,
441 &kCFTypeDictionaryKeyCallBacks,
442 &kCFTypeDictionaryValueCallBacks);
443 }
444
dbf6a266 445 if (name != NULL) {
a5f60add
A
446 CFDictionarySetValue(newDict, kSCPropNetLocalHostName, name);
447 } else {
448 CFDictionaryRemoveValue(newDict, kSCPropNetLocalHostName);
449 }
450
451 if (CFDictionaryGetCount(newDict) > 0) {
dbf6a266 452 ok = SCPreferencesPathSetValue(prefs, path, newDict);
a5f60add 453 } else {
dbf6a266 454 ok = SCPreferencesPathRemoveValue(prefs, path);
a5f60add
A
455 }
456
dbf6a266
A
457 CFRelease(path);
458 CFRelease(newDict);
a5f60add
A
459
460 return ok;
461}
edebe297
A
462
463
464Boolean
465_SC_CFStringIsValidNetBIOSName(CFStringRef name)
466{
467 if (!isA_CFString(name)) {
468 return FALSE;
469 }
470
471 if (CFStringGetLength(name) > 15) {
472 return FALSE;
473 }
474
475 return TRUE;
476}