Skip to content

Commit

Permalink
dir: add new resource User to config
Browse files Browse the repository at this point in the history
- previously used as a alias for Console
- separated struct user_acl contained in UserResource and ConsoleResource
- only refered to when using pam authentication
- corrected pam documentation
  • Loading branch information
franku committed Sep 4, 2019
1 parent 60ac6a1 commit 2f02eab
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 60 deletions.
20 changes: 10 additions & 10 deletions core/src/dird/authenticate_console.cc
Expand Up @@ -83,7 +83,7 @@ OptionResult ConsoleAuthenticator::DoDefaultAuthentication()

auth_success_ = ua_->UA_sock->AuthenticateInboundConnection(
NULL, my_config, default_console_name.c_str(), me->password_, me);
ua_->cons = nullptr;
ua_->user_acl = nullptr;
return OptionResult::Completed;
}

Expand All @@ -100,9 +100,9 @@ void ConsoleAuthenticator::DoNamedAuthentication()
NULL, my_config, console_name_.c_str(),
optional_console_resource_->password_, optional_console_resource_);
if (auth_success_) {
ua_->cons = optional_console_resource_;
ua_->user_acl = &optional_console_resource_->user_acl;
} else {
ua_->cons = nullptr;
ua_->user_acl = nullptr;
Dmsg1(200, "Could not authenticate console %s\n", console_name_.c_str());
}
}
Expand Down Expand Up @@ -220,9 +220,9 @@ bool ConsoleAuthenticatorFrom_18_2::SendInfoMessage()
message += BAREOS_SERVICES_MESSAGE;
message += "\n";
message += "You are ";
if (ua_->cons) {
if (ua_->user_acl) {
message += "logged in as: ";
message += ua_->cons->resource_name_;
message += ua_->user_acl->corresponding_resource->resource_name_;
} else {
message += "connected using the default console";
}
Expand Down Expand Up @@ -325,18 +325,18 @@ OptionResult ConsoleAuthenticatorFrom_18_2::AuthenticatePamUser()
std::string authenticated_username;
if (!PamAuthenticateUser(ua_->UA_sock, pam_username, pam_password,
authenticated_username)) {
ua_->cons = nullptr;
ua_->user_acl = nullptr;
auth_success_ = false;
} else {
ConsoleResource* user = (ConsoleResource*)my_config->GetResWithName(
R_CONSOLE, authenticated_username.c_str());
UserResource* user = (UserResource*)my_config->GetResWithName(
R_USER, authenticated_username.c_str());
if (!user) {
Dmsg1(200, "No user config found for user %s\n",
authenticated_username.c_str());
ua_->cons = nullptr;
ua_->user_acl = nullptr;
auth_success_ = false;
} else {
ua_->cons = user;
ua_->user_acl = &user->user_acl;
auth_success_ = true;
}
}
Expand Down
91 changes: 69 additions & 22 deletions core/src/dird/dird_conf.cc
Expand Up @@ -105,6 +105,7 @@ static PoolResource* res_pool;
static MessagesResource* res_msgs;
static CounterResource* res_counter;
static DeviceResource* res_dev;
static UserResource* res_user;


/* clang-format off */
Expand Down Expand Up @@ -186,31 +187,42 @@ static ResourceItem profile_items[] = {
{nullptr, 0, 0, nullptr, 0, 0, nullptr, nullptr, nullptr}
};

#define USER_ACL(resource) \
{ "JobACL", CFG_TYPE_ACL, ITEM(resource, user_acl.ACL_lists), Job_ACL, 0, NULL, NULL, NULL },\
{ "ClientACL", CFG_TYPE_ACL, ITEM(resource, user_acl.ACL_lists), Client_ACL, 0, NULL, NULL, NULL },\
{ "StorageACL", CFG_TYPE_ACL, ITEM(resource, user_acl.ACL_lists), Storage_ACL, 0, NULL, NULL, NULL },\
{ "ScheduleACL", CFG_TYPE_ACL, ITEM(resource, user_acl.ACL_lists), Schedule_ACL, 0, NULL, NULL, NULL },\
{ "RunACL", CFG_TYPE_ACL, ITEM(resource, user_acl.ACL_lists), Run_ACL, 0, NULL, NULL, NULL },\
{ "PoolACL", CFG_TYPE_ACL, ITEM(resource, user_acl.ACL_lists), Pool_ACL, 0, NULL, NULL, NULL },\
{ "CommandACL", CFG_TYPE_ACL, ITEM(resource, user_acl.ACL_lists), Command_ACL, 0, NULL, NULL, NULL },\
{ "FileSetACL", CFG_TYPE_ACL, ITEM(resource, user_acl.ACL_lists), FileSet_ACL, 0, NULL, NULL, NULL },\
{ "CatalogACL", CFG_TYPE_ACL, ITEM(resource, user_acl.ACL_lists), Catalog_ACL, 0, NULL, NULL, NULL },\
{ "WhereACL", CFG_TYPE_ACL, ITEM(resource, user_acl.ACL_lists), Where_ACL, 0, NULL, NULL, NULL },\
{ "PluginOptionsACL", CFG_TYPE_ACL, ITEM(resource, user_acl.ACL_lists), PluginOptions_ACL, 0, NULL, NULL, NULL },\
{ "Profile", CFG_TYPE_ALIST_RES, ITEM(resource, user_acl.profiles), R_PROFILE, 0, NULL, "14.2.3-",\
"Profiles can be assigned to a Console. ACL are checked until either a deny ACL is found or an allow ACL. "\
"First the console ACL is checked then any profile the console is linked to." }


static ResourceItem con_items[] = {
{ "Name", CFG_TYPE_NAME, ITEM(res_con, resource_name_), 0, CFG_ITEM_REQUIRED, NULL, NULL, NULL },
{ "Description", CFG_TYPE_STR, ITEM(res_con, description_), 0, 0, NULL, NULL, NULL },
{ "Password", CFG_TYPE_AUTOPASSWORD, ITEM(res_con, password_), 0, CFG_ITEM_REQUIRED, NULL, NULL, NULL },
{ "JobACL", CFG_TYPE_ACL, ITEM(res_con, ACL_lists), Job_ACL, 0, NULL, NULL, NULL },
{ "ClientACL", CFG_TYPE_ACL, ITEM(res_con, ACL_lists), Client_ACL, 0, NULL, NULL, NULL },
{ "StorageACL", CFG_TYPE_ACL, ITEM(res_con, ACL_lists), Storage_ACL, 0, NULL, NULL, NULL },
{ "ScheduleACL", CFG_TYPE_ACL, ITEM(res_con, ACL_lists), Schedule_ACL, 0, NULL, NULL, NULL },
{ "RunACL", CFG_TYPE_ACL, ITEM(res_con, ACL_lists), Run_ACL, 0, NULL, NULL, NULL },
{ "PoolACL", CFG_TYPE_ACL, ITEM(res_con, ACL_lists), Pool_ACL, 0, NULL, NULL, NULL },
{ "CommandACL", CFG_TYPE_ACL, ITEM(res_con, ACL_lists), Command_ACL, 0, NULL, NULL, NULL },
{ "FileSetACL", CFG_TYPE_ACL, ITEM(res_con, ACL_lists), FileSet_ACL, 0, NULL, NULL, NULL },
{ "CatalogACL", CFG_TYPE_ACL, ITEM(res_con, ACL_lists), Catalog_ACL, 0, NULL, NULL, NULL },
{ "WhereACL", CFG_TYPE_ACL, ITEM(res_con, ACL_lists), Where_ACL, 0, NULL, NULL, NULL },
{ "PluginOptionsACL", CFG_TYPE_ACL, ITEM(res_con, ACL_lists), PluginOptions_ACL, 0, NULL, NULL, NULL },
{ "Profile", CFG_TYPE_ALIST_RES, ITEM(res_con, profiles), R_PROFILE, 0, NULL, "14.2.3-",
"Profiles can be assigned to a Console. ACL are checked until either a deny ACL is found or an allow ACL. "
"First the console ACL is checked then any profile the console is linked to." },
USER_ACL(res_con),
{ "UsePamAuthentication", CFG_TYPE_BOOL, ITEM(res_con, use_pam_authentication_), 0, CFG_ITEM_DEFAULT,
"false", "18.2.4-", NULL },
TLS_COMMON_CONFIG(res_con),
TLS_CERT_CONFIG(res_con),
{nullptr, 0, 0, nullptr, 0, 0, nullptr, nullptr, nullptr}
};

static ResourceItem user_items[] = {
{ "Name", CFG_TYPE_NAME, ITEM(res_user, resource_name_), 0, CFG_ITEM_REQUIRED, NULL, NULL, NULL },
{ "Description", CFG_TYPE_STR, ITEM(res_user, description_), 0, 0, NULL, NULL, NULL },
USER_ACL(res_user),
{nullptr, 0, 0, nullptr, 0, 0, nullptr, nullptr, nullptr}
};

static ResourceItem cli_items[] = {
{ "Name", CFG_TYPE_NAME, ITEM(res_client, resource_name_), 0, CFG_ITEM_REQUIRED, NULL, NULL,
"The name of the resource." },
Expand Down Expand Up @@ -548,10 +560,10 @@ static ResourceTable resources[] = {
[] (){ res_profile = new ProfileResource(); }, reinterpret_cast<BareosResource**>(&res_profile) },
{ "Console", con_items, R_CONSOLE, sizeof(ConsoleResource),
[] (){ res_con = new ConsoleResource(); }, reinterpret_cast<BareosResource**>(&res_con) },
{ "User", con_items, R_CONSOLE, sizeof(ConsoleResource),
[] (){ res_con = new ConsoleResource(); }, reinterpret_cast<BareosResource**>(&res_con) },
{ "Device", NULL, R_DEVICE, sizeof(DeviceResource),
[] (){ res_dev = new DeviceResource(); }, reinterpret_cast<BareosResource**>(&res_dev) },/* info obtained from SD */
{ "User", user_items, R_USER, sizeof(UserResource),
[] (){ res_user = new UserResource(); }, reinterpret_cast<BareosResource**>(&res_user) },
{nullptr, nullptr, 0, 0, nullptr, nullptr}
};

Expand Down Expand Up @@ -2380,7 +2392,21 @@ static bool UpdateResourcePointer(int type, ResourceItem* items)
} else {
p->tls_cert_.allowed_certificate_common_names_ =
std::move(res_con->tls_cert_.allowed_certificate_common_names_);
p->profiles = res_con->profiles;
p->user_acl.profiles = res_con->user_acl.profiles;
p->user_acl.corresponding_resource = p;
}
break;
}
case R_USER: {
UserResource* p = dynamic_cast<UserResource*>(
my_config->GetResWithName(R_USER, res_user->resource_name_));
if (!p) {
Emsg1(M_ERROR, 0, _("Cannot find User resource %s\n"),
res_user->resource_name_);
return false;
} else {
p->user_acl.profiles = res_user->user_acl.profiles;
p->user_acl.corresponding_resource = p;
}
break;
}
Expand Down Expand Up @@ -3703,7 +3729,8 @@ static void ConfigBeforeCallback(ConfigurationParser& my_config)
{R_SCHEDULE, "R_SCHEDULE"}, {R_FILESET, "R_FILESET"},
{R_POOL, "R_POOL"}, {R_MSGS, "R_MSGS"},
{R_COUNTER, "R_COUNTER"}, {R_PROFILE, "R_PROFILE"},
{R_CONSOLE, "R_CONSOLE"}, {R_DEVICE, "R_DEVICE"}};
{R_CONSOLE, "R_CONSOLE"}, {R_DEVICE, "R_DEVICE"},
{R_USER, "R_USER"}};
my_config.InitializeQualifiedResourceNameTypeConverter(map);
}

Expand Down Expand Up @@ -3768,6 +3795,10 @@ static bool AddResourceCopyToEndOfChain(int type,
new_resource = res_con;
res_con = nullptr;
break;
case R_USER:
new_resource = res_user;
res_user = nullptr;
break;
case R_DEVICE:
new_resource = res_dev;
res_dev = nullptr;
Expand Down Expand Up @@ -3847,6 +3878,7 @@ static void DumpResource(int type,
case R_DIRECTOR:
case R_PROFILE:
case R_CONSOLE:
case R_USER:
case R_COUNTER:
case R_CLIENT:
case R_DEVICE:
Expand Down Expand Up @@ -3950,11 +3982,26 @@ static void FreeResource(BareosResource* res, int type)
ConsoleResource* p = dynamic_cast<ConsoleResource*>(res);
assert(p);
if (p->password_.value) { free(p->password_.value); }
if (p->profiles) { delete p->profiles; }
if (p->user_acl.profiles) { delete p->user_acl.profiles; }
for (int i = 0; i < Num_ACL; i++) {
if (p->ACL_lists[i]) {
delete p->ACL_lists[i];
p->ACL_lists[i] = NULL;
if (p->user_acl.ACL_lists[i]) {
delete p->user_acl.ACL_lists[i];
p->user_acl.corresponding_resource = nullptr;
p->user_acl.ACL_lists[i] = NULL;
}
}
delete p;
break;
}
case R_USER: {
UserResource* p = dynamic_cast<UserResource*>(res);
assert(p);
if (p->user_acl.profiles) { delete p->user_acl.profiles; }
for (int i = 0; i < Num_ACL; i++) {
if (p->user_acl.ACL_lists[i]) {
delete p->user_acl.ACL_lists[i];
p->user_acl.corresponding_resource = nullptr;
p->user_acl.ACL_lists[i] = NULL;
}
}
delete p;
Expand Down
20 changes: 16 additions & 4 deletions core/src/dird/dird_conf.h
Expand Up @@ -62,8 +62,9 @@ enum
R_PROFILE,
R_CONSOLE,
R_DEVICE,
R_USER,
R_FIRST = R_DIRECTOR,
R_LAST = R_DEVICE /* keep this updated */
R_LAST = R_USER /* keep this updated */
};

/**
Expand Down Expand Up @@ -225,6 +226,12 @@ class ProfileResource : public BareosResource {
alist* ACL_lists[Num_ACL] = {0}; /**< Pointers to ACLs */
};

struct UserAcl {
BareosResource* corresponding_resource = nullptr;
alist* ACL_lists[Num_ACL] = {0}; /**< Pointers to ACLs */
alist* profiles = nullptr; /**< Pointers to profile resources */
};

/**
* Console Resource
*/
Expand All @@ -234,12 +241,17 @@ class ConsoleResource
public:
ConsoleResource() = default;
virtual ~ConsoleResource() = default;

alist* ACL_lists[Num_ACL] = {0}; /**< Pointers to ACLs */
alist* profiles = nullptr; /**< Pointers to profile resources */
UserAcl user_acl;
bool use_pam_authentication_ = false; /**< PAM Console */
};

class UserResource : public BareosResource {
public:
UserResource() = default;
virtual ~UserResource() = default;
UserAcl user_acl;
};

/**
* Catalog Resource
*/
Expand Down
2 changes: 1 addition & 1 deletion core/src/dird/ua.cc
Expand Up @@ -35,7 +35,7 @@ UaContext::UaContext()
, shared_db(nullptr)
, private_db(nullptr)
, catalog(nullptr)
, cons(nullptr)
, user_acl(nullptr)
, cmd(nullptr)
, args(nullptr)
, errmsg(nullptr)
Expand Down
3 changes: 2 additions & 1 deletion core/src/dird/ua.h
Expand Up @@ -53,6 +53,7 @@ class ScheduleResource;
struct RestoreBootstrapRecord;
struct ua_cmdstruct;
class UnifiedStorageResource;
struct UserAcl;

class UaContext {
public:
Expand All @@ -63,7 +64,7 @@ class UaContext {
BareosDb* shared_db; /**< Shared database connection used by multiple ua's */
BareosDb* private_db; /**< Private database connection only used by this ua */
CatalogResource* catalog;
ConsoleResource* cons; /**< Console resource */
UserAcl* user_acl; /**< acl from console or user resource */
POOLMEM* cmd; /**< Return command/name buffer */
POOLMEM* args; /**< Command line arguments */
POOLMEM* errmsg; /**< Store error message */
Expand Down
20 changes: 10 additions & 10 deletions core/src/dird/ua_acl.cc
Expand Up @@ -248,22 +248,22 @@ bool UaContext::AclAccessOk(int acl,
/*
* If no console resource => default console and all is permitted
*/
if (!cons) {
Dmsg0(1400, "Root cons access OK.\n");
if (!user_acl) {
Dmsg0(1400, "Root user access OK.\n");
retval = true;
goto bail_out;
}

retval = FindInAclList(cons->ACL_lists[acl], acl, item, len);
retval = FindInAclList(user_acl->ACL_lists[acl], acl, item, len);

/*
* If we didn't find a matching ACL try to use the profiles this console is
* connected to.
*/
if (!retval && cons->profiles && cons->profiles->size()) {
if (!retval && user_acl->profiles && user_acl->profiles->size()) {
ProfileResource* profile = nullptr;

foreach_alist (profile, cons->profiles) {
foreach_alist (profile, user_acl->profiles) {
retval = FindInAclList(profile->ACL_lists[acl], acl, item, len);

/*
Expand Down Expand Up @@ -291,19 +291,19 @@ bool UaContext::AclNoRestrictions(int acl)
/*
* If no console resource => default console and all is permitted
*/
if (!cons) { return true; }
if (!user_acl) { return true; }

if (cons->ACL_lists[acl]) {
for (int i = 0; i < cons->ACL_lists[acl]->size(); i++) {
list_value = (char*)cons->ACL_lists[acl]->get(i);
if (user_acl->ACL_lists[acl]) {
for (int i = 0; i < user_acl->ACL_lists[acl]->size(); i++) {
list_value = (char*)user_acl->ACL_lists[acl]->get(i);

if (*list_value == '!') { return false; }

if (Bstrcasecmp("*all*", list_value)) { return true; }
}
}

foreach_alist (profile, cons->profiles) {
foreach_alist (profile, user_acl->profiles) {
if (profile) {
if (profile->ACL_lists[acl]) {
for (int i = 0; i < profile->ACL_lists[acl]->size(); i++) {
Expand Down
17 changes: 10 additions & 7 deletions core/src/dird/ua_audit.cc
Expand Up @@ -61,11 +61,13 @@ static inline void LogAuditEventAclMsg(UaContext* ua,
int acl,
const char* item)
{
const char* console_name;
const char* user_name;
const char* host;
const char* acl_type_name;

console_name = (ua->cons) ? ua->cons->resource_name_ : "default";
user_name = (ua->user_acl)
? ua->user_acl->corresponding_resource->resource_name_
: "default";
host = (ua->UA_sock) ? ua->UA_sock->host() : "unknown";

switch (acl) {
Expand Down Expand Up @@ -107,7 +109,7 @@ static inline void LogAuditEventAclMsg(UaContext* ua,
break;
}

Emsg4(M_AUDIT, 0, audit_msg, console_name, host, acl_type_name, item);
Emsg4(M_AUDIT, 0, audit_msg, user_name, host, acl_type_name, item);
}

void UaContext::LogAuditEventAclFailure(int acl, const char* item)
Expand All @@ -131,15 +133,16 @@ void UaContext::LogAuditEventAclSuccess(int acl, const char* item)
*/
void UaContext::LogAuditEventCmdline()
{
const char* console_name;
const char* user_name;
const char* host;

if (!me->auditing) { return; }

console_name = cons ? cons->resource_name_ : "default";
user_name =
user_acl ? user_acl->corresponding_resource->resource_name_ : "default";
host = UA_sock ? UA_sock->host() : "unknown";

Emsg3(M_AUDIT, 0, _("Console [%s] from [%s] cmdline %s\n"), console_name,
host, cmd);
Emsg3(M_AUDIT, 0, _("Console [%s] from [%s] cmdline %s\n"), user_name, host,
cmd);
}
} /* namespace directordaemon */

0 comments on commit 2f02eab

Please sign in to comment.