diff --git a/usr.sbin/ctld/Makefile b/usr.sbin/ctld/Makefile --- a/usr.sbin/ctld/Makefile +++ b/usr.sbin/ctld/Makefile @@ -5,7 +5,7 @@ PACKAGE= iscsi PROG= ctld -SRCS= ctld.c discovery.c isns.c kernel.c +SRCS= ctld.c conf.c discovery.c isns.c kernel.c SRCS+= login.c parse.y token.l y.tab.h uclparse.c CFLAGS+= -I${.CURDIR} CFLAGS+= -I${SRCTOP}/sys diff --git a/usr.sbin/ctld/conf.h b/usr.sbin/ctld/conf.h new file mode 100644 --- /dev/null +++ b/usr.sbin/ctld/conf.h @@ -0,0 +1,100 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2012 The FreeBSD Foundation + * + * This software was developed by Edward Tomasz Napierala under sponsorship + * from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __CONF_H__ +#define __CONF_H__ + +/* + * This file defines the interface between parse.y and the rest of + * ctld. + */ + +bool auth_group_start(const char *name); +void auth_group_finish(void); +bool auth_group_add_chap(const char *user, const char *secret); +bool auth_group_add_chap_mutual(const char *user, const char *secret, + const char *user2, const char *secret2); +bool auth_group_add_initiator_name(const char *name); +bool auth_group_add_initiator_portal(const char *portal); +bool auth_group_set_type(const char *type); + +void conf_set_debug(int debug); +void conf_set_isns_period(int period); +void conf_set_isns_timeout(int timeout); +void conf_set_maxproc(int maxproc); +bool conf_set_pidfile_path(const char *path); +void conf_set_timeout(int timeout); + +bool isns_add_server(const char *addr); + +bool portal_group_start(const char *name); +void portal_group_finish(void); +bool portal_group_add_listen(const char *listen, bool iser); +bool portal_group_add_option(const char *name, const char *value); +bool portal_group_set_discovery_auth_group(const char *name); +bool portal_group_set_dscp(u_int dscp); +bool portal_group_set_filter(const char *filter); +void portal_group_set_foreign(void); +bool portal_group_set_offload(const char *offload); +bool portal_group_set_pcp(u_int pcp); +bool portal_group_set_redirection(const char *addr); +void portal_group_set_tag(uint16_t tag); + +bool target_start(const char *name); +void target_finish(void); +bool target_add_chap(const char *user, const char *secret); +bool target_add_chap_mutual(const char *user, const char *secret, + const char *user2, const char *secret2); +bool target_add_initiator_name(const char *name); +bool target_add_initiator_portal(const char *addr); +bool target_add_lun(u_int id, const char *name); +bool target_add_portal_group(const char *pg_name, const char *ag_name); +bool target_set_alias(const char *alias); +bool target_set_auth_group(const char *name); +bool target_set_auth_type(const char *type); +bool target_set_physical_port(const char *pport); +bool target_set_redirection(const char *addr); +bool target_start_lun(u_int id); + +bool lun_start(const char *name); +void lun_finish(void); +bool lun_add_option(const char *name, const char *value); +bool lun_set_backend(const char *value); +bool lun_set_blocksize(size_t value); +bool lun_set_ctl_lun(uint32_t value); +bool lun_set_device_id(const char *value); +bool lun_set_device_type(const char *value); +bool lun_set_path(const char *value); +bool lun_set_serial(const char *value); +bool lun_set_size(uint64_t value); + +bool parse_conf(const char *path); + +#endif /* !__CONF_H__ */ diff --git a/usr.sbin/ctld/conf.c b/usr.sbin/ctld/conf.c new file mode 100644 --- /dev/null +++ b/usr.sbin/ctld/conf.c @@ -0,0 +1,772 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2012 The FreeBSD Foundation + * + * This software was developed by Edward Tomasz Napierala under sponsorship + * from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "conf.h" +#include "ctld.h" + +static struct conf *conf = NULL; +static struct auth_group *auth_group = NULL; +static struct portal_group *portal_group = NULL; +static struct target *target = NULL; +static struct lun *lun = NULL; + +void +conf_start(struct conf *new_conf) +{ + assert(conf == NULL); + conf = new_conf; +} + +void +conf_finish(void) +{ + auth_group = NULL; + portal_group = NULL; + target = NULL; + lun = NULL; + conf = NULL; +} + +bool +isns_add_server(const char *addr) +{ + return (isns_new(conf, addr)); +} + +void +conf_set_debug(int debug) +{ + conf->conf_debug = debug; +} + +void +conf_set_isns_period(int period) +{ + conf->conf_isns_period = period; +} + +void +conf_set_isns_timeout(int timeout) +{ + conf->conf_isns_timeout = timeout; +} + +void +conf_set_maxproc(int maxproc) +{ + conf->conf_maxproc = maxproc; +} + +bool +conf_set_pidfile_path(const char *path) +{ + if (conf->conf_pidfile_path != NULL) { + log_warnx("pidfile specified more than once"); + return (false); + } + conf->conf_pidfile_path = checked_strdup(path); + return (true); +} + +void +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 { + if (ag->ag_name != NULL) + log_warnx("invalid auth-type \"%s\" for auth-group " + "\"%s\"", str, ag->ag_name); + else + log_warnx("invalid auth-type \"%s\" for target " + "\"%s\"", str, ag->ag_target->t_name); + return (false); + } + + if (ag->ag_type != AG_TYPE_UNKNOWN && ag->ag_type != type) { + if (ag->ag_name != NULL) { + log_warnx("cannot set auth-type to \"%s\" for " + "auth-group \"%s\"; already has a different " + "type", str, ag->ag_name); + } else { + log_warnx("cannot set auth-type to \"%s\" for target " + "\"%s\"; already has a different type", + str, ag->ag_target->t_name); + } + 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)); +} + +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)); +} + +bool +auth_group_add_initiator_name(const char *name) +{ + return (auth_name_new(auth_group, name)); +} + +bool +auth_group_add_initiator_portal(const char *portal) +{ + return (auth_portal_new(auth_group, portal)); +} + +bool +auth_group_set_type(const char *type) +{ + return (_auth_group_set_type(auth_group, type)); +} + +bool +auth_group_start(const char *name) +{ + /* + * Make it possible to redefine the default auth-group. but + * only once. + */ + if (strcmp(name, "default") == 0) { + if (conf->conf_default_ag_defined) { + log_warnx("duplicated auth-group \"default\""); + return (false); + } + + conf->conf_default_ag_defined = true; + auth_group = auth_group_find(conf, "default"); + return (true); + } + + auth_group = auth_group_new(conf, name); + return (auth_group != NULL); +} + +void +auth_group_finish(void) +{ + auth_group = NULL; +} + +bool +portal_group_start(const char *name) +{ + /* + * Make it possible to redefine the default portal-group. but + * only once. + */ + if (strcmp(name, "default") == 0) { + if (conf->conf_default_pg_defined) { + log_warnx("duplicated portal-group \"default\""); + return (false); + } + + conf->conf_default_pg_defined = true; + portal_group = portal_group_find(conf, "default"); + return (true); + } + + portal_group = portal_group_new(conf, name); + return (portal_group != NULL); +} + +void +portal_group_finish(void) +{ + portal_group = NULL; +} + +bool +portal_group_add_listen(const char *listen, bool iser) +{ + return (portal_group_add_portal(portal_group, listen, iser)); +} + +bool +portal_group_add_option(const char *name, const char *value) +{ + return (option_new(portal_group->pg_options, name, value)); +} + +bool +portal_group_set_discovery_auth_group(const char *name) +{ + if (portal_group->pg_discovery_auth_group != NULL) { + 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) { + log_warnx("unknown discovery-auth-group \"%s\" " + "for portal-group \"%s\"", name, portal_group->pg_name); + return (false); + } + return (true); +} + +bool +portal_group_set_dscp(u_int dscp) +{ + if (dscp >= 0x40) { + log_warnx("invalid DSCP value %u for portal-group \"%s\"", + dscp, portal_group->pg_name); + return (false); + } + + portal_group->pg_dscp = dscp; + return (true); +} + +bool +portal_group_set_filter(const char *str) +{ + int filter; + + if (strcmp(str, "none") == 0) { + filter = PG_FILTER_NONE; + } else if (strcmp(str, "portal") == 0) { + filter = PG_FILTER_PORTAL; + } else if (strcmp(str, "portal-name") == 0) { + filter = PG_FILTER_PORTAL_NAME; + } else if (strcmp(str, "portal-name-auth") == 0) { + filter = PG_FILTER_PORTAL_NAME_AUTH; + } else { + log_warnx("invalid discovery-filter \"%s\" for portal-group " + "\"%s\"; valid values are \"none\", \"portal\", " + "\"portal-name\", and \"portal-name-auth\"", + str, portal_group->pg_name); + return (false); + } + + if (portal_group->pg_discovery_filter != PG_FILTER_UNKNOWN && + portal_group->pg_discovery_filter != filter) { + log_warnx("cannot set discovery-filter to \"%s\" for " + "portal-group \"%s\"; already has a different " + "value", str, portal_group->pg_name); + return (false); + } + + portal_group->pg_discovery_filter = filter; + + return (true); +} + +void +portal_group_set_foreign(void) +{ + portal_group->pg_foreign = true; +} + +bool +portal_group_set_offload(const char *offload) +{ + + if (portal_group->pg_offload != NULL) { + log_warnx("cannot set offload to \"%s\" for " + "portal-group \"%s\"; already defined", + offload, portal_group->pg_name); + return (false); + } + + portal_group->pg_offload = checked_strdup(offload); + + return (true); +} + +bool +portal_group_set_pcp(u_int pcp) +{ + if (pcp > 7) { + log_warnx("invalid PCP value %u for portal-group \"%s\"", + pcp, portal_group->pg_name); + return (false); + } + + portal_group->pg_pcp = pcp; + return (true); +} + +bool +portal_group_set_redirection(const char *addr) +{ + + if (portal_group->pg_redirection != NULL) { + log_warnx("cannot set redirection to \"%s\" for " + "portal-group \"%s\"; already defined", + addr, portal_group->pg_name); + return (false); + } + + portal_group->pg_redirection = checked_strdup(addr); + + return (true); +} + +void +portal_group_set_tag(uint16_t tag) +{ + portal_group->pg_tag = tag; +} + +bool +lun_start(const char *name) +{ + lun = lun_new(conf, name); + return (lun != NULL); +} + +void +lun_finish(void) +{ + lun = NULL; +} + +bool +lun_add_option(const char *name, const char *value) +{ + return (option_new(lun->l_options, name, value)); +} + +bool +lun_set_backend(const char *value) +{ + if (lun->l_backend != NULL) { + log_warnx("backend for lun \"%s\" specified more than once", + lun->l_name); + return (false); + } + + lun->l_backend = checked_strdup(value); + return (true); +} + +bool +lun_set_blocksize(size_t value) +{ + if (lun->l_blocksize != 0) { + log_warnx("blocksize for lun \"%s\" specified more than once", + lun->l_name); + return (false); + } + lun->l_blocksize = value; + return (true); +} + +bool +lun_set_device_type(const char *value) +{ + uint64_t device_type; + + if (strcasecmp(value, "disk") == 0 || + strcasecmp(value, "direct") == 0) + device_type = T_DIRECT; + else if (strcasecmp(value, "processor") == 0) + device_type = T_PROCESSOR; + else if (strcasecmp(value, "cd") == 0 || + strcasecmp(value, "cdrom") == 0 || + strcasecmp(value, "dvd") == 0 || + strcasecmp(value, "dvdrom") == 0) + device_type = T_CDROM; + else if (expand_number(value, &device_type) != 0 || device_type > 15) { + log_warnx("invalid device-type \"%s\" for lun \"%s\"", value, + lun->l_name); + return (false); + } + + lun->l_device_type = device_type; + return (true); +} + +bool +lun_set_device_id(const char *value) +{ + if (lun->l_device_id != NULL) { + log_warnx("device_id for lun \"%s\" specified more than once", + lun->l_name); + return (false); + } + + lun->l_device_id = checked_strdup(value); + return (true); +} + +bool +lun_set_path(const char *value) +{ + if (lun->l_path != NULL) { + log_warnx("path for lun \"%s\" specified more than once", + lun->l_name); + return (false); + } + + lun->l_path = checked_strdup(value); + return (true); +} + +bool +lun_set_serial(const char *value) +{ + if (lun->l_serial != NULL) { + log_warnx("serial for lun \"%s\" specified more than once", + lun->l_name); + return (false); + } + + lun->l_serial = checked_strdup(value); + return (true); +} + +bool +lun_set_size(uint64_t value) +{ + if (lun->l_size != 0) { + log_warnx("size for lun \"%s\" specified more than once", + lun->l_name); + return (false); + } + + lun->l_size = value; + return (true); +} + +bool +lun_set_ctl_lun(uint32_t value) +{ + + if (lun->l_ctl_lun >= 0) { + log_warnx("ctl_lun for lun \"%s\" specified more than once", + lun->l_name); + return (false); + } + lun->l_ctl_lun = value; + return (true); +} + +bool +target_start(const char *name) +{ + target = target_new(conf, name); + return (target != NULL); +} + +void +target_finish(void) +{ + target = NULL; +} + +bool +target_add_chap(const char *user, const char *secret) +{ + if (target->t_auth_group != NULL) { + if (target->t_auth_group->ag_name != NULL) { + log_warnx("cannot use both auth-group and " + "chap for target \"%s\"", target->t_name); + return (false); + } + } else { + target->t_auth_group = auth_group_new(conf, NULL); + if (target->t_auth_group == NULL) + return (false); + target->t_auth_group->ag_target = target; + } + return (auth_new_chap(target->t_auth_group, user, secret)); +} + +bool +target_add_chap_mutual(const char *user, const char *secret, + const char *user2, const char *secret2) +{ + if (target->t_auth_group != NULL) { + if (target->t_auth_group->ag_name != NULL) { + log_warnx("cannot use both auth-group and " + "chap-mutual for target \"%s\"", target->t_name); + return (false); + } + } else { + target->t_auth_group = auth_group_new(conf, NULL); + if (target->t_auth_group == NULL) + return (false); + target->t_auth_group->ag_target = target; + } + return (auth_new_chap_mutual(target->t_auth_group, user, secret, user2, + secret2)); +} + +bool +target_add_initiator_name(const char *name) +{ + if (target->t_auth_group != NULL) { + if (target->t_auth_group->ag_name != NULL) { + log_warnx("cannot use both auth-group and " + "initiator-name for target \"%s\"", target->t_name); + return (false); + } + } else { + target->t_auth_group = auth_group_new(conf, NULL); + if (target->t_auth_group == NULL) + return (false); + target->t_auth_group->ag_target = target; + } + return (auth_name_new(target->t_auth_group, name)); +} + +bool +target_add_initiator_portal(const char *addr) +{ + if (target->t_auth_group != NULL) { + if (target->t_auth_group->ag_name != NULL) { + log_warnx("cannot use both auth-group and " + "initiator-portal for target \"%s\"", + target->t_name); + return (false); + } + } else { + target->t_auth_group = auth_group_new(conf, NULL); + if (target->t_auth_group == NULL) + return (false); + target->t_auth_group->ag_target = target; + } + return (auth_portal_new(target->t_auth_group, addr)); +} + +bool +target_add_lun(u_int id, const char *name) +{ + struct lun *t_lun; + + if (id >= MAX_LUNS) { + log_warnx("LUN %u too big for target \"%s\"", id, + target->t_name); + return (false); + } + + if (target->t_luns[id] != NULL) { + log_warnx("duplicate LUN %u for target \"%s\"", id, + target->t_name); + return (false); + } + + t_lun = lun_find(conf, name); + if (t_lun == NULL) { + log_warnx("unknown LUN named %s used for target \"%s\"", + name, target->t_name); + return (false); + } + + target->t_luns[id] = t_lun; + return (true); +} + +bool +target_add_portal_group(const char *pg_name, const char *ag_name) +{ + struct portal_group *pg; + struct auth_group *ag; + struct port *p; + + pg = portal_group_find(conf, pg_name); + if (pg == NULL) { + log_warnx("unknown portal-group \"%s\" for target \"%s\"", + pg_name, target->t_name); + return (false); + } + + if (ag_name != NULL) { + ag = auth_group_find(conf, ag_name); + if (ag == NULL) { + log_warnx("unknown auth-group \"%s\" for target \"%s\"", + ag_name, target->t_name); + return (false); + } + } else + ag = NULL; + + p = port_new(conf, target, pg); + if (p == NULL) { + log_warnx("can't link portal-group \"%s\" to target \"%s\"", + pg_name, target->t_name); + return (false); + } + p->p_auth_group = ag; + return (true); +} + +bool +target_set_alias(const char *alias) +{ + if (target->t_alias != NULL) { + log_warnx("alias for target \"%s\" specified more than once", + target->t_name); + return (false); + } + target->t_alias = checked_strdup(alias); + return (true); +} + +bool +target_set_auth_group(const char *name) +{ + if (target->t_auth_group != NULL) { + if (target->t_auth_group->ag_name != NULL) + log_warnx("auth-group for target \"%s\" " + "specified more than once", target->t_name); + else + log_warnx("cannot use both auth-group and explicit " + "authorisations for target \"%s\"", target->t_name); + return (false); + } + target->t_auth_group = auth_group_find(conf, name); + if (target->t_auth_group == NULL) { + log_warnx("unknown auth-group \"%s\" for target \"%s\"", name, + target->t_name); + return (false); + } + return (true); +} + +bool +target_set_auth_type(const char *type) +{ + if (target->t_auth_group != NULL) { + if (target->t_auth_group->ag_name != NULL) { + log_warnx("cannot use both auth-group and " + "auth-type for target \"%s\"", target->t_name); + return (false); + } + } else { + target->t_auth_group = auth_group_new(conf, NULL); + if (target->t_auth_group == NULL) + return (false); + target->t_auth_group->ag_target = target; + } + return (_auth_group_set_type(target->t_auth_group, type)); +} + +bool +target_set_physical_port(const char *pport) +{ + if (target->t_pport != NULL) { + log_warnx("cannot set multiple physical ports for target " + "\"%s\"", target->t_name); + return (false); + } + target->t_pport = checked_strdup(pport); + return (true); +} + +bool +target_set_redirection(const char *addr) +{ + + if (target->t_redirection != NULL) { + log_warnx("cannot set redirection to \"%s\" for " + "target \"%s\"; already defined", + addr, target->t_name); + return (false); + } + + target->t_redirection = checked_strdup(addr); + + return (true); +} + +bool +target_start_lun(u_int id) +{ + struct lun *new_lun; + char *name; + + if (id >= MAX_LUNS) { + log_warnx("LUN %u too big for target \"%s\"", id, + target->t_name); + return (false); + } + + if (target->t_luns[id] != NULL) { + log_warnx("duplicate LUN %u for target \"%s\"", id, + target->t_name); + return (false); + } + + if (asprintf(&name, "%s,lun,%u", target->t_name, id) <= 0) + log_err(1, "asprintf"); + + new_lun = lun_new(conf, name); + if (new_lun == NULL) + return (false); + + lun_set_scsiname(new_lun, name); + free(name); + + target->t_luns[id] = new_lun; + + lun = new_lun; + return (true); +} diff --git a/usr.sbin/ctld/ctld.h b/usr.sbin/ctld/ctld.h --- a/usr.sbin/ctld/ctld.h +++ b/usr.sbin/ctld/ctld.h @@ -168,7 +168,7 @@ char *l_path; char *l_scsiname; char *l_serial; - int64_t l_size; + uint64_t l_size; int l_ctl_lun; }; @@ -247,30 +247,29 @@ extern int ctl_fd; -bool parse_conf(struct conf *newconf, const char *path); -bool uclparse_conf(struct conf *conf, const char *path); +bool uclparse_conf(const char *path); struct conf *conf_new(void); struct conf *conf_new_from_kernel(struct kports *kports); void conf_delete(struct conf *conf); +void conf_finish(void); +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); void auth_group_delete(struct auth_group *ag); struct auth_group *auth_group_find(const struct conf *conf, const char *name); -bool auth_group_set_type(struct auth_group *ag, - const char *type); -const struct auth *auth_new_chap(struct auth_group *ag, - const char *user, const char *secret); -const struct auth *auth_new_chap_mutual(struct auth_group *ag, +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); -const struct auth_name *auth_name_new(struct auth_group *ag, +bool auth_name_new(struct auth_group *ag, const char *initiator_name); bool auth_name_defined(const struct auth_group *ag); const struct auth_name *auth_name_find(const struct auth_group *ag, @@ -278,7 +277,7 @@ bool auth_name_check(const struct auth_group *ag, const char *initiator_name); -const struct auth_portal *auth_portal_new(struct auth_group *ag, +bool auth_portal_new(struct auth_group *ag, const char *initiator_portal); bool auth_portal_defined(const struct auth_group *ag); const struct auth_portal *auth_portal_find(const struct auth_group *ag, @@ -290,14 +289,8 @@ void portal_group_delete(struct portal_group *pg); struct portal_group *portal_group_find(const struct conf *conf, const char *name); -bool portal_group_add_listen(struct portal_group *pg, - const char *listen, bool iser); -bool portal_group_set_filter(struct portal_group *pg, - const char *filter); -bool portal_group_set_offload(struct portal_group *pg, - const char *offload); -bool portal_group_set_redirection(struct portal_group *pg, - const char *addr); +bool portal_group_add_portal(struct portal_group *pg, + const char *value, bool iser); bool isns_new(struct conf *conf, const char *addr); void isns_delete(struct isns *is); @@ -329,21 +322,11 @@ void target_delete(struct target *target); struct target *target_find(struct conf *conf, const char *name); -bool target_set_redirection(struct target *target, - const char *addr); struct lun *lun_new(struct conf *conf, const char *name); void lun_delete(struct lun *lun); struct lun *lun_find(const struct conf *conf, const char *name); -void lun_set_backend(struct lun *lun, const char *value); -void lun_set_device_type(struct lun *lun, uint8_t value); -void lun_set_blocksize(struct lun *lun, size_t value); -void lun_set_device_id(struct lun *lun, const char *value); -void lun_set_path(struct lun *lun, const char *value); void lun_set_scsiname(struct lun *lun, const char *value); -void lun_set_serial(struct lun *lun, const char *value); -void lun_set_size(struct lun *lun, int64_t value); -void lun_set_ctl_lun(struct lun *lun, uint32_t value); bool option_new(nvlist_t *nvl, const char *name, const char *value); diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c --- a/usr.sbin/ctld/ctld.c +++ b/usr.sbin/ctld/ctld.c @@ -49,7 +49,9 @@ #include #include #include +#include +#include "conf.h" #include "ctld.h" #include "isns.h" @@ -237,7 +239,7 @@ } } -const struct auth * +bool auth_new_chap(struct auth_group *ag, const char *user, const char *secret) { @@ -253,7 +255,7 @@ log_warnx("cannot mix \"chap\" authentication with " "other types for target \"%s\"", ag->ag_target->t_name); - return (NULL); + return (false); } auth = auth_new(ag); @@ -262,10 +264,10 @@ auth_check_secret_length(auth); - return (auth); + return (true); } -const struct auth * +bool auth_new_chap_mutual(struct auth_group *ag, const char *user, const char *secret, const char *user2, const char *secret2) { @@ -282,7 +284,7 @@ log_warnx("cannot mix \"chap-mutual\" authentication " "with other types for target \"%s\"", ag->ag_target->t_name); - return (NULL); + return (false); } auth = auth_new(ag); @@ -293,10 +295,10 @@ auth_check_secret_length(auth); - return (auth); + return (true); } -const struct auth_name * +bool auth_name_new(struct auth_group *ag, const char *name) { struct auth_name *an; @@ -307,7 +309,7 @@ an->an_auth_group = ag; an->an_initiator_name = checked_strdup(name); TAILQ_INSERT_TAIL(&ag->ag_names, an, an_next); - return (an); + return (true); } static void @@ -352,7 +354,7 @@ return (true); } -const struct auth_portal * +bool auth_portal_new(struct auth_group *ag, const char *portal) { struct auth_portal *ap; @@ -401,13 +403,13 @@ ap->ap_mask = m; free(str); TAILQ_INSERT_TAIL(&ag->ag_portals, ap, ap_next); - return (ap); + return (true); error: free(str); free(ap); log_warnx("incorrect initiator portal \"%s\"", portal); - return (NULL); + return (false); } static void @@ -540,47 +542,6 @@ return (NULL); } -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 { - if (ag->ag_name != NULL) - log_warnx("invalid auth-type \"%s\" for auth-group " - "\"%s\"", str, ag->ag_name); - else - log_warnx("invalid auth-type \"%s\" for target " - "\"%s\"", str, ag->ag_target->t_name); - return (false); - } - - if (ag->ag_type != AG_TYPE_UNKNOWN && ag->ag_type != type) { - if (ag->ag_name != NULL) { - log_warnx("cannot set auth-type to \"%s\" for " - "auth-group \"%s\"; already has a different " - "type", str, ag->ag_name); - } else { - log_warnx("cannot set auth-type to \"%s\" for target " - "\"%s\"; already has a different type", - str, ag->ag_target->t_name); - } - return (false); - } - - ag->ag_type = type; - - return (true); -} - static struct portal * portal_new(struct portal_group *pg) { @@ -723,7 +684,7 @@ } bool -portal_group_add_listen(struct portal_group *pg, const char *value, bool iser) +portal_group_add_portal(struct portal_group *pg, const char *value, bool iser) { struct portal *portal; @@ -1007,72 +968,6 @@ set_timeout(0, false); } -bool -portal_group_set_filter(struct portal_group *pg, const char *str) -{ - int filter; - - if (strcmp(str, "none") == 0) { - filter = PG_FILTER_NONE; - } else if (strcmp(str, "portal") == 0) { - filter = PG_FILTER_PORTAL; - } else if (strcmp(str, "portal-name") == 0) { - filter = PG_FILTER_PORTAL_NAME; - } else if (strcmp(str, "portal-name-auth") == 0) { - filter = PG_FILTER_PORTAL_NAME_AUTH; - } else { - log_warnx("invalid discovery-filter \"%s\" for portal-group " - "\"%s\"; valid values are \"none\", \"portal\", " - "\"portal-name\", and \"portal-name-auth\"", - str, pg->pg_name); - return (false); - } - - if (pg->pg_discovery_filter != PG_FILTER_UNKNOWN && - pg->pg_discovery_filter != filter) { - log_warnx("cannot set discovery-filter to \"%s\" for " - "portal-group \"%s\"; already has a different " - "value", str, pg->pg_name); - return (false); - } - - pg->pg_discovery_filter = filter; - - return (true); -} - -bool -portal_group_set_offload(struct portal_group *pg, const char *offload) -{ - - if (pg->pg_offload != NULL) { - log_warnx("cannot set offload to \"%s\" for " - "portal-group \"%s\"; already defined", - offload, pg->pg_name); - return (false); - } - - pg->pg_offload = checked_strdup(offload); - - return (true); -} - -bool -portal_group_set_redirection(struct portal_group *pg, const char *addr) -{ - - if (pg->pg_redirection != NULL) { - log_warnx("cannot set redirection to \"%s\" for " - "portal-group \"%s\"; already defined", - addr, pg->pg_name); - return (false); - } - - pg->pg_redirection = checked_strdup(addr); - - return (true); -} - struct pport * pport_new(struct kports *kports, const char *name, uint32_t ctl_port) { @@ -1339,22 +1234,6 @@ return (NULL); } -bool -target_set_redirection(struct target *target, const char *addr) -{ - - if (target->t_redirection != NULL) { - log_warnx("cannot set redirection to \"%s\" for " - "target \"%s\"; already defined", - addr, target->t_name); - return (false); - } - - target->t_redirection = checked_strdup(addr); - - return (true); -} - struct lun * lun_new(struct conf *conf, const char *name) { @@ -1415,41 +1294,6 @@ return (NULL); } -void -lun_set_backend(struct lun *lun, const char *value) -{ - free(lun->l_backend); - lun->l_backend = checked_strdup(value); -} - -void -lun_set_blocksize(struct lun *lun, size_t value) -{ - - lun->l_blocksize = value; -} - -void -lun_set_device_type(struct lun *lun, uint8_t value) -{ - - lun->l_device_type = value; -} - -void -lun_set_device_id(struct lun *lun, const char *value) -{ - free(lun->l_device_id); - lun->l_device_id = checked_strdup(value); -} - -void -lun_set_path(struct lun *lun, const char *value) -{ - free(lun->l_path); - lun->l_path = checked_strdup(value); -} - void lun_set_scsiname(struct lun *lun, const char *value) { @@ -1457,27 +1301,6 @@ lun->l_scsiname = checked_strdup(value); } -void -lun_set_serial(struct lun *lun, const char *value) -{ - free(lun->l_serial); - lun->l_serial = checked_strdup(value); -} - -void -lun_set_size(struct lun *lun, int64_t value) -{ - - lun->l_size = value; -} - -void -lun_set_ctl_lun(struct lun *lun, uint32_t value) -{ - - lun->l_ctl_lun = value; -} - bool option_new(nvlist_t *nvl, const char *name, const char *value) { @@ -1622,7 +1445,7 @@ const struct lun *lun2; if (lun->l_backend == NULL) - lun_set_backend(lun, "block"); + lun->l_backend = checked_strdup("block"); if (strcmp(lun->l_backend, "block") == 0) { if (lun->l_path == NULL) { log_warnx("missing path for lun \"%s\"", @@ -1643,10 +1466,10 @@ } } if (lun->l_blocksize == 0) { - if (lun->l_device_type == 5) - lun_set_blocksize(lun, DEFAULT_CD_BLOCKSIZE); + if (lun->l_device_type == T_CDROM) + lun->l_blocksize = DEFAULT_CD_BLOCKSIZE; else - lun_set_blocksize(lun, DEFAULT_BLOCKSIZE); + lun->l_blocksize = DEFAULT_BLOCKSIZE; } else if (lun->l_blocksize < 0) { log_warnx("invalid blocksize for lun \"%s\"; " "must be larger than 0", lun->l_name); @@ -2066,7 +1889,7 @@ continue; } - lun_set_ctl_lun(newlun, oldlun->l_ctl_lun); + newlun->l_ctl_lun = oldlun->l_ctl_lun; } TAILQ_FOREACH_SAFE(newlun, &newconf->conf_luns, l_next, tmplun) { @@ -2565,10 +2388,12 @@ pg = portal_group_new(conf, "default"); assert(pg != NULL); + conf_start(conf); if (ucl) - valid = uclparse_conf(conf, path); + valid = uclparse_conf(path); else - valid = parse_conf(conf, path); + valid = parse_conf(path); + conf_finish(); if (!valid) { conf_delete(conf); @@ -2590,8 +2415,8 @@ "going with defaults"); pg = portal_group_find(conf, "default"); assert(pg != NULL); - portal_group_add_listen(pg, "0.0.0.0", false); - portal_group_add_listen(pg, "[::]", false); + portal_group_add_portal(pg, "0.0.0.0", false); + portal_group_add_portal(pg, "[::]", false); } conf->conf_kernel_port_on = true; diff --git a/usr.sbin/ctld/kernel.c b/usr.sbin/ctld/kernel.c --- a/usr.sbin/ctld/kernel.c +++ b/usr.sbin/ctld/kernel.c @@ -619,21 +619,24 @@ log_warnx("lun_new failed"); continue; } - lun_set_backend(cl, lun->backend_type); - lun_set_device_type(cl, lun->device_type); - lun_set_blocksize(cl, lun->blocksize); - lun_set_device_id(cl, lun->device_id); - lun_set_serial(cl, lun->serial_number); - lun_set_size(cl, lun->size_blocks * cl->l_blocksize); - lun_set_ctl_lun(cl, lun->lun_id); + cl->l_backend = lun->backend_type; + lun->backend_type = NULL; + cl->l_device_type = lun->device_type; + cl->l_blocksize = lun->blocksize; + cl->l_device_id = lun->device_id; + lun->device_id = NULL; + cl->l_serial = lun->serial_number; + lun->serial_number = NULL; + cl->l_size = lun->size_blocks * cl->l_blocksize; + cl->l_ctl_lun = lun->lun_id; cookie = NULL; while ((key = nvlist_next(lun->attr_list, NULL, &cookie)) != NULL) { if (strcmp(key, "file") == 0 || strcmp(key, "dev") == 0) { - lun_set_path(cl, - nvlist_get_string(lun->attr_list, key)); + cl->l_path = nvlist_take_string(lun->attr_list, + key); continue; } nvlist_add_string(cl->l_options, key, @@ -739,7 +742,7 @@ return (1); } - lun_set_ctl_lun(lun, req.reqdata.create.req_lun_id); + lun->l_ctl_lun = req.reqdata.create.req_lun_id; return (0); } diff --git a/usr.sbin/ctld/parse.y b/usr.sbin/ctld/parse.y --- a/usr.sbin/ctld/parse.y +++ b/usr.sbin/ctld/parse.y @@ -34,24 +34,20 @@ #include #include #include +#include +#include #include #include #include - -#include "ctld.h" #include #include +#include "conf.h" + extern FILE *yyin; extern char *yytext; extern int lineno; -static struct conf *conf = NULL; -static struct auth_group *auth_group = NULL; -static struct portal_group *portal_group = NULL; -static struct target *target = NULL; -static struct lun *lun = NULL; - extern void yyerror(const char *); extern void yyrestart(FILE *); @@ -118,7 +114,7 @@ } free($2); - conf->conf_debug = tmp; + conf_set_debug(tmp); } ; @@ -133,7 +129,7 @@ } free($2); - conf->conf_timeout = tmp; + conf_set_timeout(tmp); } ; @@ -148,18 +144,18 @@ } free($2); - conf->conf_maxproc = tmp; + conf_set_maxproc(tmp); } ; pidfile: PIDFILE STR { - if (conf->conf_pidfile_path != NULL) { - log_warnx("pidfile specified more than once"); - free($2); + bool ok; + + ok = conf_set_pidfile_path($2); + free($2); + if (!ok) return (1); - } - conf->conf_pidfile_path = $2; } ; @@ -167,7 +163,7 @@ { bool ok; - ok = isns_new(conf, $2); + ok = isns_add_server($2); free($2); if (!ok) return (1); @@ -185,7 +181,7 @@ } free($2); - conf->conf_isns_period = tmp; + conf_set_isns_period(tmp); } ; @@ -200,32 +196,24 @@ } free($2); - conf->conf_isns_timeout = tmp; + conf_set_isns_timeout(tmp); } ; auth_group: AUTH_GROUP auth_group_name OPENING_BRACKET auth_group_entries CLOSING_BRACKET { - auth_group = NULL; + auth_group_finish(); } ; auth_group_name: STR { - /* - * Make it possible to redefine default - * auth-group. but only once. - */ - if (strcmp($1, "default") == 0 && - conf->conf_default_ag_defined == false) { - auth_group = auth_group_find(conf, $1); - conf->conf_default_ag_defined = true; - } else { - auth_group = auth_group_new(conf, $1); - } + bool ok; + + ok = auth_group_start($1); free($1); - if (auth_group == NULL) + if (!ok) return (1); } ; @@ -253,7 +241,7 @@ { bool ok; - ok = auth_group_set_type(auth_group, $2); + ok = auth_group_set_type($2); free($2); if (!ok) return (1); @@ -262,48 +250,48 @@ auth_group_chap: CHAP STR STR { - const struct auth *ca; + bool ok; - ca = auth_new_chap(auth_group, $2, $3); + ok = auth_group_add_chap($2, $3); free($2); free($3); - if (ca == NULL) + if (!ok) return (1); } ; auth_group_chap_mutual: CHAP_MUTUAL STR STR STR STR { - const struct auth *ca; + bool ok; - ca = auth_new_chap_mutual(auth_group, $2, $3, $4, $5); + ok = auth_group_add_chap_mutual($2, $3, $4, $5); free($2); free($3); free($4); free($5); - if (ca == NULL) + if (!ok) return (1); } ; auth_group_initiator_name: INITIATOR_NAME STR { - const struct auth_name *an; + bool ok; - an = auth_name_new(auth_group, $2); + ok = auth_group_add_initiator_name($2); free($2); - if (an == NULL) + if (!ok) return (1); } ; auth_group_initiator_portal: INITIATOR_PORTAL STR { - const struct auth_portal *ap; + bool ok; - ap = auth_portal_new(auth_group, $2); + ok = auth_group_add_initiator_portal($2); free($2); - if (ap == NULL) + if (!ok) return (1); } ; @@ -311,25 +299,17 @@ portal_group: PORTAL_GROUP portal_group_name OPENING_BRACKET portal_group_entries CLOSING_BRACKET { - portal_group = NULL; + portal_group_finish(); } ; portal_group_name: STR { - /* - * Make it possible to redefine default - * portal-group. but only once. - */ - if (strcmp($1, "default") == 0 && - conf->conf_default_pg_defined == false) { - portal_group = portal_group_find(conf, $1); - conf->conf_default_pg_defined = true; - } else { - portal_group = portal_group_new(conf, $1); - } + bool ok; + + ok = portal_group_start($1); free($1); - if (portal_group == NULL) + if (!ok) return (1); } ; @@ -367,23 +347,12 @@ portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR { - if (portal_group->pg_discovery_auth_group != NULL) { - log_warnx("discovery-auth-group for portal-group " - "\"%s\" specified more than once", - portal_group->pg_name); - free($2); - return (1); - } - portal_group->pg_discovery_auth_group = - auth_group_find(conf, $2); - if (portal_group->pg_discovery_auth_group == NULL) { - log_warnx("unknown discovery-auth-group \"%s\" " - "for portal-group \"%s\"", - $2, portal_group->pg_name); - free($2); - return (1); - } + bool ok; + + ok = portal_group_set_discovery_auth_group($2); free($2); + if (!ok) + return (1); } ; @@ -391,7 +360,7 @@ { bool ok; - ok = portal_group_set_filter(portal_group, $2); + ok = portal_group_set_filter($2); free($2); if (!ok) return (1); @@ -401,7 +370,7 @@ portal_group_foreign: FOREIGN { - portal_group->pg_foreign = true; + portal_group_set_foreign(); } ; @@ -409,7 +378,7 @@ { bool ok; - ok = portal_group_add_listen(portal_group, $2, false); + ok = portal_group_add_listen($2, false); free($2); if (!ok) return (1); @@ -420,7 +389,7 @@ { bool ok; - ok = portal_group_add_listen(portal_group, $2, true); + ok = portal_group_add_listen($2, true); free($2); if (!ok) return (1); @@ -431,7 +400,7 @@ { bool ok; - ok = portal_group_set_offload(portal_group, $2); + ok = portal_group_set_offload($2); free($2); if (!ok) return (1); @@ -442,7 +411,7 @@ { bool ok; - ok = option_new(portal_group->pg_options, $2, $3); + ok = portal_group_add_option($2, $3); free($2); free($3); if (!ok) @@ -454,7 +423,7 @@ { bool ok; - ok = portal_group_set_redirection(portal_group, $2); + ok = portal_group_set_redirection($2); free($2); if (!ok) return (1); @@ -472,7 +441,7 @@ } free($2); - portal_group->pg_tag = tmp; + portal_group_set_tag(tmp); } ; @@ -486,38 +455,35 @@ } else if (expand_number($2, &tmp) != 0) { yyerror("invalid numeric value"); free($2); - return(1); + return (1); } free($2); - if (tmp >= 0x40) { - yyerror("invalid dscp value"); - return(1); - } - portal_group->pg_dscp = tmp; + if (!portal_group_set_dscp(tmp)) + return (1); } -| DSCP BE { portal_group->pg_dscp = IPTOS_DSCP_CS0 >> 2 ; } -| DSCP EF { portal_group->pg_dscp = IPTOS_DSCP_EF >> 2 ; } -| DSCP CS0 { portal_group->pg_dscp = IPTOS_DSCP_CS0 >> 2 ; } -| DSCP CS1 { portal_group->pg_dscp = IPTOS_DSCP_CS1 >> 2 ; } -| DSCP CS2 { portal_group->pg_dscp = IPTOS_DSCP_CS2 >> 2 ; } -| DSCP CS3 { portal_group->pg_dscp = IPTOS_DSCP_CS3 >> 2 ; } -| DSCP CS4 { portal_group->pg_dscp = IPTOS_DSCP_CS4 >> 2 ; } -| DSCP CS5 { portal_group->pg_dscp = IPTOS_DSCP_CS5 >> 2 ; } -| DSCP CS6 { portal_group->pg_dscp = IPTOS_DSCP_CS6 >> 2 ; } -| DSCP CS7 { portal_group->pg_dscp = IPTOS_DSCP_CS7 >> 2 ; } -| DSCP AF11 { portal_group->pg_dscp = IPTOS_DSCP_AF11 >> 2 ; } -| DSCP AF12 { portal_group->pg_dscp = IPTOS_DSCP_AF12 >> 2 ; } -| DSCP AF13 { portal_group->pg_dscp = IPTOS_DSCP_AF13 >> 2 ; } -| DSCP AF21 { portal_group->pg_dscp = IPTOS_DSCP_AF21 >> 2 ; } -| DSCP AF22 { portal_group->pg_dscp = IPTOS_DSCP_AF22 >> 2 ; } -| DSCP AF23 { portal_group->pg_dscp = IPTOS_DSCP_AF23 >> 2 ; } -| DSCP AF31 { portal_group->pg_dscp = IPTOS_DSCP_AF31 >> 2 ; } -| DSCP AF32 { portal_group->pg_dscp = IPTOS_DSCP_AF32 >> 2 ; } -| DSCP AF33 { portal_group->pg_dscp = IPTOS_DSCP_AF33 >> 2 ; } -| DSCP AF41 { portal_group->pg_dscp = IPTOS_DSCP_AF41 >> 2 ; } -| DSCP AF42 { portal_group->pg_dscp = IPTOS_DSCP_AF42 >> 2 ; } -| DSCP AF43 { portal_group->pg_dscp = IPTOS_DSCP_AF43 >> 2 ; } +| DSCP BE { portal_group_set_dscp(IPTOS_DSCP_CS0 >> 2); } +| DSCP EF { portal_group_set_dscp(IPTOS_DSCP_EF >> 2); } +| DSCP CS0 { portal_group_set_dscp(IPTOS_DSCP_CS0 >> 2); } +| DSCP CS1 { portal_group_set_dscp(IPTOS_DSCP_CS1 >> 2); } +| DSCP CS2 { portal_group_set_dscp(IPTOS_DSCP_CS2 >> 2); } +| DSCP CS3 { portal_group_set_dscp(IPTOS_DSCP_CS3 >> 2); } +| DSCP CS4 { portal_group_set_dscp(IPTOS_DSCP_CS4 >> 2); } +| DSCP CS5 { portal_group_set_dscp(IPTOS_DSCP_CS5 >> 2); } +| DSCP CS6 { portal_group_set_dscp(IPTOS_DSCP_CS6 >> 2); } +| DSCP CS7 { portal_group_set_dscp(IPTOS_DSCP_CS7 >> 2); } +| DSCP AF11 { portal_group_set_dscp(IPTOS_DSCP_AF11 >> 2); } +| DSCP AF12 { portal_group_set_dscp(IPTOS_DSCP_AF12 >> 2); } +| DSCP AF13 { portal_group_set_dscp(IPTOS_DSCP_AF13 >> 2); } +| DSCP AF21 { portal_group_set_dscp(IPTOS_DSCP_AF21 >> 2); } +| DSCP AF22 { portal_group_set_dscp(IPTOS_DSCP_AF22 >> 2); } +| DSCP AF23 { portal_group_set_dscp(IPTOS_DSCP_AF23 >> 2); } +| DSCP AF31 { portal_group_set_dscp(IPTOS_DSCP_AF31 >> 2); } +| DSCP AF32 { portal_group_set_dscp(IPTOS_DSCP_AF32 >> 2); } +| DSCP AF33 { portal_group_set_dscp(IPTOS_DSCP_AF33 >> 2); } +| DSCP AF41 { portal_group_set_dscp(IPTOS_DSCP_AF41 >> 2); } +| DSCP AF42 { portal_group_set_dscp(IPTOS_DSCP_AF42 >> 2); } +| DSCP AF43 { portal_group_set_dscp(IPTOS_DSCP_AF43 >> 2); } ; portal_group_pcp: PCP STR @@ -530,27 +496,26 @@ return (1); } free($2); - if (tmp > 7) { - yyerror("invalid pcp value"); - return (1); - } - portal_group->pg_pcp = tmp; + if (!portal_group_set_pcp(tmp)) + return (1); } ; lun: LUN lun_name OPENING_BRACKET lun_entries CLOSING_BRACKET { - lun = NULL; + lun_finish(); } ; lun_name: STR { - lun = lun_new(conf, $1); + bool ok; + + ok = lun_start($1); free($1); - if (lun == NULL) + if (!ok) return (1); } ; @@ -558,15 +523,17 @@ target: TARGET target_name OPENING_BRACKET target_entries CLOSING_BRACKET { - target = NULL; + target_finish(); } ; target_name: STR { - target = target_new(conf, $1); + bool ok; + + ok = target_start($1); free($1); - if (target == NULL) + if (!ok) return (1); } ; @@ -606,37 +573,23 @@ target_alias: ALIAS STR { - if (target->t_alias != NULL) { - log_warnx("alias for target \"%s\" " - "specified more than once", target->t_name); - free($2); + bool ok; + + ok = target_set_alias($2); + free($2); + if (!ok) return (1); - } - target->t_alias = $2; } ; target_auth_group: AUTH_GROUP STR { - if (target->t_auth_group != NULL) { - if (target->t_auth_group->ag_name != NULL) - log_warnx("auth-group for target \"%s\" " - "specified more than once", target->t_name); - else - log_warnx("cannot use both auth-group and explicit " - "authorisations for target \"%s\"", - target->t_name); - free($2); - return (1); - } - target->t_auth_group = auth_group_find(conf, $2); - if (target->t_auth_group == NULL) { - log_warnx("unknown auth-group \"%s\" for target " - "\"%s\"", $2, target->t_name); - free($2); - return (1); - } + bool ok; + + ok = target_set_auth_group($2); free($2); + if (!ok) + return (1); } ; @@ -644,23 +597,7 @@ { bool ok; - if (target->t_auth_group != NULL) { - if (target->t_auth_group->ag_name != NULL) { - log_warnx("cannot use both auth-group and " - "auth-type for target \"%s\"", - target->t_name); - free($2); - return (1); - } - } else { - target->t_auth_group = auth_group_new(conf, NULL); - if (target->t_auth_group == NULL) { - free($2); - return (1); - } - target->t_auth_group->ag_target = target; - } - ok = auth_group_set_type(target->t_auth_group, $2); + ok = target_set_auth_type($2); free($2); if (!ok) return (1); @@ -669,183 +606,81 @@ target_chap: CHAP STR STR { - const struct auth *ca; - - if (target->t_auth_group != NULL) { - if (target->t_auth_group->ag_name != NULL) { - log_warnx("cannot use both auth-group and " - "chap for target \"%s\"", - target->t_name); - free($2); - free($3); - return (1); - } - } else { - target->t_auth_group = auth_group_new(conf, NULL); - if (target->t_auth_group == NULL) { - free($2); - free($3); - return (1); - } - target->t_auth_group->ag_target = target; - } - ca = auth_new_chap(target->t_auth_group, $2, $3); + bool ok; + + ok = target_add_chap($2, $3); free($2); free($3); - if (ca == NULL) + if (!ok) return (1); } ; target_chap_mutual: CHAP_MUTUAL STR STR STR STR { - const struct auth *ca; - - if (target->t_auth_group != NULL) { - if (target->t_auth_group->ag_name != NULL) { - log_warnx("cannot use both auth-group and " - "chap-mutual for target \"%s\"", - target->t_name); - free($2); - free($3); - free($4); - free($5); - return (1); - } - } else { - target->t_auth_group = auth_group_new(conf, NULL); - if (target->t_auth_group == NULL) { - free($2); - free($3); - free($4); - free($5); - return (1); - } - target->t_auth_group->ag_target = target; - } - ca = auth_new_chap_mutual(target->t_auth_group, - $2, $3, $4, $5); + bool ok; + + ok = target_add_chap_mutual($2, $3, $4, $5); free($2); free($3); free($4); free($5); - if (ca == NULL) + if (!ok) return (1); } ; target_initiator_name: INITIATOR_NAME STR { - const struct auth_name *an; - - if (target->t_auth_group != NULL) { - if (target->t_auth_group->ag_name != NULL) { - log_warnx("cannot use both auth-group and " - "initiator-name for target \"%s\"", - target->t_name); - free($2); - return (1); - } - } else { - target->t_auth_group = auth_group_new(conf, NULL); - if (target->t_auth_group == NULL) { - free($2); - return (1); - } - target->t_auth_group->ag_target = target; - } - an = auth_name_new(target->t_auth_group, $2); + bool ok; + + ok = target_add_initiator_name($2); free($2); - if (an == NULL) + if (!ok) return (1); } ; target_initiator_portal: INITIATOR_PORTAL STR { - const struct auth_portal *ap; - - if (target->t_auth_group != NULL) { - if (target->t_auth_group->ag_name != NULL) { - log_warnx("cannot use both auth-group and " - "initiator-portal for target \"%s\"", - target->t_name); - free($2); - return (1); - } - } else { - target->t_auth_group = auth_group_new(conf, NULL); - if (target->t_auth_group == NULL) { - free($2); - return (1); - } - target->t_auth_group->ag_target = target; - } - ap = auth_portal_new(target->t_auth_group, $2); + bool ok; + + ok = target_add_initiator_portal($2); free($2); - if (ap == NULL) + if (!ok) return (1); } ; target_portal_group: PORTAL_GROUP STR STR { - struct portal_group *tpg; - struct auth_group *tag; - struct port *tp; - - tpg = portal_group_find(conf, $2); - if (tpg == NULL) { - log_warnx("unknown portal-group \"%s\" for target " - "\"%s\"", $2, target->t_name); - free($2); - free($3); - return (1); - } + bool ok; + + ok = target_add_portal_group($2, $3); free($2); - tag = auth_group_find(conf, $3); - if (tag == NULL) { - log_warnx("unknown auth-group \"%s\" for target " - "\"%s\"", $3, target->t_name); - free($3); - return (1); - } free($3); - tp = port_new(conf, target, tpg); - if (tp == NULL) { - log_warnx("can't link portal-group \"%s\" to target " - "\"%s\"", tpg->pg_name, target->t_name); + if (!ok) return (1); - } - tp->p_auth_group = tag; } | PORTAL_GROUP STR { - struct portal_group *tpg; - struct port *tp; + bool ok; - tpg = portal_group_find(conf, $2); - if (tpg == NULL) { - log_warnx("unknown portal-group \"%s\" for target " - "\"%s\"", $2, target->t_name); - free($2); - return (1); - } + ok = target_add_portal_group($2, NULL); free($2); - tp = port_new(conf, target, tpg); - if (tp == NULL) { - log_warnx("can't link portal-group \"%s\" to target " - "\"%s\"", tpg->pg_name, target->t_name); + if (!ok) return (1); - } } ; target_port: PORT STR { - target->t_pport = strdup($2); + bool ok; + ok = target_set_physical_port($2); free($2); + if (!ok) + return (1); } ; @@ -853,7 +688,7 @@ { bool ok; - ok = target_set_redirection(target, $2); + ok = target_set_redirection($2); free($2); if (!ok) return (1); @@ -863,15 +698,13 @@ target_lun: LUN lun_number OPENING_BRACKET lun_entries CLOSING_BRACKET { - lun = NULL; + lun_finish(); } ; lun_number: STR { uint64_t tmp; - int ret; - char *name; if (expand_number($1, &tmp) != 0) { yyerror("invalid numeric value"); @@ -879,26 +712,16 @@ return (1); } free($1); - if (tmp >= MAX_LUNS) { - yyerror("LU number is too big"); - return (1); - } - ret = asprintf(&name, "%s,lun,%ju", target->t_name, tmp); - if (ret <= 0) - log_err(1, "asprintf"); - lun = lun_new(conf, name); - if (lun == NULL) + if (!target_start_lun(tmp)) return (1); - - lun_set_scsiname(lun, name); - target->t_luns[tmp] = lun; } ; target_lun_ref: LUN STR STR { uint64_t tmp; + bool ok; if (expand_number($2, &tmp) != 0) { yyerror("invalid numeric value"); @@ -907,18 +730,11 @@ return (1); } free($2); - if (tmp >= MAX_LUNS) { - yyerror("LU number is too big"); - free($3); - return (1); - } - lun = lun_find(conf, $3); + ok = target_add_lun(tmp, $3); free($3); - if (lun == NULL) + if (!ok) return (1); - - target->t_luns[tmp] = lun; } ; @@ -951,15 +767,12 @@ lun_backend: BACKEND STR { - if (lun->l_backend != NULL) { - log_warnx("backend for lun \"%s\" " - "specified more than once", - lun->l_name); - free($2); - return (1); - } - lun_set_backend(lun, $2); + bool ok; + + ok = lun_set_backend($2); free($2); + if (!ok) + return (1); } ; @@ -974,53 +787,30 @@ } free($2); - if (lun->l_blocksize != 0) { - log_warnx("blocksize for lun \"%s\" " - "specified more than once", - lun->l_name); + if (!lun_set_blocksize(tmp)) return (1); - } - lun_set_blocksize(lun, tmp); } ; lun_device_id: DEVICE_ID STR { - if (lun->l_device_id != NULL) { - log_warnx("device_id for lun \"%s\" " - "specified more than once", - lun->l_name); - free($2); - return (1); - } - lun_set_device_id(lun, $2); + bool ok; + + ok = lun_set_device_id($2); free($2); + if (!ok) + return (1); } ; lun_device_type: DEVICE_TYPE STR { - uint64_t tmp; + bool ok; - if (strcasecmp($2, "disk") == 0 || - strcasecmp($2, "direct") == 0) - tmp = 0; - else if (strcasecmp($2, "processor") == 0) - tmp = 3; - else if (strcasecmp($2, "cd") == 0 || - strcasecmp($2, "cdrom") == 0 || - strcasecmp($2, "dvd") == 0 || - strcasecmp($2, "dvdrom") == 0) - tmp = 5; - else if (expand_number($2, &tmp) != 0 || - tmp > 15) { - yyerror("invalid numeric value"); - free($2); - return (1); - } + ok = lun_set_device_type($2); free($2); - - lun_set_device_type(lun, tmp); + if (!ok) + return (1); } ; @@ -1035,13 +825,8 @@ } free($2); - if (lun->l_ctl_lun >= 0) { - log_warnx("ctl_lun for lun \"%s\" " - "specified more than once", - lun->l_name); + if (!lun_set_ctl_lun(tmp)) return (1); - } - lun_set_ctl_lun(lun, tmp); } ; @@ -1049,7 +834,7 @@ { bool ok; - ok = option_new(lun->l_options, $2, $3); + ok = lun_add_option($2, $3); free($2); free($3); if (!ok) @@ -1059,29 +844,23 @@ lun_path: PATH STR { - if (lun->l_path != NULL) { - log_warnx("path for lun \"%s\" " - "specified more than once", - lun->l_name); - free($2); - return (1); - } - lun_set_path(lun, $2); + bool ok; + + ok = lun_set_path($2); free($2); + if (!ok) + return (1); } ; lun_serial: SERIAL STR { - if (lun->l_serial != NULL) { - log_warnx("serial for lun \"%s\" " - "specified more than once", - lun->l_name); - free($2); - return (1); - } - lun_set_serial(lun, $2); + bool ok; + + ok = lun_set_serial($2); free($2); + if (!ok) + return (1); } ; @@ -1096,13 +875,8 @@ } free($2); - if (lun->l_size != 0) { - log_warnx("size for lun \"%s\" " - "specified more than once", - lun->l_name); + if (!lun_set_size(tmp)) return (1); - } - lun_set_size(lun, tmp); } ; %% @@ -1116,11 +890,10 @@ } bool -parse_conf(struct conf *newconf, const char *path) +parse_conf(const char *path) { int error; - conf = newconf; yyin = fopen(path, "r"); if (yyin == NULL) { log_warn("unable to open configuration file %s", path); @@ -1130,10 +903,6 @@ lineno = 1; yyrestart(yyin); error = yyparse(); - auth_group = NULL; - portal_group = NULL; - target = NULL; - lun = NULL; fclose(yyin); return (error == 0); diff --git a/usr.sbin/ctld/uclparse.c b/usr.sbin/ctld/uclparse.c --- a/usr.sbin/ctld/uclparse.c +++ b/usr.sbin/ctld/uclparse.c @@ -41,173 +41,185 @@ #include #include +#include "conf.h" #include "ctld.h" -static struct conf *conf = NULL; - static bool uclparse_toplevel(const ucl_object_t *); -static bool uclparse_chap(struct auth_group *, const ucl_object_t *); -static bool uclparse_chap_mutual(struct auth_group *, const ucl_object_t *); +static bool uclparse_chap(const char *, const ucl_object_t *); +static bool uclparse_chap_mutual(const char *, const ucl_object_t *); static bool uclparse_lun(const char *, const ucl_object_t *); static bool uclparse_auth_group(const char *, const ucl_object_t *); static bool uclparse_portal_group(const char *, const ucl_object_t *); static bool uclparse_target(const char *, const ucl_object_t *); -static bool uclparse_target_portal_group(struct target *, const ucl_object_t *); -static bool uclparse_target_lun(struct target *, const ucl_object_t *); +static bool uclparse_target_portal_group(const char *, const ucl_object_t *); +static bool uclparse_target_lun(const char *, const ucl_object_t *); static bool -uclparse_chap(struct auth_group *auth_group, const ucl_object_t *obj) +uclparse_chap(const char *ag_name, const ucl_object_t *obj) { - const struct auth *ca; const ucl_object_t *user, *secret; - assert(auth_group != NULL); user = ucl_object_find_key(obj, "user"); if (!user || user->type != UCL_STRING) { log_warnx("chap section in auth-group \"%s\" is missing " - "\"user\" string key", auth_group->ag_name); + "\"user\" string key", ag_name); return (false); } secret = ucl_object_find_key(obj, "secret"); if (!secret || secret->type != UCL_STRING) { log_warnx("chap section in auth-group \"%s\" is missing " - "\"secret\" string key", auth_group->ag_name); + "\"secret\" string key", ag_name); return (false); } - ca = auth_new_chap(auth_group, + return (auth_group_add_chap( ucl_object_tostring(user), - ucl_object_tostring(secret)); - - if (ca == NULL) - return (false); - - return (true); + ucl_object_tostring(secret))); } static bool -uclparse_chap_mutual(struct auth_group *auth_group, const ucl_object_t *obj) +uclparse_chap_mutual(const char *ag_name, const ucl_object_t *obj) { - const struct auth *ca; const ucl_object_t *user, *secret, *mutual_user; const ucl_object_t *mutual_secret; - assert(auth_group != NULL); user = ucl_object_find_key(obj, "user"); if (!user || user->type != UCL_STRING) { log_warnx("chap-mutual section in auth-group \"%s\" is missing " - "\"user\" string key", auth_group->ag_name); + "\"user\" string key", ag_name); return (false); } secret = ucl_object_find_key(obj, "secret"); if (!secret || secret->type != UCL_STRING) { log_warnx("chap-mutual section in auth-group \"%s\" is missing " - "\"secret\" string key", auth_group->ag_name); + "\"secret\" string key", ag_name); return (false); } mutual_user = ucl_object_find_key(obj, "mutual-user"); if (!user || user->type != UCL_STRING) { log_warnx("chap-mutual section in auth-group \"%s\" is missing " - "\"mutual-user\" string key", auth_group->ag_name); + "\"mutual-user\" string key", ag_name); return (false); } mutual_secret = ucl_object_find_key(obj, "mutual-secret"); if (!secret || secret->type != UCL_STRING) { log_warnx("chap-mutual section in auth-group \"%s\" is missing " - "\"mutual-secret\" string key", auth_group->ag_name); + "\"mutual-secret\" string key", ag_name); return (false); } - ca = auth_new_chap_mutual(auth_group, + return (auth_group_add_chap_mutual( ucl_object_tostring(user), ucl_object_tostring(secret), ucl_object_tostring(mutual_user), - ucl_object_tostring(mutual_secret)); - - if (ca == NULL) - return (false); - - return (true); + ucl_object_tostring(mutual_secret))); } static bool -uclparse_target_portal_group(struct target *target, const ucl_object_t *obj) +uclparse_target_chap(const char *t_name, const ucl_object_t *obj) { - struct portal_group *tpg; - struct auth_group *tag = NULL; - struct port *tp; - const ucl_object_t *portal_group, *auth_group; + const ucl_object_t *user, *secret; - portal_group = ucl_object_find_key(obj, "name"); - if (!portal_group || portal_group->type != UCL_STRING) { - log_warnx("portal-group section in target \"%s\" is missing " - "\"name\" string key", target->t_name); + user = ucl_object_find_key(obj, "user"); + if (!user || user->type != UCL_STRING) { + log_warnx("chap section in target \"%s\" is missing " + "\"user\" string key", t_name); return (false); } - auth_group = ucl_object_find_key(obj, "auth-group-name"); - if (auth_group && auth_group->type != UCL_STRING) { - log_warnx("portal-group section in target \"%s\" is missing " - "\"auth-group-name\" string key", target->t_name); + secret = ucl_object_find_key(obj, "secret"); + if (!secret || secret->type != UCL_STRING) { + log_warnx("chap section in target \"%s\" is missing " + "\"secret\" string key", t_name); return (false); } + return (target_add_chap( + ucl_object_tostring(user), + ucl_object_tostring(secret))); +} + +static bool +uclparse_target_chap_mutual(const char *t_name, const ucl_object_t *obj) +{ + const ucl_object_t *user, *secret, *mutual_user; + const ucl_object_t *mutual_secret; - tpg = portal_group_find(conf, ucl_object_tostring(portal_group)); - if (tpg == NULL) { - log_warnx("unknown portal-group \"%s\" for target " - "\"%s\"", ucl_object_tostring(portal_group), target->t_name); + user = ucl_object_find_key(obj, "user"); + if (!user || user->type != UCL_STRING) { + log_warnx("chap-mutual section in target \"%s\" is missing " + "\"user\" string key", t_name); return (false); } - if (auth_group) { - tag = auth_group_find(conf, ucl_object_tostring(auth_group)); - if (tag == NULL) { - log_warnx("unknown auth-group \"%s\" for target " - "\"%s\"", ucl_object_tostring(auth_group), - target->t_name); - return (false); - } + secret = ucl_object_find_key(obj, "secret"); + if (!secret || secret->type != UCL_STRING) { + log_warnx("chap-mutual section in target \"%s\" is missing " + "\"secret\" string key", t_name); + return (false); } - tp = port_new(conf, target, tpg); - if (tp == NULL) { - log_warnx("can't link portal-group \"%s\" to target " - "\"%s\"", ucl_object_tostring(portal_group), target->t_name); + mutual_user = ucl_object_find_key(obj, "mutual-user"); + if (!user || user->type != UCL_STRING) { + log_warnx("chap-mutual section in target \"%s\" is missing " + "\"mutual-user\" string key", t_name); return (false); } - tp->p_auth_group = tag; - return (true); + mutual_secret = ucl_object_find_key(obj, "mutual-secret"); + if (!secret || secret->type != UCL_STRING) { + log_warnx("chap-mutual section in target \"%s\" is missing " + "\"mutual-secret\" string key", t_name); + return (false); + } + + return (target_add_chap_mutual( + ucl_object_tostring(user), + ucl_object_tostring(secret), + ucl_object_tostring(mutual_user), + ucl_object_tostring(mutual_secret))); } static bool -uclparse_target_lun(struct target *target, const ucl_object_t *obj) +uclparse_target_portal_group(const char *t_name, const ucl_object_t *obj) { - struct lun *lun; - uint64_t tmp; + const ucl_object_t *portal_group, *auth_group; + const char *ag_name; - if (obj->type == UCL_INT) { - char *name; + portal_group = ucl_object_find_key(obj, "name"); + if (!portal_group || portal_group->type != UCL_STRING) { + log_warnx("portal-group section in target \"%s\" is missing " + "\"name\" string key", t_name); + return (false); + } - tmp = ucl_object_toint(obj); - if (tmp >= MAX_LUNS) { - log_warnx("LU number %ju in target \"%s\" is too big", - tmp, target->t_name); + auth_group = ucl_object_find_key(obj, "auth-group-name"); + if (auth_group != NULL) { + if (auth_group->type != UCL_STRING) { + log_warnx("\"auth-group-name\" property in " + "portal-group section for target \"%s\" is not " + "a string", t_name); return (false); } + ag_name = ucl_object_tostring(auth_group); + } else + ag_name = NULL; - asprintf(&name, "%s,lun,%ju", target->t_name, tmp); - lun = lun_new(conf, name); - if (lun == NULL) - return (false); + return (target_add_portal_group(ucl_object_tostring(portal_group), + ag_name)); +} - lun_set_scsiname(lun, name); - target->t_luns[tmp] = lun; +static bool +uclparse_target_lun(const char *t_name, const ucl_object_t *obj) +{ + if (obj->type == UCL_INT) { + if (!target_start_lun(ucl_object_toint(obj))) + return (false); + lun_finish(); return (true); } @@ -217,27 +229,19 @@ if (num == NULL || num->type != UCL_INT) { log_warnx("lun section in target \"%s\" is missing " - "\"number\" integer property", target->t_name); - return (false); - } - tmp = ucl_object_toint(num); - if (tmp >= MAX_LUNS) { - log_warnx("LU number %ju in target \"%s\" is too big", - tmp, target->t_name); + "\"number\" integer property", t_name); return (false); } if (name == NULL || name->type != UCL_STRING) { log_warnx("lun section in target \"%s\" is missing " - "\"name\" string property", target->t_name); + "\"name\" string property", t_name); return (false); } - lun = lun_find(conf, ucl_object_tostring(name)); - if (lun == NULL) + if (!target_add_lun(ucl_object_toint(num), + ucl_object_tostring(name))) return (false); - - target->t_luns[tmp] = lun; } return (true); @@ -255,7 +259,7 @@ if (strcmp(key, "debug") == 0) { if (obj->type == UCL_INT) - conf->conf_debug = ucl_object_toint(obj); + conf_set_debug(ucl_object_toint(obj)); else { log_warnx("\"debug\" property value is not integer"); return (false); @@ -264,7 +268,7 @@ if (strcmp(key, "timeout") == 0) { if (obj->type == UCL_INT) - conf->conf_timeout = ucl_object_toint(obj); + conf_set_timeout(ucl_object_toint(obj)); else { log_warnx("\"timeout\" property value is not integer"); return (false); @@ -273,7 +277,7 @@ if (strcmp(key, "maxproc") == 0) { if (obj->type == UCL_INT) - conf->conf_maxproc = ucl_object_toint(obj); + conf_set_maxproc(ucl_object_toint(obj)); else { log_warnx("\"maxproc\" property value is not integer"); return (false); @@ -281,10 +285,11 @@ } if (strcmp(key, "pidfile") == 0) { - if (obj->type == UCL_STRING) - conf->conf_pidfile_path = strdup( - ucl_object_tostring(obj)); - else { + if (obj->type == UCL_STRING) { + if (!conf_set_pidfile_path( + ucl_object_tostring(obj))) + return (false); + } else { log_warnx("\"pidfile\" property value is not string"); return (false); } @@ -298,7 +303,7 @@ if (child->type != UCL_STRING) return (false); - if (!isns_new(conf, + if (!isns_add_server( ucl_object_tostring(child))) return (false); } @@ -311,7 +316,7 @@ if (strcmp(key, "isns-period") == 0) { if (obj->type == UCL_INT) - conf->conf_isns_period = ucl_object_toint(obj); + conf_set_isns_period(ucl_object_toint(obj)); else { log_warnx("\"isns-period\" property value is not integer"); return (false); @@ -320,7 +325,7 @@ if (strcmp(key, "isns-timeout") == 0) { if (obj->type == UCL_INT) - conf->conf_isns_timeout = ucl_object_toint(obj); + conf_set_isns_timeout(ucl_object_toint(obj)); else { log_warnx("\"isns-timeout\" property value is not integer"); return (false); @@ -390,22 +395,11 @@ static bool uclparse_auth_group(const char *name, const ucl_object_t *top) { - struct auth_group *auth_group; - const struct auth_name *an; - const struct auth_portal *ap; ucl_object_iter_t it = NULL, it2 = NULL; const ucl_object_t *obj = NULL, *tmp = NULL; const char *key; - if (strcmp(name, "default") == 0 && - conf->conf_default_ag_defined == false) { - auth_group = auth_group_find(conf, name); - conf->conf_default_ag_defined = true; - } else { - auth_group = auth_group_new(conf, name); - } - - if (auth_group == NULL) + if (!auth_group_start(name)) return (false); while ((obj = ucl_iterate_object(top, &it, true))) { @@ -414,8 +408,8 @@ if (strcmp(key, "auth-type") == 0) { const char *value = ucl_object_tostring(obj); - if (!auth_group_set_type(auth_group, value)) - return (false); + if (!auth_group_set_type(value)) + goto fail; } if (strcmp(key, "chap") == 0) { @@ -423,13 +417,13 @@ log_warnx("\"chap\" property of " "auth-group \"%s\" is not an array", name); - return (false); + goto fail; } it2 = NULL; while ((tmp = ucl_iterate_object(obj, &it2, true))) { - if (!uclparse_chap(auth_group, tmp)) - return (false); + if (!uclparse_chap(name, tmp)) + goto fail; } } @@ -438,13 +432,13 @@ log_warnx("\"chap-mutual\" property of " "auth-group \"%s\" is not an array", name); - return (false); + goto fail; } it2 = NULL; while ((tmp = ucl_iterate_object(obj, &it2, true))) { - if (!uclparse_chap_mutual(auth_group, tmp)) - return (false); + if (!uclparse_chap_mutual(name, tmp)) + goto fail; } } @@ -453,16 +447,15 @@ log_warnx("\"initiator-name\" property of " "auth-group \"%s\" is not an array", name); - return (false); + goto fail; } it2 = NULL; while ((tmp = ucl_iterate_object(obj, &it2, true))) { const char *value = ucl_object_tostring(tmp); - an = auth_name_new(auth_group, value); - if (an == NULL) - return (false); + if (!auth_group_add_initiator_name(value)) + goto fail; } } @@ -471,198 +464,184 @@ log_warnx("\"initiator-portal\" property of " "auth-group \"%s\" is not an array", name); - return (false); + goto fail; } it2 = NULL; while ((tmp = ucl_iterate_object(obj, &it2, true))) { const char *value = ucl_object_tostring(tmp); - ap = auth_portal_new(auth_group, value); - if (ap == NULL) - return (false); + if (!auth_group_add_initiator_portal(value)) + goto fail; } } } + auth_group_finish(); return (true); +fail: + auth_group_finish(); + return (false); } static bool -uclparse_dscp(const char *group_type, struct portal_group *portal_group, +uclparse_dscp(const char *group_type, const char *pg_name, const ucl_object_t *obj) { const char *key; if ((obj->type != UCL_STRING) && (obj->type != UCL_INT)) { log_warnx("\"dscp\" property of %s group \"%s\" is not a " - "string or integer", group_type, portal_group->pg_name); + "string or integer", group_type, pg_name); return (false); } if (obj->type == UCL_INT) - portal_group->pg_dscp = ucl_object_toint(obj); + return (portal_group_set_dscp(ucl_object_toint(obj))); + + key = ucl_object_tostring(obj); + if (strcmp(key, "0x") == 0) + return (portal_group_set_dscp(strtol(key + 2, NULL, 16))); + + if (strcmp(key, "be") == 0 || strcmp(key, "cs0") == 0) + portal_group_set_dscp(IPTOS_DSCP_CS0 >> 2); + else if (strcmp(key, "ef") == 0) + portal_group_set_dscp(IPTOS_DSCP_EF >> 2); + else if (strcmp(key, "cs0") == 0) + portal_group_set_dscp(IPTOS_DSCP_CS0 >> 2); + else if (strcmp(key, "cs1") == 0) + portal_group_set_dscp(IPTOS_DSCP_CS1 >> 2); + else if (strcmp(key, "cs2") == 0) + portal_group_set_dscp(IPTOS_DSCP_CS2 >> 2); + else if (strcmp(key, "cs3") == 0) + portal_group_set_dscp(IPTOS_DSCP_CS3 >> 2); + else if (strcmp(key, "cs4") == 0) + portal_group_set_dscp(IPTOS_DSCP_CS4 >> 2); + else if (strcmp(key, "cs5") == 0) + portal_group_set_dscp(IPTOS_DSCP_CS5 >> 2); + else if (strcmp(key, "cs6") == 0) + portal_group_set_dscp(IPTOS_DSCP_CS6 >> 2); + else if (strcmp(key, "cs7") == 0) + portal_group_set_dscp(IPTOS_DSCP_CS7 >> 2); + else if (strcmp(key, "af11") == 0) + portal_group_set_dscp(IPTOS_DSCP_AF11 >> 2); + else if (strcmp(key, "af12") == 0) + portal_group_set_dscp(IPTOS_DSCP_AF12 >> 2); + else if (strcmp(key, "af13") == 0) + portal_group_set_dscp(IPTOS_DSCP_AF13 >> 2); + else if (strcmp(key, "af21") == 0) + portal_group_set_dscp(IPTOS_DSCP_AF21 >> 2); + else if (strcmp(key, "af22") == 0) + portal_group_set_dscp(IPTOS_DSCP_AF22 >> 2); + else if (strcmp(key, "af23") == 0) + portal_group_set_dscp(IPTOS_DSCP_AF23 >> 2); + else if (strcmp(key, "af31") == 0) + portal_group_set_dscp(IPTOS_DSCP_AF31 >> 2); + else if (strcmp(key, "af32") == 0) + portal_group_set_dscp(IPTOS_DSCP_AF32 >> 2); + else if (strcmp(key, "af33") == 0) + portal_group_set_dscp(IPTOS_DSCP_AF33 >> 2); + else if (strcmp(key, "af41") == 0) + portal_group_set_dscp(IPTOS_DSCP_AF41 >> 2); + else if (strcmp(key, "af42") == 0) + portal_group_set_dscp(IPTOS_DSCP_AF42 >> 2); + else if (strcmp(key, "af43") == 0) + portal_group_set_dscp(IPTOS_DSCP_AF43 >> 2); else { - key = ucl_object_tostring(obj); - if (strcmp(key, "0x") == 0) - portal_group->pg_dscp = strtol(key + 2, NULL, 16); - else if (strcmp(key, "be") == 0 || strcmp(key, "cs0") == 0) - portal_group->pg_dscp = IPTOS_DSCP_CS0 >> 2; - else if (strcmp(key, "ef") == 0) - portal_group->pg_dscp = IPTOS_DSCP_EF >> 2; - else if (strcmp(key, "cs0") == 0) - portal_group->pg_dscp = IPTOS_DSCP_CS0 >> 2; - else if (strcmp(key, "cs1") == 0) - portal_group->pg_dscp = IPTOS_DSCP_CS1 >> 2; - else if (strcmp(key, "cs2") == 0) - portal_group->pg_dscp = IPTOS_DSCP_CS2 >> 2; - else if (strcmp(key, "cs3") == 0) - portal_group->pg_dscp = IPTOS_DSCP_CS3 >> 2; - else if (strcmp(key, "cs4") == 0) - portal_group->pg_dscp = IPTOS_DSCP_CS4 >> 2; - else if (strcmp(key, "cs5") == 0) - portal_group->pg_dscp = IPTOS_DSCP_CS5 >> 2; - else if (strcmp(key, "cs6") == 0) - portal_group->pg_dscp = IPTOS_DSCP_CS6 >> 2; - else if (strcmp(key, "cs7") == 0) - portal_group->pg_dscp = IPTOS_DSCP_CS7 >> 2; - else if (strcmp(key, "af11") == 0) - portal_group->pg_dscp = IPTOS_DSCP_AF11 >> 2; - else if (strcmp(key, "af12") == 0) - portal_group->pg_dscp = IPTOS_DSCP_AF12 >> 2; - else if (strcmp(key, "af13") == 0) - portal_group->pg_dscp = IPTOS_DSCP_AF13 >> 2; - else if (strcmp(key, "af21") == 0) - portal_group->pg_dscp = IPTOS_DSCP_AF21 >> 2; - else if (strcmp(key, "af22") == 0) - portal_group->pg_dscp = IPTOS_DSCP_AF22 >> 2; - else if (strcmp(key, "af23") == 0) - portal_group->pg_dscp = IPTOS_DSCP_AF23 >> 2; - else if (strcmp(key, "af31") == 0) - portal_group->pg_dscp = IPTOS_DSCP_AF31 >> 2; - else if (strcmp(key, "af32") == 0) - portal_group->pg_dscp = IPTOS_DSCP_AF32 >> 2; - else if (strcmp(key, "af33") == 0) - portal_group->pg_dscp = IPTOS_DSCP_AF33 >> 2; - else if (strcmp(key, "af41") == 0) - portal_group->pg_dscp = IPTOS_DSCP_AF41 >> 2; - else if (strcmp(key, "af42") == 0) - portal_group->pg_dscp = IPTOS_DSCP_AF42 >> 2; - else if (strcmp(key, "af43") == 0) - portal_group->pg_dscp = IPTOS_DSCP_AF43 >> 2; - else { - log_warnx("\"dscp\" property value is not a supported textual value"); - return (false); - } + log_warnx("\"dscp\" property value is not a supported textual value"); + return (false); } return (true); } static bool -uclparse_pcp(const char *group_type, struct portal_group *portal_group, +uclparse_pcp(const char *group_type, const char *pg_name, const ucl_object_t *obj) { if (obj->type != UCL_INT) { log_warnx("\"pcp\" property of %s group \"%s\" is not an " - "integer", group_type, portal_group->pg_name); + "integer", group_type, pg_name); return (false); } - portal_group->pg_pcp = ucl_object_toint(obj); - if (!((portal_group->pg_pcp >= 0) && (portal_group->pg_pcp <= 7))) { - log_warnx("invalid \"pcp\" value %d, using default", - portal_group->pg_pcp); - portal_group->pg_pcp = -1; - } - return (true); + return (portal_group_set_pcp(ucl_object_toint(obj))); } static bool uclparse_portal_group(const char *name, const ucl_object_t *top) { - struct portal_group *portal_group; ucl_object_iter_t it = NULL, it2 = NULL; const ucl_object_t *obj = NULL, *tmp = NULL; const char *key; - if (strcmp(name, "default") == 0 && - conf->conf_default_pg_defined == false) { - portal_group = portal_group_find(conf, name); - conf->conf_default_pg_defined = true; - } else { - portal_group = portal_group_new(conf, name); - } - - if (portal_group == NULL) + if (!portal_group_start(name)) return (false); while ((obj = ucl_iterate_object(top, &it, true))) { key = ucl_object_key(obj); if (strcmp(key, "discovery-auth-group") == 0) { - portal_group->pg_discovery_auth_group = - auth_group_find(conf, ucl_object_tostring(obj)); - if (portal_group->pg_discovery_auth_group == NULL) { - log_warnx("unknown discovery-auth-group \"%s\" " - "for portal-group \"%s\"", - ucl_object_tostring(obj), - portal_group->pg_name); - return (false); + if (obj->type != UCL_STRING) { + log_warnx("\"discovery-auth-group\" property " + "of portal-group \"%s\" is not a string", + name); + goto fail; } + + if (!portal_group_set_discovery_auth_group( + ucl_object_tostring(obj))) + goto fail; } if (strcmp(key, "discovery-filter") == 0) { if (obj->type != UCL_STRING) { log_warnx("\"discovery-filter\" property of " "portal-group \"%s\" is not a string", - portal_group->pg_name); - return (false); + name); + goto fail; } - if (!portal_group_set_filter(portal_group, - ucl_object_tostring(obj))) - return (false); + if (!portal_group_set_filter(ucl_object_tostring(obj))) + goto fail; } if (strcmp(key, "listen") == 0) { if (obj->type == UCL_STRING) { - if (!portal_group_add_listen(portal_group, + if (!portal_group_add_listen( ucl_object_tostring(obj), false)) - return (false); + goto fail; } else if (obj->type == UCL_ARRAY) { while ((tmp = ucl_iterate_object(obj, &it2, true))) { if (!portal_group_add_listen( - portal_group, ucl_object_tostring(tmp), false)) - return (false); + goto fail; } } else { log_warnx("\"listen\" property of " "portal-group \"%s\" is not a string", - portal_group->pg_name); - return (false); + name); + goto fail; } } if (strcmp(key, "listen-iser") == 0) { if (obj->type == UCL_STRING) { - if (!portal_group_add_listen(portal_group, + if (!portal_group_add_listen( ucl_object_tostring(obj), true)) - return (false); + goto fail; } else if (obj->type == UCL_ARRAY) { while ((tmp = ucl_iterate_object(obj, &it2, true))) { if (!portal_group_add_listen( - portal_group, ucl_object_tostring(tmp), true)) - return (false); + goto fail; } } else { log_warnx("\"listen\" property of " "portal-group \"%s\" is not a string", - portal_group->pg_name); - return (false); + name); + goto fail; } } @@ -670,55 +649,57 @@ if (obj->type != UCL_STRING) { log_warnx("\"listen\" property of " "portal-group \"%s\" is not a string", - portal_group->pg_name); - return (false); + name); + goto fail; } - if (!portal_group_set_redirection(portal_group, + if (!portal_group_set_redirection( ucl_object_tostring(obj))) - return (false); + goto fail; } if (strcmp(key, "options") == 0) { if (obj->type != UCL_OBJECT) { log_warnx("\"options\" property of portal group " - "\"%s\" is not an object", portal_group->pg_name); - return (false); + "\"%s\" is not an object", name); + goto fail; } while ((tmp = ucl_iterate_object(obj, &it2, true))) { - if (!option_new(portal_group->pg_options, + if (!portal_group_add_option( ucl_object_key(tmp), ucl_object_tostring_forced(tmp))) - return (false); + goto fail; } } if (strcmp(key, "dscp") == 0) { - if (!uclparse_dscp("portal", portal_group, obj)) - return (false); + if (!uclparse_dscp("portal", name, obj)) + goto fail; } if (strcmp(key, "pcp") == 0) { - if (!uclparse_pcp("portal", portal_group, obj)) - return (false); + if (!uclparse_pcp("portal", name, obj)) + goto fail; } } + portal_group_finish(); return (true); +fail: + portal_group_finish(); + return (false); } static bool uclparse_target(const char *name, const ucl_object_t *top) { - struct target *target; ucl_object_iter_t it = NULL, it2 = NULL; const ucl_object_t *obj = NULL, *tmp = NULL; const char *key; - target = target_new(conf, name); - if (target == NULL) + if (!target_start(name)) return (false); while ((obj = ucl_iterate_object(top, &it, true))) { @@ -727,187 +708,119 @@ if (strcmp(key, "alias") == 0) { if (obj->type != UCL_STRING) { log_warnx("\"alias\" property of target " - "\"%s\" is not a string", target->t_name); - return (false); + "\"%s\" is not a string", name); + goto fail; } - target->t_alias = strdup(ucl_object_tostring(obj)); + if (!target_set_alias(ucl_object_tostring(obj))) + goto fail; } if (strcmp(key, "auth-group") == 0) { - const char *ag; - - if (target->t_auth_group != NULL) { - if (target->t_auth_group->ag_name != NULL) - log_warnx("auth-group for target \"%s\" " - "specified more than once", - target->t_name); - else - log_warnx("cannot use both auth-group " - "and explicit authorisations for " - "target \"%s\"", target->t_name); - return (false); - } - ag = ucl_object_tostring(obj); - if (!ag) { - log_warnx("auth-group must be a string"); - return (false); - } - target->t_auth_group = auth_group_find(conf, ag); - if (target->t_auth_group == NULL) { - log_warnx("unknown auth-group \"%s\" for target " - "\"%s\"", ucl_object_tostring(obj), - target->t_name); - return (false); + if (obj->type != UCL_STRING) { + log_warnx("\"auth-group\" property of target " + "\"%s\" is not a string", name); + goto fail; } + + if (!target_set_auth_group(ucl_object_tostring(obj))) + goto fail; } if (strcmp(key, "auth-type") == 0) { - if (target->t_auth_group != NULL) { - if (target->t_auth_group->ag_name != NULL) { - log_warnx("cannot use both auth-group and " - "auth-type for target \"%s\"", - target->t_name); - return (false); - } - } else { - target->t_auth_group = auth_group_new(conf, NULL); - if (target->t_auth_group == NULL) - return (false); - - target->t_auth_group->ag_target = target; + if (obj->type != UCL_STRING) { + log_warnx("\"auth-type\" property of target " + "\"%s\" is not a string", name); + goto fail; } - if (!auth_group_set_type(target->t_auth_group, - ucl_object_tostring(obj))) - return (false); + + if (!target_set_auth_type(ucl_object_tostring(obj))) + goto fail; } if (strcmp(key, "chap") == 0) { - if (target->t_auth_group != NULL) { - if (target->t_auth_group->ag_name != NULL) { - log_warnx("cannot use both auth-group " - "and chap for target \"%s\"", - target->t_name); - return (false); - } - } else { - target->t_auth_group = auth_group_new(conf, NULL); - if (target->t_auth_group == NULL) { - return (false); - } - target->t_auth_group->ag_target = target; - } - if (!uclparse_chap(target->t_auth_group, obj)) - return (false); + if (!uclparse_target_chap(name, obj)) + goto fail; } if (strcmp(key, "chap-mutual") == 0) { - if (!uclparse_chap_mutual(target->t_auth_group, obj)) - return (false); + if (!uclparse_target_chap_mutual(name, obj)) + goto fail; } if (strcmp(key, "initiator-name") == 0) { - const struct auth_name *an; - - if (target->t_auth_group != NULL) { - if (target->t_auth_group->ag_name != NULL) { - log_warnx("cannot use both auth-group and " - "initiator-name for target \"%s\"", - target->t_name); - return (false); - } - } else { - target->t_auth_group = auth_group_new(conf, NULL); - if (target->t_auth_group == NULL) - return (false); - - target->t_auth_group->ag_target = target; - } - an = auth_name_new(target->t_auth_group, - ucl_object_tostring(obj)); - if (an == NULL) - return (false); + if (!target_add_initiator_name( + ucl_object_tostring(obj))) + goto fail; } if (strcmp(key, "initiator-portal") == 0) { - const struct auth_portal *ap; - - if (target->t_auth_group != NULL) { - if (target->t_auth_group->ag_name != NULL) { - log_warnx("cannot use both auth-group and " - "initiator-portal for target \"%s\"", - target->t_name); - return (false); - } - } else { - target->t_auth_group = auth_group_new(conf, NULL); - if (target->t_auth_group == NULL) - return (false); - - target->t_auth_group->ag_target = target; - } - ap = auth_portal_new(target->t_auth_group, - ucl_object_tostring(obj)); - if (ap == NULL) - return (false); + if (!target_add_initiator_portal( + ucl_object_tostring(obj))) + goto fail; } if (strcmp(key, "portal-group") == 0) { if (obj->type == UCL_OBJECT) { - if (!uclparse_target_portal_group(target, obj)) - return (false); + if (!uclparse_target_portal_group(name, obj)) + goto fail; } if (obj->type == UCL_ARRAY) { while ((tmp = ucl_iterate_object(obj, &it2, true))) { - if (!uclparse_target_portal_group(target, + if (!uclparse_target_portal_group(name, tmp)) - return (false); + goto fail; } } } if (strcmp(key, "port") == 0) { - const char *value; + if (obj->type != UCL_STRING) { + log_warnx("\"port\" property of target " + "\"%s\" is not a string", name); + goto fail; + } - value = ucl_object_tostring(obj); - target->t_pport = strdup(value); + if (!target_set_physical_port(ucl_object_tostring(obj))) + goto fail; } if (strcmp(key, "redirect") == 0) { if (obj->type != UCL_STRING) { log_warnx("\"redirect\" property of target " - "\"%s\" is not a string", target->t_name); - return (false); + "\"%s\" is not a string", name); + goto fail; } - if (!target_set_redirection(target, - ucl_object_tostring(obj))) - return (false); + if (!target_set_redirection(ucl_object_tostring(obj))) + goto fail; } if (strcmp(key, "lun") == 0) { while ((tmp = ucl_iterate_object(obj, &it2, true))) { - if (!uclparse_target_lun(target, tmp)) - return (false); + if (!uclparse_target_lun(name, tmp)) + goto fail; } } } + target_finish(); return (true); +fail: + target_finish(); + return (false); } static bool uclparse_lun(const char *name, const ucl_object_t *top) { - struct lun *lun; ucl_object_iter_t it = NULL, child_it = NULL; const ucl_object_t *obj = NULL, *child = NULL; const char *key; - lun = lun_new(conf, name); - if (lun == NULL) + if (!lun_start(name)) return (false); while ((obj = ucl_iterate_object(top, &it, true))) { @@ -917,91 +830,99 @@ if (obj->type != UCL_STRING) { log_warnx("\"backend\" property of lun " "\"%s\" is not a string", - lun->l_name); - return (false); + name); + goto fail; } - lun_set_backend(lun, ucl_object_tostring(obj)); + if (!lun_set_backend(ucl_object_tostring(obj))) + goto fail; } if (strcmp(key, "blocksize") == 0) { if (obj->type != UCL_INT) { log_warnx("\"blocksize\" property of lun " - "\"%s\" is not an integer", lun->l_name); - return (false); + "\"%s\" is not an integer", name); + goto fail; } - lun_set_blocksize(lun, ucl_object_toint(obj)); + if (!lun_set_blocksize(ucl_object_toint(obj))) + goto fail; } if (strcmp(key, "device-id") == 0) { if (obj->type != UCL_STRING) { log_warnx("\"device-id\" property of lun " - "\"%s\" is not an integer", lun->l_name); - return (false); + "\"%s\" is not an integer", name); + goto fail; } - lun_set_device_id(lun, ucl_object_tostring(obj)); + if (!lun_set_device_id(ucl_object_tostring(obj))) + goto fail; } if (strcmp(key, "options") == 0) { if (obj->type != UCL_OBJECT) { log_warnx("\"options\" property of lun " - "\"%s\" is not an object", lun->l_name); - return (false); + "\"%s\" is not an object", name); + goto fail; } while ((child = ucl_iterate_object(obj, &child_it, true))) { - if (!option_new(lun->l_options, - ucl_object_key(child), + if (!lun_add_option(ucl_object_key(child), ucl_object_tostring_forced(child))) - return (false); + goto fail; } } if (strcmp(key, "path") == 0) { if (obj->type != UCL_STRING) { log_warnx("\"path\" property of lun " - "\"%s\" is not a string", lun->l_name); - return (false); + "\"%s\" is not a string", name); + goto fail; } - lun_set_path(lun, ucl_object_tostring(obj)); + if (!lun_set_path(ucl_object_tostring(obj))) + goto fail; } if (strcmp(key, "serial") == 0) { if (obj->type != UCL_STRING) { log_warnx("\"serial\" property of lun " - "\"%s\" is not a string", lun->l_name); - return (false); + "\"%s\" is not a string", name); + goto fail; } - lun_set_serial(lun, ucl_object_tostring(obj)); + if (!lun_set_serial(ucl_object_tostring(obj))) + goto fail; } if (strcmp(key, "size") == 0) { if (obj->type != UCL_INT) { log_warnx("\"size\" property of lun " - "\"%s\" is not an integer", lun->l_name); - return (false); + "\"%s\" is not an integer", name); + goto fail; } - lun_set_size(lun, ucl_object_toint(obj)); + if (!lun_set_size(ucl_object_toint(obj))) + goto fail; } } + lun_finish(); return (true); +fail: + lun_finish(); + return (false); } bool -uclparse_conf(struct conf *newconf, const char *path) +uclparse_conf(const char *path) { struct ucl_parser *parser; ucl_object_t *top; bool parsed; - conf = newconf; parser = ucl_parser_new(0); if (!ucl_parser_add_file(parser, path)) {