]> git.saurik.com Git - apple/security.git/blob - SecurityServer/Authorization/AuthorizationData.cpp
Security-179.tar.gz
[apple/security.git] / SecurityServer / Authorization / AuthorizationData.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 * AuthorizationData.cpp
21 * Authorization
22 *
23 * Created by Michael Brouwer on Thu Oct 12 2000.
24 * Copyright (c) 2000 Apple Computer Inc. All rights reserved.
25 *
26 */
27
28 #include "AuthorizationData.h"
29
30 #include <grp.h>
31 #include <pwd.h>
32 #include <Security/checkpw.h>
33
34 #include "server.h"
35
36
37 // checkpw() that uses provided struct passwd
38 extern "C"
39 {
40 int checkpw_internal( const struct passwd *pw, const char* password );
41 }
42
43
44 namespace Authorization {
45
46
47 AuthValueRef::AuthValueRef(const AuthValue &value) :
48 RefPointer<AuthValue>(new AuthValue(value)) {}
49
50 AuthValueRef::AuthValueRef(const AuthorizationValue &value) :
51 RefPointer<AuthValue>(new AuthValue(value)) {}
52
53 AuthValue::AuthValue(const AuthorizationValue &value) :
54 mOwnsValue(false)
55 {
56 mValue.length = value.length;
57 mValue.data = value.data;
58 }
59
60 AuthValueRef::AuthValueRef(UInt32 length, void *data) :
61 RefPointer<AuthValue>(new AuthValue(length, data)) {}
62
63 AuthValue::AuthValue(UInt32 length, void *data) :
64 mOwnsValue(true)
65 {
66 mValue.length = length;
67 mValue.data = new uint8_t[length];
68 if (length)
69 memcpy(mValue.data, data, length);
70 }
71
72 AuthValue::~AuthValue()
73 {
74 if (mOwnsValue)
75 delete[] reinterpret_cast<uint8_t*>(mValue.data);
76 }
77
78 AuthValue &
79 AuthValue::operator = (const AuthValue &other)
80 {
81 if (mOwnsValue)
82 delete[] reinterpret_cast<uint8_t*>(mValue.data);
83
84 mValue = other.mValue;
85 mOwnsValue = other.mOwnsValue;
86 other.mOwnsValue = false;
87 return *this;
88 }
89
90 void
91 AuthValue::fillInAuthorizationValue(AuthorizationValue &value)
92 {
93 value.length = mValue.length;
94 value.data = mValue.data;
95 }
96
97 AuthValueVector &
98 AuthValueVector::operator = (const AuthorizationValueVector& valueVector)
99 {
100 clear();
101 for (unsigned int i=0; i < valueVector.count; i++)
102 push_back(AuthValueRef(valueVector.values[i]));
103 return *this;
104 }
105
106 void
107 AuthValueVector::copy(AuthorizationValueVector **data, size_t *length) const
108 {
109 AuthorizationValueVector valueVector;
110 valueVector.count = size();
111 valueVector.values = new AuthorizationValue[valueVector.count];
112 int i = 0;
113 for (const_iterator it = begin(); it != end(); ++it, ++i)
114 {
115 (*it)->fillInAuthorizationValue(valueVector.values[i]);
116 }
117
118 Copier<AuthorizationValueVector> flatValueVector(&valueVector);
119 *length = flatValueVector.length();
120 *data = flatValueVector.keep();
121
122 delete[] valueVector.values;
123 }
124
125 AuthItem::AuthItem(const AuthorizationItem &item) :
126 mFlags(item.flags),
127 mOwnsName(true),
128 mOwnsValue(true)
129 {
130 if (!item.name)
131 MacOSError::throwMe(errAuthorizationInternal);
132 size_t nameLen = strlen(item.name) + 1;
133 mName = new char[nameLen];
134 memcpy(const_cast<char *>(mName), item.name, nameLen);
135
136 mValue.length = item.valueLength;
137 mValue.data = new uint8_t[item.valueLength];
138 if (mValue.length)
139 memcpy(mValue.data, item.value, item.valueLength);
140 }
141
142
143 AuthItem::AuthItem(AuthorizationString name) :
144 mName(name),
145 mFlags(0),
146 mOwnsName(false),
147 mOwnsValue(false)
148 {
149 mValue.length = 0;
150 mValue.data = NULL;
151 }
152
153 AuthItem::AuthItem(AuthorizationString name, AuthorizationValue value, AuthorizationFlags flags) :
154 mFlags(flags),
155 mOwnsName(true),
156 mOwnsValue(true)
157 {
158 if (!name)
159 MacOSError::throwMe(errAuthorizationInternal);
160 size_t nameLen = strlen(name) + 1;
161 mName = new char[nameLen];
162 memcpy(const_cast<char *>(mName), name, nameLen);
163
164 mValue.length = value.length;
165 mValue.data = new uint8_t[value.length];
166 if (mValue.length)
167 memcpy(mValue.data, value.data, value.length);
168 }
169
170 AuthItem::~AuthItem()
171 {
172 if (mOwnsName)
173 delete[] mName;
174 if (mOwnsValue)
175 delete[] reinterpret_cast<uint8_t*>(mValue.data);
176 }
177
178 bool
179 AuthItem::operator < (const AuthItem &other) const
180 {
181 return strcmp(mName, other.mName) < 0;
182 }
183
184 AuthItem &
185 AuthItem::operator = (const AuthItem &other)
186 {
187 if (mOwnsName)
188 delete[] mName;
189 if (mOwnsValue)
190 delete[] reinterpret_cast<uint8_t*>(mValue.data);
191
192 mName = other.mName;
193 mValue = other.mValue;
194 mFlags = other.mFlags;
195 mOwnsName = other.mOwnsName;
196 other.mOwnsName = false;
197 mOwnsValue = other.mOwnsValue;
198 other.mOwnsValue = false;
199 return *this;
200 }
201
202 void
203 AuthItem::fillInAuthorizationItem(AuthorizationItem &item)
204 {
205 item.name = mName;
206 item.valueLength = mValue.length;
207 item.value = mValue.data;
208 item.flags = mFlags;
209 }
210
211
212 AuthItemRef::AuthItemRef(const AuthorizationItem &item) : RefPointer<AuthItem>(new AuthItem(item)) {}
213
214 AuthItemRef::AuthItemRef(AuthorizationString name) : RefPointer<AuthItem>(new AuthItem(name)) {}
215
216 AuthItemRef::AuthItemRef(AuthorizationString name, AuthorizationValue value, AuthorizationFlags flags) : RefPointer<AuthItem>(new AuthItem(name, value, flags)) {}
217
218
219 //
220 // AuthItemSet
221 //
222 AuthItemSet::AuthItemSet()
223 {
224 }
225
226 AuthItemSet::~AuthItemSet()
227 {
228 }
229
230 AuthItemSet &
231 AuthItemSet::operator = (const AuthorizationItemSet& itemSet)
232 {
233 clear();
234
235 for (unsigned int i=0; i < itemSet.count; i++)
236 insert(AuthItemRef(itemSet.items[i]));
237
238 return *this;
239 }
240
241 AuthItemSet::AuthItemSet(const AuthorizationItemSet *itemSet)
242 {
243 if (itemSet)
244 {
245 for (unsigned int i=0; i < itemSet->count; i++)
246 insert(AuthItemRef(itemSet->items[i]));
247 }
248 }
249
250 void
251 AuthItemSet::copy(AuthorizationItemSet *&data, size_t &length, CssmAllocator &alloc) const
252 {
253 AuthorizationItemSet itemSet;
254 itemSet.count = size();
255 itemSet.items = new AuthorizationItem[itemSet.count];
256 int i = 0;
257 for (const_iterator it = begin(); it != end(); ++it, ++i)
258 {
259 (*it)->fillInAuthorizationItem(itemSet.items[i]);
260 }
261
262 Copier<AuthorizationItemSet> flatItemSet(&itemSet, alloc);
263 length = flatItemSet.length();
264
265 data = flatItemSet.keep();
266 // else flatItemSet disappears again
267
268 delete[] itemSet.items;
269 }
270
271 //
272 // CredentialImpl class
273 //
274
275 // only for testing whether this credential is usable
276 CredentialImpl::CredentialImpl(const string &username, const uid_t uid, const gid_t gid, bool shared) :
277 mUsername(username), mShared(shared), mUid(uid), mGid(gid), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(true)
278 {
279 }
280
281 // credential with validity based on username/password combination.
282 CredentialImpl::CredentialImpl(const string &username, const string &password, bool shared) :
283 mUsername(username), mShared(shared), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(false)
284 {
285 // Calling into DirectoryServices can be a long term operation
286 Server::active().longTermActivity();
287
288 // try short name first
289 const char *user = username.c_str();
290 struct passwd *pw = getpwnam(user);
291
292 do {
293
294 if (!pw)
295 {
296 secdebug("autheval", "user %s not found, creating invalid credential", user);
297 break;
298 }
299
300 mUsername = string ( pw->pw_name );
301 mUid = pw->pw_uid;
302 mGid = pw->pw_gid;
303
304 const char *passwd = password.c_str();
305 int checkpw_status = checkpw_internal(pw, passwd);
306
307 if (checkpw_status != CHECKPW_SUCCESS)
308 {
309 secdebug("autheval", "checkpw() for user %s failed with error %d, creating invalid credential", user, checkpw_status);
310 break;
311 }
312
313 secdebug("autheval", "checkpw() for user %s succeeded, creating%s credential",
314 user, mShared ? " shared" : "");
315
316 mValid = true;
317
318 endpwent();
319 }
320 while (0);
321 }
322
323
324 CredentialImpl::~CredentialImpl()
325 {
326 }
327
328 bool
329 CredentialImpl::operator < (const CredentialImpl &other) const
330 {
331 if (!mShared && other.mShared)
332 return true;
333 if (!other.mShared && mShared)
334 return false;
335
336 return mUsername < other.mUsername;
337 }
338
339 // Returns true if this CredentialImpl should be shared.
340 bool
341 CredentialImpl::isShared() const
342 {
343 return mShared;
344 }
345
346 // Merge with other
347 void
348 CredentialImpl::merge(const CredentialImpl &other)
349 {
350 assert(mUsername == other.mUsername);
351
352 if (other.mValid && (!mValid || mCreationTime < other.mCreationTime))
353 {
354 mCreationTime = other.mCreationTime;
355 mUid = other.mUid;
356 mGid = other.mGid;
357 mValid = true;
358 }
359 }
360
361 // The time at which this credential was obtained.
362 CFAbsoluteTime
363 CredentialImpl::creationTime() const
364 {
365 return mCreationTime;
366 }
367
368 // Return true iff this credential is valid.
369 bool
370 CredentialImpl::isValid() const
371 {
372 return mValid;
373 }
374
375 void
376 CredentialImpl::invalidate()
377 {
378 mValid = false;
379 }
380
381 //
382 // Credential class
383 //
384 Credential::Credential() :
385 RefPointer<CredentialImpl>(NULL)
386 {
387 }
388
389 Credential::Credential(CredentialImpl *impl) :
390 RefPointer<CredentialImpl>(impl)
391 {
392 }
393
394 Credential::Credential(const string &username, const uid_t uid, const gid_t gid, bool shared) :
395 RefPointer<CredentialImpl>(new CredentialImpl(username, uid, gid, shared))
396 {
397 }
398
399 Credential::Credential(const string &username, const string &password, bool shared) :
400 RefPointer<CredentialImpl>(new CredentialImpl(username, password, shared))
401 {
402 }
403
404 Credential::~Credential()
405 {
406 }
407
408 bool
409 Credential::operator < (const Credential &other) const
410 {
411 if (!*this)
412 return other;
413
414 if (!other)
415 return false;
416
417 return (**this) < (*other);
418 }
419
420
421
422 } // end namespace Authorization