1/* 2 * Copyright (c) 2000, 2001, 2003-2005, 2007-2009, 2011, 2014 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 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 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. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* 25 * Modification History 26 * 27 * June 1, 2001 Allan Nathanson <ajn@apple.com> 28 * - public API conversion 29 * 30 * November 9, 2000 Allan Nathanson <ajn@apple.com> 31 * - initial revision 32 */ 33 34#include <SystemConfiguration/SystemConfiguration.h> 35#include <SystemConfiguration/SCPrivate.h> 36#include "SCPreferencesInternal.h" 37#include "SCNetworkConfigurationInternal.h" 38 39#include <fcntl.h> 40#include <pwd.h> 41#include <unistd.h> 42#include <sys/errno.h> 43#include <sys/param.h> 44 45__private_extern__ CF_RETURNS_RETAINED CFDataRef 46__SCPSignatureFromStatbuf(const struct stat *statBuf) 47{ 48 CFMutableDataRef signature; 49 SCPSignatureDataRef sig; 50 51 signature = CFDataCreateMutable(NULL, sizeof(SCPSignatureData)); 52 CFDataSetLength(signature, sizeof(SCPSignatureData)); 53 54 /* ALIGN: CFDataGetBytePtr aligns to at least 8 bytes */ 55 sig = (SCPSignatureDataRef)(void *)CFDataGetBytePtr(signature); 56 57 sig->st_dev = statBuf->st_dev; 58 sig->st_ino = statBuf->st_ino; 59 sig->tv_sec = statBuf->st_mtimespec.tv_sec; 60 sig->tv_nsec = statBuf->st_mtimespec.tv_nsec; 61 sig->st_size = statBuf->st_size; 62 return signature; 63} 64 65 66__private_extern__ char * 67__SCPreferencesPath(CFAllocatorRef allocator, 68 CFStringRef prefsID, 69 Boolean useNewPrefs) 70{ 71 CFStringRef path = NULL; 72 char *pathStr; 73 74 if (prefsID == NULL) { 75 /* default preference ID */ 76 path = CFStringCreateWithFormat(allocator, 77 NULL, 78 CFSTR("%@/%@"), 79 useNewPrefs ? PREFS_DEFAULT_DIR : PREFS_DEFAULT_DIR_OLD, 80 useNewPrefs ? PREFS_DEFAULT_CONFIG : PREFS_DEFAULT_CONFIG_OLD); 81 } else if (CFStringHasPrefix(prefsID, CFSTR("/"))) { 82 /* if absolute path */ 83 path = CFStringCreateCopy(allocator, prefsID); 84 } else { 85 /* relative path */ 86 path = CFStringCreateWithFormat(allocator, 87 NULL, 88 CFSTR("%@/%@"), 89 useNewPrefs ? PREFS_DEFAULT_DIR : PREFS_DEFAULT_DIR_OLD, 90 prefsID); 91 if (useNewPrefs && CFStringHasSuffix(path, CFSTR(".xml"))) { 92 CFMutableStringRef newPath; 93 94 newPath = CFStringCreateMutableCopy(allocator, 0, path); 95 CFStringReplace(newPath, 96 CFRangeMake(CFStringGetLength(newPath)-4, 4), 97 CFSTR(".plist")); 98 CFRelease(path); 99 path = newPath; 100 } 101 } 102 103 /* 104 * convert CFStringRef path to C-string path 105 */ 106 pathStr = _SC_cfstring_to_cstring(path, NULL, 0, kCFStringEncodingASCII); 107 if (pathStr == NULL) { 108 CFIndex pathLen; 109 110 pathLen = CFStringGetMaximumSizeOfFileSystemRepresentation(path); 111 pathStr = CFAllocatorAllocate(NULL, pathLen, 0); 112 if (CFStringGetFileSystemRepresentation(path, pathStr, pathLen) == FALSE) { 113 SCLog(_sc_verbose, LOG_DEBUG, CFSTR("could not convert path to C string")); 114 CFAllocatorDeallocate(NULL, pathStr); 115 pathStr = NULL; 116 } 117 } 118 119 CFRelease(path); 120 return pathStr; 121} 122 123 124__private_extern__ 125Boolean 126__SCPreferencesGetLimitSCNetworkConfiguration(SCPreferencesRef prefs) 127{ 128 SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; 129 130 if (prefs == NULL) { 131 return FALSE; 132 } 133 return prefsPrivate->limit_SCNetworkConfiguration; 134} 135 136 137__private_extern__ 138Boolean 139__SCPreferencesUsingDefaultPrefs(SCPreferencesRef prefs) 140{ 141 char *curPath; 142 Boolean isDefault = FALSE; 143 SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; 144 145 curPath = prefsPrivate->newPath ? prefsPrivate->newPath : prefsPrivate->path; 146 if (curPath != NULL) { 147 char* defPath; 148 149 defPath = __SCPreferencesPath(NULL, 150 NULL, 151 (prefsPrivate->newPath == NULL)); 152 if (defPath != NULL) { 153 if (strcmp(curPath, defPath) == 0) { 154 isDefault = TRUE; 155 } 156 CFAllocatorDeallocate(NULL, defPath); 157 } 158 } 159 return isDefault; 160} 161 162__private_extern__ 163SCPreferencesRef 164__SCPreferencesCreateNIPrefsFromPrefs(SCPreferencesRef prefs) 165{ 166 CFMutableStringRef newPath = NULL; 167 CFURLRef newURL = NULL; 168 SCPreferencesRef ni_prefs = NULL; 169 SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; 170 char * prefsPath = __SCPreferencesPath(NULL, prefsPrivate->prefsID, FALSE); 171 172 173 newPath = CFStringCreateMutable(NULL, 0); 174 CFStringAppendFormat(newPath, NULL, CFSTR("%s"), prefsPath); 175 176 CFStringFindAndReplace(newPath, PREFS_DEFAULT_CONFIG, 177 NETWORK_INTERFACES_PREFS, 178 CFRangeMake(0, CFStringGetLength(newPath)), 179 kCFCompareBackwards); 180 181 newURL = CFURLCreateWithFileSystemPath(NULL, newPath, kCFURLPOSIXPathStyle, FALSE); 182 if (CFURLResourceIsReachable(newURL, NULL) == FALSE) { 183 ni_prefs = __SCNetworkCreateDefaultNIPrefs(newPath); 184 } 185 else { 186 ni_prefs = SCPreferencesCreate(NULL, prefsPrivate->name, newPath); 187 } 188 CFAllocatorDeallocate(NULL, prefsPath); 189 CFRelease(newPath); 190 CFRelease(newURL); 191 192 return ni_prefs; 193} 194 195CFDataRef 196SCPreferencesGetSignature(SCPreferencesRef prefs) 197{ 198 SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; 199 200 if (prefs == NULL) { 201 /* sorry, you must provide a session */ 202 _SCErrorSet(kSCStatusNoPrefsSession); 203 return NULL; 204 } 205 206 __SCPreferencesAccess(prefs); 207 208 return prefsPrivate->signature; 209} 210 211 212__private_extern__ CF_RETURNS_RETAINED CFStringRef 213_SCPNotificationKey(CFAllocatorRef allocator, 214 CFStringRef prefsID, 215 int keyType) 216{ 217 CFStringRef keyStr; 218 char *path; 219 CFStringRef pathStr; 220 CFStringRef storeKey; 221 222 switch (keyType) { 223 case kSCPreferencesKeyLock : 224 keyStr = CFSTR("lock"); 225 break; 226 case kSCPreferencesKeyCommit : 227 keyStr = CFSTR("commit"); 228 break; 229 case kSCPreferencesKeyApply : 230 keyStr = CFSTR("apply"); 231 break; 232 default : 233 return NULL; 234 } 235 236 path = __SCPreferencesPath(allocator, prefsID, TRUE); 237 if (path == NULL) { 238 return NULL; 239 } 240 241 pathStr = CFStringCreateWithCStringNoCopy(allocator, 242 path, 243 kCFStringEncodingASCII, 244 kCFAllocatorNull); 245 246 storeKey = CFStringCreateWithFormat(allocator, 247 NULL, 248 CFSTR("%@%@:%@"), 249 kSCDynamicStoreDomainPrefs, 250 keyStr, 251 pathStr); 252 253 CFRelease(pathStr); 254 CFAllocatorDeallocate(NULL, path); 255 return storeKey; 256} 257 258 259CFStringRef 260SCDynamicStoreKeyCreatePreferences(CFAllocatorRef allocator, 261 CFStringRef prefsID, 262 SCPreferencesKeyType keyType) 263{ 264 return _SCPNotificationKey(allocator, prefsID, keyType); 265} 266 267 268__private_extern__ void 269__SCPreferencesSetLimitSCNetworkConfiguration(SCPreferencesRef prefs, 270 Boolean limit_SCNetworkConfiguration) 271{ 272 SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs; 273 274 if (prefs == NULL) { 275 return; 276 } 277 prefsPrivate->limit_SCNetworkConfiguration = limit_SCNetworkConfiguration; 278} 279