Skip to content

Commit

Permalink
yeah booeeee
Browse files Browse the repository at this point in the history
Required-githooks: true

Change-Id: I0da32ebcc2a16e70934ca6035d7c782ffdb5b87c
Signed-off-by: Michael MacDonald <[email protected]>
  • Loading branch information
mjmac committed Jun 13, 2024
1 parent f80f1c9 commit 43c73cc
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 20 deletions.
2 changes: 2 additions & 0 deletions src/include/daos_srv/pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ int ds_pool_svc_upgrade(uuid_t pool_uuid, d_rank_list_t *ranks);
int ds_pool_failed_add(uuid_t uuid, int rc);
void ds_pool_failed_remove(uuid_t uuid);
int ds_pool_failed_lookup(uuid_t uuid);
int
ds_pool_check_access(uuid_t pool_uuid, d_rank_list_t *ps_ranks, unsigned int flags, d_iov_t *cred);

/*
* Called by dmg on the pool service leader to list all pool handles of a pool.
Expand Down
21 changes: 16 additions & 5 deletions src/mgmt/cli_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <daos/event.h>
#include <daos/job.h>
#include <daos/pool.h>
#include <daos/security.h>
#include "svc.pb-c.h"
#include "rpc.h"
#include <errno.h>
Expand Down Expand Up @@ -1302,7 +1303,7 @@ mgmt_pool_list_cp(tse_task_t *task, void *data)
arg = (struct mgmt_pool_list_arg *)data;

if (rc) {
D_ERROR("RPC error while listing pools: " DF_RC "\n", DP_RC(rc));
DL_ERROR(rc, "RPC error while listing pools");
D_GOTO(out, rc);
}

Expand All @@ -1311,7 +1312,7 @@ mgmt_pool_list_cp(tse_task_t *task, void *data)
rc = pc_out->plo_rc;
*arg->npools = pc_out->plo_npools;
if (rc) {
D_ERROR("MGMT_POOL_LIST replied failed, rc: %d\n", rc);
DL_ERROR(rc, "MGMT_POOL_LIST replied failed");
D_GOTO(out, rc);
}

Expand All @@ -1336,7 +1337,7 @@ mgmt_pool_list_cp(tse_task_t *task, void *data)

/* allocate rank list for caller (simplifies API) */
rc = d_rank_list_dup(&cli_pool->mgpi_svc, rpc_pool->plp_svc_list);
if (rc) {
if (rc != 0) {
D_ERROR("copy RPC reply svc list failed\n");
D_GOTO(out_free_arg_pools, rc = -DER_NOMEM);
}
Expand Down Expand Up @@ -1377,7 +1378,7 @@ dc_mgmt_pool_list(tse_task_t *task)

rc = dc_mgmt_sys_attach(args->grp, &cb_args.sys);
if (rc != 0) {
D_ERROR("cannot attach to DAOS system: %s\n", args->grp);
DL_ERROR(rc, "cannot attach to DAOS system: %s", args->grp);
D_GOTO(out, rc);
}

Expand All @@ -1389,14 +1390,20 @@ dc_mgmt_pool_list(tse_task_t *task)

rc = crt_req_create(daos_task2ctx(task), &svr_ep, opc, &rpc_req);
if (rc != 0) {
D_ERROR("crt_req_create(MGMT_POOL_LIST failed, rc: %d.\n", rc);
DL_ERROR(rc, "crt_req_create(MGMT_POOL_LIST) failed");
D_GOTO(out_grp, rc);
}

D_ASSERT(rpc_req != NULL);
pc_in = crt_req_get(rpc_req);
D_ASSERT(pc_in != NULL);

rc = dc_sec_request_creds(&pc_in->pli_cred);
if (rc != 0) {
DL_ERROR(rc, "failed to obtain security credential");
D_GOTO(out_grp, rc);
}

/** fill in request buffer */
pc_in->pli_grp = (d_string_t)args->grp;
/* If provided pools is NULL, caller needs the number of pools
Expand Down Expand Up @@ -1429,6 +1436,10 @@ dc_mgmt_pool_list(tse_task_t *task)
out_put_req:
crt_req_decref(rpc_req);
crt_req_decref(rpc_req);

/* Ensure credential memory is wiped clean */
explicit_bzero(pc_in->pli_cred.iov_buf, pc_in->pli_cred.iov_buf_len);
daos_iov_free(&pc_in->pli_cred);
out_grp:
dc_mgmt_sys_detach(cb_args.sys);
out:
Expand Down
46 changes: 31 additions & 15 deletions src/mgmt/srv.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <signal.h>
#include <daos_srv/daos_engine.h>
#include <daos_srv/rsvc.h>
#include <daos_srv/pool.h>
#include <daos/drpc_modules.h>
#include <daos_mgmt.h>

Expand Down Expand Up @@ -417,10 +418,10 @@ ds_mgmt_pool_list_hdlr(crt_rpc_t *rpc)
{
struct mgmt_pool_list_in *in;
struct mgmt_pool_list_out *out;
size_t npools = 0;
size_t n_mgmt = 0, n_rpc = 0;
daos_mgmt_pool_info_t *mgmt_pools = NULL;
struct mgmt_pool_list_pool *rpc_pools = NULL;
int i, rc;
int i, rc, chk_rc;

in = crt_req_get(rpc);
D_ASSERT(in != NULL);
Expand All @@ -430,35 +431,50 @@ ds_mgmt_pool_list_hdlr(crt_rpc_t *rpc)

if (in->pli_npools > 0) {
D_ALLOC_ARRAY(mgmt_pools, in->pli_npools);
if (mgmt_pools == NULL)
if (mgmt_pools == NULL) {
D_ERROR("failed to alloc mgmt pools\n");
D_GOTO(send_resp, rc = -DER_NOMEM);
}
}

npools = in->pli_npools;
rc = ds_get_pool_list(&npools, mgmt_pools);
n_mgmt = in->pli_npools;
rc = ds_get_pool_list(&n_mgmt, mgmt_pools);
if (rc != 0) {
DL_ERROR(rc, "ds_get_pool_list() failed");
D_GOTO(send_resp, rc);
}

out->plo_npools = npools;
/* caller just needs the number of pools */
if (in->pli_npools == 0)
if (in->pli_npools == 0) {
out->plo_npools = n_mgmt;
D_GOTO(send_resp, rc);
}

D_ALLOC_ARRAY(rpc_pools, in->pli_npools);
D_ALLOC_ARRAY(rpc_pools, n_mgmt);
if (rpc_pools == NULL) {
D_ERROR("failed to alloc response pools\n");
D_GOTO(send_resp, rc = -DER_NOMEM);
}

for (i = 0; i < in->pli_npools; i++) {
uuid_copy(rpc_pools[i].plp_uuid, mgmt_pools[i].mgpi_uuid);
rpc_pools[i].plp_label = mgmt_pools[i].mgpi_label;
rpc_pools[i].plp_svc_list = mgmt_pools[i].mgpi_svc;
for (i = 0; i < n_mgmt; i++) {
daos_mgmt_pool_info_t *mgmt_pool = &mgmt_pools[i];
struct mgmt_pool_list_pool *rpc_pool = &rpc_pools[n_rpc];
chk_rc = ds_pool_check_access(mgmt_pool->mgpi_uuid, mgmt_pool->mgpi_svc, DAOS_PC_RO,
&in->pli_cred);
if (chk_rc != 0) {
if (chk_rc == -DER_NO_PERM)
continue;
else
D_GOTO(send_resp, rc = chk_rc);
}
uuid_copy(rpc_pool->plp_uuid, mgmt_pool->mgpi_uuid);
rpc_pool->plp_label = mgmt_pool->mgpi_label;
rpc_pool->plp_svc_list = mgmt_pool->mgpi_svc;
n_rpc++;
}
out->plo_pools.ca_arrays = rpc_pools;
out->plo_pools.ca_count = npools;
out->plo_pools.ca_count = n_rpc;
out->plo_npools = n_rpc;

send_resp:
out->plo_rc = rc;
Expand All @@ -467,8 +483,8 @@ ds_mgmt_pool_list_hdlr(crt_rpc_t *rpc)
if (rc != 0)
DL_ERROR(rc, "crt_reply_send() failed");

if (in->pli_npools > 0 && mgmt_pools != NULL) {
for (i = 0; i < in->pli_npools; i++) {
if (n_mgmt > 0 && mgmt_pools != NULL) {
for (i = 0; i < n_mgmt; i++) {
daos_mgmt_pool_info_t *mgmt_pool = &mgmt_pools[i];
if (mgmt_pool->mgpi_label)
D_FREE(mgmt_pool->mgpi_label);
Expand Down
2 changes: 2 additions & 0 deletions src/pool/srv_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ void ds_pool_connect_handler_v5(crt_rpc_t *rpc);
void ds_pool_disconnect_handler(crt_rpc_t *rpc);
void ds_pool_query_handler_v4(crt_rpc_t *rpc);
void ds_pool_query_handler_v5(crt_rpc_t *rpc);
void
ds_pool_check_access_handler(crt_rpc_t *rpc);
void ds_pool_prop_get_handler(crt_rpc_t *rpc);
void ds_pool_prop_set_handler(crt_rpc_t *rpc);
void ds_pool_acl_update_handler(crt_rpc_t *rpc);
Expand Down
168 changes: 168 additions & 0 deletions src/pool/srv_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -2907,6 +2907,174 @@ bulk_cb(const struct crt_bulk_cb_info *cb_info)
return 0;
}

int
ds_pool_check_access(uuid_t pool_uuid, d_rank_list_t *ps_ranks, unsigned int flags, d_iov_t *cred)
{
struct rsvc_client client;
crt_endpoint_t ep;
struct dss_module_info *info = dss_get_module_info();
crt_rpc_t *rpc;
struct pool_check_access_in *in;
struct pool_check_access_out *out;
int rc;

D_DEBUG(DB_MD, DF_UUID ": checking pool access\n", DP_UUID(pool_uuid));

rc = rsvc_client_init(&client, ps_ranks);
if (rc != 0)
goto out;

rechoose:
ep.ep_grp = NULL; /* primary group */
rc = rsvc_client_choose(&client, &ep);
if (rc != 0) {
D_ERROR(DF_UUID ": cannot find pool service: " DF_RC "\n", DP_UUID(pool_uuid),
DP_RC(rc));
goto out_client;
}

rc = pool_req_create(info->dmi_ctx, &ep, POOL_CHECK_ACCESS, &rpc);
if (rc != 0) {
D_ERROR(DF_UUID ": failed to create pool check access rpc, " DF_RC "\n",
DP_UUID(pool_uuid), DP_RC(rc));
goto out_client;
}

in = crt_req_get(rpc);
in->pcai_flags = flags;
uuid_copy(in->pcai_op.pi_uuid, pool_uuid);
uuid_clear(in->pcai_op.pi_hdl);

rc = daos_iov_copy(&in->pcai_cred, cred);
if (rc != 0) {
D_ERROR(DF_UUID ": failed to copy credential IOV, " DF_RC "\n", DP_UUID(pool_uuid),
DP_RC(rc));
goto out_client;
}

rc = dss_rpc_send(rpc);
out = crt_reply_get(rpc);
D_ASSERT(out != NULL);

rc = pool_rsvc_client_complete_rpc(&client, &ep, rc, &out->pcao_op);
if (rc == RSVC_CLIENT_RECHOOSE) {
crt_req_decref(rpc);
dss_sleep(RECHOOSE_SLEEP_MS);
goto rechoose;
}

rc = out->pcao_op.po_rc;
if (rc != 0 && rc != -DER_NO_PERM) {
D_ERROR(DF_UUID ": failed to check pool access, " DF_RC "\n", DP_UUID(pool_uuid),
DP_RC(rc));
}

crt_req_decref(rpc);
out_client:
rsvc_client_fini(&client);
out:
return rc;
}

static int
pool_check_cred_access(d_iov_t *cred, int flags, daos_prop_t *prop)
{
struct daos_prop_entry *acl_entry;
struct d_ownership owner;
struct daos_prop_entry *owner_entry;
struct daos_prop_entry *owner_grp_entry;
uint64_t sec_capas = 0;
int rc;

D_ASSERT(prop != NULL);

acl_entry = daos_prop_entry_get(prop, DAOS_PROP_PO_ACL);
D_ASSERT(acl_entry != NULL);
D_ASSERT(acl_entry->dpe_val_ptr != NULL);

owner_entry = daos_prop_entry_get(prop, DAOS_PROP_PO_OWNER);
D_ASSERT(owner_entry != NULL);
D_ASSERT(owner_entry->dpe_str != NULL);

owner_grp_entry = daos_prop_entry_get(prop, DAOS_PROP_PO_OWNER_GROUP);
D_ASSERT(owner_grp_entry != NULL);
D_ASSERT(owner_grp_entry->dpe_str != NULL);

owner.user = owner_entry->dpe_str;
owner.group = owner_grp_entry->dpe_str;

/*
* Security capabilities determine the access control policy on this
* pool handle.
*/
rc = ds_sec_pool_get_capabilities(flags, cred, &owner, acl_entry->dpe_val_ptr, &sec_capas);
if (rc != 0) {
DL_ERROR(rc, "failed to read sec capabilities");
return rc;
}

if (!ds_sec_pool_can_connect(sec_capas)) {
return -DER_NO_PERM;
}

return 0;
}

void
ds_pool_check_access_handler(crt_rpc_t *rpc)
{
struct pool_check_access_in *in = crt_req_get(rpc);
struct pool_check_access_out *out = crt_reply_get(rpc);
struct pool_svc *svc;
struct rdb_tx tx;
daos_prop_t *prop = NULL;
uint64_t prop_bits;
int rc;

D_DEBUG(DB_MD, DF_UUID ": processing rpc: %p hdl=" DF_UUID "\n",
DP_UUID(in->pcai_op.pi_uuid), rpc, DP_UUID(in->pcai_op.pi_hdl));

rc = pool_svc_lookup_leader(in->pcai_op.pi_uuid, &svc, &out->pcao_op.po_hint);
if (rc != 0)
D_GOTO(out, rc);

rc = rdb_tx_begin(svc->ps_rsvc.s_db, svc->ps_rsvc.s_term, &tx);
if (rc != 0)
D_GOTO(out_svc, rc);

ABT_rwlock_rdlock(svc->ps_lock);

prop_bits = DAOS_PO_QUERY_PROP_ALL;
rc = pool_prop_read(&tx, svc, prop_bits, &prop);
if (rc != 0) {
D_ERROR(DF_UUID ": cannot get access data for pool, "
"rc=" DF_RC "\n",
DP_UUID(in->pcai_op.pi_uuid), DP_RC(rc));
D_GOTO(out_lock, rc);
}
D_ASSERT(prop != NULL);

rc = pool_check_cred_access(&in->pcai_cred, in->pcai_flags, prop);
if (rc != 0) {
D_INFO(DF_UUID ": rejecting access based on credential, "
"rc=" DF_RC "\n",
DP_UUID(in->pcai_op.pi_uuid), DP_RC(rc));
}

out->pcao_op.po_map_version = ds_pool_get_version(svc->ps_pool);
out_lock:
ABT_rwlock_unlock(svc->ps_lock);
rdb_tx_end(&tx);
if (prop)
daos_prop_free(prop);
out_svc:
ds_rsvc_set_hint(&svc->ps_rsvc, &out->pcao_op.po_hint);
pool_svc_put_leader(svc);
out:
out->pcao_op.po_rc = rc;
crt_reply_send(rpc);
}

/* Currently we only maintain compatibility between 2 versions */
#define NUM_POOL_VERSIONS 2

Expand Down

0 comments on commit 43c73cc

Please sign in to comment.