The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=eb0dc901a54183dd8e2bd6ee37b64c7a3222301c
commit eb0dc901a54183dd8e2bd6ee37b64c7a3222301c Author: John Baldwin <j...@freebsd.org> AuthorDate: 2025-08-04 19:38:06 +0000 Commit: John Baldwin <j...@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 ***