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:
parent
63133871d2
commit
8522624d03
@ -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).
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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] = {
|
||||||
|
Loading…
Reference in New Issue
Block a user