Skip to content

Commit

Permalink
pam: implemented a local pam callback that uses a preset pam-password
Browse files Browse the repository at this point in the history
  • Loading branch information
franku committed Nov 5, 2018
1 parent 3873e33 commit 363844c
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 23 deletions.
3 changes: 2 additions & 1 deletion core/src/console/console.cc
Expand Up @@ -1095,7 +1095,8 @@ int main(int argc, char *argv[])

#if defined(HAVE_PAM)
if (console_resource && console_resource->use_pam_authentication_) {
// UA_sock->fsend("@@username:franku");
// UA_sock->fsend("@@username:bareos-pam");
// UA_sock->fsend("@@password:linuxlinux");
Bmicrosleep(1,0);
if (!ConsolePamAuthenticate(stdin, UA_sock)) {
TerminateConsole(0);
Expand Down
34 changes: 27 additions & 7 deletions core/src/dird/auth_pam.cc
Expand Up @@ -33,10 +33,11 @@ static const std::string service_name("bareos");

struct PamData {
BareosSocket *UA_sock_;
const std::string &passwd_;

PamData(BareosSocket *UA_sock) {
UA_sock_ = UA_sock;
}
PamData(BareosSocket *UA_sock, const std::string& passwd)
: UA_sock_(UA_sock)
, passwd_(passwd) { }
};

/*
Expand Down Expand Up @@ -98,6 +99,7 @@ static int PamConversionCallback(int num_msg, const struct pam_message **msgm,
}
if (pam_data->UA_sock_->recv()) {
resp[i].resp = actuallystrdup(pam_data->UA_sock_->msg);
resp[i].resp_retcode = 0;
}
if (pam_data->UA_sock_->IsStop() || pam_data->UA_sock_->IsError()) {
error = true;
Expand All @@ -119,7 +121,6 @@ static int PamConversionCallback(int num_msg, const struct pam_message **msgm,
} /* switch (msgm[i]->msg_style) { */
} /* for( ; i < num_msg ..) */


if (error) {
for (int i = 0; i < num_msg; ++i) {
if (resp[i].resp) {
Expand All @@ -137,16 +138,35 @@ static int PamConversionCallback(int num_msg, const struct pam_message **msgm,
return PAM_SUCCESS;
}

static int PamLocalCallback(int num_msg, const struct pam_message **msgm,
struct pam_response **response, void *appdata_ptr)
{
struct pam_response *resp =
reinterpret_cast<pam_response *> (actuallycalloc(
num_msg, sizeof(struct pam_response)));

PamData *pam_data = reinterpret_cast<PamData *>(appdata_ptr);

if (num_msg == 1) {
resp[0].resp = actuallystrdup(pam_data->passwd_.c_str());
resp[0].resp_retcode = 0;
}

*response = resp;
return PAM_SUCCESS;
}

bool PamAuthenticateUser(BareosSocket *UA_sock,
const std::string &username_in,
const std::string &password_in,
std::string& authenticated_username)
{
std::unique_ptr<PamData> pam_callback_data(new PamData(UA_sock));
std::unique_ptr<PamData> pam_callback_data(new PamData(UA_sock, password_in));
std::unique_ptr<struct pam_conv> pam_conversation_container(new struct pam_conv);
struct pam_handle *pamh; /* pam session handle */

pam_conversation_container->conv = PamConversionCallback;
bool not_interactive = !username_in.empty() && !password_in.empty();
pam_conversation_container->conv = not_interactive ? PamLocalCallback : PamConversionCallback;
pam_conversation_container->appdata_ptr = pam_callback_data.get();

const char *username = username_in.empty() ? nullptr : username_in.c_str();
Expand All @@ -172,7 +192,7 @@ bool PamAuthenticateUser(BareosSocket *UA_sock,
const void* data;
err = pam_get_item(pamh, PAM_USER, &data);
if (err != PAM_SUCCESS) {
Dmsg1(debuglevel, "PAM set_item failed: %s\n", pam_strerror(pamh, err));
Dmsg1(debuglevel, "PAM get_item failed: %s\n", pam_strerror(pamh, err));
return false;
} else {
if (data) {
Expand Down
44 changes: 29 additions & 15 deletions core/src/dird/authenticate.cc
Expand Up @@ -287,25 +287,35 @@ static void AuthenticateNamedConsole(std::string console_name, UaContext *ua, bo
#if defined(HAVE_PAM)
static void LookupTokenFromSocketStream(BareosSocket *ua_sock, const std::string& token, std::string& output)
{
char buffer[128];
memset(buffer, 0, sizeof(buffer));
std::unique_ptr<char> buffer(new char[token.size()]);
memset(buffer.get(), 0, token.size());

int flags = ua_sock->SetNonblocking();
int ret = ::recv(ua_sock->fd_, buffer, token.size(), MSG_PEEK);
if (ret == (int)token.size()) {
if (ua_sock->recv() <= 0) { return; }
std::string temp(ua_sock->msg);
output = temp.substr(temp.find(':')+1);
}

int tries = 3;
bool ready = false;

do {
Bmicrosleep(1,0);
int ret = ::recv(ua_sock->fd_, buffer.get(), token.size(), MSG_PEEK);
if (ret == (int)token.size()) {
if (ua_sock->recv() <= 0) { return; }
std::string temp(ua_sock->msg);
output = temp.substr(temp.find(':')+1);
ready = true;
}
} while (tries-- && !ready);

ua_sock->RestoreBlocking(flags);
}

static void LookupOptionalPamUser(BareosSocket *ua_sock, std::string& pam_username)
static void LookupOptionalUsername(BareosSocket *ua_sock, std::string& pam_username)
{
const std::string token {"@@username:"};
LookupTokenFromSocketStream(ua_sock, token, pam_username);
}

static void LookupOptionalPamPassword(BareosSocket *ua_sock, std::string& pam_password)
static void LookupOptionalPassword(BareosSocket *ua_sock, std::string& pam_password)
{
const std::string token {"@@password:"};
LookupTokenFromSocketStream(ua_sock, token, pam_password);
Expand All @@ -329,9 +339,8 @@ static bool OptionalAuthenticatePamUser(std::string console_name, UaContext *ua,
std::string pam_username;
std::string pam_password;

Bmicrosleep(1,0);
LookupOptionalPamUser(ua->UA_sock, pam_username);
LookupOptionalPamPassword(ua->UA_sock, pam_password);
LookupOptionalUsername(ua->UA_sock, pam_username);
LookupOptionalPassword(ua->UA_sock, pam_password);

std::string authenticated_username;
if (!PamAuthenticateUser(ua->UA_sock, pam_username, pam_password, authenticated_username)) {
Expand All @@ -340,8 +349,13 @@ static bool OptionalAuthenticatePamUser(std::string console_name, UaContext *ua,
} else {
ConsoleResource *user = (ConsoleResource *)my_config->GetResWithName(R_CONSOLE,
authenticated_username.c_str());
ua->cons = user;
auth_success = true;
if (!user) {
ua->cons = nullptr;
auth_success = false;
} else {
ua->cons = user;
auth_success = true;
}
}
return true;
} /* HAVE PAM */
Expand Down

0 comments on commit 363844c

Please sign in to comment.