ConfigurationAuthority.c [plain text]
#include "ConfigurationAuthority.h"
#include "ConfigurationRights.h"
#include <AssertMacros.h>
static AuthorizationRef gAuthRef = 0;
static AuthorizationItem gAuthorizations[] = { { UPDATE_SC_RIGHT, 0, NULL, 0 },
{ EDIT_SYS_KEYCHAIN_RIGHT, 0, NULL, 0 }};
static AuthorizationRights gAuthSet = { sizeof gAuthorizations / sizeof gAuthorizations[0], gAuthorizations };
static CFDictionaryRef CreateRightsDict( CFStringRef prompt)
{
CFMutableDictionaryRef dict = NULL, tmpDict;
CFMutableArrayRef mechanisms;
CFNumberRef timeout;
int val;
tmpDict = CFDictionaryCreateMutable( (CFAllocatorRef) NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
require( tmpDict != NULL, MakeDictFailed);
CFDictionaryAddValue(tmpDict, CFSTR("class"), CFSTR("user"));
CFDictionaryAddValue(tmpDict, CFSTR("comment"), prompt);
CFDictionaryAddValue(tmpDict, CFSTR("group"), CFSTR("admin"));
mechanisms = CFArrayCreateMutable((CFAllocatorRef) NULL, 1, &kCFTypeArrayCallBacks);
require( mechanisms != NULL, MakeArrayFailed);
CFArrayAppendValue( mechanisms, CFSTR("builtin:authenticate"));
CFDictionaryAddValue( tmpDict, CFSTR("mechanisms"), mechanisms);
val = 300; timeout = CFNumberCreate((CFAllocatorRef) NULL, kCFNumberIntType, &val);
require( timeout != NULL, MakeIntFailed);
CFDictionaryAddValue( tmpDict, CFSTR("timeout"), timeout);
CFDictionaryAddValue( tmpDict, CFSTR("shared"), kCFBooleanTrue);
dict = tmpDict;
tmpDict = NULL;
CFRelease( timeout);
MakeIntFailed:
CFRelease( mechanisms);
MakeArrayFailed:
if ( tmpDict)
CFRelease( tmpDict);
MakeDictFailed:
return dict;
}
OSStatus InitConfigAuthority(void)
{
OSStatus err;
CFDictionaryRef dict;
CFStringRef rightInfo;
err = AuthorizationCreate((AuthorizationRights*) NULL, (AuthorizationEnvironment*) NULL,
(AuthorizationFlags) 0, &gAuthRef);
require_noerr( err, NewAuthFailed);
err = AuthorizationRightGet( UPDATE_SC_RIGHT, (CFDictionaryRef*) NULL);
if( err == errAuthorizationDenied)
{
rightInfo = CFCopyLocalizedString(CFSTR("Authentication required to set Dynamic DNS preferences."),
CFSTR("Describes operation that requires user authorization"));
require_action( rightInfo != NULL, GetStrFailed, err=coreFoundationUnknownErr;);
dict = CreateRightsDict(rightInfo);
require_action( dict != NULL, GetStrFailed, err=coreFoundationUnknownErr;);
err = AuthorizationRightSet(gAuthRef, UPDATE_SC_RIGHT, dict, (CFStringRef) NULL,
(CFBundleRef) NULL, (CFStringRef) NULL);
CFRelease(rightInfo);
CFRelease(dict);
}
require_noerr( err, AuthSetFailed);
err = AuthorizationRightGet( EDIT_SYS_KEYCHAIN_RIGHT, (CFDictionaryRef*) NULL);
if( err == errAuthorizationDenied)
{
rightInfo = CFCopyLocalizedString( CFSTR("Authentication required to edit System Keychain."),
CFSTR("Describes operation that requires user authorization"));
require_action( rightInfo != NULL, GetStrFailed, err=coreFoundationUnknownErr;);
dict = CreateRightsDict( rightInfo);
require_action( dict != NULL, GetStrFailed, err=coreFoundationUnknownErr;);
err = AuthorizationRightSet(gAuthRef, EDIT_SYS_KEYCHAIN_RIGHT, dict, (CFStringRef) NULL,
(CFBundleRef) NULL, (CFStringRef) NULL);
CFRelease( rightInfo);
CFRelease( dict);
}
require_noerr( err, AuthSetFailed);
AuthSetFailed:
GetStrFailed:
NewAuthFailed:
return err;
}
OSStatus AttemptAcquireAuthority( Boolean allowUI)
{
AuthorizationFlags allowFlag = allowUI ? kAuthorizationFlagInteractionAllowed : 0;
OSStatus err;
err = AuthorizationCopyRights( gAuthRef, &gAuthSet, (AuthorizationEnvironment*) NULL,
kAuthorizationFlagExtendRights | kAuthorizationFlagPreAuthorize |
allowFlag,
(AuthorizationRights**) NULL);
return err;
}
OSStatus ReleaseAuthority(void)
{
(void) AuthorizationFree( gAuthRef, kAuthorizationFlagDefaults);
gAuthRef = 0;
return AuthorizationCreate( (AuthorizationRights*) NULL, (AuthorizationEnvironment*) NULL,
(AuthorizationFlags) 0, &gAuthRef);
}
Boolean CurrentlyAuthorized(void)
{
OSStatus err = AttemptAcquireAuthority(true);
return err == noErr;
}
OSStatus ExternalizeAuthority(AuthorizationExternalForm *pAuth)
{
return AuthorizationMakeExternalForm(gAuthRef, pAuth);
}