2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 // cssmaclpod - enhanced PodWrappers for ACL-related CSSM data structures
25 #include <Security/utilities.h>
26 #include <Security/cssmlist.h>
27 #include <Security/cssmalloc.h>
31 // a nicer name for an authorization tag
32 typedef CSSM_ACL_AUTHORIZATION_TAG AclAuthorization
;
33 typedef std::set
<AclAuthorization
> AclAuthorizationSet
;
37 // Enhanced POD Wrappers for the public ACL-related CSSM structures
39 class AuthorizationGroup
: public PodWrapper
<AuthorizationGroup
, CSSM_AUTHORIZATIONGROUP
> {
41 AuthorizationGroup() { NumberOfAuthTags
= 0; }
42 AuthorizationGroup(AclAuthorization auth
);
44 explicit AuthorizationGroup(const AclAuthorizationSet
&, CssmAllocator
&alloc
);
45 void destroy(CssmAllocator
&alloc
);
47 bool empty() const { return NumberOfAuthTags
== 0; }
48 unsigned int count() const { return NumberOfAuthTags
; }
49 CSSM_ACL_AUTHORIZATION_TAG
operator [] (unsigned ix
) const
50 { assert(ix
< count()); return AuthTags
[ix
]; }
52 bool contains(CSSM_ACL_AUTHORIZATION_TAG tag
) const;
53 operator AclAuthorizationSet () const;
56 class AclOwnerPrototype
;
58 class AclEntryPrototype
: public PodWrapper
<AclEntryPrototype
, CSSM_ACL_ENTRY_PROTOTYPE
> {
60 AclEntryPrototype() { clearPod(); }
61 explicit AclEntryPrototype(const AclOwnerPrototype
&proto
);
62 AclEntryPrototype(const CSSM_LIST
&subj
, bool delegate
= false)
63 { clearPod(); TypedSubject
= subj
; Delegate
= delegate
; }
65 TypedList
&subject() { return TypedList::overlay(TypedSubject
); }
66 const TypedList
&subject() const { return TypedList::overlay(TypedSubject
); }
67 bool delegate() const { return Delegate
; }
68 char *tag() { return EntryTag
; }
69 const char *tag() const { return EntryTag
; }
70 void tag(const char *tagString
);
71 AuthorizationGroup
&authorization() { return AuthorizationGroup::overlay(Authorization
); }
72 const AuthorizationGroup
&authorization() const
73 { return AuthorizationGroup::overlay(Authorization
); }
76 class AclOwnerPrototype
: public PodWrapper
<AclOwnerPrototype
, CSSM_ACL_OWNER_PROTOTYPE
> {
78 AclOwnerPrototype() { clearPod(); }
79 explicit AclOwnerPrototype(const AclEntryPrototype
&proto
)
80 { TypedSubject
= proto
.subject(); Delegate
= proto
.delegate(); }
81 AclOwnerPrototype(const CSSM_LIST
&subj
, bool delegate
= false)
82 { TypedSubject
= subj
; Delegate
= delegate
; }
84 TypedList
&subject() { return TypedList::overlay(TypedSubject
); }
85 const TypedList
&subject() const { return TypedList::overlay(TypedSubject
); }
86 bool delegate() const { return Delegate
; }
89 class AclEntryInfo
: public PodWrapper
<AclEntryInfo
, CSSM_ACL_ENTRY_INFO
> {
91 AclEntryPrototype
&proto() { return AclEntryPrototype::overlay(EntryPublicInfo
); }
92 const AclEntryPrototype
&proto() const
93 { return AclEntryPrototype::overlay(EntryPublicInfo
); }
95 operator AclEntryPrototype
&() { return proto(); }
96 operator const AclEntryPrototype
&() const { return proto(); }
98 CSSM_ACL_HANDLE
&handle() { return EntryHandle
; }
99 const CSSM_ACL_HANDLE
&handle() const { return EntryHandle
; }
102 class AclEntryInput
: public PodWrapper
<AclEntryInput
, CSSM_ACL_ENTRY_INPUT
> {
104 AclEntryInput() { clearPod(); }
105 AclEntryInput(const AclEntryPrototype
&prot
)
106 { Prototype
= prot
; Callback
= NULL
; CallerContext
= NULL
; }
108 AclEntryPrototype
&proto() { return AclEntryPrototype::overlay(Prototype
); }
109 const AclEntryPrototype
&proto() const { return AclEntryPrototype::overlay(Prototype
); }
110 //@@@ not supporting callback features (yet)
113 class AclEdit
: public PodWrapper
<AclEdit
, CSSM_ACL_EDIT
> {
115 AclEdit(CSSM_ACL_EDIT_MODE m
, CSSM_ACL_HANDLE h
, const AclEntryInput
*data
)
116 { EditMode
= m
; OldEntryHandle
= h
; NewEntry
= data
; }
117 AclEdit(const AclEntryInput
&add
)
118 { EditMode
= CSSM_ACL_EDIT_MODE_ADD
; OldEntryHandle
= CSSM_INVALID_HANDLE
; NewEntry
= &add
; }
119 AclEdit(CSSM_ACL_HANDLE h
, const AclEntryInput
&modify
)
120 { EditMode
= CSSM_ACL_EDIT_MODE_REPLACE
; OldEntryHandle
= h
; NewEntry
= &modify
; }
121 AclEdit(CSSM_ACL_HANDLE h
)
122 { EditMode
= CSSM_ACL_EDIT_MODE_DELETE
; OldEntryHandle
= h
; NewEntry
= NULL
; }
124 CSSM_ACL_EDIT_MODE
mode() const { return EditMode
; }
125 CSSM_ACL_HANDLE
handle() const { return OldEntryHandle
; }
126 const AclEntryInput
*newEntry() const { return AclEntryInput::overlay(NewEntry
); }
131 // Allocating versions of Acl structures
133 class AutoAclOwnerPrototype
{
134 NOCOPY(AutoAclOwnerPrototype
)
136 // allocator can be set after construction
137 AutoAclOwnerPrototype(CssmAllocator
*allocator
= NULL
)
138 : mAclOwnerPrototype(NULL
), mAllocator(allocator
) { }
139 ~AutoAclOwnerPrototype();
141 operator CSSM_ACL_OWNER_PROTOTYPE
*() { return make(); }
142 AclOwnerPrototype
&operator * () { return *make(); }
144 void allocator(CssmAllocator
&allocator
);
147 AclOwnerPrototype
*mAclOwnerPrototype
;
148 CssmAllocator
*mAllocator
;
150 AclOwnerPrototype
*make();
154 class AutoAclEntryInfoList
{
155 NOCOPY(AutoAclEntryInfoList
)
157 // allocator can be set after construction
158 AutoAclEntryInfoList(CssmAllocator
*allocator
= NULL
)
159 : mAclEntryInfo(NULL
), mNumberOfAclEntries(0), mAllocator(allocator
) { }
160 ~AutoAclEntryInfoList();
162 operator CSSM_ACL_ENTRY_INFO_PTR
*()
163 { return reinterpret_cast<CSSM_ACL_ENTRY_INFO_PTR
*>(&mAclEntryInfo
); }
164 operator uint32
*() { return &mNumberOfAclEntries
; }
166 void allocator(CssmAllocator
&allocator
);
168 const AclEntryInfo
&at(uint32 ix
) const { return mAclEntryInfo
[ix
]; }
169 const AclEntryInfo
&operator[](uint32 ix
) const
170 { assert(ix
< mNumberOfAclEntries
); return mAclEntryInfo
[ix
]; }
171 AclEntryInfo
&operator[](uint32 ix
)
172 { assert(ix
< mNumberOfAclEntries
); return mAclEntryInfo
[ix
]; }
174 uint32
size() const { return mNumberOfAclEntries
; } // obsolete
175 uint32
count() const { return mNumberOfAclEntries
; }
176 AclEntryInfo
*entries() const { return mAclEntryInfo
; }
179 AclEntryInfo
*mAclEntryInfo
;
180 uint32 mNumberOfAclEntries
;
181 CssmAllocator
*mAllocator
;
184 class AutoAuthorizationGroup
: public AuthorizationGroup
{
186 AutoAuthorizationGroup(CssmAllocator
&alloc
) : allocator(alloc
) { }
187 explicit AutoAuthorizationGroup(const AclAuthorizationSet
&set
,
188 CssmAllocator
&alloc
) : AuthorizationGroup(set
, alloc
), allocator(alloc
) { }
189 ~AutoAuthorizationGroup() { destroy(allocator
); }
191 CssmAllocator
&allocator
;
196 // Walkers for the CSSM API structure types
198 namespace DataWalkers
{
201 template <class Action
>
202 AclEntryInput
*walk(Action
&operate
, AclEntryInput
* &input
)
205 walk(operate
, input
->proto());
209 template <class Action
>
210 void walk(Action
&operate
, AclEntryInput
&input
)
213 walk(operate
, input
.proto());
217 template <class Action
>
218 void walk(Action
&operate
, AclEntryInfo
&info
)
221 walk(operate
, info
.proto());
224 template <class Action
>
225 void walk(Action
&operate
, const AclEntryInfo
&info
)
226 { walk(operate
, const_cast<AclEntryInfo
&>(info
)); }
228 // AuthorizationGroup
229 template <class Action
>
230 void walk(Action
&operate
, AuthorizationGroup
&auth
)
233 uint32 count
= auth
.count();
234 operate
.blob(auth
.AuthTags
, count
* sizeof(AclAuthorization
));
235 for (uint32 n
= 0; n
< count
; n
++)
236 walk(operate
, auth
.AuthTags
[n
]);
239 template <class Action
>
240 void walk(Action
&operate
, CSSM_AUTHORIZATIONGROUP
&auth
)
241 { walk(operate
, static_cast<CSSM_AUTHORIZATIONGROUP
&>(auth
)); }
244 template <class Action
>
245 void enumerate(Action
&operate
, AclEntryPrototype
&proto
)
247 walk(operate
, proto
.subject());
248 walk(operate
, proto
.authorization());
249 //@@@ ignoring validity period
252 template <class Action
>
253 void walk(Action
&operate
, AclEntryPrototype
&proto
)
256 enumerate(operate
, proto
);
259 template <class Action
>
260 AclEntryPrototype
*walk(Action
&operate
, AclEntryPrototype
* &proto
)
263 enumerate(operate
, *proto
);
268 template <class Action
>
269 void walk(Action
&operate
, AclOwnerPrototype
&proto
)
272 walk(operate
, proto
.subject());
275 template <class Action
>
276 AclOwnerPrototype
*walk(Action
&operate
, AclOwnerPrototype
* &proto
)
279 walk(operate
, proto
->subject());
284 } // end namespace DataWalkers
286 } // end namespace Security