]> git.saurik.com Git - apple/security.git/blob - SecurityServer/authority.cpp
Security-28.tar.gz
[apple/security.git] / SecurityServer / authority.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
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
8 * using this file.
9 *
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.
16 */
17
18
19 //
20 // authority - authorization manager
21 //
22 #include "authority.h"
23 #include "server.h"
24 #include "connection.h"
25 #include "session.h"
26 #include "process.h"
27
28
29 //
30 // The global dictionary of extant AuthorizationTokens
31 //
32 AuthorizationToken::AuthMap AuthorizationToken::authMap; // set of extant authorizations
33 Mutex AuthorizationToken::authMapLock; // lock for mAuthorizations (only)
34
35
36 //
37 // Construct an Authority
38 //
39 Authority::Authority(const char *configFile)
40 : Authorization::Engine(configFile)
41 {
42 }
43
44 Authority::~Authority()
45 {
46 }
47
48
49 //
50 // Create an authorization token.
51 //
52 AuthorizationToken::AuthorizationToken(Session &ssn, const CredentialSet &base)
53 : session(ssn), mBaseCreds(base), mTransferCount(INT_MAX),
54 mCreatorUid(Server::connection().process.uid())
55 {
56 // generate our (random) handle
57 Server::active().random(mHandle);
58
59 // register handle in the global map
60 StLock<Mutex> _(authMapLock);
61 authMap[mHandle] = this;
62
63 // register with parent session
64 session.addAuthorization(this);
65
66 // all ready
67 debug("SSauth", "Authorization %p created using %d credentials",
68 this, int(mBaseCreds.size()));
69 }
70
71 AuthorizationToken::~AuthorizationToken()
72 {
73 // we better be clean
74 assert(mUsingProcesses.empty());
75
76 // deregister from parent session
77 if (session.removeAuthorization(this))
78 delete &session;
79
80 debug("SSauth", "Authorization %p destroyed", this);
81 }
82
83
84 //
85 // Locate an authorization given its blob.
86 //
87 AuthorizationToken &AuthorizationToken::find(const AuthorizationBlob &blob)
88 {
89 StLock<Mutex> _(authMapLock);
90 AuthMap::iterator it = authMap.find(blob);
91 if (it == authMap.end())
92 Authorization::Error::throwMe(errAuthorizationInvalidRef);
93 return *it->second;
94 }
95
96
97 //
98 // Handle atomic deletion of AuthorizationToken objects
99 //
100 AuthorizationToken::Deleter::Deleter(const AuthorizationBlob &blob)
101 : lock(authMapLock)
102 {
103 AuthMap::iterator it = authMap.find(blob);
104 if (it == authMap.end())
105 Authorization::Error::throwMe(errAuthorizationInvalidRef);
106 mAuth = it->second;
107 }
108
109 void AuthorizationToken::Deleter::remove()
110 {
111 if (mAuth) {
112 authMap.erase(mAuth->handle());
113 delete mAuth;
114 mAuth = NULL;
115 }
116 }
117
118
119 //
120 // Given a set of credentials, add it to our private credentials and return the result
121 //
122 CredentialSet AuthorizationToken::effectiveCreds() const
123 {
124 CredentialSet result = session.authCredentials();
125 for (CredentialSet::const_iterator it = mBaseCreds.begin(); it != mBaseCreds.end(); it++)
126 if (!(*it)->isShared())
127 result.insert(*it);
128 return result;
129 }
130
131
132 //
133 // Add more credential dependencies to an authorization
134 //
135 void AuthorizationToken::mergeCredentials(const CredentialSet &add)
136 {
137 for (CredentialSet::const_iterator it = add.begin(); it != add.end(); it++) {
138 mBaseCreds.erase(*it);
139 mBaseCreds.insert(*it);
140 }
141 debug("SSauth", "Authorization %p merged %d new credentials for %d total",
142 this, int(add.size()), int(mBaseCreds.size()));
143 }
144
145
146 //
147 // Register a new process that uses this authorization token.
148 // This is an idempotent operation.
149 //
150 void AuthorizationToken::addProcess(Process &proc)
151 {
152 StLock<Mutex> _(mLock);
153 mUsingProcesses.insert(&proc);
154 debug("SSauth", "Authorization %p added process %p(%d)", this, &proc, proc.pid());
155 }
156
157
158 //
159 // Completely unregister client process.
160 // It does not matter how often it was registered with addProcess before.
161 // This returns true if no more processes use this token. Presumably you
162 // would then want to clean up, though that's up to you.
163 //
164 bool AuthorizationToken::endProcess(Process &proc)
165 {
166 StLock<Mutex> _(mLock);
167 assert(mUsingProcesses.find(&proc) != mUsingProcesses.end());
168 mUsingProcesses.erase(&proc);
169 IFDEBUG(debug("SSauth", "Authorization %p removed process %p(%d)%s",
170 this, &proc, proc.pid(), mUsingProcesses.empty() ? " FINAL" : ""));
171 return mUsingProcesses.empty();
172 }
173
174
175 //
176 // Check whether internalization/externalization is allowed
177 //
178 bool AuthorizationToken::mayExternalize(Process &) const
179 {
180 return mTransferCount > 0;
181 }
182
183 bool AuthorizationToken::mayInternalize(Process &, bool countIt)
184 {
185 StLock<Mutex> _(mLock);
186 if (mTransferCount > 0) {
187 if (countIt) {
188 mTransferCount--;
189 debug("SSauth", "Authorization %p decrement intcount to %d", this, mTransferCount);
190 }
191 return true;
192 }
193 return false;
194 }
195
196 uid_t
197 AuthorizationToken::creatorUid() const
198 {
199 return mCreatorUid;
200 }
201
202 //
203 // Call the underlying authorize() in a critical region.
204 // The engine code is not thread safe.
205 //
206
207 OSStatus Authority::authorize(const RightSet &inRights,
208 const AuthorizationEnvironment *environment,
209 AuthorizationFlags flags, const CredentialSet *inCredentials, CredentialSet *outCredentials,
210 MutableRightSet *outRights, const AuthorizationToken &auth)
211 {
212 StLock<Mutex> _(mLock);
213 return Authorization::Engine::authorize(inRights, environment,
214 flags, inCredentials, outCredentials, outRights, auth);
215 }
216