iscsi: Load CHAP secrets from file once at boot and use them in memory
For secure iSCSI targets, dynamic reconfiguration of CHAP secrets is must to have. Currently CHAP secrets are loaded for every CHAP authentication operation. The current implementation will not work correctly when CHAP secrets in the file are changed dynamically. If SPDK loads CHAP secrets from the file only at boot and they can be configured by RPCs, user can change CHAP secrets safely during run time. Even if there are any users who expect dynamic reconfiguration of CHAP secrets based on the current implementation, if we provide this better alternative based on RPCs, they will be able to continue to satisfy their requirement. This patch change the current implementation so that SPDK loads CHAP secrets from the file once at boot and uses them in memory hereafter. Besides, use fixed size buffers to hold CHAP secrets. Previously dynamically allocated buffers by strdup() had been used, but it required many nomem checks and should be avoided. Other iSCSI targets/initiators have used fixed size buffers and SPDK follows others. Set the size of buffers for both user names and secrets to 256 (the last byte is for NULL termination). 256 is sufficiently large compared with others. CHANGELOG will be updated in the separate patch because new RPCs will be added instead. Change-Id: I499e792817c2ed01c3d970bbd3d34a6b1fccf65b Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-on: https://review.gerrithub.io/421463 Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
8e8084903e
commit
b6ab3116fc
@ -403,10 +403,6 @@ static void spdk_iscsi_conn_free(struct spdk_iscsi_conn *conn)
|
||||
*/
|
||||
spdk_put_pdu(conn->pdu_in_progress);
|
||||
|
||||
free(conn->auth.user);
|
||||
free(conn->auth.secret);
|
||||
free(conn->auth.muser);
|
||||
free(conn->auth.msecret);
|
||||
free_conn(conn);
|
||||
}
|
||||
|
||||
|
@ -71,6 +71,7 @@ struct spdk_iscsi_globals g_spdk_iscsi = {
|
||||
.pg_head = TAILQ_HEAD_INITIALIZER(g_spdk_iscsi.pg_head),
|
||||
.ig_head = TAILQ_HEAD_INITIALIZER(g_spdk_iscsi.ig_head),
|
||||
.target_head = TAILQ_HEAD_INITIALIZER(g_spdk_iscsi.target_head),
|
||||
.auth_group_head = TAILQ_HEAD_INITIALIZER(g_spdk_iscsi.auth_group_head),
|
||||
};
|
||||
|
||||
/* random value generation */
|
||||
@ -679,7 +680,6 @@ spdk_iscsi_append_param(struct spdk_iscsi_conn *conn, const char *key,
|
||||
static int
|
||||
spdk_iscsi_get_authinfo(struct spdk_iscsi_conn *conn, const char *authuser)
|
||||
{
|
||||
char *authfile = NULL;
|
||||
int ag_tag;
|
||||
int rc;
|
||||
|
||||
@ -693,21 +693,11 @@ spdk_iscsi_get_authinfo(struct spdk_iscsi_conn *conn, const char *authuser)
|
||||
}
|
||||
SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "ag_tag=%d\n", ag_tag);
|
||||
|
||||
pthread_mutex_lock(&g_spdk_iscsi.mutex);
|
||||
authfile = strdup(g_spdk_iscsi.authfile);
|
||||
pthread_mutex_unlock(&g_spdk_iscsi.mutex);
|
||||
if (!authfile) {
|
||||
SPDK_ERRLOG("strdup() failed for authfile\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = spdk_iscsi_chap_get_authinfo(&conn->auth, authfile, authuser, ag_tag);
|
||||
rc = spdk_iscsi_chap_get_authinfo(&conn->auth, authuser, ag_tag);
|
||||
if (rc < 0) {
|
||||
SPDK_ERRLOG("chap_get_authinfo() failed\n");
|
||||
free(authfile);
|
||||
return -1;
|
||||
}
|
||||
free(authfile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -829,7 +819,7 @@ spdk_iscsi_auth_params(struct spdk_iscsi_conn *conn,
|
||||
SPDK_ERRLOG("iscsi_get_authinfo() failed\n");
|
||||
goto error_return;
|
||||
}
|
||||
if (conn->auth.user == NULL || conn->auth.secret == NULL) {
|
||||
if (conn->auth.user[0] == '\0' || conn->auth.secret[0] == '\0') {
|
||||
//SPDK_ERRLOG("auth user or secret is missing\n");
|
||||
SPDK_ERRLOG("auth failed (user %.64s)\n", user);
|
||||
goto error_return;
|
||||
@ -889,7 +879,7 @@ spdk_iscsi_auth_params(struct spdk_iscsi_conn *conn,
|
||||
#endif
|
||||
SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "got CHAP_I/CHAP_C\n");
|
||||
|
||||
if (conn->auth.muser == NULL || conn->auth.msecret == NULL) {
|
||||
if (conn->auth.muser[0] == '\0' || conn->auth.msecret[0] == '\0') {
|
||||
//SPDK_ERRLOG("mutual auth user or secret is missing\n");
|
||||
SPDK_ERRLOG("auth failed (user %.64s)\n", user);
|
||||
goto error_return;
|
||||
|
@ -220,14 +220,17 @@ enum session_type {
|
||||
SESSION_TYPE_DISCOVERY = 2,
|
||||
};
|
||||
|
||||
#define ISCSI_CHAP_CHALLENGE_LEN 1024
|
||||
#define ISCSI_CHAP_CHALLENGE_LEN 1024
|
||||
#define ISCSI_CHAP_MAX_USER_LEN 255
|
||||
#define ISCSI_CHAP_MAX_SECRET_LEN 255
|
||||
|
||||
struct iscsi_chap_auth {
|
||||
enum iscsi_chap_phase chap_phase;
|
||||
|
||||
char *user;
|
||||
char *secret;
|
||||
char *muser;
|
||||
char *msecret;
|
||||
char user[ISCSI_CHAP_MAX_USER_LEN + 1];
|
||||
char secret[ISCSI_CHAP_MAX_SECRET_LEN + 1];
|
||||
char muser[ISCSI_CHAP_MAX_USER_LEN + 1];
|
||||
char msecret[ISCSI_CHAP_MAX_SECRET_LEN + 1];
|
||||
|
||||
uint8_t chap_id[1];
|
||||
uint8_t chap_mid[1];
|
||||
@ -237,6 +240,20 @@ struct iscsi_chap_auth {
|
||||
uint8_t chap_mchallenge[ISCSI_CHAP_CHALLENGE_LEN];
|
||||
};
|
||||
|
||||
struct spdk_iscsi_auth_secret {
|
||||
char user[ISCSI_CHAP_MAX_USER_LEN + 1];
|
||||
char secret[ISCSI_CHAP_MAX_SECRET_LEN + 1];
|
||||
char muser[ISCSI_CHAP_MAX_USER_LEN + 1];
|
||||
char msecret[ISCSI_CHAP_MAX_SECRET_LEN + 1];
|
||||
TAILQ_ENTRY(spdk_iscsi_auth_secret) tailq;
|
||||
};
|
||||
|
||||
struct spdk_iscsi_auth_group {
|
||||
int32_t tag;
|
||||
TAILQ_HEAD(, spdk_iscsi_auth_secret) secret_head;
|
||||
TAILQ_ENTRY(spdk_iscsi_auth_group) tailq;
|
||||
};
|
||||
|
||||
struct spdk_iscsi_sess {
|
||||
uint32_t connections;
|
||||
struct spdk_iscsi_conn **conns;
|
||||
@ -308,6 +325,7 @@ struct spdk_iscsi_globals {
|
||||
TAILQ_HEAD(, spdk_iscsi_portal_grp) pg_head;
|
||||
TAILQ_HEAD(, spdk_iscsi_init_grp) ig_head;
|
||||
TAILQ_HEAD(, spdk_iscsi_tgt_node) target_head;
|
||||
TAILQ_HEAD(, spdk_iscsi_auth_group) auth_group_head;
|
||||
|
||||
int32_t timeout;
|
||||
int32_t nopininterval;
|
||||
@ -381,8 +399,8 @@ struct spdk_iscsi_opts *spdk_iscsi_opts_copy(struct spdk_iscsi_opts *src);
|
||||
void spdk_iscsi_opts_info_json(struct spdk_json_write_ctx *w);
|
||||
int spdk_iscsi_set_discovery_auth(bool disable_chap, bool require_chap,
|
||||
bool mutual_chap, int32_t chap_group);
|
||||
int spdk_iscsi_chap_get_authinfo(struct iscsi_chap_auth *auth, const char *authfile,
|
||||
const char *authuser, int ag_tag);
|
||||
int spdk_iscsi_chap_get_authinfo(struct iscsi_chap_auth *auth, const char *authuser,
|
||||
int ag_tag);
|
||||
|
||||
void spdk_iscsi_send_nopin(struct spdk_iscsi_conn *conn);
|
||||
void spdk_iscsi_task_response(struct spdk_iscsi_conn *conn,
|
||||
|
@ -801,85 +801,212 @@ spdk_iscsi_set_discovery_auth(bool disable_chap, bool require_chap, bool mutual_
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_iscsi_chap_get_authinfo(struct iscsi_chap_auth *auth, const char *authfile,
|
||||
const char *authuser, int ag_tag)
|
||||
static int
|
||||
spdk_iscsi_auth_group_add_secret(struct spdk_iscsi_auth_group *group,
|
||||
const char *user, const char *secret,
|
||||
const char *muser, const char *msecret)
|
||||
{
|
||||
struct spdk_iscsi_auth_secret *_secret;
|
||||
size_t len;
|
||||
|
||||
if (user == NULL || secret == NULL) {
|
||||
SPDK_ERRLOG("user and secret must be specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (muser != NULL && msecret == NULL) {
|
||||
SPDK_ERRLOG("msecret must be specified with muser\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(_secret, &group->secret_head, tailq) {
|
||||
if (strcmp(_secret->user, user) == 0) {
|
||||
SPDK_ERRLOG("user for secret is duplicated\n");
|
||||
return -EEXIST;
|
||||
}
|
||||
}
|
||||
|
||||
_secret = calloc(1, sizeof(*_secret));
|
||||
if (_secret == NULL) {
|
||||
SPDK_ERRLOG("calloc() failed for CHAP secret\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
len = strnlen(user, sizeof(_secret->user));
|
||||
if (len > sizeof(_secret->user) - 1) {
|
||||
SPDK_ERRLOG("CHAP user longer than %zu characters: %s\n",
|
||||
sizeof(_secret->user) - 1, user);
|
||||
free(_secret);
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(_secret->user, user, len);
|
||||
|
||||
len = strnlen(secret, sizeof(_secret->secret));
|
||||
if (len > sizeof(_secret->secret) - 1) {
|
||||
SPDK_ERRLOG("CHAP secret longer than %zu characters: %s\n",
|
||||
sizeof(_secret->secret) - 1, secret);
|
||||
free(_secret);
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(_secret->secret, secret, len);
|
||||
|
||||
if (muser != NULL) {
|
||||
len = strnlen(muser, sizeof(_secret->muser));
|
||||
if (len > sizeof(_secret->muser) - 1) {
|
||||
SPDK_ERRLOG("Mutual CHAP user longer than %zu characters: %s\n",
|
||||
sizeof(_secret->muser) - 1, muser);
|
||||
free(_secret);
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(_secret->muser, muser, len);
|
||||
|
||||
len = strnlen(msecret, sizeof(_secret->msecret));
|
||||
if (len > sizeof(_secret->msecret) - 1) {
|
||||
SPDK_ERRLOG("Mutual CHAP secret longer than %zu characters: %s\n",
|
||||
sizeof(_secret->msecret) - 1, msecret);
|
||||
free(_secret);
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(_secret->msecret, msecret, len);
|
||||
}
|
||||
|
||||
TAILQ_INSERT_TAIL(&group->secret_head, _secret, tailq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
spdk_iscsi_add_auth_group(int32_t tag, struct spdk_iscsi_auth_group **_group)
|
||||
{
|
||||
struct spdk_iscsi_auth_group *group;
|
||||
|
||||
TAILQ_FOREACH(group, &g_spdk_iscsi.auth_group_head, tailq) {
|
||||
if (group->tag == tag) {
|
||||
SPDK_ERRLOG("Auth group (%d) already exists\n", tag);
|
||||
return -EEXIST;
|
||||
}
|
||||
}
|
||||
|
||||
group = calloc(1, sizeof(*group));
|
||||
if (group == NULL) {
|
||||
SPDK_ERRLOG("calloc() failed for auth group\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
TAILQ_INIT(&group->secret_head);
|
||||
group->tag = tag;
|
||||
|
||||
TAILQ_INSERT_TAIL(&g_spdk_iscsi.auth_group_head, group, tailq);
|
||||
|
||||
*_group = group;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
spdk_iscsi_delete_auth_group(struct spdk_iscsi_auth_group *group)
|
||||
{
|
||||
struct spdk_iscsi_auth_secret *_secret, *tmp;
|
||||
|
||||
TAILQ_REMOVE(&g_spdk_iscsi.auth_group_head, group, tailq);
|
||||
|
||||
TAILQ_FOREACH_SAFE(_secret, &group->secret_head, tailq, tmp) {
|
||||
TAILQ_REMOVE(&group->secret_head, _secret, tailq);
|
||||
free(_secret);
|
||||
}
|
||||
free(group);
|
||||
}
|
||||
|
||||
static void
|
||||
spdk_iscsi_auth_groups_destroy(void)
|
||||
{
|
||||
struct spdk_iscsi_auth_group *group, *tmp;
|
||||
|
||||
TAILQ_FOREACH_SAFE(group, &g_spdk_iscsi.auth_group_head, tailq, tmp) {
|
||||
spdk_iscsi_delete_auth_group(group);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
spdk_iscsi_parse_auth_group(struct spdk_conf_section *sp)
|
||||
{
|
||||
struct spdk_conf *config = NULL;
|
||||
struct spdk_conf_section *sp;
|
||||
const char *val;
|
||||
const char *user, *muser;
|
||||
const char *secret, *msecret;
|
||||
int rc;
|
||||
int i;
|
||||
int tag;
|
||||
const char *val, *user, *secret, *muser, *msecret;
|
||||
struct spdk_iscsi_auth_group *group = NULL;
|
||||
|
||||
if (auth->user != NULL) {
|
||||
free(auth->user);
|
||||
free(auth->secret);
|
||||
free(auth->muser);
|
||||
free(auth->msecret);
|
||||
auth->user = auth->secret = NULL;
|
||||
auth->muser = auth->msecret = NULL;
|
||||
val = spdk_conf_section_get_val(sp, "Comment");
|
||||
if (val != NULL) {
|
||||
SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Comment %s\n", val);
|
||||
}
|
||||
|
||||
/* read config files */
|
||||
tag = spdk_conf_section_get_num(sp);
|
||||
|
||||
rc = spdk_iscsi_add_auth_group(tag, &group);
|
||||
if (rc != 0) {
|
||||
SPDK_ERRLOG("Failed to add auth group\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = 0; ; i++) {
|
||||
val = spdk_conf_section_get_nval(sp, "Auth", i);
|
||||
if (val == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
user = spdk_conf_section_get_nmval(sp, "Auth", i, 0);
|
||||
secret = spdk_conf_section_get_nmval(sp, "Auth", i, 1);
|
||||
muser = spdk_conf_section_get_nmval(sp, "Auth", i, 2);
|
||||
msecret = spdk_conf_section_get_nmval(sp, "Auth", i, 3);
|
||||
|
||||
rc = spdk_iscsi_auth_group_add_secret(group, user, secret, muser, msecret);
|
||||
if (rc != 0) {
|
||||
SPDK_ERRLOG("Failed to add secret to auth group\n");
|
||||
spdk_iscsi_delete_auth_group(group);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
spdk_iscsi_parse_auth_info(void)
|
||||
{
|
||||
struct spdk_conf *config;
|
||||
struct spdk_conf_section *sp;
|
||||
int rc;
|
||||
|
||||
config = spdk_conf_allocate();
|
||||
if (config == NULL) {
|
||||
SPDK_ERRLOG("allocate config fail\n");
|
||||
return -1;
|
||||
if (!config) {
|
||||
SPDK_ERRLOG("Failed to allocate config file\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = spdk_conf_read(config, authfile);
|
||||
if (rc < 0) {
|
||||
SPDK_ERRLOG("auth conf error\n");
|
||||
rc = spdk_conf_read(config, g_spdk_iscsi.authfile);
|
||||
if (rc != 0) {
|
||||
SPDK_INFOLOG(SPDK_LOG_ISCSI, "Failed to load auth file\n");
|
||||
spdk_conf_free(config);
|
||||
return -1;
|
||||
return rc;
|
||||
}
|
||||
//spdk_conf_print(config);
|
||||
|
||||
sp = spdk_conf_first_section(config);
|
||||
while (sp != NULL) {
|
||||
if (spdk_conf_section_match_prefix(sp, "AuthGroup")) {
|
||||
int group = spdk_conf_section_get_num(sp);
|
||||
if (group == 0) {
|
||||
if (spdk_conf_section_get_num(sp) == 0) {
|
||||
SPDK_ERRLOG("Group 0 is invalid\n");
|
||||
spdk_iscsi_auth_groups_destroy();
|
||||
spdk_conf_free(config);
|
||||
return -1;
|
||||
}
|
||||
if (ag_tag != group) {
|
||||
goto skip_ag_tag;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
val = spdk_conf_section_get_val(sp, "Comment");
|
||||
if (val != NULL) {
|
||||
SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "Comment %s\n", val);
|
||||
}
|
||||
for (i = 0; ; i++) {
|
||||
val = spdk_conf_section_get_nval(sp, "Auth", i);
|
||||
if (val == NULL) {
|
||||
break;
|
||||
}
|
||||
user = spdk_conf_section_get_nmval(sp, "Auth", i, 0);
|
||||
secret = spdk_conf_section_get_nmval(sp, "Auth", i, 1);
|
||||
muser = spdk_conf_section_get_nmval(sp, "Auth", i, 2);
|
||||
msecret = spdk_conf_section_get_nmval(sp, "Auth", i, 3);
|
||||
if (user != NULL) {
|
||||
if (strcasecmp(authuser, user) == 0) {
|
||||
/* match user */
|
||||
auth->user = xstrdup(user);
|
||||
auth->secret = xstrdup(secret);
|
||||
auth->muser = xstrdup(muser);
|
||||
auth->msecret = xstrdup(msecret);
|
||||
spdk_conf_free(config);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
SPDK_ERRLOG("Invalid Auth format, skip this line\n");
|
||||
continue;
|
||||
}
|
||||
rc = spdk_iscsi_parse_auth_group(sp);
|
||||
if (rc != 0) {
|
||||
SPDK_ERRLOG("parse_auth_group() failed\n");
|
||||
spdk_iscsi_auth_groups_destroy();
|
||||
spdk_conf_free(config);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
skip_ag_tag:
|
||||
sp = spdk_conf_next_section(sp);
|
||||
}
|
||||
|
||||
@ -887,6 +1014,60 @@ skip_ag_tag:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spdk_iscsi_auth_secret *
|
||||
spdk_iscsi_find_auth_secret(const char *authuser, int ag_tag)
|
||||
{
|
||||
struct spdk_iscsi_auth_group *group;
|
||||
struct spdk_iscsi_auth_secret *_secret;
|
||||
|
||||
TAILQ_FOREACH(group, &g_spdk_iscsi.auth_group_head, tailq) {
|
||||
if (group->tag == ag_tag) {
|
||||
TAILQ_FOREACH(_secret, &group->secret_head, tailq) {
|
||||
if (strcmp(_secret->user, authuser) == 0) {
|
||||
return _secret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_iscsi_chap_get_authinfo(struct iscsi_chap_auth *auth, const char *authuser,
|
||||
int ag_tag)
|
||||
{
|
||||
struct spdk_iscsi_auth_secret *_secret;
|
||||
|
||||
if (authuser == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (auth->user[0] != '\0') {
|
||||
memset(auth->user, 0, sizeof(auth->user));
|
||||
memset(auth->secret, 0, sizeof(auth->secret));
|
||||
memset(auth->muser, 0, sizeof(auth->muser));
|
||||
memset(auth->msecret, 0, sizeof(auth->msecret));
|
||||
}
|
||||
|
||||
_secret = spdk_iscsi_find_auth_secret(authuser, ag_tag);
|
||||
if (_secret == NULL) {
|
||||
SPDK_ERRLOG("CHAP secret is not found: user:%s, tag:%d\n",
|
||||
authuser, ag_tag);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
memcpy(auth->user, _secret->user, sizeof(auth->user));
|
||||
memcpy(auth->secret, _secret->secret, sizeof(auth->secret));
|
||||
|
||||
if (_secret->muser[0] != '\0') {
|
||||
memcpy(auth->muser, _secret->muser, sizeof(auth->muser));
|
||||
memcpy(auth->msecret, _secret->msecret, sizeof(auth->msecret));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
spdk_iscsi_initialize_global_params(void)
|
||||
{
|
||||
@ -1032,6 +1213,16 @@ spdk_iscsi_parse_configuration(void *ctx)
|
||||
SPDK_ERRLOG("spdk_iscsi_parse_tgt_nodes() failed\n");
|
||||
}
|
||||
|
||||
if (access(g_spdk_iscsi.authfile, R_OK) == 0) {
|
||||
rc = spdk_iscsi_parse_auth_info();
|
||||
if (rc < 0) {
|
||||
SPDK_ERRLOG("spdk_iscsi_parse_auth_info() failed\n");
|
||||
}
|
||||
} else {
|
||||
SPDK_INFOLOG(SPDK_LOG_ISCSI, "CHAP secret file is not found in the path %s\n",
|
||||
g_spdk_iscsi.authfile);
|
||||
}
|
||||
|
||||
end:
|
||||
spdk_iscsi_init_complete(rc);
|
||||
}
|
||||
@ -1118,6 +1309,7 @@ spdk_iscsi_fini_done(void *arg)
|
||||
spdk_iscsi_shutdown_tgt_nodes();
|
||||
spdk_iscsi_init_grps_destroy();
|
||||
spdk_iscsi_portal_grps_destroy();
|
||||
spdk_iscsi_auth_groups_destroy();
|
||||
free(g_spdk_iscsi.authfile);
|
||||
free(g_spdk_iscsi.nodebase);
|
||||
free(g_spdk_iscsi.poll_group);
|
||||
|
@ -97,8 +97,8 @@ spdk_iscsi_conn_free_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pd
|
||||
}
|
||||
|
||||
int
|
||||
spdk_iscsi_chap_get_authinfo(struct iscsi_chap_auth *auth, const char *authfile,
|
||||
const char *authuser, int ag_tag)
|
||||
spdk_iscsi_chap_get_authinfo(struct iscsi_chap_auth *auth, const char *authuser,
|
||||
int ag_tag)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user