Skip to content

Commit

Permalink
iscsi-scst: Add internal_portal parameter
Browse files Browse the repository at this point in the history
Add an internal_portal parameter to allow specified portals to
bypass CHAP controls for both discovery and target login.  If not
populated, then the current behavior will be preserved.
  • Loading branch information
bmeagherix committed Jul 31, 2024
1 parent 7117490 commit b7e96f0
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 1 deletion.
8 changes: 8 additions & 0 deletions iscsi-scst/README
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,13 @@ is /sys/kernel/scst_tgt/targets/iscsi. It has the following entries:
iSCSI-SCST attributes before it starts accepting new connections. 0
by default.

- internal_portal - May designate one or more existing portals as being
internal. This will eliminate the need to supply a CHAP user/secret
during discovery or target login to any targets configured on those
portals. This is particularly useful for internal targets used as
part of ALUA configuration. Multiple addresses may be supplied,
separated by space characters. Empty by default.

- link_local - if set, makes the response to an IPv6 SendTargets include
any link local addresses. Default is set.

Expand Down Expand Up @@ -552,6 +559,7 @@ both iSCSI-SCST targets will look like:
| |-- IncomingUser
| |-- OutgoingUser
| |-- enabled
| |-- internal_portal
| |-- iSNSServer
| |-- iqn.2006-10.net.vlnb:tgt
| | |-- DataDigest
Expand Down
67 changes: 67 additions & 0 deletions iscsi-scst/usr/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,18 @@ static int handle_e_get_attr_value(int fd, const struct iscsi_kern_event *event)
snprintf(res_str, sizeof(res_str), "%d\n", send_targets_link_local);
if (send_targets_link_local != DEFAULT_SEND_TARGETS_LINK_LOCAL)
add_key_mark(res_str, sizeof(res_str), 0);
} else if (strcasecmp(ISCSI_INTERNAL_PORTAL_ATTR_NAME, pp) == 0) {
if (target != NULL) {
log_error("Not NULL target %s for global attribute %s",
target->name, pp);
res = -EINVAL;
goto out_free;
}
if (internal_portal) {
snprintf(res_str, sizeof(res_str), "%s\n", internal_portal);
add_key_mark(res_str, sizeof(res_str), 0);
} else
snprintf(res_str, sizeof(res_str), "\n");
} else {
log_error("Unknown attribute %s", pp);
res = -EINVAL;
Expand All @@ -669,6 +681,14 @@ static int handle_e_get_attr_value(int fd, const struct iscsi_kern_event *event)
return res;
}

static bool is_addr(char *addr)
{
struct in_addr ia;
struct in6_addr ia6;

return (inet_pton(AF_INET, addr, &ia) == 1) || inet_pton(AF_INET6, addr, &ia6);
}

static int handle_target_redirect(struct target *target, char *p)
{
int res = 0;
Expand Down Expand Up @@ -1094,6 +1114,53 @@ static int handle_e_set_attr_value(int fd, const struct iscsi_kern_event *event)
res = -EINVAL;
goto out_free;
}
} else if (strcasecmp(ISCSI_INTERNAL_PORTAL_ATTR_NAME, pp) == 0) {
if (target != NULL) {
log_error("Not NULL target %s for global attribute %s",
target->name, pp);
res = -EINVAL;
goto out_free;
}
p = config_strip_string(p);
if (!p || *p == '\0') {
if (internal_portal)
free(internal_portal);
internal_portal = NULL;
} else {
/* We have been provided with a string, check the contents. */
if (strchr(p, ' ')) {
char *portals = strdup(p);
char *portal;

if (!portals) {
log_error("Memory error (internal_portal)");
res = -ENOMEM;
goto out_free;
}

portal = strtok(portals, " ");
while(portal != NULL) {
if (!is_addr(portal)) {
free(portals);
log_error("Invalid address supplied %s", portal);
res = -EINVAL;
goto out_free;
}
portal = strtok(NULL, " ");
}
free(portals);
} else {
/* No spaces */
if (!is_addr(p)) {
log_error("Invalid address supplied %s", p);
res = -EINVAL;
goto out_free;
}
}
if (internal_portal)
free(internal_portal);
internal_portal = strdup(p);
}
} else {
log_error("Unknown attribute %s", pp);
res = -EINVAL;
Expand Down
3 changes: 3 additions & 0 deletions iscsi-scst/usr/iscsi_scstd.c
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,9 @@ int main(int argc, char **argv)
if (err != 0)
exit(err);
err = kernel_attr_add(NULL, ISCSI_LINK_LOCAL_ATTR_NAME, 0644, 0);
if (err != 0)
exit(err);
err = kernel_attr_add(NULL, ISCSI_INTERNAL_PORTAL_ATTR_NAME, 0644, 0);
if (err != 0)
exit(err);

Expand Down
30 changes: 29 additions & 1 deletion iscsi-scst/usr/iscsid.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "iscsid.h"

int iscsi_enabled;
char *internal_portal;

static u32 ttt;

Expand Down Expand Up @@ -1011,6 +1012,32 @@ static int cmnd_exec_auth(struct connection *conn)
return res;
}

static bool on_internal_portal(struct connection *conn)
{
if (!internal_portal)
return false;

if (strchr(internal_portal, ' ')) {
char *portals = strdup(internal_portal);

if (portals) {
char *portal = strtok(portals, " ");

while(portal != NULL) {
if (!strcmp(portal, conn->target_portal)) {
free(portals);
return true;
}
portal = strtok(NULL, " ");
}
free(portals);
}
return false;
} else {
return !strcmp(internal_portal, conn->target_portal);
}
}

static void cmnd_exec_login(struct connection *conn)
{
struct iscsi_login_req_hdr *req = (struct iscsi_login_req_hdr *)&conn->req.bhs;
Expand Down Expand Up @@ -1084,7 +1111,8 @@ static void cmnd_exec_login(struct connection *conn)
if (rsp->status_class)
return;
if (!accounts_empty(conn->tid, ISCSI_USER_DIR_INCOMING))
goto auth_err;
if (!on_internal_portal(conn))
goto auth_err;
if (rsp->status_class)
return;
text_scan_login(conn);
Expand Down
1 change: 1 addition & 0 deletions iscsi-scst/usr/iscsid.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ extern const char *get_error_str(int error);

/* iscsid.c */
extern int iscsi_enabled;
extern char *internal_portal;

extern int cmnd_execute(struct connection *conn);
extern void cmnd_finish(struct connection *conn);
Expand Down
1 change: 1 addition & 0 deletions iscsi-scst/usr/param.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define ISCSI_ENABLED_ATTR_NAME "enabled"
#define ISCSI_ISNS_ENTITY_ATTR_NAME "isns_entity_name"
#define ISCSI_ALLOWED_PORTAL_ATTR_NAME "allowed_portal"
#define ISCSI_INTERNAL_PORTAL_ATTR_NAME "internal_portal"
#define ISCSI_PER_PORTAL_ACL_ATTR_NAME "per_portal_acl"
#define ISCSI_TARGET_REDIRECTION_ATTR_NAME "redirect"
#define ISCSI_TARGET_REDIRECTION_VALUE_TEMP "temp"
Expand Down

0 comments on commit b7e96f0

Please sign in to comment.