#include "credential.h"
#include <pwd.h>
#include <syslog.h>
#include <Security/checkpw.h>
extern "C" int checkpw_internal( const struct passwd *pw, const char* password );
#include "server.h"
namespace Authorization {
CredentialImpl::CredentialImpl() : mShared(false), mRight(false), mUid(0), mName(""), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(false)
{
}
CredentialImpl::CredentialImpl(const uid_t uid, const string &username, const string &realname, bool shared) : mShared(shared), mRight(false), mUid(uid), mName(username), mRealName(realname), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(true)
{
}
CredentialImpl::CredentialImpl(const string &username, const string &password, bool shared) : mShared(shared), mRight(false), mName(username), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(false)
{
Server::active().longTermActivity();
const char *user = username.c_str();
struct passwd *pw = getpwnam(user);
do {
if (!pw) {
syslog(LOG_ERR, "getpwnam() failed for user %s, creating invalid credential", user);
break;
}
mUid = pw->pw_uid;
mName = pw->pw_name;
mRealName = pw->pw_gecos;
const char *passwd = password.c_str();
int checkpw_status = checkpw_internal(pw, passwd);
if (checkpw_status != CHECKPW_SUCCESS) {
syslog(LOG_ERR, "checkpw() returned %d; failed to authenticate user %s (uid %lu).", checkpw_status, pw->pw_name, pw->pw_uid);
break;
}
syslog(LOG_INFO, "checkpw() succeeded, creating%s credential for user %s", mShared ? " shared" : "", user);
mValid = true;
endpwent();
} while (0);
}
CredentialImpl::CredentialImpl(const string &right, bool shared) : mShared(shared), mRight(true), mUid(-2), mName(right), mRealName(""), mCreationTime(CFAbsoluteTimeGetCurrent()), mValid(true)
{
}
CredentialImpl::~CredentialImpl()
{
}
bool
CredentialImpl::operator < (const CredentialImpl &other) const
{
if (!mShared && other.mShared)
return true;
if (!other.mShared && mShared)
return false;
if (mRight && !other.mRight)
return true;
if (!mRight && other.mRight)
return false;
if (mRight) {
return mName < other.mName;
} else {
return mUid < other.mUid;
}
}
bool
CredentialImpl::isShared() const
{
return mShared;
}
void
CredentialImpl::merge(const CredentialImpl &other)
{
assert(mRight == other.mRight);
if (mRight)
assert(mName == other.mName);
else
assert(mUid == other.mUid);
if (other.mValid && (!mValid || mCreationTime < other.mCreationTime))
{
mCreationTime = other.mCreationTime;
mValid = true;
}
}
CFAbsoluteTime
CredentialImpl::creationTime() const
{
return mCreationTime;
}
bool
CredentialImpl::isValid() const
{
return mValid;
}
void
CredentialImpl::invalidate()
{
mValid = false;
}
Credential::Credential() :
RefPointer<CredentialImpl>(new CredentialImpl())
{
}
Credential::Credential(CredentialImpl *impl) :
RefPointer<CredentialImpl>(impl)
{
}
Credential::Credential(const uid_t uid, const string &username, const string &realname, bool shared) :
RefPointer<CredentialImpl>(new CredentialImpl(uid, username, realname, shared))
{
}
Credential::Credential(const string &username, const string &password, bool shared) : RefPointer<CredentialImpl>(new CredentialImpl(username, password, shared))
{
}
Credential::Credential(const string &right, bool shared) : RefPointer<CredentialImpl>(new CredentialImpl(right, shared))
{
}
Credential::~Credential()
{
}
bool
Credential::operator < (const Credential &other) const
{
if (!*this)
return other;
if (!other)
return false;
return (**this) < (*other);
}
}