X-Git-Url: https://git.saurik.com/apple/securityd.git/blobdiff_plain/eeadf2e6470f45ea0275a6019635573f2a7b5a2c..4cd1cad0dea00daa03e1b54fdf2797a02373ad5b:/src/AuthorizationEngine.cpp diff --git a/src/AuthorizationEngine.cpp b/src/AuthorizationEngine.cpp index a2d0f6e..b989fc3 100644 --- a/src/AuthorizationEngine.cpp +++ b/src/AuthorizationEngine.cpp @@ -1,10 +1,8 @@ /* - * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved. + * Copyright (c) 2000-2004,2009 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. - * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -23,20 +21,11 @@ * @APPLE_LICENSE_HEADER_END@ */ - -/* - * AuthorizationEngine.cpp - * Authorization - * - * Created by Michael Brouwer on Thu Oct 12 2000. - * - */ #include "AuthorizationEngine.h" #include #include #include - #include "authority.h" #include @@ -44,7 +33,6 @@ #include #include #include -//#include "session.h" #include "server.h" #include @@ -54,9 +42,15 @@ #include #include #include +#include + +#include // AUE_ssauth* +#include "ccaudit_extensions.h" namespace Authorization { +using namespace CommonCriteria::Securityd; + // // Errors to be thrown @@ -109,6 +103,7 @@ Engine::authorize(const AuthItemSet &inRights, const AuthItemSet &environment, { CredentialSet credentials; OSStatus status = errAuthorizationSuccess; + SecurityAgent::Reason reason = SecurityAgent::noReason; // Get current time of day. CFAbsoluteTime now = CFAbsoluteTimeGetCurrent(); @@ -146,49 +141,97 @@ Engine::authorize(const AuthItemSet &inRights, const AuthItemSet &environment, // generate hints for every authorization AuthItemSet environmentToClient = environment; - AuthItemSet::const_iterator end = inRights.end(); - for (AuthItemSet::const_iterator it = inRights.begin(); it != end; ++it) + RightAuthenticationLogger logger(auth.creatorAuditToken(), AUE_ssauthorize); + + // create a vector with the first right first + std::vector tempRights; + for (AuthItemSet::const_iterator it = inRights.begin(); it != inRights.end(); ++it) { + if (inRights.firstItemName != NULL && strcmp((*it)->name(), inRights.firstItemName) == 0) + tempRights.insert(tempRights.begin(), *it); + else + tempRights.push_back(*it); + } + + bool authExtractPassword = false; + std::vector::const_iterator end = tempRights.end(); + for (std::vector::const_iterator it = tempRights.begin(); it != end; ++it) { // Get the rule for each right we are trying to obtain. const Rule &toplevelRule = mAuthdb.getRule(*it); - OSStatus result = toplevelRule->evaluate(*it, toplevelRule, environmentToClient, flags, now, inCredentials, credentials, auth); - secdebug("autheval", "evaluate rule %s for right %s returned %ld.", toplevelRule->name().c_str(), (*it)->name(), result); + if (false == authExtractPassword) + authExtractPassword = toplevelRule->extractPassword(); + + string processName = "unknown"; + string authCreatorName = "unknown"; { - CodeSigning::OSXCode *processCode = Server::process().clientCode(); - string processName = processCode ? processCode->canonicalPath() : "unknown"; - CodeSigning::OSXCode *authCreatorCode = auth.creatorCode(); - string authCreatorName = authCreatorCode ? authCreatorCode->canonicalPath() : "unknown"; - - if (result == errAuthorizationSuccess) - Syslog::info("Succeeded authorizing right %s by process %s for authorization created by %s.", (*it)->name(), processName.c_str(), authCreatorName.c_str()); - else if (result == errAuthorizationDenied) - Syslog::notice("Failed to authorize right %s by process %s for authorization created by %s.", (*it)->name(), processName.c_str(), authCreatorName.c_str()); - } - - if (result == errAuthorizationSuccess) - outRights.insert(*it); - else if (result == errAuthorizationDenied || result == errAuthorizationInteractionNotAllowed) - { - // add creator pid to authorization token - if (!(flags & kAuthorizationFlagPartialRights)) - { - status = result; - break; + StLock _(Server::process()); + if (SecCodeRef code = Server::process().currentGuest()) { + CFRef path; + if (!SecCodeCopyPath(code, kSecCSDefaultFlags, &path.aref())) + processName = cfString(path); } - } + } + authCreatorName = auth.creatorPath(); + + if (sandbox_check(Server::process().pid(), "authorization-right-obtain", SANDBOX_FILTER_RIGHT_NAME, (*it)->name())) { + Syslog::error("Sandbox denied authorizing right '%s' by client '%s' [%d]", (*it)->name(), processName.c_str(), Server::process().pid()); + return errAuthorizationDenied; + } + if (auth.creatorSandboxed() && sandbox_check(auth.creatorPid(), "authorization-right-obtain", SANDBOX_FILTER_RIGHT_NAME, (*it)->name())) { + Syslog::error("Sandbox denied authorizing right '%s' for authorization created by '%s' [%d]", (*it)->name(), authCreatorName.c_str(), auth.creatorPid()); + return errAuthorizationDenied; + } + + OSStatus result = toplevelRule->evaluate(*it, toplevelRule, environmentToClient, flags, now, inCredentials, credentials, auth, reason, authExtractPassword); + secdebug("autheval", "evaluate rule %s for right %s returned %d.", toplevelRule->name().c_str(), (*it)->name(), int(result)); + SECURITYD_AUTH_EVALRIGHT(&auth, (char *)(*it)->name(), result); + + logger.setRight((*it)->name()); + logger.logAuthorizationResult(processName.c_str(), authCreatorName.c_str(), result); + + if (result == errAuthorizationSuccess) + { + outRights.insert(*it); + Syslog::info("Succeeded authorizing right '%s' by client '%s' [%d] for authorization created by '%s' [%d] (%X,%d)", (*it)->name(), processName.c_str(), Server::process().pid(), authCreatorName.c_str(), auth.creatorPid(), uint32_t(flags), auth.operatesAsLeastPrivileged()); + } + else if (result == errAuthorizationDenied || result == errAuthorizationInteractionNotAllowed) + { + if (result == errAuthorizationDenied) + { + secdebug("autheval", "Failed to authorize right '%s' by client '%s' [%d] for authorization created by '%s' [%d] (%X,%d)", (*it)->name(), processName.c_str(), Server::process().pid(), authCreatorName.c_str(), auth.creatorPid(), uint32_t(flags), auth.operatesAsLeastPrivileged()); + } + + // add creator pid to authorization token + if (!(flags & kAuthorizationFlagPartialRights)) + { + status = result; + break; + } + } else if (result == errAuthorizationCanceled) { status = result; break; - } - else - { - Syslog::error("Engine::authorize: Rule::evaluate returned %ld returning errAuthorizationInternal", result); - status = errAuthorizationInternal; - break; + } + else + { + Syslog::error("Engine::authorize: Rule::evaluate returned %ld returning errAuthorizationInternal", result); + status = errAuthorizationInternal; + break; } } + + // purge all uid credentials from the outCredentials for least privileged mode + if (auth.operatesAsLeastPrivileged()) { + CredentialSet::const_iterator current, it = outCredentials->begin(); + while(it != outCredentials->end()) { + current = it++; + if (!(*current)->isRight()) { + outCredentials->erase(current); + } + } + } if (outCredentials) outCredentials->swap(credentials); @@ -287,12 +330,6 @@ Engine::getRule(string &inRightName, CFDictionaryRef *outRuleDefinition) OSStatus Engine::setRule(const char *inRightName, CFDictionaryRef inRuleDefinition, const CredentialSet *inCredentials, CredentialSet *outCredentials, AuthorizationToken &auth) { - // Get current time of day. - CFAbsoluteTime now = CFAbsoluteTimeGetCurrent(); - - // Update rules from database if needed - mAuthdb.sync(now); - // Validate rule by constructing it from the passed dictionary if (!mAuthdb.validateRule(inRightName, inRuleDefinition)) return errAuthorizationDenied; // @@@ separate error for this?