2 * Copyright (c) 2000-2001,2003-2007,2011 Apple 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 // acls - securityd ACL implementation
28 // These classes implement securityd's local ACL machine in terms of the generic
29 // ObjectAcl model. In particular, they define securityd's AclValidationEnvironment,
30 // which hooks the real-world state into the abstract AclSubject submachines.
32 // Note that these classes are *complete* but *extendable*. The default implementation
33 // uses unmodified local ObjectAcl state. Subclasses (and certain AclSubjects) may delegate
34 // validation to outside agents (such as a tokend) and thus act as caching forwarding agents.
40 #include <securityd_client/sscommon.h>
41 #include <security_cdsa_utilities/cssmacl.h>
42 #include <security_cdsa_utilities/context.h>
43 #include <security_cdsa_utilities/acl_process.h>
44 #include <security_cdsa_utilities/acl_codesigning.h>
45 #include <security_cdsa_utilities/acl_secret.h>
46 #include <security_cdsa_utilities/acl_preauth.h>
47 #include <security_cdsa_utilities/acl_prompted.h>
48 #include <security_cdsa_utilities/acl_threshold.h>
49 #include "acl_partition.h"
51 using namespace SecurityServer
;
57 class SecurityServerEnvironment
;
61 // Interesting entitlements
63 static const char migrationEntitlement
[] = "com.apple.private.security.allow-migration";
67 // ACL implementation as used by the SecurityServer
69 class SecurityServerAcl
: public ObjectAcl
{
71 SecurityServerAcl() : ObjectAcl(Allocator::standard()), aclSequence(Mutex::recursive
) { }
72 virtual ~SecurityServerAcl();
74 // validation calls restated
75 virtual void validate(AclAuthorization auth
, const AccessCredentials
*cred
, Database
*relatedDatabase
);
76 void validate(AclAuthorization auth
, const Context
&context
, Database
*relatedDatabase
);
78 // CSSM layer ACL calls
79 virtual void getOwner(AclOwnerPrototype
&owner
);
80 virtual void getAcl(const char *tag
, uint32
&count
, AclEntryInfo
*&acls
);
81 virtual void changeAcl(const AclEdit
&edit
, const AccessCredentials
*cred
,
82 Database
*relatedDatabase
);
83 virtual void changeOwner(const AclOwnerPrototype
&newOwner
, const AccessCredentials
*cred
,
84 Database
*relatedDatabase
);
86 // to be provided by implementations
87 virtual AclKind
aclKind() const = 0;
89 // a helper to (try to) add an ACL to a "standard form" item ACL
90 static bool addToStandardACL(const AclValidationContext
&context
, AclSubject
*subject
);
91 static bool looksLikeLegacyDotMac(const AclValidationContext
&context
);
93 bool createClientPartitionID(Process
& process
);
94 bool addClientPartitionID(Process
& process
);
96 // implicit partitioning support
97 PartitionAclSubject
* findPartitionSubject();
98 CFDictionaryRef
createPartitionPayload();
100 // aclSequence is taken to serialize ACL validations to pick up mutual changes
104 void validatePartition(SecurityServerEnvironment
& env
, bool prompt
);
105 bool extendPartition(SecurityServerEnvironment
& env
);
110 // Our implementation of an ACL validation environment uses information
111 // derived from a Connection object. It implements context for a fair number
112 // of subject types (see the inheritance list below).
114 class SecurityServerEnvironment
: public virtual AclValidationEnvironment
,
115 public virtual ProcessAclSubject::Environment
,
116 public virtual CodeSignatureAclSubject::Environment
,
117 public virtual SecretAclSubject::Environment
,
118 public virtual PromptedAclSubject::Environment
,
119 public virtual PreAuthorizationAcls::Environment
{
121 SecurityServerEnvironment(SecurityServerAcl
&baseAcl
, Database
*db
)
122 : acl(baseAcl
), database(db
) { }
124 SecurityServerAcl
&acl
;
125 Database
* const database
;
128 uid_t
getuid() const;
129 gid_t
getgid() const;
130 pid_t
getpid() const;
131 bool verifyCodeSignature(const OSXVerifier
&verifier
, const AclValidationContext
&context
);
132 bool validateSecret(const SecretAclSubject
*me
, const AccessCredentials
*cred
);
133 bool getSecret(CssmOwnedData
&secret
, const CssmData
&prompt
) const;
134 ObjectAcl
*preAuthSource();
135 Adornable
&store(const AclSubject
*subject
);
138 ThresholdAclSubject
*standardSubject(const AclValidationContext
&context
);
143 // An abstract source of a SecurityServerAcl.
144 // There is a default implementation, which throws OBJECT_ACL_NOT_SUPPORTED.
149 virtual ~AclSource();
152 virtual SecurityServerAcl
&acl(); // defaults to "no ACL; throw exception"
153 virtual Database
*relatedDatabase(); // optionally, a Database related to me
156 // Forward ACL calls, passing some locally obtained stuff along.
157 // These are virtual so an AclSource can override them. Such overrides
158 // should enhance/post-process rather than replace functionality.
160 virtual void getOwner(AclOwnerPrototype
&owner
)
161 { return acl().getOwner(owner
); }
162 virtual void getAcl(const char *tag
, uint32
&count
, AclEntryInfo
*&acls
)
163 { return acl().getAcl(tag
, count
, acls
); }
164 virtual void changeAcl(const AclEdit
&edit
, const AccessCredentials
*cred
)
165 { return acl().changeAcl(edit
, cred
, relatedDatabase()); }
166 virtual void changeOwner(const AclOwnerPrototype
&newOwner
, const AccessCredentials
*cred
)
167 { return acl().changeOwner(newOwner
, cred
, relatedDatabase()); }
168 virtual void validate(AclAuthorization auth
, const AccessCredentials
*cred
, Database
* relatedDb
= NULL
)
169 { acl().validate(auth
, cred
, relatedDb
? relatedDb
: relatedDatabase()); }
170 virtual void validate(AclAuthorization auth
, const Context
&context
, Database
* relatedDb
= NULL
)
171 { acl().validate(auth
, context
, relatedDb
? relatedDb
: relatedDatabase()); }