]>
git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSMacOSX/mdns_objects/mdns_managed_defaults.c
2 * Copyright (c) 2020 Apple Inc. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * https://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "mdns_managed_defaults.h"
19 #include "mdns_helpers.h"
21 #include <CoreUtils/CoreUtils.h>
23 //======================================================================================================================
26 // Managed defaults is currently only for iOS-like OSes.
27 #if !defined(TARGET_OS_IOS_LIKE_DEVICE)
28 #error "TARGET_OS_IOS_LIKE_DEVICE is not defined"
31 MDNS_LOG_CATEGORY_DEFINE(managed_defaults
, "managed_defaults");
33 //======================================================================================================================
34 // MARK: - Local Prototypes
36 #if TARGET_OS_IOS_LIKE_DEVICE
38 _mdns_managed_defaults_create_domain_url(const char *domain
, OSStatus
*out_error
);
40 static CFReadStreamRef
41 _mdns_managed_defaults_create_opened_read_stream(CFURLRef url
, OSStatus
*out_error
);
43 static CFDictionaryRef
44 _mdns_managed_defaults_create_dictionary_from_stream(CFReadStreamRef stream
, OSStatus
*out_error
);
48 _mdns_managed_defaults_get_int64(CFDictionaryRef defaults
, CFStringRef key
, OSStatus
*out_error
);
50 #define _assign_null_safe(PTR, VALUE) \
57 //======================================================================================================================
58 // MARK: - Public Functions
60 #if TARGET_OS_IOS_LIKE_DEVICE
62 mdns_managed_defaults_create(const char * const domain
, OSStatus
* const out_error
)
64 CFDictionaryRef result
= NULL
;
65 OSStatus err
, tmp_err
;
66 CFURLRef url
= _mdns_managed_defaults_create_domain_url(domain
, &tmp_err
);
67 require_action_quiet(url
, exit
, err
= tmp_err
; os_log_error(_mdns_managed_defaults_log(),
68 "Failed to create URL -- domain: %{public}s, error: %{mdns:err}ld", domain
, (long)err
));
70 CFReadStreamRef stream
= _mdns_managed_defaults_create_opened_read_stream(url
, &tmp_err
);
71 require_action_quiet(stream
, exit
, err
= tmp_err
; os_log_error(_mdns_managed_defaults_log(),
72 "Failed to create read stream -- url: %{public}@, error: %{mdns:err}ld", url
, (long)err
));
74 CFDictionaryRef plist
= _mdns_managed_defaults_create_dictionary_from_stream(stream
, &tmp_err
);
76 require_action_quiet(plist
, exit
, err
= tmp_err
; os_log_error(_mdns_managed_defaults_log(),
77 "Failed to create dictionary -- url: %{public}@, error: %{mdns:err}ld", url
, (long)err
));
84 _assign_null_safe(out_error
, err
);
89 mdns_managed_defaults_create(__unused
const char * const domain
, OSStatus
* const out_error
)
91 os_log_info(_mdns_managed_defaults_log(), "Managed defaults is not supported on this OS");
92 _assign_null_safe(out_error
, kUnsupportedErr
);
95 #endif // TARGET_OS_IOS_LIKE_DEVICE
97 //======================================================================================================================
100 mdns_managed_defaults_get_int_clamped(const CFDictionaryRef defaults
, const CFStringRef key
, const int fallback_value
,
101 OSStatus
* const out_error
)
105 const int64_t value
= _mdns_managed_defaults_get_int64(defaults
, key
, &err
);
106 require_noerr_action_quiet(err
, exit
, result
= fallback_value
);
108 result
= (int)Clamp(value
, INT_MIN
, INT_MAX
);
111 _assign_null_safe(out_error
, err
);
115 //======================================================================================================================
116 // MARK: - Private Functions
118 #if TARGET_OS_IOS_LIKE_DEVICE
120 _mdns_managed_defaults_create_domain_url(const char * const domain
, OSStatus
* const out_error
)
123 CFURLRef result
= NULL
;
124 char *path_cstr
= NULL
;
125 asprintf(&path_cstr
, "/Library/Managed Preferences/mobile/%s.plist", domain
);
126 require_action_quiet(path_cstr
, exit
, err
= kNoMemoryErr
);
128 CFStringRef path
= CFStringCreateWithCStringNoCopy(NULL
, path_cstr
, kCFStringEncodingUTF8
, kCFAllocatorMalloc
);
129 require_action_quiet(path
, exit
, ForgetMem(&path_cstr
); err
= kNoResourcesErr
);
132 CFURLRef url
= CFURLCreateWithFileSystemPath(kCFAllocatorDefault
, path
, kCFURLPOSIXPathStyle
, false);
134 require_action_quiet(url
, exit
, err
= kNoResourcesErr
);
140 _assign_null_safe(out_error
, err
);
144 //======================================================================================================================
146 static CFReadStreamRef
147 _mdns_managed_defaults_create_opened_read_stream(const CFURLRef url
, OSStatus
* const out_error
)
150 CFReadStreamRef result
= NULL
;
151 CFReadStreamRef stream
= CFReadStreamCreateWithFile(kCFAllocatorDefault
, url
);
152 require_action_quiet(stream
, exit
, err
= kNoResourcesErr
);
154 const Boolean ok
= CFReadStreamOpen(stream
);
155 require_action_quiet(ok
, exit
, ForgetCF(&stream
); err
= kOpenErr
);
161 _assign_null_safe(out_error
, err
);
165 //======================================================================================================================
168 _mdns_get_cferror_code(CFErrorRef error
);
170 static CFDictionaryRef
171 _mdns_managed_defaults_create_dictionary_from_stream(const CFReadStreamRef stream
, OSStatus
* const out_error
)
174 CFErrorRef error
= NULL
;
175 CFDictionaryRef result
= NULL
;
176 CFPropertyListRef plist
= CFPropertyListCreateWithStream(NULL
, stream
, 0, kCFPropertyListImmutable
, NULL
, &error
);
177 require_action_quiet(plist
, exit
, err
= _mdns_get_cferror_code(error
); os_log_error(_mdns_managed_defaults_log(),
178 "CFPropertyListCreateWithStream failed: %{public}@", error
));
179 require_action_quiet(CFIsType(plist
, CFDictionary
), exit
, ForgetCF(&plist
); err
= kTypeErr
);
186 _assign_null_safe(out_error
, err
);
191 _mdns_get_cferror_code(const CFErrorRef error
)
193 return (error
? ((OSStatus
)CFErrorGetCode(error
)) : kUnknownErr
);
195 #endif // TARGET_OS_IOS_LIKE_DEVICE
197 //======================================================================================================================
200 _mdns_managed_defaults_get_int64(const CFDictionaryRef defaults
, const CFStringRef key
, OSStatus
* const out_error
)
204 const CFNumberRef number
= CFDictionaryGetValue(defaults
, key
);
205 require_action_quiet(number
!= NULL
, exit
, err
= kNotFoundErr
);
206 require_action_quiet(CFIsType(number
, CFNumber
), exit
, err
= kTypeErr
);
207 require_action_quiet(!CFNumberIsFloatType(number
), exit
, err
= kTypeErr
);
210 const Boolean ok
= CFNumberGetValue(number
, kCFNumberSInt64Type
, &value
);
211 require_action_quiet(ok
, exit
, err
= kUnknownErr
);
217 _assign_null_safe(out_error
, err
);