Skip to content

Commit

Permalink
pam: basic authentication works
Browse files Browse the repository at this point in the history
  • Loading branch information
Torsten Ueberschar authored and franku committed May 29, 2018
1 parent be62daa commit 17dfb75
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 61 deletions.
2 changes: 2 additions & 0 deletions core/src/include/baconfig.h
Expand Up @@ -595,6 +595,8 @@ DLL_IMP_EXP int msg_(const char *file, int line, POOLMEM *&pool_buf, const char
#define bstrdup(str) strcpy((char *)bmalloc(strlen((str))+1),(str))
#endif

#define actuallystrdup(str) strcpy((char *)actuallymalloc(strlen((str))+1), (str))

#ifdef DEBUG
#define bmalloc(size) b_malloc(__FILE__, __LINE__, (size))
#endif
Expand Down
106 changes: 45 additions & 61 deletions core/src/lib/pam_handler.cc
Expand Up @@ -11,109 +11,93 @@ static const int debuglevel = 200;

static const std::string service_name("bareos");


class PamData {
std::string username_;
public:
std::string password_;
std::string username_;

public:
PamData(std::string username, std::string password) {
username_ = username;
password_ = password;
}

private:
inline int callback(int num_msg, const struct pam_message **msg, struct pam_response **resp) const;
bool send(struct pam_response **response, const char *data) const;
};

/// this is the PAM Handler Callback
int PamData::callback(
int num_msg,
const struct pam_message **msg,
struct pam_response **resp
) const {
if (!msg || !*msg || !resp) {
/// PAM-Callback calls Bareos PAM-Handler
static int conv(int num_msg, const struct pam_message **msgm,
struct pam_response **response, void *appdata_ptr) {
if (!num_msg || !*msgm || !response) {
return PAM_BUF_ERR;
}

const pam_message *m = *msg;
if ((num_msg <= 0) || (num_msg > PAM_MAX_NUM_MSG)) {
return (PAM_CONV_ERR);
}

struct pam_response *resp;
auto pam_data = reinterpret_cast<PamData *>(appdata_ptr);

if ((*resp = static_cast<pam_response *>(calloc(num_msg, sizeof(struct pam_response)))) == nullptr) {
if ((resp = static_cast<pam_response *>(actuallycalloc(num_msg, sizeof(struct pam_response)))) == nullptr) {
return PAM_BUF_ERR;
}

switch ((*msg)->msg_style) {
case PAM_PROMPT_ECHO_OFF: {
return send(resp, password_.c_str()) ? PAM_SUCCESS : PAM_CONV_ERR;
}
switch ((*msgm)->msg_style) {
case PAM_PROMPT_ECHO_OFF:
case PAM_PROMPT_ECHO_ON: {
return send(resp, username_.c_str()) ? PAM_SUCCESS : PAM_CONV_ERR;
resp->resp = actuallystrdup(pam_data->password_.c_str());
break;
}
case PAM_ERROR_MSG:
case PAM_TEXT_INFO:
case PAM_TEXT_INFO:break;
default: {
(void) fprintf(stderr, "message[%d]: unknown type %d/val=\"%s\"\n",
1, m->msg_style, m->msg);
/* error, service module won't clean up */
const pam_message *m = *msgm;
Dmsg3(debuglevel, "message[%d]: pam error type: %d error: \"%s\"\n",
1, m->msg_style, m->msg);
goto err;
}
}
free(resp);
*resp = NULL;
return PAM_CONV_ERR;
}

bool PamData::send(
struct pam_response **response,
const char *data) const {
struct pam_response *resp =
(struct pam_response *) calloc(1, sizeof(struct pam_response));

if (!resp) {
return false;
}
resp->resp = bstrdup(data);
resp->resp_retcode = resp->resp ? PAM_SUCCESS : PAM_BUF_ERR;
*response = resp;
return true;
}

/// PAM-Callback calls Bareos PAM-Handler
static int conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) {
const pam_message *m = *msg;
struct pam_response *r;

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

err:
for (int i = 0; i < num_msg; ++i) {
if (resp[i].resp != NULL) {
memset(resp[i].resp, 0, strlen(resp[i].resp));
free(resp[i].resp);
}
}
memset(resp, 0, num_msg * sizeof *resp);
free(resp);
*response = NULL;
return PAM_CONV_ERR;
}

bool pam_authenticate_useragent(std::string username, std::string password) {

PamData pam_data(username, password);

const struct pam_conv pam_conversation = {conv, (void *) &pam_data};

pam_handle_t *pamh = nullptr;

/* START */
int err = pam_start(service_name.c_str(),
username.c_str(),
&pam_conversation,
&pamh);
int err = pam_start(service_name.c_str(), username.c_str(), &pam_conversation, &pamh);
if (err != PAM_SUCCESS) {
Dmsg1(debuglevel, "PAM start failed: %s\n", pam_strerror(pamh, err));
}

err = pam_set_item(pamh, PAM_RUSER, username.c_str());
if (err != PAM_SUCCESS) {
Dmsg1(debuglevel, "PAM start failed: %s", pam_strerror(pamh, err));
Dmsg1(debuglevel, "PAM set_item failed: %s\n", pam_strerror(pamh, err));
}

/* AUTHENTICATE */
err = pam_authenticate(pamh, 0);
if (err != PAM_SUCCESS) {
Dmsg1(debuglevel, "PAM authentication failed: %s", pam_strerror(pamh, err));
Dmsg1(debuglevel, "PAM authentication failed: %s\n", pam_strerror(pamh, err));
}

/* END */
err = pam_end(pamh, err);
if (err != PAM_SUCCESS) {
Dmsg1(debuglevel, "PAM end failed: %s", pam_strerror(pamh, err));
if (pam_end(pamh, err) != PAM_SUCCESS) {
Dmsg1(debuglevel, "PAM end failed: %s\n", pam_strerror(pamh, err));
return false;
}

return err == 0;
Expand Down

0 comments on commit 17dfb75

Please sign in to comment.