2 * Copyright (c) 2000-2004,2006 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
26 // objectacl - core implementation of an ACL-bearing object
31 #include <security_cdsa_utilities/aclsubject.h>
32 #include <security_utilities/globalizer.h>
42 // An in-memory ACL object.
43 // This class implements an ACL-for-a-protected-object. It is complete in that
44 // it provides full ACL management functionality. You still need to (globally)
45 // register makers for the ACL subject types you want to use.
46 // Note that ObjectAcl does no integrity checking. ObjectAcl objects need to be
47 // protected from hostile access (by e.g. address space separation), and exported
48 // ACLs need to be protected somehow (by hiding, signing, or whatever works in
52 friend AclSubject::Maker::Maker(CSSM_ACL_SUBJECT_TYPE
);
55 typedef RefPointer
<AclSubject
> AclSubjectPointer
;
57 typedef LowLevelMemoryUtilities::Writer Writer
;
58 typedef LowLevelMemoryUtilities::Reader Reader
;
61 ObjectAcl(Allocator
&alloc
);
62 ObjectAcl(const AclEntryPrototype
&proto
, Allocator
&alloc
);
69 // access control validation (evaluation)
72 // validate(): succeed or throw exception
73 void validate(AclAuthorization auth
, const AccessCredentials
*cred
,
74 AclValidationEnvironment
*env
= NULL
);
75 void validate(AclValidationContext
&ctx
);
77 // validates(): return true or false (or throw on error)
78 bool validates(AclAuthorization auth
, const AccessCredentials
*cred
,
79 AclValidationEnvironment
*env
= NULL
);
80 bool validates(AclValidationContext
&ctx
);
82 // owner validation (simpler)
83 void validateOwner(AclAuthorization authorizationHint
, const AccessCredentials
*cred
,
84 AclValidationEnvironment
*env
= NULL
);
85 void validateOwner(AclValidationContext
&ctx
);
87 // CSSM-style ACL access operations
88 // (Gets are not const because underlying implementations usually want them writable)
89 void cssmGetAcl(const char *tag
, uint32
&count
, AclEntryInfo
* &acls
);
90 void cssmChangeAcl(const AclEdit
&edit
, const AccessCredentials
*cred
,
91 AclValidationEnvironment
*env
= NULL
);
92 void cssmGetOwner(AclOwnerPrototype
&owner
);
93 void cssmChangeOwner(const AclOwnerPrototype
&newOwner
, const AccessCredentials
*cred
,
94 AclValidationEnvironment
*env
= NULL
);
96 void cssmSetInitial(const AclEntryPrototype
&proto
);
97 void cssmSetInitial(const AclSubjectPointer
&subject
);
99 // Acl I/O (to/from memory blobs)
100 void exportBlob(CssmData
&publicBlob
, CssmData
&privateBlob
);
101 void importBlob(const void *publicBlob
, const void *privateBlob
);
103 // clear everything from this ACL (return it to un-initialized state)
106 // setup hooks (called to delayed-construct the contents before use) - empty defaults
107 virtual void instantiateAcl(); // called before ACL contents are used by external calls
108 virtual void changedAcl(); // called after an ACL has been (possibly) changed
110 // debug dump support (always there but stubbed out unless DEBUGDUMP)
111 virtual void debugDump(const char *what
= NULL
) const;
116 AclSubjectPointer subject
; // subject representation
117 bool delegate
; // delegation flag
119 Entry() { } // make invalid Entry
121 void toOwnerInfo(CSSM_ACL_OWNER_PROTOTYPE
&info
,
122 Allocator
&alloc
) const; // encode copy in CSSM format
124 virtual bool authorizes(AclAuthorization auth
) const = 0;
125 virtual bool validate(const AclValidationContext
&ctx
) const = 0;
127 template <class Action
>
128 void exportBlob(Action
&pub
, Action
&priv
)
130 Endian
<uint32
> del
= delegate
; pub(del
); // 4 bytes delegate flag
131 exportSubject(subject
, pub
, priv
); // subject itself (polymorphic)
133 void importBlob(Reader
&pub
, Reader
&priv
);
135 IFDUMP(virtual void debugDump() const);
138 void init(const AclSubjectPointer
&subject
, bool delegate
= false);
139 void init(const TypedList
&subject
, bool delegate
= false) { init(make(subject
), delegate
); }
142 Entry(const AclEntryPrototype
&proto
) { init(proto
.subject(), proto
.delegate()); }
143 Entry(const AclOwnerPrototype
&proto
) { init(proto
.subject()); }
144 Entry(const AclSubjectPointer
&subject
) { init(subject
); }
148 class OwnerEntry
: public Entry
{
150 OwnerEntry() { } // invalid OwnerEntry
151 template <class Input
>
152 OwnerEntry(const Input
&owner
) : Entry(owner
) { }
154 bool authorizes(AclAuthorization auth
) const;
155 bool validate(const AclValidationContext
&ctx
) const;
158 class AclEntry
: public Entry
{
160 std::string tag
; // entry tag
161 AclAuthorizationSet authorizations
; // set of authorizations
162 bool authorizesAnything
; // has the _ANY authorization tag
163 //@@@ time range not yet implemented
164 CSSM_ACL_HANDLE handle
; // entry handle
166 AclEntry() { } // invalid AclEntry
167 AclEntry(const AclSubjectPointer
&subject
);
168 AclEntry(const AclEntryPrototype
&proto
);
170 void toEntryInfo(CSSM_ACL_ENTRY_PROTOTYPE
&info
,
171 Allocator
&alloc
) const; // encode copy in CSSM format
173 bool authorizes(AclAuthorization auth
) const;
174 bool validate(const AclValidationContext
&ctx
) const;
176 template <class Action
>
177 void exportBlob(Action
&pub
, Action
&priv
)
179 Entry::exportBlob(pub
, priv
);
180 const char *s
= tag
.c_str(); pub(s
);
181 uint32 aa
= authorizesAnything
; pub(aa
);
182 if (!authorizesAnything
) {
183 Endian
<uint32
> count
= (uint32
)authorizations
.size(); pub(count
);
184 for (AclAuthorizationSet::iterator it
= authorizations
.begin();
185 it
!= authorizations
.end(); it
++) {
186 Endian
<AclAuthorization
> auth
= *it
; pub(auth
);
189 //@@@ export time range
191 void importBlob(Reader
&pub
, Reader
&priv
);
193 IFDUMP(void debugDump() const);
197 // These helpers deal with transferring one subject from/to reader/writer streams.
198 // You'd usually only call those from complex subject implementations (e.g. threshold)
199 template <class Action
>
200 static void exportSubject(AclSubject
*subject
, Action
&pub
, Action
&priv
)
202 Endian
<uint32
> typeAndVersion
= subject
->type() | subject
->version() << AclSubject::versionShift
;
204 subject
->exportBlob(pub
, priv
);
206 static AclSubject
*importSubject(Reader
&pub
, Reader
&priv
);
209 typedef std::multimap
<string
, AclEntry
> EntryMap
;
211 EntryMap::iterator
begin() { return mEntries
.begin(); }
212 EntryMap::iterator
end() { return mEntries
.end(); }
213 EntryMap::const_iterator
begin() const { return mEntries
.begin(); }
214 EntryMap::const_iterator
end() const { return mEntries
.end(); }
216 unsigned int getRange(const std::string
&tag
,
217 pair
<EntryMap::const_iterator
, EntryMap::const_iterator
> &range
) const;
218 EntryMap::iterator
findEntryHandle(CSSM_ACL_HANDLE handle
);
220 // construct an AclSubject through the Maker registry (by subject type)
221 static AclSubject
*make(const TypedList
&list
); // make from CSSM form
222 static AclSubject
*make(uint32 typeAndVersion
,
223 Reader
&pub
, Reader
&priv
); // make from export form
226 template <class Input
>
227 void owner(const Input
&input
);
228 void entries(uint32 count
, const AclEntryInfo
*infos
);
231 void add(const std::string
&tag
, const AclEntry
&newEntry
);
232 void add(const std::string
&tag
, AclEntry newEntry
, CSSM_ACL_HANDLE handle
);
235 EntryMap mEntries
; // ACL entries indexed by tag
236 OwnerEntry mOwner
; // ACL owner entry
237 CSSM_ACL_HANDLE mNextHandle
; // next unused entry handle value
240 typedef map
<CSSM_ACL_SUBJECT_TYPE
, AclSubject::Maker
*> MakerMap
;
241 static ModuleNexus
<MakerMap
> makers
; // registered subject Makers
243 static AclSubject::Maker
&makerFor(CSSM_ACL_SUBJECT_TYPE type
);
247 } // end namespace Security