blob: e6706b8dc3e1c159b20161691a7cff9000577320 [file] [log] [blame]
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "pam_client.h"
#include "base/logging.h"
namespace chromeos {
const char PamClient::kDisplayName[] = ":0.0";
const char PamClient::kLocalUser[] = "root";
const char PamClient::kLocalHost[] = "localhost";
int PamClient::PamConversationCallback(int num_msg,
const struct pam_message** msg,
struct pam_response** resp,
void* credentials) {
*resp = new struct pam_response[num_msg];
PamClient::UserCredentials* user_credentials =
static_cast<PamClient::UserCredentials*>(credentials);
for (int i = 0; i < num_msg; i++) {
resp[i]->resp = 0;
resp[i]->resp_retcode = 0;
switch (msg[i]->msg_style) {
case PAM_PROMPT_ECHO_ON:
resp[i]->resp = strdup(user_credentials->username.c_str());
break;
case PAM_PROMPT_ECHO_OFF:
resp[i]->resp = strdup(user_credentials->password.c_str());
break;
}
}
return PAM_SUCCESS;
}
void PamClient::Init(const std::string& service_name) {
last_pam_result_ = pam_start(service_name.c_str(), NULL,
&pam_conversation_callback_, &pam_handle_);
if (last_pam_result_)
LOG(ERROR) << "didn't start pam: "
<< pam_strerror(pam_handle_, last_pam_result_);
// Set startup items
last_pam_result_ = pam_set_item(pam_handle_, PAM_TTY, kDisplayName);
last_pam_result_ = pam_set_item(pam_handle_, PAM_RHOST, kLocalHost);
last_pam_result_ = pam_set_item(pam_handle_, PAM_RUSER, kLocalUser);
}
PamClient::PamClient()
: pam_handle_(NULL), last_pam_result_(PAM_SUCCESS) {
// Initialize pam with our service name, no default user name,
// pam conversation handle and finally our pam handle
pam_conversation_callback_.conv = PamConversationCallback;
pam_conversation_callback_.appdata_ptr =
static_cast<void*>(&user_credentials_);
}
PamClient::~PamClient() {
last_pam_result_ = pam_end(pam_handle_, last_pam_result_);
}
bool PamClient::Authenticate(const std::string& username,
const std::string& password) {
user_credentials_.username.assign(username);
user_credentials_.password.assign(password);
// TODO(sosa) - add better logging data by adding different cases
last_pam_result_ = pam_authenticate(pam_handle_, 0);
return last_pam_result_ == PAM_SUCCESS;
}
bool PamClient::StartSession() {
// TODO(sosa) - add better logging data by adding different cases
last_pam_result_ = pam_setcred(pam_handle_, PAM_ESTABLISH_CRED);
if (last_pam_result_ == PAM_SUCCESS) {
last_pam_result_ = pam_open_session(pam_handle_, 0);
}
return last_pam_result_ == PAM_SUCCESS;
}
bool PamClient::CloseSession() {
// TODO(sosa) - add better logging data by adding different cases
last_pam_result_ = pam_close_session(pam_handle_, 0);
if (last_pam_result_)
LOG(WARNING) << "didn't close session: "
<< pam_strerror(pam_handle_, last_pam_result_);
// Do this regardless of last result
last_pam_result_ = pam_setcred(pam_handle_, PAM_DELETE_CRED);
return last_pam_result_ == PAM_SUCCESS;
}
} // namespace chromeos