opal: Add multiuser support

Admin can enable user and add user to locking range.
Then the user can lock/unlock his range.

Change-Id: Ifc5a8cf5c6b5febeb59c86333981f0cf5b938500
Signed-off-by: Chunyang Hui <chunyang.hui@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/460891
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Chunyang Hui 2019-07-09 17:48:09 +08:00 committed by Changpeng Liu
parent 63133871d2
commit 8522624d03
6 changed files with 577 additions and 48 deletions

View File

@ -96,6 +96,8 @@ NVMe Opal library add support for activating locking SP which will make the tran
from "Manufactured-Inactive" state to "Manufactured" state. Upon successfully invoking from "Manufactured-Inactive" state to "Manufactured" state. Upon successfully invoking
of this method, lock and unlock features will be enabled. of this method, lock and unlock features will be enabled.
NVMe Opal library add support for locking/unlocking range and list locking range info. NVMe Opal library add support for locking/unlocking range and list locking range info.
NVMe opal library add support for multiuser. Admin can enable user and add user to specific
locking range and the user can lock/unlock his range.
Added spdk_nvme_ctrlr_io_cmd_raw_no_payload_build() allowing a caller to pass Added spdk_nvme_ctrlr_io_cmd_raw_no_payload_build() allowing a caller to pass
a completely formed command to an NVMe submission queue (buffer addresses and all). a completely formed command to an NVMe submission queue (buffer addresses and all).

View File

@ -962,8 +962,12 @@ opal_usage(void)
printf("\n"); printf("\n");
printf("\t[1: scan device]\n"); printf("\t[1: scan device]\n");
printf("\t[2: init - take ownership and activate locking]\n"); printf("\t[2: init - take ownership and activate locking]\n");
printf("\t[3: setup locking range and enable locking]\n"); printf("\t[3: setup locking range]\n");
printf("\t[4: list locking ranges]\n"); printf("\t[4: list locking ranges]\n");
printf("\t[5: enable user]\n");
printf("\t[6: set new password]\n");
printf("\t[7: add user to locking range]\n");
printf("\t[8: lock/unlock range]\n");
printf("\t[9: revert tper]\n"); printf("\t[9: revert tper]\n");
printf("\t[0: quit]\n"); printf("\t[0: quit]\n");
} }
@ -1053,10 +1057,8 @@ opal_setup_lockingrange(struct dev *iter)
int ch; int ch;
uint64_t range_start; uint64_t range_start;
uint64_t range_length; uint64_t range_length;
int locking_range_flag; int locking_range_id;
struct spdk_opal_locking_range_info *info; struct spdk_opal_locking_range_info *info;
int state;
enum spdk_opal_lock_state state_flag;
if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) { if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) {
iter->opal_dev = spdk_opal_init_dev(iter->ctrlr); iter->opal_dev = spdk_opal_init_dev(iter->ctrlr);
@ -1068,15 +1070,8 @@ opal_setup_lockingrange(struct dev *iter)
while ((ch = getchar()) != '\n' && ch != EOF); while ((ch = getchar()) != '\n' && ch != EOF);
passwd_p = get_line(passwd, MAX_PASSWORD_SIZE, stdin, true); passwd_p = get_line(passwd, MAX_PASSWORD_SIZE, stdin, true);
if (passwd_p) { if (passwd_p) {
ret = spdk_opal_cmd_lock_unlock(iter->opal_dev, OPAL_ADMIN1, OPAL_READWRITE,
OPAL_LOCKING_RANGE_GLOBAL, passwd_p);
if (ret) {
printf("Unlock range failure: %d\n", ret);
return;
}
printf("Specify locking range id:\n"); printf("Specify locking range id:\n");
if (!scanf("%d", &locking_range_flag)) { if (!scanf("%d", &locking_range_id)) {
printf("Invalid locking range id\n"); printf("Invalid locking range id\n");
} }
@ -1090,46 +1085,20 @@ opal_setup_lockingrange(struct dev *iter)
printf("Invalid range start address\n"); printf("Invalid range start address\n");
} }
opal_locking_usage();
if (!scanf("%d", &state)) {
printf("Invalid option\n");
}
switch (state) {
case 1:
state_flag = OPAL_RWLOCK;
break;
case 2:
state_flag = OPAL_READONLY;
break;
case 3:
state_flag = OPAL_READWRITE;
break;
default:
printf("Invalid options\n");
return;
}
ret = spdk_opal_cmd_setup_locking_range(iter->opal_dev, ret = spdk_opal_cmd_setup_locking_range(iter->opal_dev,
OPAL_ADMIN1, locking_range_flag, range_start, range_length, passwd_p); OPAL_ADMIN1, locking_range_id, range_start, range_length, passwd_p);
if (ret) { if (ret) {
printf("Setup locking range failure: %d\n", ret); printf("Setup locking range failure: %d\n", ret);
return; return;
} }
ret = spdk_opal_cmd_lock_unlock(iter->opal_dev, OPAL_ADMIN1, state_flag,
locking_range_flag, passwd_p);
if (ret) {
printf("Unlock range failure: %d\n", ret);
return;
}
ret = spdk_opal_cmd_get_locking_range_info(iter->opal_dev, ret = spdk_opal_cmd_get_locking_range_info(iter->opal_dev,
passwd_p, locking_range_flag); passwd_p, OPAL_ADMIN1, locking_range_id);
if (ret) { if (ret) {
printf("Get locking range info failure: %d\n", ret); printf("Get locking range info failure: %d\n", ret);
return; return;
} }
info = spdk_opal_get_locking_range_info(iter->opal_dev, locking_range_flag); info = spdk_opal_get_locking_range_info(iter->opal_dev, locking_range_id);
printf("locking range ID: %d\n", info->locking_range_id); printf("locking range ID: %d\n", info->locking_range_id);
printf("range start: %ld\n", info->range_start); printf("range start: %ld\n", info->range_start);
@ -1181,7 +1150,7 @@ opal_list_locking_ranges(struct dev *iter)
max_ranges = spdk_opal_get_max_locking_ranges(iter->opal_dev); max_ranges = spdk_opal_get_max_locking_ranges(iter->opal_dev);
for (i = 0; i < max_ranges; i++) { for (i = 0; i < max_ranges; i++) {
ret = spdk_opal_cmd_get_locking_range_info(iter->opal_dev, ret = spdk_opal_cmd_get_locking_range_info(iter->opal_dev,
passwd_p, i); passwd_p, OPAL_ADMIN1, i);
if (ret) { if (ret) {
printf("Get locking range info failure: %d\n", ret); printf("Get locking range info failure: %d\n", ret);
return; return;
@ -1214,6 +1183,251 @@ opal_list_locking_ranges(struct dev *iter)
} }
} }
static void
opal_new_user_enable(struct dev *iter)
{
int user_id;
char passwd[MAX_PASSWORD_SIZE] = {0};
char *passwd_p;
char user_pw[MAX_PASSWORD_SIZE] = {0};
char *user_pw_p;
int ret;
int ch;
if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) {
iter->opal_dev = spdk_opal_init_dev(iter->ctrlr);
if (iter->opal_dev == NULL) {
return;
}
if (spdk_opal_supported(iter->opal_dev)) {
printf("Please input admin password:\n");
while ((ch = getchar()) != '\n' && ch != EOF);
passwd_p = get_line(passwd, MAX_PASSWORD_SIZE, stdin, true);
if (passwd_p) {
printf("which user to enable: ");
if (!scanf("%d", &user_id)) {
printf("Invalid user id\n");
spdk_opal_close(iter->opal_dev);
return;
}
ret = spdk_opal_cmd_enable_user(iter->opal_dev, user_id, passwd_p);
if (ret) {
printf("Enable user failure error code: %d\n", ret);
spdk_opal_close(iter->opal_dev);
return;
}
printf("Please set a new password for this user:\n");
while ((ch = getchar()) != '\n' && ch != EOF);
user_pw_p = get_line(user_pw, MAX_PASSWORD_SIZE, stdin, true);
if (user_pw_p == NULL) {
printf("Input password invalid. Enable user failure\n");
spdk_opal_close(iter->opal_dev);
return;
}
ret = spdk_opal_cmd_set_new_passwd(iter->opal_dev, user_id, user_pw_p, passwd_p, true);
if (ret) {
printf("Set new password failure error code: %d\n", ret);
spdk_opal_close(iter->opal_dev);
return;
}
printf("...\n...\nEnable User Success\n");
} else {
printf("Input password invalid. Enable user failure\n");
}
}
spdk_opal_close(iter->opal_dev);
} else {
printf("%04x:%02x:%02x.%02x: NVMe Security Support/Receive Not supported.\nOpal Not Supported\n\n\n",
iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func);
}
}
static void
opal_change_password(struct dev *iter)
{
int user_id;
char old_passwd[MAX_PASSWORD_SIZE] = {0};
char *old_passwd_p;
char new_passwd[MAX_PASSWORD_SIZE] = {0};
char *new_passwd_p;
int ret;
int ch;
if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) {
iter->opal_dev = spdk_opal_init_dev(iter->ctrlr);
if (iter->opal_dev == NULL) {
return;
}
if (spdk_opal_supported(iter->opal_dev)) {
printf("user id: ");
if (!scanf("%d", &user_id)) {
printf("Invalid user id\n");
spdk_opal_close(iter->opal_dev);
return;
}
printf("Password:\n");
while ((ch = getchar()) != '\n' && ch != EOF);
old_passwd_p = get_line(old_passwd, MAX_PASSWORD_SIZE, stdin, true);
if (old_passwd_p) {
printf("Please input new password:\n");
new_passwd_p = get_line(new_passwd, MAX_PASSWORD_SIZE, stdin, true);
if (new_passwd_p == NULL) {
printf("Input password invalid. Change password failure\n");
spdk_opal_close(iter->opal_dev);
return;
}
ret = spdk_opal_cmd_set_new_passwd(iter->opal_dev, user_id, new_passwd_p, old_passwd_p, false);
if (ret) {
printf("Set new password failure error code: %d\n", ret);
spdk_opal_close(iter->opal_dev);
return;
}
printf("...\n...\nChange password Success\n");
} else {
printf("Input password invalid. Change password failure\n");
}
}
spdk_opal_close(iter->opal_dev);
} else {
printf("%04x:%02x:%02x.%02x: NVMe Security Support/Receive Not supported.\nOpal Not Supported\n\n\n",
iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func);
}
}
static void
opal_add_user_to_locking_range(struct dev *iter)
{
int locking_range_id, user_id;
char passwd[MAX_PASSWORD_SIZE] = {0};
char *passwd_p;
int ret;
int ch;
if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) {
iter->opal_dev = spdk_opal_init_dev(iter->ctrlr);
if (iter->opal_dev == NULL) {
return;
}
if (spdk_opal_supported(iter->opal_dev)) {
printf("Please input admin password:\n");
while ((ch = getchar()) != '\n' && ch != EOF);
passwd_p = get_line(passwd, MAX_PASSWORD_SIZE, stdin, true);
if (passwd_p) {
printf("Specify locking range id:\n");
if (!scanf("%d", &locking_range_id)) {
printf("Invalid locking range id\n");
spdk_opal_close(iter->opal_dev);
return;
}
printf("which user to enable:\n");
if (!scanf("%d", &user_id)) {
printf("Invalid user id\n");
spdk_opal_close(iter->opal_dev);
return;
}
ret = spdk_opal_cmd_add_user_to_locking_range(iter->opal_dev, user_id, locking_range_id,
OPAL_READONLY,
passwd_p);
ret += spdk_opal_cmd_add_user_to_locking_range(iter->opal_dev, user_id, locking_range_id,
OPAL_READWRITE,
passwd_p);
if (ret) {
printf("Add user to locking range error: %d\n", ret);
return;
}
printf("...\n...\nAdd user to locking range Success\n");
} else {
printf("Input password invalid. Add user to locking range failure\n");
}
}
spdk_opal_close(iter->opal_dev);
} else {
printf("%04x:%02x:%02x.%02x: NVMe Security Support/Receive Not supported.\nOpal Not Supported\n\n\n",
iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func);
}
}
static void
opal_user_lock_unlock_range(struct dev *iter)
{
char passwd[MAX_PASSWORD_SIZE] = {0};
char *passwd_p;
int ch;
int ret;
int user_id;
int locking_range_id;
int state;
enum spdk_opal_lock_state state_flag;
if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) {
iter->opal_dev = spdk_opal_init_dev(iter->ctrlr);
if (iter->opal_dev == NULL) {
return;
}
if (spdk_opal_supported(iter->opal_dev)) {
printf("User id: ");
if (!scanf("%d", &user_id)) {
printf("Invalid user id\n");
spdk_opal_close(iter->opal_dev);
return;
}
printf("Please input password:\n");
while ((ch = getchar()) != '\n' && ch != EOF);
passwd_p = get_line(passwd, MAX_PASSWORD_SIZE, stdin, true);
if (passwd_p) {
printf("Specify locking range id:\n");
if (!scanf("%d", &locking_range_id)) {
printf("Invalid locking range id\n");
spdk_opal_close(iter->opal_dev);
return;
}
opal_locking_usage();
if (!scanf("%d", &state)) {
printf("Invalid option\n");
}
switch (state) {
case 1:
state_flag = OPAL_RWLOCK;
break;
case 2:
state_flag = OPAL_READONLY;
break;
case 3:
state_flag = OPAL_READWRITE;
break;
default:
printf("Invalid options\n");
return;
}
ret = spdk_opal_cmd_lock_unlock(iter->opal_dev, user_id, state_flag,
locking_range_id, passwd_p);
if (ret) {
printf("lock/unlock range failure: %d\n", ret);
return;
}
printf("...\n...\nLock/unlock range Success\n");
} else {
printf("Input password invalid. lock/unlock range failure\n");
}
}
spdk_opal_close(iter->opal_dev);
} else {
printf("%04x:%02x:%02x.%02x: NVMe Security Support/Receive Not supported.\nOpal Not Supported\n\n\n",
iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func);
}
}
static void static void
opal_revert_tper(struct dev *iter) opal_revert_tper(struct dev *iter)
{ {
@ -1222,6 +1436,7 @@ opal_revert_tper(struct dev *iter)
int ret; int ret;
int ch; int ch;
if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) { if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) {
iter->opal_dev = spdk_opal_init_dev(iter->ctrlr); iter->opal_dev = spdk_opal_init_dev(iter->ctrlr);
if (iter->opal_dev == NULL) { if (iter->opal_dev == NULL) {
@ -1289,6 +1504,18 @@ test_opal(void)
case 4: case 4:
opal_list_locking_ranges(ctrlr); opal_list_locking_ranges(ctrlr);
break; break;
case 5:
opal_new_user_enable(ctrlr);
break;
case 6:
opal_change_password(ctrlr);
break;
case 7:
opal_add_user_to_locking_range(ctrlr);
break;
case 8:
opal_user_lock_unlock_range(ctrlr);
break;
case 9: case 9:
opal_revert_tper(ctrlr); opal_revert_tper(ctrlr);
break; break;

View File

@ -184,7 +184,17 @@ int spdk_opal_cmd_setup_locking_range(struct spdk_opal_dev *dev, enum spdk_opal_
int spdk_opal_cmd_get_max_ranges(struct spdk_opal_dev *dev, const char *passwd); int spdk_opal_cmd_get_max_ranges(struct spdk_opal_dev *dev, const char *passwd);
int spdk_opal_cmd_get_locking_range_info(struct spdk_opal_dev *dev, const char *passwd, int spdk_opal_cmd_get_locking_range_info(struct spdk_opal_dev *dev, const char *passwd,
enum spdk_opal_user user_id,
enum spdk_opal_locking_range locking_range_id); enum spdk_opal_locking_range locking_range_id);
int spdk_opal_cmd_enable_user(struct spdk_opal_dev *dev, enum spdk_opal_user user_id,
const char *passwd);
int spdk_opal_cmd_add_user_to_locking_range(struct spdk_opal_dev *dev, enum spdk_opal_user user_id,
enum spdk_opal_locking_range locking_range_id,
enum spdk_opal_lock_state lock_flag, const char *passwd);
int spdk_opal_cmd_set_new_passwd(struct spdk_opal_dev *dev, enum spdk_opal_user user_id,
const char *new_passwd, const char *old_passwd, bool new_user);
struct spdk_opal_locking_range_info *spdk_opal_get_locking_range_info(struct spdk_opal_dev *dev, struct spdk_opal_locking_range_info *spdk_opal_get_locking_range_info(struct spdk_opal_dev *dev,
enum spdk_opal_locking_range id); enum spdk_opal_locking_range id);
uint8_t spdk_opal_get_max_locking_ranges(struct spdk_opal_dev *dev); uint8_t spdk_opal_get_max_locking_ranges(struct spdk_opal_dev *dev);

View File

@ -177,6 +177,9 @@ enum spdk_opal_token {
/* Autority table */ /* Autority table */
SPDK_OPAL_AUTH_ENABLE = 0x05, SPDK_OPAL_AUTH_ENABLE = 0x05,
/* ACE table */
SPDK_OPAL_BOOLEAN_EXPR = 0x03,
}; };
/* /*

View File

@ -1048,6 +1048,19 @@ opal_start_anybody_adminsp_session(struct spdk_opal_dev *dev)
UID_ADMINSP, NULL, 0); UID_ADMINSP, NULL, 0);
} }
static int
opal_start_admin_session(struct spdk_opal_dev *dev, void *data)
{
struct spdk_opal_key *opal_key = data;
if (opal_key == NULL) {
SPDK_ERRLOG("No key found for auth session\n");
return -EINVAL;
}
return opal_start_generic_session(dev, UID_ADMIN1, UID_LOCKINGSP,
opal_key->key, opal_key->key_len);
}
static int static int
opal_get_msid_cpin_pin_cb(struct spdk_opal_dev *dev, void *data) opal_get_msid_cpin_pin_cb(struct spdk_opal_dev *dev, void *data)
{ {
@ -1540,7 +1553,7 @@ opal_get_locking_range_info_cb(struct spdk_opal_dev *dev, void *data)
return error; return error;
} }
if (id > dev->max_ranges) { if (dev->max_ranges != 0 && id > dev->max_ranges) {
SPDK_ERRLOG("Locking range ID not valid\n"); SPDK_ERRLOG("Locking range ID not valid\n");
return -EINVAL; return -EINVAL;
} }
@ -1606,6 +1619,134 @@ opal_get_locking_range_info(struct spdk_opal_dev *dev,
return opal_finalize_and_send(dev, 1, opal_get_locking_range_info_cb, &locking_range_id); return opal_finalize_and_send(dev, 1, opal_get_locking_range_info_cb, &locking_range_id);
} }
static int
opal_enable_user(struct spdk_opal_dev *dev, struct opal_common_session *session)
{
int err = 0;
uint8_t uid_user[OPAL_UID_LENGTH];
err = opal_build_locking_user(uid_user, OPAL_UID_LENGTH, session->who);
opal_clear_cmd(dev);
opal_set_comid(dev, dev->comid);
opal_add_token_u8(&err, dev, SPDK_OPAL_CALL);
opal_add_token_bytestring(&err, dev, uid_user, OPAL_UID_LENGTH);
opal_add_token_bytestring(&err, dev, spdk_opal_method[SET_METHOD], OPAL_UID_LENGTH);
opal_add_tokens(&err, dev, 11,
SPDK_OPAL_STARTLIST,
SPDK_OPAL_STARTNAME,
SPDK_OPAL_VALUES,
SPDK_OPAL_STARTLIST,
SPDK_OPAL_STARTNAME,
SPDK_OPAL_AUTH_ENABLE,
SPDK_OPAL_TRUE,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_ENDLIST,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_ENDLIST);
if (err) {
SPDK_ERRLOG("Error Building enable user command\n");
return err;
}
return opal_finalize_and_send(dev, 1, opal_parse_and_check_status, NULL);
}
static int
opal_add_user_to_locking_range(struct spdk_opal_dev *dev,
struct spdk_opal_locking_session *locking_session)
{
int err = 0;
uint8_t uid_user[OPAL_UID_LENGTH];
uint8_t uid_locking_range[OPAL_UID_LENGTH];
err = opal_build_locking_user(uid_user, OPAL_UID_LENGTH, locking_session->session.who);
if (err) {
return err;
}
switch (locking_session->l_state) {
case OPAL_READONLY:
memcpy(uid_locking_range, spdk_opal_uid[UID_LOCKINGRANGE_ACE_RDLOCKED], OPAL_UID_LENGTH);
break;
case OPAL_READWRITE:
memcpy(uid_locking_range, spdk_opal_uid[UID_LOCKINGRANGE_ACE_WRLOCKED], OPAL_UID_LENGTH);
break;
default:
SPDK_ERRLOG("locking state should only be OPAL_READONLY or OPAL_READWRITE\n");
return -EINVAL;
}
uid_locking_range[7] = locking_session->session.opal_key->locking_range;
opal_clear_cmd(dev);
opal_set_comid(dev, dev->comid);
opal_add_token_u8(&err, dev, SPDK_OPAL_CALL);
opal_add_token_bytestring(&err, dev, uid_locking_range, OPAL_UID_LENGTH);
opal_add_token_bytestring(&err, dev, spdk_opal_method[SET_METHOD], OPAL_UID_LENGTH);
opal_add_tokens(&err, dev, 8,
SPDK_OPAL_STARTLIST,
SPDK_OPAL_STARTNAME,
SPDK_OPAL_VALUES,
SPDK_OPAL_STARTLIST,
SPDK_OPAL_STARTNAME,
SPDK_OPAL_BOOLEAN_EXPR,
SPDK_OPAL_STARTLIST,
SPDK_OPAL_STARTNAME);
opal_add_token_bytestring(&err, dev, spdk_opal_uid[UID_HALF_AUTHORITY_OBJ_REF],
OPAL_UID_LENGTH / 2);
opal_add_token_bytestring(&err, dev, uid_user, OPAL_UID_LENGTH);
opal_add_tokens(&err, dev, 2, SPDK_OPAL_ENDNAME, SPDK_OPAL_STARTNAME);
opal_add_token_bytestring(&err, dev, spdk_opal_uid[UID_HALF_AUTHORITY_OBJ_REF],
OPAL_UID_LENGTH / 2);
opal_add_token_bytestring(&err, dev, uid_user, OPAL_UID_LENGTH);
opal_add_tokens(&err, dev, 2, SPDK_OPAL_ENDNAME, SPDK_OPAL_STARTNAME);
opal_add_token_bytestring(&err, dev, spdk_opal_uid[UID_HALF_BOOLEAN_ACE], OPAL_UID_LENGTH / 2);
opal_add_tokens(&err, dev, 7,
SPDK_OPAL_TRUE,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_ENDLIST,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_ENDLIST,
SPDK_OPAL_ENDNAME,
SPDK_OPAL_ENDLIST);
if (err) {
SPDK_ERRLOG("Error building add user to locking range command\n");
return err;
}
return opal_finalize_and_send(dev, 1, opal_parse_and_check_status, NULL);
}
static int
opal_new_user_passwd(struct spdk_opal_dev *dev, struct opal_common_session *session)
{
uint8_t uid_cpin[OPAL_UID_LENGTH];
int ret;
if (session->who == OPAL_ADMIN1) {
memcpy(uid_cpin, spdk_opal_uid[UID_C_PIN_ADMIN1], OPAL_UID_LENGTH);
} else {
memcpy(uid_cpin, spdk_opal_uid[UID_C_PIN_USER1], OPAL_UID_LENGTH);
uid_cpin[7] = session->who;
}
ret = opal_generic_pw_cmd(session->opal_key->key, session->opal_key->key_len, uid_cpin, dev);
if (ret != 0) {
SPDK_ERRLOG("Error building set password command\n");
return ret;
}
return opal_finalize_and_send(dev, 1, opal_parse_and_check_status, NULL);
}
static int static int
opal_set_sid_cpin_pin(struct spdk_opal_dev *dev, void *data) opal_set_sid_cpin_pin(struct spdk_opal_dev *dev, void *data)
{ {
@ -1994,6 +2135,7 @@ end:
int int
spdk_opal_cmd_get_locking_range_info(struct spdk_opal_dev *dev, const char *passwd, spdk_opal_cmd_get_locking_range_info(struct spdk_opal_dev *dev, const char *passwd,
enum spdk_opal_user user_id,
enum spdk_opal_locking_range locking_range_id) enum spdk_opal_locking_range locking_range_id)
{ {
struct spdk_opal_key opal_key; struct spdk_opal_key opal_key;
@ -2004,6 +2146,51 @@ spdk_opal_cmd_get_locking_range_info(struct spdk_opal_dev *dev, const char *pass
return -ENODEV; return -ENODEV;
} }
ret = opal_init_key(&opal_key, passwd, locking_range_id);
if (ret != 0) {
return ret;
}
memset(&session, 0, sizeof(struct opal_common_session));
session.opal_key = &opal_key;
session.who = user_id;
pthread_mutex_lock(&dev->mutex_lock);
ret = opal_start_auth_session(dev, &session);
if (ret) {
SPDK_ERRLOG("start authenticate session error %d: %s\n", ret, opal_error_to_human(ret));
pthread_mutex_unlock(&dev->mutex_lock);
return ret;
}
ret = opal_get_locking_range_info(dev, locking_range_id);
if (ret) {
SPDK_ERRLOG("get locking range info error %d: %s\n", ret, opal_error_to_human(ret));
goto end;
}
end:
ret += opal_end_session(dev);
if (ret) {
SPDK_ERRLOG("end session error %d: %s\n", ret, opal_error_to_human(ret));
}
pthread_mutex_unlock(&dev->mutex_lock);
return ret;
}
int
spdk_opal_cmd_enable_user(struct spdk_opal_dev *dev, enum spdk_opal_user user_id,
const char *passwd)
{
struct spdk_opal_key opal_key;
struct opal_common_session session;
int ret;
if (!dev || dev->supported == false) {
return -ENODEV;
}
ret = opal_init_key(&opal_key, passwd, OPAL_LOCKING_RANGE_GLOBAL); ret = opal_init_key(&opal_key, passwd, OPAL_LOCKING_RANGE_GLOBAL);
if (ret != 0) { if (ret != 0) {
return ret; return ret;
@ -2011,19 +2198,119 @@ spdk_opal_cmd_get_locking_range_info(struct spdk_opal_dev *dev, const char *pass
memset(&session, 0, sizeof(struct opal_common_session)); memset(&session, 0, sizeof(struct opal_common_session));
session.opal_key = &opal_key; session.opal_key = &opal_key;
session.who = OPAL_ADMIN1; session.who = user_id;
pthread_mutex_lock(&dev->mutex_lock); pthread_mutex_lock(&dev->mutex_lock);
ret = opal_start_auth_session(dev, &session); ret = opal_start_admin_session(dev, session.opal_key);
if (ret) {
SPDK_ERRLOG("start locking SP session error %d: %s\n", ret, opal_error_to_human(ret));
pthread_mutex_unlock(&dev->mutex_lock);
return ret;
}
ret = opal_enable_user(dev, &session);
if (ret) {
SPDK_ERRLOG("enable user error %d: %s\n", ret, opal_error_to_human(ret));
goto end;
}
end:
ret += opal_end_session(dev);
if (ret) {
SPDK_ERRLOG("end session error %d: %s\n", ret, opal_error_to_human(ret));
}
pthread_mutex_unlock(&dev->mutex_lock);
return ret;
}
int
spdk_opal_cmd_add_user_to_locking_range(struct spdk_opal_dev *dev, enum spdk_opal_user user_id,
enum spdk_opal_locking_range locking_range_id,
enum spdk_opal_lock_state lock_flag, const char *passwd)
{
struct spdk_opal_key opal_key;
struct spdk_opal_locking_session locking_session;
int ret;
if (!dev || dev->supported == false) {
return -ENODEV;
}
ret = opal_init_key(&opal_key, passwd, locking_range_id);
if (ret != 0) {
return ret;
}
memset(&locking_session, 0, sizeof(struct spdk_opal_locking_session));
locking_session.session.opal_key = &opal_key;
locking_session.session.who = user_id;
locking_session.l_state = lock_flag;
pthread_mutex_lock(&dev->mutex_lock);
ret = opal_start_admin_session(dev, locking_session.session.opal_key);
if (ret) {
SPDK_ERRLOG("start locking SP session error %d: %s\n", ret, opal_error_to_human(ret));
pthread_mutex_unlock(&dev->mutex_lock);
return ret;
}
ret = opal_add_user_to_locking_range(dev, &locking_session);
if (ret) {
SPDK_ERRLOG("add user to locking range error %d: %s\n", ret, opal_error_to_human(ret));
goto end;
}
end:
ret += opal_end_session(dev);
if (ret) {
SPDK_ERRLOG("end session error %d: %s\n", ret, opal_error_to_human(ret));
}
pthread_mutex_unlock(&dev->mutex_lock);
return ret;
}
int
spdk_opal_cmd_set_new_passwd(struct spdk_opal_dev *dev, enum spdk_opal_user user_id,
const char *new_passwd, const char *old_passwd, bool new_user)
{
struct spdk_opal_key old_key;
struct spdk_opal_key new_key;
struct spdk_opal_new_pw_session session;
int ret;
if (!dev || dev->supported == false) {
return -ENODEV;
}
ret = opal_init_key(&old_key, old_passwd, OPAL_LOCKING_RANGE_GLOBAL);
if (ret != 0) {
return ret;
}
ret = opal_init_key(&new_key, new_passwd, OPAL_LOCKING_RANGE_GLOBAL);
if (ret != 0) {
return ret;
}
memset(&session, 0, sizeof(struct spdk_opal_new_pw_session));
session.new_session.who = user_id;
session.new_session.opal_key = &new_key;
session.old_session.who = new_user ? OPAL_ADMIN1 : user_id;
session.old_session.opal_key = &old_key;
pthread_mutex_lock(&dev->mutex_lock);
ret = opal_start_auth_session(dev, &session.old_session);
if (ret) { if (ret) {
SPDK_ERRLOG("start authenticate session error %d: %s\n", ret, opal_error_to_human(ret)); SPDK_ERRLOG("start authenticate session error %d: %s\n", ret, opal_error_to_human(ret));
pthread_mutex_unlock(&dev->mutex_lock); pthread_mutex_unlock(&dev->mutex_lock);
return ret; return ret;
} }
ret = opal_get_locking_range_info(dev, locking_range_id); ret = opal_new_user_passwd(dev, &session.new_session);
if (ret) { if (ret) {
SPDK_ERRLOG("get locking range info error %d: %s\n", ret, opal_error_to_human(ret)); SPDK_ERRLOG("set new passwd error %d: %s\n", ret, opal_error_to_human(ret));
goto end; goto end;
} }

View File

@ -143,7 +143,7 @@ struct spdk_opal_locking_session {
struct spdk_opal_new_pw_session { struct spdk_opal_new_pw_session {
struct opal_common_session old_session; struct opal_common_session old_session;
struct opal_common_session new_pw_session; struct opal_common_session new_session;
}; };
const uint8_t spdk_opal_uid[][OPAL_UID_LENGTH] = { const uint8_t spdk_opal_uid[][OPAL_UID_LENGTH] = {