git: eb0dc901a541 - main - ctld: Convert struct auth_group to a C++ class
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 04 Aug 2025 19:46:48 UTC
The branch main has been updated by jhb:
URL: https://cgit.FreeBSD.org/src/commit/?id=eb0dc901a54183dd8e2bd6ee37b64c7a3222301c
commit eb0dc901a54183dd8e2bd6ee37b64c7a3222301c
Author: John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2025-08-04 19:38:06 +0000
Commit: John Baldwin <jhb@FreeBSD.org>
CommitDate: 2025-08-04 19:38:06 +0000
ctld: Convert struct auth_group to a C++ class
Make data members private and convert functions for adding and
checking user and initiator authentication into class methods.
Use std::string to store the label for an auth_group and add a label()
method to retrieve a const C string version for logging.
Replace AG_TYPE_* macros with a scoped enum.
Replace the TAILQ of auth_group objects in struct conf with an
unordered_map<> of named auth_group objects. Anonymous auth_group
objects for targets are no longer stored in a global data structure.
Since a target can have a pointer to either named or anonymous
objects, use a shared_ptr<> to store references to auth_group objects.
Use the shared_ptr<>'s reference count to determine if a named
auth_group is unused in conf_verify() instead of walking all the
linked lists to check for references.
While here, avoid making a second copy of socket address for a client
and instead just store a pointer in ctld_connection.
Sponsored by: Chelsio Communications
Pull Request: https://github.com/freebsd/freebsd-src/pull/1794
---
usr.sbin/ctld/conf.cc | 74 ++++---------
usr.sbin/ctld/ctld.cc | 260 ++++++++++++++++++++-------------------------
usr.sbin/ctld/ctld.hh | 115 ++++++++++----------
usr.sbin/ctld/discovery.cc | 18 ++--
usr.sbin/ctld/login.cc | 35 +++---
5 files changed, 221 insertions(+), 281 deletions(-)
diff --git a/usr.sbin/ctld/conf.cc b/usr.sbin/ctld/conf.cc
index 4354d25147a4..a30bf72c0469 100644
--- a/usr.sbin/ctld/conf.cc
+++ b/usr.sbin/ctld/conf.cc
@@ -114,64 +114,35 @@ conf_set_timeout(int timeout)
conf->conf_timeout = timeout;
}
-static bool
-_auth_group_set_type(struct auth_group *ag, const char *str)
-{
- int type;
-
- if (strcmp(str, "none") == 0) {
- type = AG_TYPE_NO_AUTHENTICATION;
- } else if (strcmp(str, "deny") == 0) {
- type = AG_TYPE_DENY;
- } else if (strcmp(str, "chap") == 0) {
- type = AG_TYPE_CHAP;
- } else if (strcmp(str, "chap-mutual") == 0) {
- type = AG_TYPE_CHAP_MUTUAL;
- } else {
- log_warnx("invalid auth-type \"%s\" for %s", str, ag->ag_label);
- return (false);
- }
-
- if (ag->ag_type != AG_TYPE_UNKNOWN && ag->ag_type != type) {
- log_warnx("cannot set auth-type to \"%s\" for %s; "
- "already has a different type", str, ag->ag_label);
- return (false);
- }
-
- ag->ag_type = type;
-
- return (true);
-}
-
bool
auth_group_add_chap(const char *user, const char *secret)
{
- return (auth_new_chap(auth_group, user, secret));
+ return (auth_group->add_chap(user, secret));
}
bool
auth_group_add_chap_mutual(const char *user, const char *secret,
const char *user2, const char *secret2)
{
- return (auth_new_chap_mutual(auth_group, user, secret, user2, secret2));
+ return (auth_group->add_chap_mutual(user, secret, user2, secret2));
}
bool
auth_group_add_initiator_name(const char *name)
{
- return (auth_name_new(auth_group, name));
+ return (auth_group->add_initiator_name(name));
}
bool
auth_group_add_initiator_portal(const char *portal)
{
- return (auth_portal_new(auth_group, portal));
+ return (auth_group->add_initiator_portal(portal));
}
bool
auth_group_set_type(const char *type)
{
- return (_auth_group_set_type(auth_group, type));
+ return (auth_group->set_type(type));
}
bool
@@ -188,12 +159,12 @@ auth_group_start(const char *name)
}
conf->conf_default_ag_defined = true;
- auth_group = auth_group_find(conf, "default");
+ auth_group = auth_group_find(conf, "default").get();
return (true);
}
auth_group = auth_group_new(conf, name);
- return (auth_group != NULL);
+ return (auth_group != nullptr);
}
void
@@ -245,14 +216,14 @@ portal_group_add_option(const char *name, const char *value)
bool
portal_group_set_discovery_auth_group(const char *name)
{
- if (portal_group->pg_discovery_auth_group != NULL) {
+ if (portal_group->pg_discovery_auth_group != nullptr) {
log_warnx("discovery-auth-group for portal-group "
"\"%s\" specified more than once",
portal_group->pg_name);
return (false);
}
portal_group->pg_discovery_auth_group = auth_group_find(conf, name);
- if (portal_group->pg_discovery_auth_group == NULL) {
+ if (portal_group->pg_discovery_auth_group == nullptr) {
log_warnx("unknown discovery-auth-group \"%s\" "
"for portal-group \"%s\"", name, portal_group->pg_name);
return (false);
@@ -518,15 +489,15 @@ target_finish(void)
static bool
target_use_private_auth(const char *keyword)
{
- if (target->t_auth_group != NULL) {
+ if (target->t_auth_group != nullptr) {
if (!target->t_private_auth) {
log_warnx("cannot use both auth-group and "
"%s for target \"%s\"", keyword, target->t_name);
return (false);
}
} else {
- target->t_auth_group = auth_group_new(conf, target);
- if (target->t_auth_group == NULL)
+ target->t_auth_group = auth_group_new(target);
+ if (target->t_auth_group == nullptr)
return (false);
target->t_private_auth = true;
}
@@ -538,7 +509,7 @@ target_add_chap(const char *user, const char *secret)
{
if (!target_use_private_auth("chap"))
return (false);
- return (auth_new_chap(target->t_auth_group, user, secret));
+ return (target->t_auth_group->add_chap(user, secret));
}
bool
@@ -547,7 +518,7 @@ target_add_chap_mutual(const char *user, const char *secret,
{
if (!target_use_private_auth("chap-mutual"))
return (false);
- return (auth_new_chap_mutual(target->t_auth_group, user, secret, user2,
+ return (target->t_auth_group->add_chap_mutual(user, secret, user2,
secret2));
}
@@ -556,7 +527,7 @@ target_add_initiator_name(const char *name)
{
if (!target_use_private_auth("initiator-name"))
return (false);
- return (auth_name_new(target->t_auth_group, name));
+ return (target->t_auth_group->add_initiator_name(name));
}
bool
@@ -564,7 +535,7 @@ target_add_initiator_portal(const char *addr)
{
if (!target_use_private_auth("initiator-portal"))
return (false);
- return (auth_portal_new(target->t_auth_group, addr));
+ return (target->t_auth_group->add_initiator_portal(addr));
}
bool
@@ -599,7 +570,7 @@ bool
target_add_portal_group(const char *pg_name, const char *ag_name)
{
struct portal_group *pg;
- struct auth_group *ag;
+ auth_group_sp ag;
struct port *p;
pg = portal_group_find(conf, pg_name);
@@ -616,8 +587,7 @@ target_add_portal_group(const char *pg_name, const char *ag_name)
ag_name, target->t_name);
return (false);
}
- } else
- ag = NULL;
+ }
p = port_new(conf, target, pg);
if (p == NULL) {
@@ -625,7 +595,7 @@ target_add_portal_group(const char *pg_name, const char *ag_name)
pg_name, target->t_name);
return (false);
}
- p->p_auth_group = ag;
+ p->p_auth_group = std::move(ag);
return (true);
}
@@ -644,7 +614,7 @@ target_set_alias(const char *alias)
bool
target_set_auth_group(const char *name)
{
- if (target->t_auth_group != NULL) {
+ if (target->t_auth_group != nullptr) {
if (target->t_private_auth)
log_warnx("cannot use both auth-group and explicit "
"authorisations for target \"%s\"", target->t_name);
@@ -654,7 +624,7 @@ target_set_auth_group(const char *name)
return (false);
}
target->t_auth_group = auth_group_find(conf, name);
- if (target->t_auth_group == NULL) {
+ if (target->t_auth_group == nullptr) {
log_warnx("unknown auth-group \"%s\" for target \"%s\"", name,
target->t_name);
return (false);
@@ -667,7 +637,7 @@ target_set_auth_type(const char *type)
{
if (!target_use_private_auth("auth-type"))
return (false);
- return (_auth_group_set_type(target->t_auth_group, type));
+ return (target->t_auth_group->set_type(type));
}
bool
diff --git a/usr.sbin/ctld/ctld.cc b/usr.sbin/ctld/ctld.cc
index 396b8db13323..b2cf31fff18f 100644
--- a/usr.sbin/ctld/ctld.cc
+++ b/usr.sbin/ctld/ctld.cc
@@ -100,12 +100,9 @@ conf_new(void)
{
struct conf *conf;
- conf = reinterpret_cast<struct conf *>(calloc(1, sizeof(*conf)));
- if (conf == NULL)
- log_err(1, "calloc");
+ conf = new struct conf();
TAILQ_INIT(&conf->conf_luns);
TAILQ_INIT(&conf->conf_targets);
- TAILQ_INIT(&conf->conf_auth_groups);
TAILQ_INIT(&conf->conf_ports);
TAILQ_INIT(&conf->conf_portal_groups);
TAILQ_INIT(&conf->conf_isns);
@@ -124,7 +121,6 @@ conf_delete(struct conf *conf)
{
struct lun *lun, *ltmp;
struct target *targ, *tmp;
- struct auth_group *ag, *cagtmp;
struct portal_group *pg, *cpgtmp;
struct isns *is, *istmp;
@@ -134,30 +130,65 @@ conf_delete(struct conf *conf)
lun_delete(lun);
TAILQ_FOREACH_SAFE(targ, &conf->conf_targets, t_next, tmp)
target_delete(targ);
- TAILQ_FOREACH_SAFE(ag, &conf->conf_auth_groups, ag_next, cagtmp)
- auth_group_delete(ag);
TAILQ_FOREACH_SAFE(pg, &conf->conf_portal_groups, pg_next, cpgtmp)
portal_group_delete(pg);
TAILQ_FOREACH_SAFE(is, &conf->conf_isns, i_next, istmp)
isns_delete(is);
assert(TAILQ_EMPTY(&conf->conf_ports));
free(conf->conf_pidfile_path);
- free(conf);
+ delete conf;
+}
+
+bool
+auth_group::set_type(const char *str)
+{
+ auth_type type;
+
+ if (strcmp(str, "none") == 0) {
+ type = auth_type::NO_AUTHENTICATION;
+ } else if (strcmp(str, "deny") == 0) {
+ type = auth_type::DENY;
+ } else if (strcmp(str, "chap") == 0) {
+ type = auth_type::CHAP;
+ } else if (strcmp(str, "chap-mutual") == 0) {
+ type = auth_type::CHAP_MUTUAL;
+ } else {
+ log_warnx("invalid auth-type \"%s\" for %s", str, label());
+ return (false);
+ }
+
+ if (ag_type != auth_type::UNKNOWN && ag_type != type) {
+ log_warnx("cannot set auth-type to \"%s\" for %s; "
+ "already has a different type", str, label());
+ return (false);
+ }
+
+ ag_type = type;
+
+ return (true);
+}
+
+void
+auth_group::set_type(auth_type type)
+{
+ assert(ag_type == auth_type::UNKNOWN);
+
+ ag_type = type;
}
const struct auth *
-auth_find(const struct auth_group *ag, const char *user)
+auth_group::find_auth(std::string_view user) const
{
- auto it = ag->ag_auths.find(user);
- if (it == ag->ag_auths.end())
+ auto it = ag_auths.find(std::string(user));
+ if (it == ag_auths.end())
return (nullptr);
return (&it->second);
}
-static void
-auth_check_secret_length(const struct auth_group *ag, const char *user,
- const char *secret, const char *secret_type)
+void
+auth_group::check_secret_length(const char *user, const char *secret,
+ const char *secret_type)
{
size_t len;
@@ -165,34 +196,31 @@ auth_check_secret_length(const struct auth_group *ag, const char *user,
assert(len != 0);
if (len > 16) {
log_warnx("%s for user \"%s\", %s, is too long; it should be "
- "at most 16 characters long", secret_type, user,
- ag->ag_label);
+ "at most 16 characters long", secret_type, user, label());
}
if (len < 12) {
log_warnx("%s for user \"%s\", %s, is too short; it should be "
- "at least 12 characters long", secret_type, user,
- ag->ag_label);
+ "at least 12 characters long", secret_type, user, label());
}
}
bool
-auth_new_chap(struct auth_group *ag, const char *user,
- const char *secret)
+auth_group::add_chap(const char *user, const char *secret)
{
- if (ag->ag_type == AG_TYPE_UNKNOWN)
- ag->ag_type = AG_TYPE_CHAP;
- if (ag->ag_type != AG_TYPE_CHAP) {
+ if (ag_type == auth_type::UNKNOWN)
+ ag_type = auth_type::CHAP;
+ if (ag_type != auth_type::CHAP) {
log_warnx("cannot mix \"chap\" authentication with "
- "other types for %s", ag->ag_label);
+ "other types for %s", label());
return (false);
}
- auth_check_secret_length(ag, user, secret, "secret");
+ check_secret_length(user, secret, "secret");
- const auto &pair = ag->ag_auths.try_emplace(user, secret);
+ const auto &pair = ag_auths.try_emplace(user, secret);
if (!pair.second) {
log_warnx("duplicate credentials for user \"%s\" for %s",
- user, ag->ag_label);
+ user, label());
return (false);
}
@@ -200,25 +228,24 @@ auth_new_chap(struct auth_group *ag, const char *user,
}
bool
-auth_new_chap_mutual(struct auth_group *ag, const char *user,
- const char *secret, const char *user2, const char *secret2)
+auth_group::add_chap_mutual(const char *user, const char *secret,
+ const char *user2, const char *secret2)
{
- if (ag->ag_type == AG_TYPE_UNKNOWN)
- ag->ag_type = AG_TYPE_CHAP_MUTUAL;
- if (ag->ag_type != AG_TYPE_CHAP_MUTUAL) {
+ if (ag_type == auth_type::UNKNOWN)
+ ag_type = auth_type::CHAP_MUTUAL;
+ if (ag_type != auth_type::CHAP_MUTUAL) {
log_warnx("cannot mix \"chap-mutual\" authentication "
- "with other types for %s", ag->ag_label);
+ "with other types for %s", label());
return (false);
}
- auth_check_secret_length(ag, user, secret, "secret");
- auth_check_secret_length(ag, user, secret2, "mutual secret");
+ check_secret_length(user, secret, "secret");
+ check_secret_length(user, secret2, "mutual secret");
- const auto &pair = ag->ag_auths.try_emplace(user, secret, user2,
- secret2);
+ const auto &pair = ag_auths.try_emplace(user, secret, user2, secret2);
if (!pair.second) {
log_warnx("duplicate credentials for user \"%s\" for %s",
- user, ag->ag_label);
+ user, label());
return (false);
}
@@ -226,20 +253,20 @@ auth_new_chap_mutual(struct auth_group *ag, const char *user,
}
bool
-auth_name_new(struct auth_group *ag, const char *name)
+auth_group::add_initiator_name(std::string_view name)
{
/* Silently ignore duplicates. */
- ag->ag_names.emplace(name);
+ ag_names.emplace(name);
return (true);
}
bool
-auth_name_check(const struct auth_group *ag, const char *initiator_name)
+auth_group::initiator_permitted(std::string_view initiator_name) const
{
- if (ag->ag_names.empty())
+ if (ag_names.empty())
return (true);
- return (ag->ag_names.count(initiator_name) != 0);
+ return (ag_names.count(std::string(initiator_name)) != 0);
}
bool
@@ -309,15 +336,16 @@ auth_portal::parse(const char *portal)
}
bool
-auth_portal_new(struct auth_group *ag, const char *portal)
+auth_group::add_initiator_portal(const char *portal)
{
auth_portal ap;
if (!ap.parse(portal)) {
- log_warnx("invalid initiator portal \"%s\"", portal);
+ log_warnx("invalid initiator portal \"%s\" for %s", portal,
+ label());
return (false);
}
- ag->ag_portals.emplace_back(ap);
+ ag_portals.emplace_back(ap);
return (true);
}
@@ -354,80 +382,46 @@ auth_portal::matches(const struct sockaddr *sa) const
}
bool
-auth_portal_check(const struct auth_group *ag,
- const struct sockaddr_storage *sa)
+auth_group::initiator_permitted(const struct sockaddr *sa) const
{
- if (ag->ag_portals.empty())
+ if (ag_portals.empty())
return (true);
- for (const auth_portal &ap : ag->ag_portals)
- if (ap.matches((const struct sockaddr *)sa))
+ for (const auth_portal &ap : ag_portals)
+ if (ap.matches(sa))
return (true);
return (false);
}
-static struct auth_group *
-auth_group_create(struct conf *conf, const char *name, char *label)
-{
- struct auth_group *ag;
-
- ag = new auth_group();
- if (name != NULL)
- ag->ag_name = checked_strdup(name);
- ag->ag_label = label;
- ag->ag_conf = conf;
- TAILQ_INSERT_TAIL(&conf->conf_auth_groups, ag, ag_next);
-
- return (ag);
-}
-
struct auth_group *
auth_group_new(struct conf *conf, const char *name)
{
- struct auth_group *ag;
- char *label;
-
- ag = auth_group_find(conf, name);
- if (ag != NULL) {
+ const auto &pair = conf->conf_auth_groups.try_emplace(name,
+ std::make_shared<auth_group>(freebsd::stringf("auth-group \"%s\"",
+ name)));
+ if (!pair.second) {
log_warnx("duplicated auth-group \"%s\"", name);
return (NULL);
}
- asprintf(&label, "auth-group \"%s\"", name);
- return (auth_group_create(conf, name, label));
+ return (pair.first->second.get());
}
-struct auth_group *
-auth_group_new(struct conf *conf, struct target *target)
+auth_group_sp
+auth_group_new(struct target *target)
{
- char *label;
-
- asprintf(&label, "target \"%s\"", target->t_name);
- return (auth_group_create(conf, NULL, label));
+ return (std::make_shared<auth_group>(freebsd::stringf("target \"%s\"",
+ target->t_name)));
}
-void
-auth_group_delete(struct auth_group *ag)
-{
- TAILQ_REMOVE(&ag->ag_conf->conf_auth_groups, ag, ag_next);
-
- free(ag->ag_label);
- free(ag->ag_name);
- delete ag;
-}
-
-struct auth_group *
+auth_group_sp
auth_group_find(const struct conf *conf, const char *name)
{
- struct auth_group *ag;
-
- assert(name != NULL);
- TAILQ_FOREACH(ag, &conf->conf_auth_groups, ag_next) {
- if (ag->ag_name != NULL && strcmp(ag->ag_name, name) == 0)
- return (ag);
- }
+ auto it = conf->conf_auth_groups.find(name);
+ if (it == conf->conf_auth_groups.end())
+ return {};
- return (NULL);
+ return (it->second);
}
static struct portal *
@@ -466,9 +460,7 @@ portal_group_new(struct conf *conf, const char *name)
return (NULL);
}
- pg = reinterpret_cast<struct portal_group *>(calloc(1, sizeof(*pg)));
- if (pg == NULL)
- log_err(1, "calloc");
+ pg = new portal_group();
pg->pg_name = checked_strdup(name);
pg->pg_options = nvlist_create(0);
TAILQ_INIT(&pg->pg_portals);
@@ -498,7 +490,7 @@ portal_group_delete(struct portal_group *pg)
free(pg->pg_name);
free(pg->pg_offload);
free(pg->pg_redirection);
- free(pg);
+ delete pg;
}
struct portal_group *
@@ -920,9 +912,7 @@ port_new(struct conf *conf, struct target *target, struct portal_group *pg)
free(name);
return (NULL);
}
- port = reinterpret_cast<struct port *>(calloc(1, sizeof(*port)));
- if (port == NULL)
- log_err(1, "calloc");
+ port = new struct port();
port->p_conf = conf;
port->p_name = name;
TAILQ_INSERT_TAIL(&conf->conf_ports, port, p_next);
@@ -965,9 +955,7 @@ port_new_ioctl(struct conf *conf, struct kports *kports, struct target *target,
free(name);
return (NULL);
}
- port = reinterpret_cast<struct port *>(calloc(1, sizeof(*port)));
- if (port == NULL)
- log_err(1, "calloc");
+ port = new struct port();
port->p_conf = conf;
port->p_name = name;
port->p_ioctl_port = true;
@@ -994,9 +982,7 @@ port_new_pp(struct conf *conf, struct target *target, struct pport *pp)
free(name);
return (NULL);
}
- port = reinterpret_cast<struct port *>(calloc(1, sizeof(*port)));
- if (port == NULL)
- log_err(1, "calloc");
+ port = new struct port();
port->p_conf = conf;
port->p_name = name;
TAILQ_INSERT_TAIL(&conf->conf_ports, port, p_next);
@@ -1075,9 +1061,7 @@ target_new(struct conf *conf, const char *name)
if (valid_iscsi_name(name, log_warnx) == false) {
return (NULL);
}
- targ = reinterpret_cast<struct target *>(calloc(1, sizeof(*targ)));
- if (targ == NULL)
- log_err(1, "calloc");
+ targ = new target();
targ->t_name = checked_strdup(name);
/*
@@ -1106,7 +1090,7 @@ target_delete(struct target *targ)
free(targ->t_pport);
free(targ->t_name);
free(targ->t_redirection);
- free(targ);
+ delete targ;
}
struct target *
@@ -1260,7 +1244,7 @@ connection_new(struct portal *portal, int fd, const char *host,
conn->conn.conn_socket = fd;
conn->conn_portal = portal;
conn->conn_initiator_addr = checked_strdup(host);
- memcpy(&conn->conn_initiator_sa, client_sa, client_sa->sa_len);
+ conn->conn_initiator_sa = client_sa;
return (conn);
}
@@ -1324,9 +1308,7 @@ conf_verify_lun(struct lun *lun)
bool
conf_verify(struct conf *conf)
{
- struct auth_group *ag;
struct portal_group *pg;
- struct port *port;
struct target *targ;
struct lun *lun;
bool found;
@@ -1393,32 +1375,16 @@ conf_verify(struct conf *conf)
pg->pg_unassigned = true;
}
}
- TAILQ_FOREACH(ag, &conf->conf_auth_groups, ag_next) {
- found = false;
- TAILQ_FOREACH(targ, &conf->conf_targets, t_next) {
- if (targ->t_auth_group == ag) {
- found = true;
- break;
- }
- }
- TAILQ_FOREACH(port, &conf->conf_ports, p_next) {
- if (port->p_auth_group == ag) {
- found = true;
- break;
- }
- }
- TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) {
- if (pg->pg_discovery_auth_group == ag) {
- found = true;
- break;
- }
- }
- if (!found && ag->ag_name != NULL &&
- strcmp(ag->ag_name, "default") != 0 &&
- strcmp(ag->ag_name, "no-authentication") != 0 &&
- strcmp(ag->ag_name, "no-access") != 0) {
+ for (const auto &kv : conf->conf_auth_groups) {
+ const std::string &ag_name = kv.first;
+ if (ag_name == "default" ||
+ ag_name == "no-authentication" ||
+ ag_name == "no-access")
+ continue;
+
+ if (kv.second.use_count() == 1) {
log_warnx("auth-group \"%s\" not assigned "
- "to any target", ag->ag_name);
+ "to any target", ag_name.c_str());
}
}
@@ -2200,11 +2166,11 @@ conf_new_from_file(const char *path, bool ucl)
ag = auth_group_new(conf, "no-authentication");
assert(ag != NULL);
- ag->ag_type = AG_TYPE_NO_AUTHENTICATION;
+ ag->set_type(auth_type::NO_AUTHENTICATION);
ag = auth_group_new(conf, "no-access");
assert(ag != NULL);
- ag->ag_type = AG_TYPE_DENY;
+ ag->set_type(auth_type::DENY);
pg = portal_group_new(conf, "default");
assert(pg != NULL);
@@ -2226,9 +2192,9 @@ conf_new_from_file(const char *path, bool ucl)
if (conf->conf_default_ag_defined == false) {
log_debugx("auth-group \"default\" not defined; "
"going with defaults");
- ag = auth_group_find(conf, "default");
+ ag = auth_group_find(conf, "default").get();
assert(ag != NULL);
- ag->ag_type = AG_TYPE_DENY;
+ ag->set_type(auth_type::DENY);
}
if (conf->conf_default_pg_defined == false) {
diff --git a/usr.sbin/ctld/ctld.hh b/usr.sbin/ctld/ctld.hh
index fa0b2256f8be..585e5d24663d 100644
--- a/usr.sbin/ctld/ctld.hh
+++ b/usr.sbin/ctld/ctld.hh
@@ -42,6 +42,7 @@
#include <libutil.h>
#include <list>
+#include <memory>
#include <string>
#include <string_view>
#include <unordered_map>
@@ -83,23 +84,47 @@ private:
int ap_mask = 0;
};
-#define AG_TYPE_UNKNOWN 0
-#define AG_TYPE_DENY 1
-#define AG_TYPE_NO_AUTHENTICATION 2
-#define AG_TYPE_CHAP 3
-#define AG_TYPE_CHAP_MUTUAL 4
+enum class auth_type {
+ UNKNOWN,
+ DENY,
+ NO_AUTHENTICATION,
+ CHAP,
+ CHAP_MUTUAL
+};
struct auth_group {
- TAILQ_ENTRY(auth_group) ag_next;
- struct conf *ag_conf;
- char *ag_name;
- char *ag_label;
- int ag_type;
+ auth_group(std::string label) : ag_label(label) {}
+
+ auth_type type() const { return ag_type; }
+ bool set_type(const char *str);
+ void set_type(auth_type type);
+
+ const char *label() const { return ag_label.c_str(); }
+
+ bool add_chap(const char *user, const char *secret);
+ bool add_chap_mutual(const char *user, const char *secret,
+ const char *user2, const char *secret2);
+ const struct auth *find_auth(std::string_view user) const;
+
+ bool add_initiator_name(std::string_view initiator_name);
+ bool initiator_permitted(std::string_view initiator_name) const;
+
+ bool add_initiator_portal(const char *initiator_portal);
+ bool initiator_permitted(const struct sockaddr *sa) const;
+
+private:
+ void check_secret_length(const char *user, const char *secret,
+ const char *secret_type);
+
+ std::string ag_label;
+ auth_type ag_type = auth_type::UNKNOWN;
std::unordered_map<std::string, auth> ag_auths;
std::unordered_set<std::string> ag_names;
std::list<auth_portal> ag_portals;
};
+using auth_group_sp = std::shared_ptr<auth_group>;
+
struct portal {
TAILQ_ENTRY(portal) p_next;
struct portal_group *p_portal_group;
@@ -125,14 +150,14 @@ struct portal_group {
struct conf *pg_conf;
nvlist_t *pg_options;
char *pg_name;
- struct auth_group *pg_discovery_auth_group;
- int pg_discovery_filter;
- bool pg_foreign;
- bool pg_unassigned;
+ auth_group_sp pg_discovery_auth_group;
+ int pg_discovery_filter = PG_FILTER_UNKNOWN;
+ bool pg_foreign = false;
+ bool pg_unassigned = false;
TAILQ_HEAD(, portal) pg_portals;
TAILQ_HEAD(, port) pg_ports;
- char *pg_offload;
- char *pg_redirection;
+ char *pg_offload = nullptr;
+ char *pg_redirection = nullptr;
int pg_dscp;
int pg_pcp;
@@ -156,15 +181,15 @@ struct port {
TAILQ_ENTRY(port) p_ts;
struct conf *p_conf;
char *p_name;
- struct auth_group *p_auth_group;
- struct portal_group *p_portal_group;
- struct pport *p_pport;
+ auth_group_sp p_auth_group;
+ struct portal_group *p_portal_group = nullptr;
+ struct pport *p_pport = nullptr;
struct target *p_target;
- bool p_ioctl_port;
- int p_ioctl_pp;
- int p_ioctl_vp;
- uint32_t p_ctl_port;
+ bool p_ioctl_port = false;
+ int p_ioctl_pp = 0;
+ int p_ioctl_vp = 0;
+ uint32_t p_ctl_port = 0;
};
struct lun {
@@ -187,8 +212,8 @@ struct lun {
struct target {
TAILQ_ENTRY(target) t_next;
struct conf *t_conf;
- struct lun *t_luns[MAX_LUNS];
- struct auth_group *t_auth_group;
+ struct lun *t_luns[MAX_LUNS] = {};
+ auth_group_sp t_auth_group;
TAILQ_HEAD(, port) t_ports;
char *t_name;
char *t_alias;
@@ -206,10 +231,10 @@ struct isns {
};
struct conf {
- char *conf_pidfile_path;
+ char *conf_pidfile_path = nullptr;
TAILQ_HEAD(, lun) conf_luns;
TAILQ_HEAD(, target) conf_targets;
- TAILQ_HEAD(, auth_group) conf_auth_groups;
+ std::unordered_map<std::string, auth_group_sp> conf_auth_groups;
TAILQ_HEAD(, port) conf_ports;
TAILQ_HEAD(, portal_group) conf_portal_groups;
TAILQ_HEAD(, isns) conf_isns;
@@ -220,13 +245,13 @@ struct conf {
int conf_maxproc;
#ifdef ICL_KERNEL_PROXY
- int conf_portal_id;
+ int conf_portal_id = 0;
#endif
- struct pidfh *conf_pidfh;
+ struct pidfh *conf_pidfh = nullptr;
- bool conf_default_pg_defined;
- bool conf_default_ag_defined;
- bool conf_kernel_port_on;
+ bool conf_default_pg_defined = false;
+ bool conf_default_ag_defined = false;
+ bool conf_kernel_port_on = false;
};
/* Physical ports exposed by the kernel */
@@ -248,7 +273,7 @@ struct ctld_connection {
char *conn_initiator_addr;
char *conn_initiator_alias;
uint8_t conn_initiator_isid[6];
- struct sockaddr_storage conn_initiator_sa;
+ const struct sockaddr *conn_initiator_sa;
int conn_max_recv_data_segment_limit;
int conn_max_send_data_segment_limit;
int conn_max_burst_limit;
@@ -270,30 +295,10 @@ void conf_start(struct conf *new_conf);
bool conf_verify(struct conf *conf);
struct auth_group *auth_group_new(struct conf *conf, const char *name);
-struct auth_group *auth_group_new(struct conf *conf,
- struct target *target);
-void auth_group_delete(struct auth_group *ag);
-struct auth_group *auth_group_find(const struct conf *conf,
+auth_group_sp auth_group_new(struct target *target);
+auth_group_sp auth_group_find(const struct conf *conf,
const char *name);
-bool auth_new_chap(struct auth_group *ag, const char *user,
- const char *secret);
-bool auth_new_chap_mutual(struct auth_group *ag,
- const char *user, const char *secret,
- const char *user2, const char *secret2);
-const struct auth *auth_find(const struct auth_group *ag,
- const char *user);
-
-bool auth_name_new(struct auth_group *ag,
- const char *initiator_name);
-bool auth_name_check(const struct auth_group *ag,
- const char *initiator_name);
-
-bool auth_portal_new(struct auth_group *ag,
- const char *initiator_portal);
-bool auth_portal_check(const struct auth_group *ag,
- const struct sockaddr_storage *sa);
-
struct portal_group *portal_group_new(struct conf *conf, const char *name);
void portal_group_delete(struct portal_group *pg);
struct portal_group *portal_group_find(const struct conf *conf,
diff --git a/usr.sbin/ctld/discovery.cc b/usr.sbin/ctld/discovery.cc
index c4bfb94669f9..5ef8a7e7027b 100644
--- a/usr.sbin/ctld/discovery.cc
+++ b/usr.sbin/ctld/discovery.cc
@@ -156,32 +156,32 @@ discovery_target_filtered_out(const struct ctld_connection *conn,
int error;
targ = port->p_target;
- ag = port->p_auth_group;
- if (ag == NULL)
- ag = targ->t_auth_group;
+ ag = port->p_auth_group.get();
+ if (ag == nullptr)
+ ag = targ->t_auth_group.get();
pg = conn->conn_portal->p_portal_group;
assert(pg->pg_discovery_filter != PG_FILTER_UNKNOWN);
if (pg->pg_discovery_filter >= PG_FILTER_PORTAL &&
- !auth_portal_check(ag, &conn->conn_initiator_sa)) {
+ !ag->initiator_permitted(conn->conn_initiator_sa)) {
log_debugx("initiator does not match initiator portals "
"allowed for target \"%s\"; skipping", targ->t_name);
return (true);
}
if (pg->pg_discovery_filter >= PG_FILTER_PORTAL_NAME &&
- !auth_name_check(ag, conn->conn_initiator_name)) {
+ !ag->initiator_permitted(conn->conn_initiator_name)) {
log_debugx("initiator does not match initiator names "
"allowed for target \"%s\"; skipping", targ->t_name);
return (true);
}
if (pg->pg_discovery_filter >= PG_FILTER_PORTAL_NAME_AUTH &&
- ag->ag_type != AG_TYPE_NO_AUTHENTICATION) {
+ ag->type() != auth_type::NO_AUTHENTICATION) {
if (conn->conn_chap == NULL) {
- assert(pg->pg_discovery_auth_group->ag_type ==
- AG_TYPE_NO_AUTHENTICATION);
+ assert(pg->pg_discovery_auth_group->type() ==
*** 114 LINES SKIPPED ***