Skip to content

Commit

Permalink
Add non-expanded ACL reporting for collections
Browse files Browse the repository at this point in the history
To date baton reported non-expanded ACLs for data objects only
(expansion meaning an access control for a group reporting all group
members in addition to the group itself). This was because baton
avoided using specific queries in case the required query was not
installed.

This change achieves non-expanded ACLs for collections in the same way
that the native "ils" icommand does; by using a specific query that is
supplied with iRODS and therefore wil be present unless removed by an
administrator.

This change also adds a new JSON property "type" to each AC. This
reports the user type that the AC represents e.g. rodsuser, rodsadmin,
group.
  • Loading branch information
kjsanger committed Jan 24, 2025
1 parent 0ae63d8 commit e51277b
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 33 deletions.
3 changes: 3 additions & 0 deletions src/json.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@
#define JSON_OWNER_KEY "owner"
#define JSON_LEVEL_KEY "level"

// Users and groups
#define JSON_USER_TYPE_KEY "type" // Values being e.g. rodsadmin, rodsuser, rodsgroup

// Metadata attributes, values
#define JSON_AVUS_KEY "avus"
#define JSON_ATTRIBUTE_KEY "attribute"
Expand Down
2 changes: 1 addition & 1 deletion src/json_query.c
Original file line number Diff line number Diff line change
Expand Up @@ -1260,7 +1260,7 @@ json_t *map_access_args(json_t *query, baton_error_t *error) {
return NULL;
}

json_t *revmap_access_result(json_t *acl, baton_error_t *error) {
json_t *revmap_access_result(json_t *acl, baton_error_t *error) {
size_t num_elts;

init_baton_error(error);
Expand Down
71 changes: 39 additions & 32 deletions src/list.c
Original file line number Diff line number Diff line change
Expand Up @@ -387,25 +387,9 @@ json_t *list_permissions(rcComm_t *conn, rodsPath_t *rods_path,
// while a collections readable by public would show as
//
// irods#testZone:own irods#testZone:read object
// john#testZone:read object alice#testZone:read object
// bob#testZone:read object alice#testZone:read object
//
// where irods, john and alice are the members of "public".

// This reports groups unexpanded (substuting COL_DATA_USER_NAME
// for COL_USER_NAME reports constituent users):
query_format_in_t obj_format =
{ .num_columns = 3,
.columns = { COL_USER_NAME, COL_USER_ZONE,
COL_DATA_ACCESS_NAME },
.labels = { JSON_OWNER_KEY, JSON_ZONE_KEY, JSON_LEVEL_KEY } };

// This reports constituent users (substituing COL_USER_NAME
// for COL_COLL_USER_NAME causes incorrect reporting)
query_format_in_t col_format =
{ .num_columns = 3,
.columns = { COL_COLL_USER_NAME, COL_COLL_USER_ZONE,
COL_COLL_ACCESS_NAME },
.labels = { JSON_OWNER_KEY, JSON_ZONE_KEY, JSON_LEVEL_KEY } };
// where irods, bob and alice are the members of "public".

init_baton_error(error);

Expand All @@ -420,17 +404,51 @@ json_t *list_permissions(rcComm_t *conn, rodsPath_t *rods_path,
case DATA_OBJ_T:
logmsg(TRACE, "Identified '%s' as a data object",
rods_path->outPath);

// This reports groups unexpanded (substuting COL_DATA_USER_NAME
// for COL_USER_NAME reports constituent users):
query_format_in_t obj_format =
{ .num_columns = 3,
.columns = { COL_USER_NAME, COL_USER_ZONE,
COL_DATA_ACCESS_NAME },
.labels = { JSON_OWNER_KEY, JSON_ZONE_KEY, JSON_LEVEL_KEY } };

query_in = make_query_input(SEARCH_MAX_ROWS, obj_format.num_columns,
obj_format.columns);
query_in = prepare_obj_acl_list(query_in, rods_path);

// We need to add a zone hint to return results from other zones.
// Without it, we will only see ACLs in the current zone. The
// iRODS path seems to work for this purpose
addKeyVal(&query_in->condInput, ZONE_KW, rods_path->outPath);
logmsg(DEBUG, "Using zone hint '%s'", rods_path->outPath);
results = do_query(conn, query_in, obj_format.labels, error);
if (error->code != 0) goto error;

logmsg(DEBUG, "Obtained ACL data on '%s'", rods_path->outPath);
free_query_input(query_in);
if (error->code != 0) goto error;
break;

case COLL_OBJ_T:
logmsg(TRACE, "Identified '%s' as a collection",
rods_path->outPath);
query_in = make_query_input(SEARCH_MAX_ROWS, col_format.num_columns,
col_format.columns);
query_in = prepare_col_acl_list(query_in, rods_path);

genQueryOut_t *query_out = NULL;
int status = queryCollAclSpecific(conn, rods_path->outPath, rods_path->outPath,
&query_out);
if (status < 0) {
set_baton_error(error, status,
"Failed to query ACL on '%s': error %d", rods_path->outPath, status);
goto error;
}

results = make_json_objects(query_out,
(const char *[]) { JSON_OWNER_KEY, JSON_ZONE_KEY,
JSON_LEVEL_KEY, JSON_USER_TYPE_KEY });

free_query_output(query_out);
// freeGenQueryOut(&query_out);
break;

default:
Expand All @@ -441,17 +459,6 @@ json_t *list_permissions(rcComm_t *conn, rodsPath_t *rods_path,
goto error;
}

// We need to add a zone hint to return results from other zones.
// Without it, we will only see ACLs in the current zone. The
// iRODS path seems to work for this purpose
addKeyVal(&query_in->condInput, ZONE_KW, rods_path->outPath);
logmsg(DEBUG, "Using zone hint '%s'", rods_path->outPath);
results = do_query(conn, query_in, obj_format.labels, error);
if (error->code != 0) goto error;

logmsg(DEBUG, "Obtained ACL data on '%s'", rods_path->outPath);
free_query_input(query_in);

results = revmap_access_result(results, error);
if (error->code != 0) goto error;

Expand Down

0 comments on commit e51277b

Please sign in to comment.