summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/mDNSMacOSX/PreferencePane/ddnswriteconfig.m
diff options
context:
space:
mode:
Diffstat (limited to 'mDNSResponder/mDNSMacOSX/PreferencePane/ddnswriteconfig.m')
-rw-r--r--mDNSResponder/mDNSMacOSX/PreferencePane/ddnswriteconfig.m462
1 files changed, 0 insertions, 462 deletions
diff --git a/mDNSResponder/mDNSMacOSX/PreferencePane/ddnswriteconfig.m b/mDNSResponder/mDNSMacOSX/PreferencePane/ddnswriteconfig.m
deleted file mode 100644
index 8e64fc46..00000000
--- a/mDNSResponder/mDNSMacOSX/PreferencePane/ddnswriteconfig.m
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- File: ddnswriteconfig.m
-
- Abstract: Setuid root tool invoked by Preference Pane to perform
- privileged accesses to system configuration preferences and the system keychain.
- Invoked by PrivilegedOperations.c.
-
- Copyright: (c) Copyright 2005 Apple Computer, Inc. All rights reserved.
-
- Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
- ("Apple") in consideration of your agreement to the following terms, and your
- use, installation, modification or redistribution of this Apple software
- constitutes acceptance of these terms. If you do not agree with these terms,
- please do not use, install, modify or redistribute this Apple software.
-
- In consideration of your agreement to abide by the following terms, and subject
- to these terms, Apple grants you a personal, non-exclusive license, under Apple's
- copyrights in this original Apple software (the "Apple Software"), to use,
- reproduce, modify and redistribute the Apple Software, with or without
- modifications, in source and/or binary forms; provided that if you redistribute
- the Apple Software in its entirety and without modifications, you must retain
- this notice and the following text and disclaimers in all such redistributions of
- the Apple Software. Neither the name, trademarks, service marks or logos of
- Apple Computer, Inc. may be used to endorse or promote products derived from the
- Apple Software without specific prior written permission from Apple. Except as
- expressly stated in this notice, no other rights or licenses, express or implied,
- are granted by Apple herein, including but not limited to any patent rights that
- may be infringed by your derivative works or by other works in which the Apple
- Software may be incorporated.
-
- The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
- WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
- WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
- COMBINATION WITH YOUR PRODUCTS.
-
- IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
- OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
- (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#import "PrivilegedOperations.h"
-#import "ConfigurationRights.h"
-
-#import <stdio.h>
-#import <stdint.h>
-#import <stdlib.h>
-#import <unistd.h>
-#import <fcntl.h>
-#import <errno.h>
-#import <sys/types.h>
-#import <sys/stat.h>
-#import <sys/mman.h>
-#import <mach-o/dyld.h>
-#import <dns_sd.h>
-#import <AssertMacros.h>
-#import <Security/Security.h>
-#import <CoreServices/CoreServices.h>
-#import <CoreFoundation/CoreFoundation.h>
-#import <SystemConfiguration/SystemConfiguration.h>
-#import <Foundation/Foundation.h>
-
-
-static AuthorizationRef gAuthRef = 0;
-
-static OSStatus
-WriteArrayToDynDNS(CFStringRef arrayKey, CFArrayRef domainArray)
-{
- SCPreferencesRef store;
- OSStatus err = noErr;
- CFDictionaryRef origDict;
- CFMutableDictionaryRef dict = NULL;
- Boolean result;
- CFStringRef scKey = CFSTR("/System/Network/DynamicDNS");
-
-
- // Add domain to the array member ("arrayKey") of the DynamicDNS dictionary
- // Will replace duplicate, at head of list
- // At this point, we only support a single-item list
- store = SCPreferencesCreate(NULL, CFSTR("com.apple.preference.bonjour"), NULL);
- require_action(store != NULL, SysConfigErr, err=paramErr;);
- require_action(true == SCPreferencesLock( store, true), LockFailed, err=coreFoundationUnknownErr;);
-
- origDict = SCPreferencesPathGetValue(store, scKey);
- if (origDict)
- {
- dict = CFDictionaryCreateMutableCopy(NULL, 0, origDict);
- }
-
- if (!dict)
- {
- dict = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- }
- require_action( dict != NULL, NoDict, err=memFullErr;);
-
- if (CFArrayGetCount(domainArray) > 0)
- {
- CFDictionarySetValue(dict, arrayKey, domainArray);
- }
- else
- {
- CFDictionaryRemoveValue(dict, arrayKey);
- }
-
- result = SCPreferencesPathSetValue(store, scKey, dict);
- require_action(result, SCError, err=kernelPrivilegeErr;);
-
- result = SCPreferencesCommitChanges(store);
- require_action(result, SCError, err=kernelPrivilegeErr;);
- result = SCPreferencesApplyChanges(store);
- require_action(result, SCError, err=kernelPrivilegeErr;);
-
-SCError:
- CFRelease(dict);
-NoDict:
- SCPreferencesUnlock(store);
-LockFailed:
- CFRelease(store);
-SysConfigErr:
- return err;
-}
-
-
-static int
-readTaggedBlock(int fd, u_int32_t *pTag, u_int32_t *pLen, char **ppBuff)
-// Read tag, block len and block data from stream and return. Dealloc *ppBuff via free().
-{
- ssize_t num;
- u_int32_t tag, len; // Don't use ssize_t because that's different on 32- vs. 64-bit
- int result = 0;
-
- num = read(fd, &tag, sizeof tag);
- require_action(num == sizeof tag, GetTagFailed, result = -1;);
- num = read(fd, &len, sizeof len);
- require_action(num == sizeof len, GetLenFailed, result = -1;);
-
- *ppBuff = (char*) malloc( len);
- require_action(*ppBuff != NULL, AllocFailed, result = -1;);
-
- num = read(fd, *ppBuff, len);
- if (num == (ssize_t)len)
- {
- *pTag = tag;
- *pLen = len;
- }
- else
- {
- free(*ppBuff);
- result = -1;
- }
-
-AllocFailed:
-GetLenFailed:
-GetTagFailed:
- return result;
-}
-
-
-
-static int
-SetAuthInfo( int fd)
-{
- int result = 0;
- u_int32_t tag, len;
- char *p;
-
- result = readTaggedBlock( fd, &tag, &len, &p);
- require( result == 0, ReadParamsFailed);
- require( len == sizeof(AuthorizationExternalForm), ReadParamsFailed);
- require( len == kAuthorizationExternalFormLength, ReadParamsFailed);
-
- if (gAuthRef != 0)
- {
- (void) AuthorizationFree(gAuthRef, kAuthorizationFlagDefaults);
- gAuthRef = 0;
- }
-
- result = AuthorizationCreateFromExternalForm((AuthorizationExternalForm*) p, &gAuthRef);
-
- free( p);
-ReadParamsFailed:
- return result;
-}
-
-
-static int
-HandleWriteDomain(int fd, int domainType)
-{
- CFArrayRef domainArray;
- CFDataRef domainData;
- int result = 0;
- u_int32_t tag, len;
- char *p;
-
- AuthorizationItem scAuth = { UPDATE_SC_RIGHT, 0, NULL, 0 };
- AuthorizationRights authSet = { 1, &scAuth };
-
- if (noErr != (result = AuthorizationCopyRights(gAuthRef, &authSet, NULL, (AuthorizationFlags)0, NULL)))
- return result;
-
- result = readTaggedBlock(fd, &tag, &len, &p);
- require(result == 0, ReadParamsFailed);
-
- domainData = CFDataCreate(NULL, (UInt8 *)p, len);
- domainArray = (CFArrayRef)[NSUnarchiver unarchiveObjectWithData:(NSData *)domainData];
- CFRelease(domainData);
- free(p);
-
- if (domainType)
- {
- result = WriteArrayToDynDNS(SC_DYNDNS_REGDOMAINS_KEY, domainArray);
- }
- else
- {
- result = WriteArrayToDynDNS(SC_DYNDNS_BROWSEDOMAINS_KEY, domainArray);
- }
-
-ReadParamsFailed:
- return result;
-}
-
-
-static int
-HandleWriteHostname(int fd)
-{
- CFArrayRef domainArray;
- CFDataRef domainData;
- int result = 0;
- u_int32_t tag, len;
- char *p;
-
- AuthorizationItem scAuth = { UPDATE_SC_RIGHT, 0, NULL, 0 };
- AuthorizationRights authSet = { 1, &scAuth };
-
- if (noErr != (result = AuthorizationCopyRights(gAuthRef, &authSet, NULL, (AuthorizationFlags) 0, NULL)))
- return result;
-
- result = readTaggedBlock(fd, &tag, &len, &p);
- require(result == 0, ReadParamsFailed);
-
- domainData = CFDataCreate(NULL, (const UInt8 *)p, len);
- domainArray = (CFArrayRef)[NSUnarchiver unarchiveObjectWithData:(NSData *)domainData];
- result = WriteArrayToDynDNS(SC_DYNDNS_HOSTNAMES_KEY, domainArray);
- CFRelease(domainData);
- free(p);
-
-ReadParamsFailed:
- return result;
-}
-
-
-static SecAccessRef
-MyMakeUidAccess(uid_t uid)
-{
- // make the "uid/gid" ACL subject
- // this is a CSSM_LIST_ELEMENT chain
- CSSM_ACL_PROCESS_SUBJECT_SELECTOR selector = {
- CSSM_ACL_PROCESS_SELECTOR_CURRENT_VERSION, // selector version
- CSSM_ACL_MATCH_UID, // set mask: match uids (only)
- uid, // uid to match
- 0 // gid (not matched here)
- };
- CSSM_LIST_ELEMENT subject2 = { NULL, 0, 0, {{0,0,0}} };
- subject2.Element.Word.Data = (UInt8 *)&selector;
- subject2.Element.Word.Length = sizeof(selector);
- CSSM_LIST_ELEMENT subject1 = { &subject2, CSSM_ACL_SUBJECT_TYPE_PROCESS, CSSM_LIST_ELEMENT_WORDID, {{0,0,0}} };
-
-
- // rights granted (replace with individual list if desired)
- CSSM_ACL_AUTHORIZATION_TAG rights[] = {
- CSSM_ACL_AUTHORIZATION_ANY // everything
- };
- // owner component (right to change ACL)
- CSSM_ACL_OWNER_PROTOTYPE owner = {
- // TypedSubject
- { CSSM_LIST_TYPE_UNKNOWN, &subject1, &subject2 },
- // Delegate
- false
- };
- // ACL entries (any number, just one here)
- CSSM_ACL_ENTRY_INFO acls =
- {
- // CSSM_ACL_ENTRY_PROTOTYPE
- {
- { CSSM_LIST_TYPE_UNKNOWN, &subject1, &subject2 }, // TypedSubject
- false, // Delegate
- { sizeof(rights) / sizeof(rights[0]), rights }, // Authorization rights for this entry
- { { 0, 0 }, { 0, 0 } }, // CSSM_ACL_VALIDITY_PERIOD
- "" // CSSM_STRING EntryTag
- },
- // CSSM_ACL_HANDLE
- 0
- };
-
- SecAccessRef a = NULL;
- (void) SecAccessCreateFromOwnerAndACL(&owner, 1, &acls, &a);
- return a;
-}
-
-
-static OSStatus
-MyAddDynamicDNSPassword(SecKeychainRef keychain, SecAccessRef a, UInt32 serviceNameLength, const char *serviceName,
- UInt32 accountNameLength, const char *accountName, UInt32 passwordLength, const void *passwordData)
-{
- char * description = DYNDNS_KEYCHAIN_DESCRIPTION;
- UInt32 descriptionLength = strlen(DYNDNS_KEYCHAIN_DESCRIPTION);
- UInt32 type = 'ddns';
- UInt32 creator = 'ddns';
- UInt32 typeLength = sizeof(type);
- UInt32 creatorLength = sizeof(creator);
- OSStatus err;
-
- // set up attribute vector (each attribute consists of {tag, length, pointer})
- SecKeychainAttribute attrs[] = { { kSecLabelItemAttr, serviceNameLength, (char *)serviceName },
- { kSecAccountItemAttr, accountNameLength, (char *)accountName },
- { kSecServiceItemAttr, serviceNameLength, (char *)serviceName },
- { kSecDescriptionItemAttr, descriptionLength, (char *)description },
- { kSecTypeItemAttr, typeLength, (UInt32 *)&type },
- { kSecCreatorItemAttr, creatorLength, (UInt32 *)&creator } };
- SecKeychainAttributeList attributes = { sizeof(attrs) / sizeof(attrs[0]), attrs };
-
- err = SecKeychainItemCreateFromContent(kSecGenericPasswordItemClass, &attributes, passwordLength, passwordData, keychain, a, NULL);
- return err;
-}
-
-
-static int
-SetKeychainEntry(int fd)
-// Create a new entry in system keychain, or replace existing
-{
- CFDataRef secretData;
- CFDictionaryRef secretDictionary;
- CFStringRef keyNameString;
- CFStringRef domainString;
- CFStringRef secretString;
- SecKeychainItemRef item = NULL;
- int result = 0;
- u_int32_t tag, len;
- char *p;
- char keyname[kDNSServiceMaxDomainName];
- char domain[kDNSServiceMaxDomainName];
- char secret[kDNSServiceMaxDomainName];
-
- AuthorizationItem kcAuth = { EDIT_SYS_KEYCHAIN_RIGHT, 0, NULL, 0 };
- AuthorizationRights authSet = { 1, &kcAuth };
-
- if (noErr != (result = AuthorizationCopyRights(gAuthRef, &authSet, NULL, (AuthorizationFlags)0, NULL)))
- return result;
-
- result = readTaggedBlock(fd, &tag, &len, &p);
- require_noerr(result, ReadParamsFailed);
-
- secretData = CFDataCreate(NULL, (UInt8 *)p, len);
- secretDictionary = (CFDictionaryRef)[NSUnarchiver unarchiveObjectWithData:(NSData *)secretData];
- CFRelease(secretData);
- free(p);
-
- keyNameString = (CFStringRef)CFDictionaryGetValue(secretDictionary, SC_DYNDNS_KEYNAME_KEY);
- assert(keyNameString != NULL);
-
- domainString = (CFStringRef)CFDictionaryGetValue(secretDictionary, SC_DYNDNS_DOMAIN_KEY);
- assert(domainString != NULL);
-
- secretString = (CFStringRef)CFDictionaryGetValue(secretDictionary, SC_DYNDNS_SECRET_KEY);
- assert(secretString != NULL);
-
- CFStringGetCString(keyNameString, keyname, kDNSServiceMaxDomainName, kCFStringEncodingUTF8);
- CFStringGetCString(domainString, domain, kDNSServiceMaxDomainName, kCFStringEncodingUTF8);
- CFStringGetCString(secretString, secret, kDNSServiceMaxDomainName, kCFStringEncodingUTF8);
-
- result = SecKeychainSetPreferenceDomain(kSecPreferencesDomainSystem);
- if (result == noErr)
- {
- result = SecKeychainFindGenericPassword(NULL, strlen(domain), domain, 0, NULL, 0, NULL, &item);
- if (result == noErr)
- {
- result = SecKeychainItemDelete(item);
- if (result != noErr) fprintf(stderr, "SecKeychainItemDelete returned %d\n", result);
- }
-
- result = MyAddDynamicDNSPassword(NULL, MyMakeUidAccess(0), strlen(domain), domain, strlen(keyname)+1, keyname, strlen(secret)+1, secret);
- if (result != noErr) fprintf(stderr, "MyAddDynamicDNSPassword returned %d\n", result);
- if (item) CFRelease(item);
- }
-
-ReadParamsFailed:
- return result;
-}
-
-
-int main( int argc, char **argv)
-/* argv[0] is the exec path; argv[1] is a fd for input data; argv[2]... are operation codes.
- The tool supports the following operations:
- V -- exit with status PRIV_OP_TOOL_VERS
- A -- read AuthInfo from input pipe
- Wd -- write registration domain to dynamic store
- Wb -- write browse domain to dynamic store
- Wh -- write hostname to dynamic store
- Wk -- write keychain entry for given account name
-*/
-{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- int commFD = -1, iArg, result = 0;
-
- if ( 0 != seteuid( 0))
- return -1;
-
- if ( argc == 3 && 0 == strcmp( argv[2], "V"))
- return PRIV_OP_TOOL_VERS;
-
- if ( argc > 1)
- {
- commFD = strtol( argv[1], NULL, 0);
- lseek( commFD, 0, SEEK_SET);
- }
- for ( iArg = 2; iArg < argc && result == 0; iArg++)
- {
- if ( 0 == strcmp( "A", argv[ iArg])) // get auth info
- {
- result = SetAuthInfo( commFD);
- }
- else if ( 0 == strcmp( "Wd", argv[ iArg])) // Write registration domain
- {
- result = HandleWriteDomain( commFD, 1);
- }
- else if ( 0 == strcmp( "Wb", argv[ iArg])) // Write browse domain
- {
- result = HandleWriteDomain( commFD, 0);
- }
- else if ( 0 == strcmp( "Wh", argv[ iArg])) // Write hostname
- {
- result = HandleWriteHostname( commFD);
- }
- else if ( 0 == strcmp( "Wk", argv[ iArg])) // Write keychain entry
- {
- result = SetKeychainEntry( commFD);
- }
- }
- [pool release];
- return result;
-}
-
-// Note: The C preprocessor stringify operator ('#') makes a string from its argument, without macro expansion
-// e.g. If "version" is #define'd to be "4", then STRINGIFY_AWE(version) will return the string "version", not "4"
-// To expand "version" to its value before making the string, use STRINGIFY(version) instead
-#define STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) #s
-#define STRINGIFY(s) STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s)
-
-// NOT static -- otherwise the compiler may optimize it out
-// The "@(#) " pattern is a special prefix the "what" command looks for
-const char VersionString_SCCS[] = "@(#) ddnswriteconfig " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
-
-#if _BUILDING_XCODE_PROJECT_
-// If the process crashes, then this string will be magically included in the automatically-generated crash log
-const char *__crashreporter_info__ = VersionString_SCCS + 5;
-asm(".desc ___crashreporter_info__, 0x10");
-#endif