X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/bac41a7b9a0a9254fa30f8bb6e6038ab71a483e2..ce0ac947b4708d0bc1c7e6789b3e1f3bfc80d6e9:/cdsa/cdsa_utilities/cssmacl.cpp?ds=inline diff --git a/cdsa/cdsa_utilities/cssmacl.cpp b/cdsa/cdsa_utilities/cssmacl.cpp index cc700e22..5f5af270 100644 --- a/cdsa/cdsa_utilities/cssmacl.cpp +++ b/cdsa/cdsa_utilities/cssmacl.cpp @@ -19,14 +19,11 @@ // // cssmacl - core ACL management interface // -#ifdef __MWERKS__ -#define _CPP_CSSMACL -#endif - #include #include #include #include +#include using namespace DataWalkers; @@ -102,13 +99,15 @@ ObjectAcl::~ObjectAcl() void ObjectAcl::cssmSetInitial(const AclEntryPrototype &proto) { owner = OwnerEntry(proto); - entries.insert(EntryMap::value_type("", proto))->second.handle = nextHandle++; + entries.insert(EntryMap::value_type(proto.tag(), proto))->second.handle = nextHandle++; + IFDUMPING("acl", debugDump("create/proto")); } void ObjectAcl::cssmSetInitial(const AclSubjectPointer &subject) { owner = OwnerEntry(subject); entries.insert(EntryMap::value_type("", subject))->second.handle = nextHandle++; + IFDUMPING("acl", debugDump("create/subject")); } ObjectAcl::Entry::~Entry() @@ -137,8 +136,11 @@ public: }; void ObjectAcl::validate(AclAuthorization auth, const AccessCredentials *cred, - AclValidationEnvironment *env) const + AclValidationEnvironment *env) { + // make sure we are ready to go + instantiateAcl(); + //@@@ should pre-screen based on requested auth, maybe? BaseValidationContext ctx(cred, auth, env); @@ -146,7 +148,7 @@ void ObjectAcl::validate(AclAuthorization auth, const AccessCredentials *cred, // try owner (owner can do anything) if (owner.validate(ctx)) return; -#endif ACL_OMNIPOTENT_OWNER +#endif //ACL_OMNIPOTENT_OWNER // try applicable ACLs pair range; @@ -162,8 +164,9 @@ void ObjectAcl::validate(AclAuthorization auth, const AccessCredentials *cred, } void ObjectAcl::validateOwner(AclAuthorization authorizationHint, - const AccessCredentials *cred, AclValidationEnvironment *env) const + const AccessCredentials *cred, AclValidationEnvironment *env) { + instantiateAcl(); BaseValidationContext ctx(cred, authorizationHint, env); if (owner.validate(ctx)) return; @@ -178,7 +181,7 @@ void ObjectAcl::validateOwner(AclAuthorization authorizationHint, void ObjectAcl::exportBlob(CssmData &publicBlob, CssmData &privateBlob) { Writer::Counter pubSize, privSize; - uint32 entryCount = entries.size(); + Endian entryCount = entries.size(); owner.exportBlob(pubSize, privSize); pubSize(entryCount); for (Iterator it = begin(); it != end(); it++) @@ -190,6 +193,7 @@ void ObjectAcl::exportBlob(CssmData &publicBlob, CssmData &privateBlob) pubWriter(entryCount); for (Iterator it = begin(); it != end(); it++) it->second.exportBlob(pubWriter, privWriter); + IFDUMPING("acl", debugDump("exported")); } @@ -203,7 +207,9 @@ void ObjectAcl::importBlob(const void *publicBlob, const void *privateBlob) { Reader pubReader(publicBlob), privReader(privateBlob); owner.importBlob(pubReader, privReader); - uint32 entryCount; pubReader(entryCount); + Endian entryCountIn; pubReader(entryCountIn); + uint32 entryCount = entryCountIn; + entries.erase(begin(), end()); for (uint32 n = 0; n < entryCount; n++) { AclEntry newEntry; @@ -214,18 +220,44 @@ void ObjectAcl::importBlob(const void *publicBlob, const void *privateBlob) } +// +// Import/export helpers for subjects. +// This is exported to (subject implementation) callers to maintain consistency +// in binary format handling. +// +AclSubject *ObjectAcl::importSubject(Reader &pub, Reader &priv) +{ + Endian typeAndVersion; pub(typeAndVersion); + return make(typeAndVersion, pub, priv); +} + + +// +// Setup/update hooks +// +void ObjectAcl::instantiateAcl() +{ + // nothing by default +} + +void ObjectAcl::changedAcl() +{ + // nothing by default +} + + // // ACL utility methods // unsigned int ObjectAcl::getRange(const char *tag, pair &range) const { - if (tag) { + if (tag && tag[0]) { // tag restriction in effect range = entries.equal_range(tag); uint32 count = entries.count(tag); if (count == 0) CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG); return count; - } else { + } else { // try all tags range.first = entries.begin(); range.second = entries.end(); return entries.size(); @@ -246,6 +278,7 @@ ObjectAcl::Iterator ObjectAcl::findEntryHandle(CSSM_ACL_HANDLE handle) // void ObjectAcl::cssmGetAcl(const char *tag, uint32 &count, AclEntryInfo * &acls) { + instantiateAcl(); pair range; count = getRange(tag, range); acls = allocator.alloc(count); @@ -262,6 +295,9 @@ void ObjectAcl::cssmChangeAcl(const AclEdit &edit, { IFDUMPING("acl", debugDump("acl-change-from")); + // make sure we're ready to go + instantiateAcl(); + // validate access credentials validateOwner(CSSM_ACL_AUTHORIZATION_CHANGE_ACL, cred, env); @@ -288,12 +324,16 @@ void ObjectAcl::cssmChangeAcl(const AclEdit &edit, default: CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_EDIT_MODE); } + + // notify change + changedAcl(); - IFDUMPING("acl", debugDump("owner-change-to")); + IFDUMPING("acl", debugDump("acl-change-to")); } void ObjectAcl::cssmGetOwner(AclOwnerPrototype &outOwner) { + instantiateAcl(); outOwner.TypedSubject = owner.subject->toList(allocator); outOwner.Delegate = owner.delegate; } @@ -303,11 +343,15 @@ void ObjectAcl::cssmChangeOwner(const AclOwnerPrototype &newOwner, { IFDUMPING("acl", debugDump("owner-change-from")); + instantiateAcl(); + // only the owner entry can match validateOwner(CSSM_ACL_AUTHORIZATION_CHANGE_OWNER, cred, env); // okay, replace it owner = newOwner; + + changedAcl(); IFDUMPING("acl", debugDump("owner-change-to")); } @@ -324,12 +368,11 @@ void ObjectAcl::Entry::init(const AclSubjectPointer &subject, bool delegate) void ObjectAcl::Entry::importBlob(Reader &pub, Reader &priv) { - // delegate is trivial - pub(delegate); - - // now reconstruct the (polymorphic) subject - CSSM_ACL_SUBJECT_TYPE subjectType; pub(subjectType); - subject = make(subjectType, pub, priv); + Endian del; + pub(del); // read del from the public blob + + delegate = del; // 4 bytes delegate flag + subject = importSubject(pub, priv); } @@ -396,12 +439,19 @@ void ObjectAcl::AclEntry::importBlob(Reader &pub, Reader &priv) { Entry::importBlob(pub, priv); const char *s; pub(s); tag = s; - pub(authorizesAnything); + + // authorizesAnything is on disk as a 4-byte flag + Endian tmpAuthorizesAnything; + pub(tmpAuthorizesAnything); + authorizesAnything = tmpAuthorizesAnything; + authorizations.erase(authorizations.begin(), authorizations.end()); if (!authorizesAnything) { - uint32 count; pub(count); + Endian countIn; pub(countIn); + uint32 count = countIn; + for (uint32 n = 0; n < count; n++) { - AclAuthorization auth; pub(auth); + Endian auth; pub(auth); authorizations.insert(auth); } } @@ -424,9 +474,10 @@ AclSubject *ObjectAcl::make(const TypedList &list) return makerFor(list.type()).make(list); } -AclSubject *ObjectAcl::make(CSSM_ACL_SUBJECT_TYPE type, Reader &pub, Reader &priv) +AclSubject *ObjectAcl::make(uint32 typeAndVersion, Reader &pub, Reader &priv) { - return makerFor(type).make(pub, priv); + // this type is encoded as (version << 24) | type + return makerFor(typeAndVersion & ~AclSubject::versionMask).make(typeAndVersion >> AclSubject::versionShift, pub, priv); } AclSubject::Maker &ObjectAcl::makerFor(CSSM_ACL_SUBJECT_TYPE type) @@ -461,7 +512,7 @@ void AclSubject::Maker::crack(const CssmList &list, uint32 count, ListElement ** } CSSM_WORDID_TYPE AclSubject::Maker::getWord(const ListElement &elem, - int min = 0, int max = INT_MAX) + int min /*= 0*/, int max /*= INT_MAX*/) { if (elem.type() != CSSM_LIST_ELEMENT_WORDID) CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_SUBJECT_VALUE); @@ -473,12 +524,14 @@ CSSM_WORDID_TYPE AclSubject::Maker::getWord(const ListElement &elem, // -// Debug dumping support +// Debug dumping support. +// Leave the ObjectAcl::debugDump method in (stubbed out) +// to keep the virtual table layout stable, and to allow +// proper linking in weird mix-and-match scenarios. // -#if defined(DEBUGDUMP) - void ObjectAcl::debugDump(const char *what) const { +#if defined(DEBUGDUMP) if (!what) what = "Dump"; Debug::dump("%p ACL %s: %d entries\n", this, what, int(entries.size())); @@ -490,10 +543,29 @@ void ObjectAcl::debugDump(const char *what) const Debug::dump("]\n"); } Debug::dump("%p ACL END\n", this); +#endif //DEBUGDUMP } +void AclSubject::debugDump() const +{ +#if defined(DEBUGDUMP) + switch (type()) { + case CSSM_ACL_SUBJECT_TYPE_ANY: + Debug::dump("ANY"); + break; + default: + Debug::dump("subject type=%d", int(type())); + break; + } +#endif //DEBUGDUMP +} + +#if defined(DEBUGDUMP) + void ObjectAcl::Entry::debugDump() const { + if (AclSubject::Version v = subject->version()) + Debug::dump("V=%d ", v); subject->debugDump(); if (delegate) Debug::dump(" DELEGATE"); @@ -513,16 +585,4 @@ void ObjectAcl::AclEntry::debugDump() const } } -void AclSubject::debugDump() const -{ - switch (type()) { - case CSSM_ACL_SUBJECT_TYPE_ANY: - Debug::dump("ANY"); - break; - default: - Debug::dump("subject type=%d", int(type())); - break; - } -} - #endif //DEBUGDUMP