]> git.saurik.com Git - apple/securityd.git/blob - src/credential.cpp
securityd-40120.tar.gz
[apple/securityd.git] / src / credential.cpp
1 /*
2 * Copyright (c) 2000-2004,2009 Apple 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 #include "credential.h"
25 #include <pwd.h>
26 #include <syslog.h>
27
28 #include <Security/checkpw.h>
29 extern "C" int checkpw_internal( const struct passwd *pw, const char* password );
30 #include "server.h"
31
32 namespace Authorization {
33
34 // default credential: invalid for everything, needed as a default session credential
35 CredentialImpl::CredentialImpl() : mShared(false), mRight(false), mRightName(""), mGroupName(""), mUid(0), mUserName(""), mRealName(""), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(false)
36 {
37 }
38
39 // only for testing whether this credential is usable
40 CredentialImpl::CredentialImpl(const uid_t uid, const string &username, const string &realname, const string &groupname, bool shared) : mShared(shared), mRight(false), mRightName(""), mGroupName(groupname), mUid(uid), mUserName(username), mRealName(realname), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(true)
41 {
42 }
43
44 CredentialImpl::CredentialImpl(const string &username, const string &password, bool shared) : mShared(shared), mRight(false), mRightName(""), mGroupName(""), mUserName(username), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(false)
45 {
46 Server::active().longTermActivity();
47 const char *user = username.c_str();
48 struct passwd *pw = getpwnam(user);
49
50 do {
51 if (!pw) {
52 syslog(LOG_ERR, "getpwnam() failed for user %s, creating invalid credential", user);
53 break;
54 }
55
56 mUid = pw->pw_uid;
57 mUserName = pw->pw_name;
58 mRealName = pw->pw_gecos;
59
60 const char *passwd = password.c_str();
61 int checkpw_status = checkpw_internal(pw, passwd);
62
63 if (checkpw_status != CHECKPW_SUCCESS) {
64 syslog(LOG_ERR, "checkpw() returned %d; failed to authenticate user %s (uid %lu).", checkpw_status, pw->pw_name, pw->pw_uid);
65 break;
66 }
67
68 syslog(LOG_INFO, "checkpw() succeeded, creating%s credential for user %s", mShared ? " shared" : "", user);
69
70 mValid = true;
71
72 endpwent();
73 } while (0);
74 }
75
76 // least-privilege
77 // @@@ arguably we don't care about the UID any more and should not
78 // require it in this ctor
79 CredentialImpl::CredentialImpl(const string &right, const uid_t uid, bool shared) : mShared(shared), mRight(true), mRightName(right), mGroupName(""), mUid(uid), mUserName(""), mRealName(""), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(true)
80 {
81 }
82
83 CredentialImpl::~CredentialImpl()
84 {
85 }
86
87 bool
88 CredentialImpl::operator < (const CredentialImpl &other) const
89 {
90 // Desired ordering characteristics:
91 //
92 // - unshared before shared
93 // - least privilege before non-least privilege
94 // - for least privilege credentials with the same sharing characteristics,
95 // order on the basis of right strings
96 // - orthographic order of group names
97 //
98 // UID used to be the primary distinguishing element, but it can't be
99 // trusted--it's gathered as a side effect, potentially by an external
100 // process.
101 //
102 // Nothing is sacred about this ordering; we just had to pick something.
103
104 if (!mShared && other.mShared)
105 return true;
106 if (!other.mShared && mShared)
107 return false;
108 if (mRight && !other.mRight)
109 return true;
110 if (!mRight && other.mRight)
111 return false;
112 if (mRight && other.mRight)
113 return mRightName < other.mRightName;
114 else
115 return mGroupName < other.mGroupName;
116 }
117
118 // Returns true if this CredentialImpl should be shared.
119 bool
120 CredentialImpl::isShared() const
121 {
122 return mShared;
123 }
124
125 // Merge with other
126 void
127 CredentialImpl::merge(const CredentialImpl &other)
128 {
129 // try to ensure that the credentials are the same type
130 assert(mRight == other.mRight);
131 if (mRight)
132 assert(mRightName == other.mRightName);
133 else
134 assert(mGroupName == other.mGroupName);
135
136 if (other.mValid && (!mValid || mCreationTime < other.mCreationTime))
137 {
138 mCreationTime = other.mCreationTime;
139 mValid = true;
140 }
141 }
142
143 // The time at which this credential was obtained.
144 CFAbsoluteTime
145 CredentialImpl::creationTime() const
146 {
147 return mCreationTime;
148 }
149
150 // Return true iff this credential is valid.
151 bool
152 CredentialImpl::isValid() const
153 {
154 return mValid;
155 }
156
157 void
158 CredentialImpl::invalidate()
159 {
160 mValid = false;
161 }
162
163 //
164 // Credential class
165 //
166 Credential::Credential() :
167 RefPointer<CredentialImpl>(new CredentialImpl())
168 {
169 }
170
171 Credential::Credential(CredentialImpl *impl) :
172 RefPointer<CredentialImpl>(impl)
173 {
174 }
175
176 Credential::Credential(const uid_t uid, const string &username, const string &realname, const string &groupname, bool shared) :
177 RefPointer<CredentialImpl>(new CredentialImpl(uid, username, realname, groupname, shared))
178 {
179 }
180
181 Credential::Credential(const string &username, const string &password, bool shared) : RefPointer<CredentialImpl>(new CredentialImpl(username, password, shared))
182 {
183 }
184
185 Credential::Credential(const string &right, const uid_t uid, bool shared) : RefPointer<CredentialImpl>(new CredentialImpl(right, uid, shared))
186 {
187 }
188
189 Credential::~Credential()
190 {
191 }
192
193 bool
194 Credential::operator < (const Credential &other) const
195 {
196 if (!*this)
197 return other;
198
199 if (!other)
200 return false;
201
202 return (**this) < (*other);
203 }
204
205 } // end namespace Authorization
206
207