]> git.saurik.com Git - apple/securityd.git/blob - src/acls.cpp
securityd-26674.tar.gz
[apple/securityd.git] / src / acls.cpp
1 /*
2 * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 //
26 // acls - securityd ACL implementation
27 //
28 #include "acls.h"
29 #include "connection.h"
30 #include "server.h"
31 #include "agentquery.h"
32 #include "tokendatabase.h"
33
34 // ACL subjects whose Environments we implement
35 #include <security_cdsa_utilities/acl_any.h>
36 #include <security_cdsa_utilities/acl_password.h>
37 #include <security_cdsa_utilities/acl_threshold.h>
38
39
40 //
41 // SecurityServerAcl is virtual
42 //
43 SecurityServerAcl::~SecurityServerAcl()
44 { }
45
46
47 //
48 // The default implementation of the ACL interface simply uses the local ObjectAcl
49 // data. You can customize this by implementing instantiateAcl() [from ObjectAcl]
50 // or by overriding these methods as desired.
51 // Note: While you can completely ignore the ObjectAcl personality if you wish, it's
52 // usually smarter to adapt it.
53 //
54 void SecurityServerAcl::getOwner(AclOwnerPrototype &owner)
55 {
56 ObjectAcl::cssmGetOwner(owner);
57 }
58
59 void SecurityServerAcl::getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls)
60 {
61 ObjectAcl::cssmGetAcl(tag, count, acls);
62 }
63
64 void SecurityServerAcl::changeAcl(const AclEdit &edit, const AccessCredentials *cred,
65 Database *db)
66 {
67 SecurityServerEnvironment env(*this, db);
68 ObjectAcl::cssmChangeAcl(edit, cred, &env);
69 }
70
71 void SecurityServerAcl::changeOwner(const AclOwnerPrototype &newOwner,
72 const AccessCredentials *cred, Database *db)
73 {
74 SecurityServerEnvironment env(*this, db);
75 ObjectAcl::cssmChangeOwner(newOwner, cred, &env);
76 }
77
78
79 //
80 // Modified validate() methods to connect all the conduits...
81 //
82 void SecurityServerAcl::validate(AclAuthorization auth, const AccessCredentials *cred, Database *db)
83 {
84 SecurityServerEnvironment env(*this, db);
85 StLock<Mutex> objectSequence(aclSequence);
86 StLock<Mutex> processSequence(Server::process().aclSequence);
87 ObjectAcl::validate(auth, cred, &env);
88 }
89
90 void SecurityServerAcl::validate(AclAuthorization auth, const Context &context, Database *db)
91 {
92 validate(auth,
93 context.get<AccessCredentials>(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS), db);
94 }
95
96
97 //
98 // External storage interface
99 //
100 Adornable &SecurityServerEnvironment::store(const AclSubject *subject)
101 {
102 switch (subject->type()) {
103 case CSSM_ACL_SUBJECT_TYPE_PREAUTH:
104 {
105 if (TokenDatabase *tokenDb = dynamic_cast<TokenDatabase *>(database))
106 return tokenDb->common().store();
107 }
108 break;
109 default:
110 break;
111 }
112 CssmError::throwMe(CSSM_ERRCODE_ACL_SUBJECT_TYPE_NOT_SUPPORTED);
113 }
114
115
116 //
117 // ProcessAclSubject personality: uid/gid/pid come from the active Process object
118 //
119 uid_t SecurityServerEnvironment::getuid() const
120 {
121 return Server::process().uid();
122 }
123
124 gid_t SecurityServerEnvironment::getgid() const
125 {
126 return Server::process().gid();
127 }
128
129 pid_t SecurityServerEnvironment::getpid() const
130 {
131 return Server::process().pid();
132 }
133
134
135 //
136 // CodeSignatureAclSubject personality: take code signature from active Process object
137 //
138 bool SecurityServerEnvironment::verifyCodeSignature(const CodeSigning::Signature *signature,
139 const CssmData *comment)
140 {
141 return Server::codeSignatures().verify(Server::process(), signature, comment);
142 }
143
144
145 //
146 // PromptedAclSubject personality: Get a secret by prompting through SecurityAgent
147 //
148 bool SecurityServerEnvironment::getSecret(CssmOwnedData &secret, const CssmData &prompt) const
149 {
150 //@@@ ignoring prompt - not used right now
151 if (database) {
152 QueryPIN query(*database);
153 query.inferHints(Server::process());
154 if (!query()) { // success
155 secret = query.pin();
156 return true;
157 }
158 }
159 return false;
160 }
161
162
163 //
164 // SecretAclSubject personality: externally validate a secret (passphrase etc.)
165 // Right now, this always goes to the (Token)Database object, because that's where
166 // the PIN ACL entries are. We could direct this at the ObjectAcl (database or key)
167 // instead and rely on tokend to perform the PIN mapping, but the generic tokend
168 // wrappers do not (currently) perform any ACL validation, so every tokend would have
169 // to re-implement that. Perhaps in the next ACL revamp cycle...
170 //
171 bool SecurityServerEnvironment::validateSecret(const SecretAclSubject *me,
172 const AccessCredentials *cred)
173 {
174 return database && database->validateSecret(me, cred);
175 }
176
177
178 //
179 // PreAuthenticationAclSubject personality - refer to database (ObjectAcl)
180 //
181 ObjectAcl *SecurityServerEnvironment::preAuthSource()
182 {
183 return database ? &database->acl() : NULL;
184 }
185
186
187 //
188 // The default AclSource denies having an ACL at all
189 //
190 AclSource::~AclSource()
191 { /* virtual */ }
192
193 SecurityServerAcl &AclSource::acl()
194 {
195 CssmError::throwMe(CSSM_ERRCODE_OBJECT_ACL_NOT_SUPPORTED);
196 }
197
198 Database *AclSource::relatedDatabase()
199 {
200 return NULL;
201 }