-/* Copyright (c) 2012 Apple Inc. All rights reserved. */
-
-#include "Authorization.h"
-#include "authd_private.h"
-#include "authutilities.h"
-#include "debugging.h"
-
-#include <Security/AuthorizationPriv.h>
-#include <Security/AuthorizationDB.h>
-#include <Security/AuthorizationTags.h>
-#include <Security/AuthorizationTagsPriv.h>
-#include <xpc/xpc.h>
-#include <xpc/private.h>
-#include <mach/mach.h>
-#include <syslog.h>
-#include <AssertMacros.h>
-#include <CoreFoundation/CFXPCBridge.h>
-
-static dispatch_queue_t
-get_authorization_dispatch_queue()
-{
- static dispatch_once_t onceToken = 0;
- static dispatch_queue_t connection_queue = NULL;
-
- dispatch_once(&onceToken, ^{
- connection_queue = dispatch_queue_create("authorization-connection-queue", DISPATCH_QUEUE_SERIAL);
- });
-
- return connection_queue;
-}
-
-static xpc_connection_t
-get_authorization_connection()
-{
- static xpc_connection_t connection = NULL;
-
- dispatch_sync(get_authorization_dispatch_queue(), ^{
- if (connection == NULL) {
- connection = xpc_connection_create(SECURITY_AUTH_NAME, NULL);
-
- if (!connection) {
- syslog(LOG_ERR, "Authorization, failed to create xpc connection to %s", SECURITY_AUTH_NAME);
- connection = xpc_connection_create(SECURITY_AUTH_NAME, NULL);
- }
-
- xpc_connection_set_event_handler(connection, ^(xpc_object_t event) {
- if (xpc_get_type(event) == XPC_TYPE_ERROR) {
- if (event == XPC_ERROR_CONNECTION_INVALID) {
- syslog(LOG_ERR, "Authorization, server not available");
- }
- // XPC_ERROR_CONNECTION_INTERRUPTED
- // XPC_ERROR_TERMINATION_IMMINENT
- } else {
- char * desc = xpc_copy_description(event);
- syslog(LOG_ERR, "Authorization, we should never get messages on this connection: %s", desc);
- free(desc);
- }
- });
-
- xpc_connection_resume(connection);
-
- // Send
- xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
- xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_SETUP);
- mach_port_t bootstrap = MACH_PORT_NULL;
- task_get_bootstrap_port(mach_task_self(), &bootstrap);
- xpc_dictionary_set_mach_send(message, AUTH_XPC_BOOTSTRAP, bootstrap);
- xpc_object_t reply = xpc_connection_send_message_with_reply_sync(connection, message);
- xpc_release_safe(message);
- xpc_release_safe(reply);
- }
- });
-
- return connection;
-}
-
-static void
-setItemSet(xpc_object_t message, const char * key, const AuthorizationItemSet * itemSet)
-{
- xpc_object_t serialized = SerializeItemSet(itemSet);
- if (serialized) {
- xpc_dictionary_set_value(message, key, serialized);
- xpc_release(serialized);
- }
-}
-
-OSStatus AuthorizationCreate(const AuthorizationRights *rights,
- const AuthorizationEnvironment *environment,
- AuthorizationFlags flags,
- AuthorizationRef *authorization)
-{
- OSStatus status = errAuthorizationInternal;
- xpc_object_t message = NULL;
- xpc_object_t reply = NULL;
-
-// require_action(!(rights == NULL && authorization == NULL), done, status = errAuthorizationInvalidSet);
-
- // Send
- message = xpc_dictionary_create(NULL, NULL, 0);
- require_action(message != NULL, done, status = errAuthorizationInternal);
-
- xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_CREATE);
- setItemSet(message, AUTH_XPC_RIGHTS, rights);
- setItemSet(message, AUTH_XPC_ENVIROMENT, environment);
- xpc_dictionary_set_uint64(message, AUTH_XPC_FLAGS, flags | (authorization ? 0 : kAuthorizationFlagNoData));
-
- // Reply
- reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
- require_action(reply != NULL, done, status = errAuthorizationInternal);
- require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
-
- // Status
- status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
-
- // Out
- if (authorization && status == errAuthorizationSuccess) {
- size_t len;
- const void * data = xpc_dictionary_get_data(reply, AUTH_XPC_BLOB, &len);
- require_action(data != NULL, done, status = errAuthorizationInternal);
- assert(len == sizeof(AuthorizationBlob));
-
- AuthorizationBlob * blob = (AuthorizationBlob*)calloc(1u, sizeof(AuthorizationBlob));
- require_action(blob != NULL, done, status = errAuthorizationInternal);
- *blob = *(AuthorizationBlob*)data;
-
- *authorization = (AuthorizationRef)blob;
- }
-
-done:
- xpc_release_safe(message);
- xpc_release_safe(reply);
- return status;
-}
-
-OSStatus AuthorizationCreateWithAuditToken(audit_token_t token,
- const AuthorizationEnvironment *environment,
- AuthorizationFlags flags,
- AuthorizationRef *authorization)
-{
- OSStatus status = errAuthorizationInternal;
- xpc_object_t message = NULL;
- xpc_object_t reply = NULL;
-
- require_action(authorization != NULL, done, status = errAuthorizationInvalidPointer);
-
- // Send
- message = xpc_dictionary_create(NULL, NULL, 0);
- require_action(message != NULL, done, status = errAuthorizationInternal);
-
- xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_CREATE_WITH_AUDIT_TOKEN);
- xpc_dictionary_set_data(message, AUTH_XPC_DATA, &token, sizeof(token));
- setItemSet(message, AUTH_XPC_ENVIROMENT, environment);
- xpc_dictionary_set_uint64(message, AUTH_XPC_FLAGS, flags);
-
- // Reply
- reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
- require_action(reply != NULL, done, status = errAuthorizationInternal);
- require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
-
- // Status
- status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
-
- // Out
- if (status == errAuthorizationSuccess) {
- size_t len;
- const void * data = xpc_dictionary_get_data(reply, AUTH_XPC_BLOB, &len);
- require_action(data != NULL, done, status = errAuthorizationInternal);
- assert(len == sizeof(AuthorizationBlob));
-
- AuthorizationBlob * blob = (AuthorizationBlob*)calloc(1u, sizeof(AuthorizationBlob));
- require_action(blob != NULL, done, status = errAuthorizationInternal);
- *blob = *(AuthorizationBlob*)data;
-
- *authorization = (AuthorizationRef)blob;
- }
-
-done:
- xpc_release_safe(message);
- xpc_release_safe(reply);
- return status;
-}
-
-OSStatus AuthorizationFree(AuthorizationRef authorization, AuthorizationFlags flags)
-{
- OSStatus status = errAuthorizationInternal;
- xpc_object_t message = NULL;
- xpc_object_t reply = NULL;
- AuthorizationBlob *blob = NULL;
-
- require_action(authorization != NULL, done, status = errAuthorizationInvalidRef);
- blob = (AuthorizationBlob *)authorization;
-
- // Send
- message = xpc_dictionary_create(NULL, NULL, 0);
- require_action(message != NULL, done, status = errAuthorizationInternal);
-
- xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_FREE);
- xpc_dictionary_set_data(message, AUTH_XPC_BLOB, blob, sizeof(AuthorizationBlob));
- xpc_dictionary_set_uint64(message, AUTH_XPC_FLAGS, flags);
-
- // Reply
- reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
- require_action(reply != NULL, done, status = errAuthorizationInternal);
- require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
-
- // Status
- status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
-
- // Free
- free(blob);
-
-done:
- xpc_release_safe(message);
- xpc_release_safe(reply);
- return status;
-}
-
-static OSStatus
-_AuthorizationCopyRights_send_message(xpc_object_t message, AuthorizationRights **authorizedRights)
-{
- OSStatus status = errAuthorizationInternal;
- xpc_object_t reply = NULL;
-
- // Send
- require_action(message != NULL, done, status = errAuthorizationInternal);
-
- // Reply
- reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
- require_action(reply != NULL, done, status = errAuthorizationInternal);
- require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
-
- // Status
- status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
-
- // Out
- if (authorizedRights && status == errAuthorizationSuccess) {
- xpc_object_t tmpItems = xpc_dictionary_get_value(reply, AUTH_XPC_OUT_ITEMS);
- AuthorizationRights * grantedRights = DeserializeItemSet(tmpItems);
- require_action(grantedRights != NULL, done, status = errAuthorizationInternal);
-
- *authorizedRights = grantedRights;
- }
-
-done:
- xpc_release_safe(reply);
- return status;
-}
-
-static OSStatus
-_AuthorizationCopyRights_prepare_message(AuthorizationRef authorization, const AuthorizationRights *rights, const AuthorizationEnvironment *environment, AuthorizationFlags flags, xpc_object_t *message_out)
-{
- OSStatus status = errAuthorizationInternal;
- AuthorizationBlob *blob = NULL;
- xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0);
- require_action(message != NULL, done, status = errAuthorizationInternal);
-
- require_action(authorization != NULL, done, status = errAuthorizationInvalidRef);
- blob = (AuthorizationBlob *)authorization;
-
- xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_COPY_RIGHTS);
- xpc_dictionary_set_data(message, AUTH_XPC_BLOB, blob, sizeof(AuthorizationBlob));
- setItemSet(message, AUTH_XPC_RIGHTS, rights);
- setItemSet(message, AUTH_XPC_ENVIROMENT, environment);
- xpc_dictionary_set_uint64(message, AUTH_XPC_FLAGS, flags);
-
- *message_out = message;
- message = NULL;
- status = errAuthorizationSuccess;
-
-done:
- xpc_release_safe(message);
- return status;
-}
-
-OSStatus AuthorizationCopyRights(AuthorizationRef authorization,
- const AuthorizationRights *rights,
- const AuthorizationEnvironment *environment,
- AuthorizationFlags flags,
- AuthorizationRights **authorizedRights)
-{
- OSStatus status = errAuthorizationInternal;
- xpc_object_t message = NULL;
-
- require_noerr(status = _AuthorizationCopyRights_prepare_message(authorization, rights, environment, flags, &message), done);
- require_noerr(status = _AuthorizationCopyRights_send_message(message, authorizedRights), done);
-
-done:
- xpc_release_safe(message);
- return status;
-}
-
-
-void AuthorizationCopyRightsAsync(AuthorizationRef authorization,
- const AuthorizationRights *rights,
- const AuthorizationEnvironment *environment,
- AuthorizationFlags flags,
- AuthorizationAsyncCallback callbackBlock)
-{
- OSStatus prepare_status = errAuthorizationInternal;
- __block xpc_object_t message = NULL;
-
- prepare_status = _AuthorizationCopyRights_prepare_message(authorization, rights, environment, flags, &message);
- if (prepare_status != errAuthorizationSuccess) {
- callbackBlock(prepare_status, NULL);
- }
-
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- AuthorizationRights *blockAuthorizedRights = NULL;
- OSStatus status = _AuthorizationCopyRights_send_message(message, &blockAuthorizedRights);
- callbackBlock(status, blockAuthorizedRights);
- xpc_release_safe(message);
- });
-}
-
-OSStatus AuthorizationDismiss()
-{
- OSStatus status = errAuthorizationInternal;
- xpc_object_t message = NULL;
- xpc_object_t reply = NULL;
-
- // Send
- message = xpc_dictionary_create(NULL, NULL, 0);
- require(message != NULL, done);
-
- xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_DISMISS);
-
- // Reply
- reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
- require_action(reply != NULL, done, status = errAuthorizationInternal);
- require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
-
- // Status
- status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
-
-done:
- xpc_release_safe(message);
- xpc_release_safe(reply);
- return status;
-}
-
-OSStatus AuthorizationCopyInfo(AuthorizationRef authorization,
- AuthorizationString tag,
- AuthorizationItemSet **info)
-{
- OSStatus status = errAuthorizationInternal;
- xpc_object_t message = NULL;
- xpc_object_t reply = NULL;
- AuthorizationBlob *blob = NULL;
-
- require_action(info != NULL, done, status = errAuthorizationInvalidSet);
- require_action(authorization != NULL, done, status = errAuthorizationInvalidRef);
- blob = (AuthorizationBlob *)authorization;
-
- // Send
- message = xpc_dictionary_create(NULL, NULL, 0);
- require_action(message != NULL, done, status = errAuthorizationInternal);
-
- xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_COPY_INFO);
- xpc_dictionary_set_data(message, AUTH_XPC_BLOB, blob, sizeof(AuthorizationBlob));
- if (tag) {
- xpc_dictionary_set_string(message, AUTH_XPC_TAG, tag);
- }
-
- // Reply
- reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
- require_action(reply != NULL, done, status = errAuthorizationInternal);
- require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
-
- // Status
- status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
-
- // Out
- if (info && status == errAuthorizationSuccess) {
- xpc_object_t tmpItems = xpc_dictionary_get_value(reply, AUTH_XPC_OUT_ITEMS);
- AuthorizationRights * outInfo = DeserializeItemSet(tmpItems);
- require_action(outInfo != NULL, done, status = errAuthorizationInternal);
-
- *info = outInfo;
- }
-
-done:
- xpc_release_safe(message);
- xpc_release_safe(reply);
- return status;
-}
-
-OSStatus AuthorizationMakeExternalForm(AuthorizationRef authorization,
- AuthorizationExternalForm *extForm)
-{
- OSStatus status = errAuthorizationInternal;
- xpc_object_t message = NULL;
- xpc_object_t reply = NULL;
- AuthorizationBlob *blob = NULL;
-
- require_action(extForm != NULL, done, status = errAuthorizationInvalidPointer);
- require_action(authorization != NULL, done, status = errAuthorizationInvalidRef);
- blob = (AuthorizationBlob *)authorization;
-
- // Send
- message = xpc_dictionary_create(NULL, NULL, 0);
- require_action(message != NULL, done, status = errAuthorizationInternal);
-
- xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_MAKE_EXTERNAL_FORM);
- xpc_dictionary_set_data(message, AUTH_XPC_BLOB, blob, sizeof(AuthorizationBlob));
-
- // Reply
- reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
- require_action(reply != NULL, done, status = errAuthorizationInternal);
- require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
-
- // Status
- status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
-
- // out
- if (status == errAuthorizationSuccess) {
- size_t len;
- const void * data = xpc_dictionary_get_data(reply, AUTH_XPC_EXTERNAL, &len);
- require_action(data != NULL, done, status = errAuthorizationInternal);
- assert(len == sizeof(AuthorizationExternalForm));
-
- *extForm = *(AuthorizationExternalForm*)data;
- }
-
-done:
- xpc_release_safe(message);
- xpc_release_safe(reply);
- return status;
-}
-
-OSStatus AuthorizationCreateFromExternalForm(const AuthorizationExternalForm *extForm,
- AuthorizationRef *authorization)
-{
- OSStatus status = errAuthorizationInternal;
- xpc_object_t message = NULL;
- xpc_object_t reply = NULL;
-
- require_action(extForm != NULL, done, status = errAuthorizationInvalidPointer);
- require_action(authorization != NULL, done, status = errAuthorizationInvalidRef);
-
- // Send
- message = xpc_dictionary_create(NULL, NULL, 0);
- require_action(message != NULL, done, status = errAuthorizationInternal);
-
- xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_CREATE_FROM_EXTERNAL_FORM);
- xpc_dictionary_set_data(message, AUTH_XPC_EXTERNAL, extForm, sizeof(AuthorizationExternalForm));
-
- // Reply
- reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
- require_action(reply != NULL, done, status = errAuthorizationInternal);
- require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
-
- // Status
- status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
-
- // Out
- if (authorization && status == errAuthorizationSuccess) {
- size_t len;
- const void * data = xpc_dictionary_get_data(reply, AUTH_XPC_BLOB, &len);
- require_action(data != NULL, done, status = errAuthorizationInternal);
- assert(len == sizeof(AuthorizationBlob));
-
- AuthorizationBlob * blob = (AuthorizationBlob*)calloc(1u, sizeof(AuthorizationBlob));
- require_action(blob != NULL, done, status = errAuthorizationInternal);
- *blob = *(AuthorizationBlob*)data;
-
- *authorization = (AuthorizationRef)blob;
- }
-
-done:
- xpc_release_safe(message);
- xpc_release_safe(reply);
- return status;
-}
-
-OSStatus AuthorizationFreeItemSet(AuthorizationItemSet *set)
-{
- FreeItemSet(set);
- return errAuthorizationSuccess;
-}
-
-OSStatus AuthorizationEnableSmartCard(AuthorizationRef authRef, Boolean enable)
-{
- OSStatus status = errAuthorizationInternal;
- xpc_object_t message = NULL;
- xpc_object_t reply = NULL;
- AuthorizationBlob *blob = NULL;
-
- // Send
- message = xpc_dictionary_create(NULL, NULL, 0);
- require_action(message != NULL, done, status = errAuthorizationInternal);
- require_action(authRef != NULL, done, status = errAuthorizationInvalidRef);
- blob = (AuthorizationBlob *)authRef;
- xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_ENABLE_SMARTCARD);
- xpc_dictionary_set_data(message, AUTH_XPC_BLOB, blob, sizeof(AuthorizationBlob));
- xpc_dictionary_set_bool(message, AUTH_XPC_DATA, enable);
-
- // Reply
- reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
- require_action(reply != NULL, done, status = errAuthorizationInternal);
- require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
-
- status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
-
-done:
- xpc_release_safe(message);
- xpc_release_safe(reply);
- return status;
-}
-
-
-OSStatus AuthorizationRightGet(const char *rightName,
- CFDictionaryRef *rightDefinition)
-{
- OSStatus status = errAuthorizationInternal;
- xpc_object_t message = NULL;
- xpc_object_t reply = NULL;
-
- require_action(rightName != NULL, done, status = errAuthorizationInvalidPointer);
-
- // Send
- message = xpc_dictionary_create(NULL, NULL, 0);
- require_action(message != NULL, done, status = errAuthorizationInternal);
-
- xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_RIGHT_GET);
- xpc_dictionary_set_string(message, AUTH_XPC_RIGHT_NAME, rightName);
-
- // Reply
- reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
- require_action(reply != NULL, done, status = errAuthorizationInternal);
- require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
-
- // Status
- status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
-
- // Out
- if (rightDefinition && status == errAuthorizationSuccess) {
- xpc_object_t value = xpc_dictionary_get_value(reply, AUTH_XPC_DATA);
- require_action(value != NULL, done, status = errAuthorizationInternal);
- require_action(xpc_get_type(value) == XPC_TYPE_DICTIONARY, done, status = errAuthorizationInternal);
-
- CFTypeRef cfdict = _CFXPCCreateCFObjectFromXPCObject(value);
- require_action(cfdict != NULL, done, status = errAuthorizationInternal);
-
- *rightDefinition = cfdict;
- }
-
-done:
- xpc_release_safe(message);
- xpc_release_safe(reply);
- return status;
-}
-
-OSStatus AuthorizationRightSet(AuthorizationRef authRef,
- const char *rightName,
- CFTypeRef rightDefinition,
- CFStringRef descriptionKey,
- CFBundleRef bundle,
- CFStringRef tableName)
-{
- OSStatus status = errAuthorizationInternal;
- xpc_object_t message = NULL;
- xpc_object_t reply = NULL;
- AuthorizationBlob *blob = NULL;
- CFMutableDictionaryRef rightDict = NULL;
- CFBundleRef clientBundle = bundle;
-
- if (bundle) {
- CFRetain(bundle);
- }
-
- require_action(rightDefinition != NULL, done, status = errAuthorizationInvalidPointer);
- require_action(rightName != NULL, done, status = errAuthorizationInvalidPointer);
- require_action(authRef != NULL, done, status = errAuthorizationInvalidRef);
- blob = (AuthorizationBlob *)authRef;
-
- // Send
- message = xpc_dictionary_create(NULL, NULL, 0);
- require_action(message != NULL, done, status = errAuthorizationInternal);
-
- xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_RIGHT_SET);
- xpc_dictionary_set_data(message, AUTH_XPC_BLOB, blob, sizeof(AuthorizationBlob));
- xpc_dictionary_set_string(message, AUTH_XPC_RIGHT_NAME, rightName);
-
- // Create rightDict
- if (CFGetTypeID(rightDefinition) == CFStringGetTypeID()) {
- rightDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- require_action(rightDict != NULL, done, status = errAuthorizationInternal);
-
- CFDictionarySetValue(rightDict, CFSTR(kAuthorizationRightRule), rightDefinition);
-
- } else if (CFGetTypeID(rightDefinition) == CFDictionaryGetTypeID()) {
- rightDict = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, rightDefinition);
- require_action(rightDict != NULL, done, status = errAuthorizationInternal);
-
- } else {
- status = errAuthorizationInvalidPointer;
- goto done;
- }
-
- // Create locDict
- if (descriptionKey) {
- CFMutableDictionaryRef locDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- require_action(locDict != NULL, done, status = errAuthorizationInternal);
-
- if (clientBundle == NULL) {
- clientBundle = CFBundleGetMainBundle();
- CFRetain(clientBundle);
- }
-
- if (clientBundle) {
- CFArrayRef bundleLocalizations = CFBundleCopyBundleLocalizations(clientBundle);
- if (bundleLocalizations) {
- // for every CFString in localizations do
- CFIndex locIndex, allLocs = CFArrayGetCount(bundleLocalizations);
- for (locIndex = 0; locIndex < allLocs; locIndex++)
- {
- CFStringRef oneLocalization = (CFStringRef)CFArrayGetValueAtIndex(bundleLocalizations, locIndex);
-
- if (!oneLocalization)
- continue;
-
- // @@@ no way to get "Localized" and "strings" as constants?
- CFURLRef locURL = CFBundleCopyResourceURLForLocalization(clientBundle, tableName ? tableName : CFSTR("Localizable"), CFSTR("strings"), NULL /*subDirName*/, oneLocalization);
-
- if (!locURL)
- continue;
-
- CFDataRef tableData = NULL;
- SInt32 errCode;
- CFStringRef errStr = NULL;
- CFPropertyListRef stringTable = NULL;
-
- CFURLCreateDataAndPropertiesFromResource(CFGetAllocator(clientBundle), locURL, &tableData, NULL, NULL, &errCode);
- CFReleaseSafe(locURL);
- if (errCode)
- {
- CFReleaseSafe(tableData);
- continue;
- }
-
- stringTable = CFPropertyListCreateFromXMLData(CFGetAllocator(clientBundle), tableData, kCFPropertyListImmutable, &errStr);
- CFReleaseSafe(errStr);
- CFReleaseSafe(tableData);
-
- CFStringRef value = (CFStringRef)CFDictionaryGetValue(stringTable, descriptionKey);
- if (value == NULL || CFEqual(value, CFSTR(""))) {
- CFReleaseSafe(stringTable);
- continue;
- } else {
- // oneLocalization/value into our dictionary
- CFDictionarySetValue(locDict, oneLocalization, value);
- CFReleaseSafe(stringTable);
- }
- }
- CFReleaseSafe(bundleLocalizations);
- }
- }
-
- // add the description as the default localization into the dictionary
- CFDictionarySetValue(locDict, CFSTR(""), descriptionKey);
-
- // stuff localization table into right definition
- CFDictionarySetValue(rightDict, CFSTR(kAuthorizationRuleParameterDefaultPrompt), locDict);
- CFReleaseSafe(locDict);
- }
-
- xpc_object_t value = _CFXPCCreateXPCObjectFromCFObject(rightDict);
- xpc_dictionary_set_value(message, AUTH_XPC_DATA, value);
- xpc_release_safe(value);
-
- // Reply
- reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
- require_action(reply != NULL, done, status = errAuthorizationInternal);
- require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
-
- // Status
- status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
-
-done:
- CFReleaseSafe(clientBundle);
- CFReleaseSafe(rightDict);
- xpc_release_safe(message);
- xpc_release_safe(reply);
- return status;
-}
-
-OSStatus AuthorizationRightRemove(AuthorizationRef authorization,
- const char *rightName)
-{
- OSStatus status = errAuthorizationInternal;
- xpc_object_t message = NULL;
- xpc_object_t reply = NULL;
- AuthorizationBlob *blob = NULL;
-
- require_action(rightName != NULL, done, status = errAuthorizationInvalidPointer);
- require_action(authorization != NULL, done, status = errAuthorizationInvalidRef);
- blob = (AuthorizationBlob *)authorization;
-
- // Send
- message = xpc_dictionary_create(NULL, NULL, 0);
- require_action(message != NULL, done, status = errAuthorizationInternal);
-
- xpc_dictionary_set_uint64(message, AUTH_XPC_TYPE, AUTHORIZATION_RIGHT_REMOVE);
- xpc_dictionary_set_data(message, AUTH_XPC_BLOB, blob, sizeof(AuthorizationBlob));
- xpc_dictionary_set_string(message, AUTH_XPC_RIGHT_NAME, rightName);
-
- // Reply
- reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message);
- require_action(reply != NULL, done, status = errAuthorizationInternal);
- require_action(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal);
-
- // Status
- status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS);
-
-done:
- xpc_release_safe(message);
- xpc_release_safe(reply);
- return status;
-}