/* * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. * * The contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). * You may not use this file except in compliance with the License. Please obtain * a copy of the License at http://www.apple.com/publicsource and read it before * using this file. * * This Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the * specific language governing rights and limitations under the License. */ /* * AuthorizationData.cpp * Authorization * * Created by Michael Brouwer on Thu Oct 12 2000. * Copyright (c) 2000 Apple Computer Inc. All rights reserved. * */ #include "AuthorizationData.h" #include #include #include #include "server.h" // checkpw() that uses provided struct passwd extern "C" { int checkpw_internal( const struct passwd *pw, const char* password ); } namespace Authorization { AuthValueRef::AuthValueRef(const AuthValue &value) : RefPointer(new AuthValue(value)) {} AuthValueRef::AuthValueRef(const AuthorizationValue &value) : RefPointer(new AuthValue(value)) {} AuthValue::AuthValue(const AuthorizationValue &value) : mOwnsValue(false) { mValue.length = value.length; mValue.data = value.data; } AuthValueRef::AuthValueRef(UInt32 length, void *data) : RefPointer(new AuthValue(length, data)) {} AuthValue::AuthValue(UInt32 length, void *data) : mOwnsValue(true) { mValue.length = length; mValue.data = new uint8_t[length]; if (length) memcpy(mValue.data, data, length); } AuthValue::~AuthValue() { if (mOwnsValue) delete[] reinterpret_cast(mValue.data); } AuthValue & AuthValue::operator = (const AuthValue &other) { if (mOwnsValue) delete[] reinterpret_cast(mValue.data); mValue = other.mValue; mOwnsValue = other.mOwnsValue; other.mOwnsValue = false; return *this; } void AuthValue::fillInAuthorizationValue(AuthorizationValue &value) { value.length = mValue.length; value.data = mValue.data; } AuthValueVector & AuthValueVector::operator = (const AuthorizationValueVector& valueVector) { clear(); for (unsigned int i=0; i < valueVector.count; i++) push_back(AuthValueRef(valueVector.values[i])); return *this; } void AuthValueVector::copy(AuthorizationValueVector **data, size_t *length) const { AuthorizationValueVector valueVector; valueVector.count = size(); valueVector.values = new AuthorizationValue[valueVector.count]; int i = 0; for (const_iterator it = begin(); it != end(); ++it, ++i) { (*it)->fillInAuthorizationValue(valueVector.values[i]); } Copier flatValueVector(&valueVector); *length = flatValueVector.length(); *data = flatValueVector.keep(); delete[] valueVector.values; } AuthItem::AuthItem(const AuthorizationItem &item) : mFlags(item.flags), mOwnsName(true), mOwnsValue(true) { if (!item.name) MacOSError::throwMe(errAuthorizationInternal); size_t nameLen = strlen(item.name) + 1; mName = new char[nameLen]; memcpy(const_cast(mName), item.name, nameLen); mValue.length = item.valueLength; mValue.data = new uint8_t[item.valueLength]; if (mValue.length) memcpy(mValue.data, item.value, item.valueLength); } AuthItem::AuthItem(AuthorizationString name) : mName(name), mFlags(0), mOwnsName(false), mOwnsValue(false) { mValue.length = 0; mValue.data = NULL; } AuthItem::AuthItem(AuthorizationString name, AuthorizationValue value, AuthorizationFlags flags) : mFlags(flags), mOwnsName(true), mOwnsValue(true) { if (!name) MacOSError::throwMe(errAuthorizationInternal); size_t nameLen = strlen(name) + 1; mName = new char[nameLen]; memcpy(const_cast(mName), name, nameLen); mValue.length = value.length; mValue.data = new uint8_t[value.length]; if (mValue.length) memcpy(mValue.data, value.data, value.length); } AuthItem::~AuthItem() { if (mOwnsName) delete[] mName; if (mOwnsValue) delete[] reinterpret_cast(mValue.data); } bool AuthItem::operator < (const AuthItem &other) const { return strcmp(mName, other.mName) < 0; } AuthItem & AuthItem::operator = (const AuthItem &other) { if (mOwnsName) delete[] mName; if (mOwnsValue) delete[] reinterpret_cast(mValue.data); mName = other.mName; mValue = other.mValue; mFlags = other.mFlags; mOwnsName = other.mOwnsName; other.mOwnsName = false; mOwnsValue = other.mOwnsValue; other.mOwnsValue = false; return *this; } void AuthItem::fillInAuthorizationItem(AuthorizationItem &item) { item.name = mName; item.valueLength = mValue.length; item.value = mValue.data; item.flags = mFlags; } AuthItemRef::AuthItemRef(const AuthorizationItem &item) : RefPointer(new AuthItem(item)) {} AuthItemRef::AuthItemRef(AuthorizationString name) : RefPointer(new AuthItem(name)) {} AuthItemRef::AuthItemRef(AuthorizationString name, AuthorizationValue value, AuthorizationFlags flags) : RefPointer(new AuthItem(name, value, flags)) {} // // AuthItemSet // AuthItemSet::AuthItemSet() { } AuthItemSet::~AuthItemSet() { } AuthItemSet & AuthItemSet::operator = (const AuthorizationItemSet& itemSet) { clear(); for (unsigned int i=0; i < itemSet.count; i++) insert(AuthItemRef(itemSet.items[i])); return *this; } AuthItemSet::AuthItemSet(const AuthorizationItemSet *itemSet) { if (itemSet) { for (unsigned int i=0; i < itemSet->count; i++) insert(AuthItemRef(itemSet->items[i])); } } void AuthItemSet::copy(AuthorizationItemSet *&data, size_t &length, CssmAllocator &alloc) const { AuthorizationItemSet itemSet; itemSet.count = size(); itemSet.items = new AuthorizationItem[itemSet.count]; int i = 0; for (const_iterator it = begin(); it != end(); ++it, ++i) { (*it)->fillInAuthorizationItem(itemSet.items[i]); } Copier flatItemSet(&itemSet, alloc); length = flatItemSet.length(); data = flatItemSet.keep(); // else flatItemSet disappears again delete[] itemSet.items; } // // CredentialImpl class // // only for testing whether this credential is usable CredentialImpl::CredentialImpl(const string &username, const uid_t uid, const gid_t gid, bool shared) : mUsername(username), mShared(shared), mUid(uid), mGid(gid), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(true) { } // credential with validity based on username/password combination. CredentialImpl::CredentialImpl(const string &username, const string &password, bool shared) : mUsername(username), mShared(shared), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(false) { // Calling into DirectoryServices can be a long term operation Server::active().longTermActivity(); // try short name first const char *user = username.c_str(); struct passwd *pw = getpwnam(user); do { if (!pw) { secdebug("autheval", "user %s not found, creating invalid credential", user); break; } mUsername = string ( pw->pw_name ); mUid = pw->pw_uid; mGid = pw->pw_gid; const char *passwd = password.c_str(); int checkpw_status = checkpw_internal(pw, passwd); if (checkpw_status != CHECKPW_SUCCESS) { secdebug("autheval", "checkpw() for user %s failed with error %d, creating invalid credential", user, checkpw_status); break; } secdebug("autheval", "checkpw() for user %s succeeded, creating%s credential", user, mShared ? " shared" : ""); mValid = true; endpwent(); } while (0); } CredentialImpl::~CredentialImpl() { } bool CredentialImpl::operator < (const CredentialImpl &other) const { if (!mShared && other.mShared) return true; if (!other.mShared && mShared) return false; return mUsername < other.mUsername; } // Returns true if this CredentialImpl should be shared. bool CredentialImpl::isShared() const { return mShared; } // Merge with other void CredentialImpl::merge(const CredentialImpl &other) { assert(mUsername == other.mUsername); if (other.mValid && (!mValid || mCreationTime < other.mCreationTime)) { mCreationTime = other.mCreationTime; mUid = other.mUid; mGid = other.mGid; mValid = true; } } // The time at which this credential was obtained. CFAbsoluteTime CredentialImpl::creationTime() const { return mCreationTime; } // Return true iff this credential is valid. bool CredentialImpl::isValid() const { return mValid; } void CredentialImpl::invalidate() { mValid = false; } // // Credential class // Credential::Credential() : RefPointer(NULL) { } Credential::Credential(CredentialImpl *impl) : RefPointer(impl) { } Credential::Credential(const string &username, const uid_t uid, const gid_t gid, bool shared) : RefPointer(new CredentialImpl(username, uid, gid, shared)) { } Credential::Credential(const string &username, const string &password, bool shared) : RefPointer(new CredentialImpl(username, password, shared)) { } Credential::~Credential() { } bool Credential::operator < (const Credential &other) const { if (!*this) return other; if (!other) return false; return (**this) < (*other); } } // end namespace Authorization