bool ObjectAcl::validates(AclValidationContext &ctx)
{
	// make sure we are ready to go
	instantiateAcl();

	IFDUMPING("acleval", Debug::dump("<<WANT(%d)<", ctx.authorization()));

    //@@@ should pre-screen based on requested auth, maybe?

#if defined(ACL_OMNIPOTENT_OWNER)
    // try owner (owner can do anything)
    if (mOwner.validate(ctx))
        return;
#endif //ACL_OMNIPOTENT_OWNER

    // try applicable ACLs
    pair<EntryMap::const_iterator, EntryMap::const_iterator> range;
    if (getRange(ctx.s_credTag(), range) == 0)	// no such tag
        CssmError::throwMe(CSSM_ERRCODE_ACL_ENTRY_TAG_NOT_FOUND);
    // try each entry in turn
    for (EntryMap::const_iterator it = range.first; it != range.second; it++) {
        const AclEntry &slot = it->second;
		IFDUMPING("acleval", (Debug::dump(" EVAL["), slot.debugDump(), Debug::dump("]")));
        if (slot.authorizes(ctx.authorization())) {
			ctx.init(this, slot.subject);
			ctx.entryTag(slot.tag);
			if (slot.validate(ctx)) {
				IFDUMPING("acleval", Debug::dump(">PASS>>\n"));
				return true;		// passed
			}
			IFDUMPING("acleval", Debug::dump(" NO"));
		}
    }
	IFDUMPING("acleval", Debug::dump(">FAIL>>\n"));
	return false;	// no joy
}
bool SourceAclSubject::SourceAclSubject::validate(const AclValidationContext &baseCtx) const
{
	// try to authenticate our sub-subject
	if (Environment *env = baseCtx.environment<Environment>()) {
		AclAuthorization auth = baseCtx.authorization();
		if (!CSSM_ACL_AUTHORIZATION_IS_PREAUTH(auth))	// all muddled up; bail
			CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE);
		uint32 slot = CSSM_ACL_AUTHORIZATION_PREAUTH_SLOT(auth);
		secdebug("preauth", "using state %d@%p", slot, &env->store(this));
		bool &accepted = env->store(this).attachment<AclState>((void *)((size_t) slot)).accepted;
		if (!accepted) {
			secdebug("preauth", "%p needs to authenticate its subject", this);
			SourceValidationContext ctx(baseCtx);
			if (mSourceSubject->validate(ctx)) {
				secdebug("preauth", "%p pre-authenticated", this);
				accepted = true;
			}
		}
		return accepted;
	}
	return false;
}