Skip to content

Commit

Permalink
pam: applied patches von torstenu
Browse files Browse the repository at this point in the history
  • Loading branch information
franku committed May 30, 2018
1 parent fb28cb7 commit b7850ae
Show file tree
Hide file tree
Showing 16 changed files with 153 additions and 31 deletions.
2 changes: 2 additions & 0 deletions core/cmake/BareosFindAllLibraries.cmake
Expand Up @@ -58,6 +58,8 @@ BareosFindLibraryAndHeaders("cap" "sys/capability.h")
BareosFindLibraryAndHeaders("gfapi" "glusterfs/api/glfs.h")
BareosFindLibraryAndHeaders("droplet" "droplet.h")

BareosFindLibraryAndHeaders("pam" "security/pam_appl.h")

BareosFindLibraryAndHeaders("lzo2" "lzo/lzoconf.h")
if (${LZO2_FOUND})
SET(HAVE_LZO 1)
Expand Down
3 changes: 1 addition & 2 deletions core/src/dird/CMakeLists.txt
Expand Up @@ -68,7 +68,7 @@ set(BAREOS_DIR_LIBRARIES
bareosfind
${LMDB_LIBS}
${NDMP_LIBS}
)
)

IF(HAVE_WIN32)
LIST(APPEND BAREOS_DIR_LIBRARIES
Expand Down Expand Up @@ -98,7 +98,6 @@ target_link_libraries(bareos-dbcheck
# jansson ${OPENSSL_LIBS} acl cap lzo2
#)


INSTALL(TARGETS bareos-dir bareos-dbcheck DESTINATION "${sbindir}")
INSTALL(FILES query.sql DESTINATION "${scriptdir}")

Expand Down
2 changes: 1 addition & 1 deletion core/src/dird/fd_cmds.cc
Expand Up @@ -1196,7 +1196,7 @@ void DoClientResolve(UaContext *ua, ClientResource *client)
* After receiving a connection (in socket_server.c) if it is
* from the File daemon, this routine is called.
*/
void *handle_filed_connection(ConnectionPool *connections, BareosSocket *fd,
void *HandleFiledConnection(ConnectionPool *connections, BareosSocket *fd,
char *client_name, int fd_protocol_version)
{
ClientResource *client_resource;
Expand Down
2 changes: 1 addition & 1 deletion core/src/dird/fd_cmds.h
Expand Up @@ -40,7 +40,7 @@ bool SendRestoreObjects(JobControlRecord *jcr, JobId_t JobId, bool send_global);
bool CancelFileDaemonJob(UaContext *ua, JobControlRecord *jcr);
void DoNativeClientStatus(UaContext *ua, ClientResource *client, char *cmd);
void DoClientResolve(UaContext *ua, ClientResource *client);
void *handle_filed_connection(ConnectionPool *connections, BareosSocket *fd,
void *HandleFiledConnection(ConnectionPool *connections, BareosSocket *fd,
char *client_name, int fd_protocol_version);

ConnectionPool *get_client_connections();
Expand Down
8 changes: 4 additions & 4 deletions core/src/dird/socket_server.cc
Expand Up @@ -62,7 +62,7 @@ ConnectionPool *get_client_connections()
return client_connections;
}

static void *handle_connection_request(void *arg)
static void *HandleConnectionRequest(void *arg)
{
BareosSocket *bs = (BareosSocket *)arg;
char name[MAX_NAME_LENGTH];
Expand Down Expand Up @@ -95,10 +95,10 @@ static void *handle_connection_request(void *arg)
if ((sscanf(bs->msg, hello_client_with_version, name, &fd_protocol_version) == 2) ||
(sscanf(bs->msg, hello_client, name) == 1)) {
Dmsg1(110, "Got a FD connection at %s\n", bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL)));
return handle_filed_connection(client_connections, bs, name, fd_protocol_version);
return HandleFiledConnection(client_connections, bs, name, fd_protocol_version);
}

return handle_UA_client_request(bs);
return HandleUserAgentClientRequest(bs);
}

extern "C" void *connect_thread(void *arg)
Expand All @@ -115,7 +115,7 @@ extern "C" void *connect_thread(void *arg)
sock_fds,
&socket_workq,
me->nokeepalive,
handle_connection_request);
HandleConnectionRequest);

return NULL;
}
Expand Down
26 changes: 16 additions & 10 deletions core/src/dird/ua_server.cc
Expand Up @@ -38,6 +38,7 @@
#include "dird/ua_output.h"
#include "dird/ua_server.h"
#include "lib/bnet.h"
#include "lib/pam_handler.h"

/* Imported variables */

Expand Down Expand Up @@ -75,7 +76,7 @@ JobControlRecord *new_control_jcr(const char *base_name, int job_type)
/**
* Handle Director User Agent commands
*/
void *handle_UA_client_request(BareosSocket *user)
void *HandleUserAgentClientRequest(BareosSocket *user_agent_socket)
{
int status;
UaContext *ua;
Expand All @@ -86,19 +87,24 @@ void *handle_UA_client_request(BareosSocket *user)
jcr = new_control_jcr("-Console-", JT_CONSOLE);

ua = new_ua_context(jcr);
ua->UA_sock = user;
ua->UA_sock = user_agent_socket;
SetJcrInTsd(INVALID_JCR);

if (!AuthenticateUserAgent(ua)) {
goto getout;
}

if (!pam_authenticate_useragent("user", "passwocht")) {
goto getout;
}


while (!ua->quit) {
if (ua->api) {
user->signal(BNET_MAIN_PROMPT);
user_agent_socket->signal(BNET_MAIN_PROMPT);
}

status = user->recv();
status = user_agent_socket->recv();
if (status >= 0) {
PmStrcpy(ua->cmd, ua->UA_sock->msg);
ParseUaArgs(ua);
Expand All @@ -114,30 +120,30 @@ void *handle_UA_client_request(BareosSocket *user)
ua->user_notified_msg_pending = false;
} else if (!ua->gui && !ua->user_notified_msg_pending && console_msg_pending) {
if (ua->api) {
user->signal(BNET_MSGS_PENDING);
user_agent_socket->signal(BNET_MSGS_PENDING);
} else {
bsendmsg(ua, _("You have messages.\n"));
}
ua->user_notified_msg_pending = true;
}
}
if (!ua->api) {
user->signal(BNET_EOD); /* send end of command */
user_agent_socket->signal(BNET_EOD); /* send end of command */
}
}
} else if (IsBnetStop(user)) {
} else if (IsBnetStop(user_agent_socket)) {
ua->quit = true;
} else { /* signal */
user->signal(BNET_POLL);
user_agent_socket->signal(BNET_POLL);
}
}

getout:
CloseDb(ua);
FreeUaContext(ua);
FreeJcr(jcr);
user->close();
delete user;
user_agent_socket->close();
delete user_agent_socket;

return NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/dird/ua_server.h
Expand Up @@ -22,7 +22,7 @@
#ifndef BAREOS_DIRD_UA_SERVER_H_
#define BAREOS_DIRD_UA_SERVER_H_

void *handle_UA_client_request(BareosSocket *user);
void *HandleUserAgentClientRequest(BareosSocket *user);
UaContext *new_ua_context(JobControlRecord *jcr);
JobControlRecord *new_control_jcr(const char *base_name, int job_type);
void FreeUaContext(UaContext *ua);
Expand Down
2 changes: 1 addition & 1 deletion core/src/filed/filed.cc
Expand Up @@ -37,7 +37,7 @@
#include "lib/bsignal.h"

/* Imported Functions */
extern void *handle_connection_request(void *dir_sock);
extern void *HandleConnectionRequest(void *dir_sock);
extern bool ParseFdConfig(ConfigurationParser *config, const char *configfile, int exit_code);
extern void PrintMessage(void *sock, const char *fmt, ...);

Expand Down
4 changes: 2 additions & 2 deletions core/src/filed/socket_server.cc
Expand Up @@ -51,7 +51,7 @@ static alist *sock_fds = NULL;
* - If it was a connection from an SD, call handle_stored_connection()
* - Otherwise it was a connection from the DIR, call handle_director_connection()
*/
static void *handle_connection_request(void *arg)
static void *HandleConnectionRequest(void *arg)
{
BareosSocket *bs = (BareosSocket *)arg;
char tbuf[100];
Expand Down Expand Up @@ -109,7 +109,7 @@ void StartSocketServer(dlist *addrs)
sock_fds,
&socket_workq,
me->nokeepalive,
handle_connection_request);
HandleConnectionRequest);
}

void StopSocketServer(bool wait)
Expand Down
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
7 changes: 4 additions & 3 deletions core/src/lib/CMakeLists.txt
Expand Up @@ -26,7 +26,8 @@ include_directories(../include ..
${LZO2_INCLUDE_DIRS}
${CAP_INCLUDE_DIRS}
${WRAP_INCLUDE_DIRS}
)
${PAM_INCLUDE_DIRS}
)

set(INCLUDE_FILES ../include/baconfig.h ../include/bareos.h
../include/bc_types.h ../include/config.h
Expand Down Expand Up @@ -55,7 +56,7 @@ set (BAREOS_SRCS address_conf.cc alist.cc attr.cc attribs.cc base64.cc
queue.cc rblist.cc runscript.cc rwlock.cc scan.cc scsi_crypto.cc scsi_lli.cc
sellist.cc serial.cc sha1.cc signal.cc smartall.cc
tls_gnutls.cc tls_none.cc tls_nss.cc tls_conf.cc tls_openssl.cc tree.cc util.cc var.cc
watchdog.cc workq.cc)
watchdog.cc workq.cc pam_handler.cc pam_handler.h)

IF(HAVE_WIN32)
LIST(APPEND BAREOS_SRCS
Expand All @@ -74,7 +75,7 @@ add_library(bareos SHARED ${BAREOS_SRCS})
target_link_libraries(bareos
${OPENSSL_LIBRARIES} ${PTHREAD_LIBRARIES} ${FASTLZ_LIBRARIES} ${ZLIB_LIBRARIES}
${ACL_LIBRARIES} ${LZO2_LIBRARIES} ${CAP_LIBRARIES} ${WRAP_LIBRARIES} ${CAM_LIBRARIES}
${WINDOWS_LIBRARIES} ${JANSSON_LIBRARIES})
${WINDOWS_LIBRARIES} ${JANSSON_LIBRARIES} ${PAM_LIBRARIES})

set (BAREOSCFG_SRCS ini.cc lex.cc parse_bsr.cc )

Expand Down
104 changes: 104 additions & 0 deletions core/src/lib/pam_handler.cc
@@ -0,0 +1,104 @@
//
// Created by torsten on 17.04.18.
//
#include "pam_handler.h"

#include "bareos.h"
#include <cstring>
#include <security/pam_appl.h>

static const int debuglevel = 200;

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

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

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

/// 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;
}

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 *>(actuallycalloc(num_msg, sizeof(struct pam_response)))) == nullptr) {
return PAM_BUF_ERR;
}

switch ((*msgm)->msg_style) {
case PAM_PROMPT_ECHO_OFF:
case PAM_PROMPT_ECHO_ON: {
resp->resp = actuallystrdup(pam_data->password_.c_str());
break;
}
case PAM_ERROR_MSG:
case PAM_TEXT_INFO:break;
default: {
const pam_message *m = *msgm;
Dmsg3(debuglevel, "message[%d]: pam error type: %d error: \"%s\"\n",
1, m->msg_style, m->msg);
goto err;
}
}

*response = resp;
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);
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 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\n", pam_strerror(pamh, err));
}

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

return err == 0;
}
8 changes: 8 additions & 0 deletions core/src/lib/pam_handler.h
@@ -0,0 +1,8 @@
#ifndef BAREOS_PAM_H
#define BAREOS_PAM_H

#include <string>

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

#endif //BAREOS_PAM_H
2 changes: 1 addition & 1 deletion core/src/stored/fd_cmds.cc
Expand Up @@ -111,7 +111,7 @@ static char Job_end[] =
* After receiving a connection (in dircmd.c) if it is
* from the File daemon, this routine is called.
*/
void *handle_filed_connection(BareosSocket *fd, char *job_name)
void *HandleFiledConnection(BareosSocket *fd, char *job_name)
{
JobControlRecord *jcr;

Expand Down
2 changes: 1 addition & 1 deletion core/src/stored/fd_cmds.h
Expand Up @@ -21,7 +21,7 @@
#ifndef BAREOS_STORED_FD_CMDS_H_
#define BAREOS_STORED_FD_CMDS_H_

void *handle_filed_connection(BareosSocket *fd, char *job_name);
void *HandleFiledConnection(BareosSocket *fd, char *job_name);
void RunJob(JobControlRecord *jcr);
void DoFdCommands(JobControlRecord *jcr);

Expand Down
8 changes: 4 additions & 4 deletions core/src/stored/socket_server.cc
Expand Up @@ -53,11 +53,11 @@ static pthread_t tcp_server_tid;
* Note, we are running as a separate thread of the Storage daemon.
*
* Basic tasks done here:
* - If it was a connection from the FD, call handle_filed_connection()
* - If it was a connection from the FD, call HandleFiledConnection()
* - If it was a connection from another SD, call handle_stored_connection()
* - Otherwise it was a connection from the DIR, call handle_director_connection()
*/
static void *handle_connection_request(void *arg)
static void *HandleConnectionRequest(void *arg)
{
BareosSocket *bs = (BareosSocket *)arg;
char name[MAX_NAME_LENGTH];
Expand Down Expand Up @@ -88,7 +88,7 @@ static void *handle_connection_request(void *arg)
*/
if (sscanf(bs->msg, "Hello Start Job %127s", name) == 1) {
Dmsg1(110, "Got a FD connection at %s\n", bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL)));
return handle_filed_connection(bs, name);
return HandleFiledConnection(bs, name);
}

/*
Expand Down Expand Up @@ -123,7 +123,7 @@ void StartSocketServer(dlist *addrs)
sock_fds,
&socket_workq,
me->nokeepalive,
handle_connection_request);
HandleConnectionRequest);
}

void StopSocketServer()
Expand Down

0 comments on commit b7850ae

Please sign in to comment.