/*
- * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
+ * Copyright (c) 2000-2004,2009 Apple Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <Security/AuthorizationPriv.h>
#include <Security/AuthorizationDB.h>
-
#include "authority.h"
#include <Security/AuthorizationTags.h>
#include <security_utilities/logging.h>
#include <security_utilities/cfutilities.h>
#include <security_utilities/debugging.h>
-//#include "session.h"
#include "server.h"
#include <CoreFoundation/CFData.h>
#include <errno.h>
#include <fcntl.h>
#include <float.h>
+#include <sandbox.h>
-#include <bsm/audit_uevents.h>
+#include <bsm/audit_uevents.h> // AUE_ssauth*
+#include "ccaudit_extensions.h"
namespace Authorization {
+using namespace CommonCriteria::Securityd;
+
//
// Errors to be thrown
{
CredentialSet credentials;
OSStatus status = errAuthorizationSuccess;
+ SecurityAgent::Reason reason = SecurityAgent::noReason;
// Get current time of day.
CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
// 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<AuthItemRef> 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<AuthItemRef>::const_iterator end = tempRights.end();
+ for (std::vector<AuthItemRef>::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);
- {
- string processName = "unknown";
- if (SecCodeRef code = Server::process().currentGuest()) {
- CFRef<CFURLRef> path;
- if (!SecCodeCopyPath(code, kSecCSDefaultFlags, &path.aref()))
- processName = cfString(path);
- }
- string authCreatorName = "unknown";
- if (SecStaticCodeRef code = auth.creatorCode()) {
- CFRef<CFURLRef> path;
- if (!SecCodeCopyPath(code, kSecCSDefaultFlags, &path.aref()))
- authCreatorName = cfString(path);
- }
+ if (false == authExtractPassword)
+ authExtractPassword = toplevelRule->extractPassword();
- if (result == errAuthorizationSuccess) {
- Syslog::info("Succeeded authorizing right %s by client %s for authorization created by %s.", (*it)->name(), processName.c_str(), authCreatorName.c_str());
- CommonCriteria::AuditRecord auditrec(auth.creatorAuditToken());
- auditrec.submit(AUE_ssauthorize, CommonCriteria::errNone, (*it)->name());
- } else if (result == errAuthorizationDenied) {
- Syslog::notice("Failed to authorize right %s by client %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)
+ string processName = "unknown";
+ string authCreatorName = "unknown";
{
- // add creator pid to authorization token
- if (!(flags & kAuthorizationFlagPartialRights))
- {
- status = result;
- break;
+ StLock<Mutex> _(Server::process());
+ if (SecCodeRef code = Server::process().currentGuest()) {
+ CFRef<CFURLRef> 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);