Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Reject creating tags of the wrong subtype #2362

Merged
merged 4 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions src/manage_pg.c
Original file line number Diff line number Diff line change
Expand Up @@ -970,6 +970,104 @@ manage_create_sql_functions ()
" $$ LANGUAGE plpgsql"
" IMMUTABLE;");

sql ("CREATE OR REPLACE FUNCTION tag_resources_count ("
" tag_id integer,"
" tag_type text)"
" RETURNS integer AS $$"
" DECLARE usage_types text[];"
" BEGIN"
" IF tag_type = 'audit' OR tag_type = 'audit_report'"
" OR tag_type = 'policy'"
" THEN"
" usage_types := ARRAY['audit', 'policy'];"
" ELSIF tag_type = 'task' OR tag_type = 'report'"
" OR tag_type = 'config'"
" THEN"
" usage_types := ARRAY['scan'];"
" END IF;"
" CASE"
" WHEN tag_type = 'audit' OR tag_type = 'task'"
" THEN RETURN (SELECT count(*)"
" FROM tag_resources"
" JOIN tasks"
" ON tasks.id = resource"
" WHERE tag_resources.tag = tag_id"
" AND tasks.usage_type = ANY(usage_types)"
" AND resource_location = " G_STRINGIFY (LOCATION_TABLE) ");"
" WHEN tag_type = 'policy' OR tag_type = 'config'"
" THEN RETURN (SELECT count(*)"
" FROM tag_resources"
" JOIN configs"
" ON configs.id = resource"
" WHERE tag_resources.tag = tag_id"
" AND configs.usage_type = ANY(usage_types)"
" AND resource_location = " G_STRINGIFY (LOCATION_TABLE) ");"
" WHEN tag_type = 'audit_report' OR tag_type = 'report'"
" THEN RETURN (SELECT count(*)"
" FROM tag_resources"
" JOIN tasks"
" ON tasks.id = (SELECT task FROM reports"
" WHERE reports.id = resource)"
" WHERE tag_resources.tag = tag_id"
" AND tasks.usage_type = ANY(usage_types)"
" AND resource_location = " G_STRINGIFY (LOCATION_TABLE) ");"
" ELSE"
" RETURN (SELECT count(*)"
" FROM tag_resources"
" WHERE tag_resources.tag = tag_id"
" AND resource_location = " G_STRINGIFY (LOCATION_TABLE) ");"
" END CASE;"
" END;"
" $$ LANGUAGE plpgsql"
" IMMUTABLE;");

sql ("CREATE OR REPLACE FUNCTION tag_resources_trash_count ("
" tag_id integer,"
" tag_type text)"
" RETURNS integer AS $$"
" DECLARE usage_types text[];"
" BEGIN"
" IF tag_type = 'audit' OR tag_type = 'audit_report'"
" OR tag_type = 'policy'"
" THEN"
" usage_types := ARRAY['audit', 'policy'];"
" ELSIF tag_type = 'task' OR tag_type = 'report'"
" OR tag_type = 'config'"
" THEN"
" usage_types := ARRAY['scan'];"
" END IF;"
" CASE"
" WHEN tag_type = 'audit' OR tag_type = 'task'"
" THEN RETURN (SELECT count(*)"
" FROM tag_resources_trash"
" JOIN tasks"
" ON tasks.id = resource"
" WHERE tag_resources_trash.tag = tag_id"
" AND tasks.usage_type = ANY(usage_types));"
" WHEN tag_type = 'policy' OR tag_type = 'config'"
" THEN RETURN (SELECT count(*)"
" FROM tag_resources_trash"
" JOIN configs"
" ON configs.id = resource"
" WHERE tag_resources_trash.tag = tag_id"
" AND configs.usage_type = ANY(usage_types));"
" WHEN tag_type = 'audit_report' OR tag_type = 'report'"
" THEN RETURN (SELECT count(*)"
" FROM tag_resources_trash"
" JOIN tasks"
" ON tasks.id = (SELECT task FROM reports"
" WHERE reports.id = resource)"
" WHERE tag_resources_trash.tag = tag_id"
" AND tasks.usage_type = ANY(usage_types));"
" ELSE"
" RETURN (SELECT count(*)"
" FROM tag_resources_trash"
" WHERE tag_resources_trash.tag = tag_id);"
" END CASE;"
" END;"
" $$ LANGUAGE plpgsql"
" IMMUTABLE;");

/* Functions in SQL. */

if (sql_int ("SELECT (EXISTS (SELECT * FROM information_schema.tables"
Expand Down
84 changes: 71 additions & 13 deletions src/manage_sql.c
Original file line number Diff line number Diff line change
Expand Up @@ -29703,7 +29703,7 @@ print_report_xml_start (report_t report, report_t delta, task_t task,
{
iterator_t tags;

init_resource_tag_iterator (&tags, "report", report, 1, NULL, 1);
init_resource_tag_iterator (&tags, report_type, report, 1, NULL, 1);

while (next (&tags))
{
Expand Down Expand Up @@ -57003,14 +57003,18 @@ tag_add_resource (tag_t tag, const char *type, const char *uuid,
* @brief Find a resource by UUID and add it as a tag resource.
*
* @param[in] tag Tag to attach to the resource.
* @param[in] type The resource Type.
* @param[in] type The resource type.
* @param[in] tag_type The tag type. Could be a sub-type.
* @param[in] uuid The resource UUID.
* @param[in] permission The permission required to get the resource.
*
* @return 0 success, -1 error, 1 resource not found.
*/
static int
tag_add_resource_uuid (tag_t tag, const char *type, const char *uuid,
tag_add_resource_uuid (tag_t tag,
const char *type,
const char *tag_type,
const char *uuid,
const char *permission)
{
int resource_location = LOCATION_TABLE;
Expand Down Expand Up @@ -57041,6 +57045,43 @@ tag_add_resource_uuid (tag_t tag, const char *type, const char *uuid,
if (resource == 0)
return 1;

if ((strcmp (type, "task") == 0)
|| (strcmp (type, "config") == 0)
|| (strcmp (type, "report") == 0))
{
gchar *usage_type;
if (strcmp (type, "report"))
usage_type = sql_string ("SELECT usage_type FROM %ss WHERE id = %llu",
type, resource);
else
{
task_t task;
if (report_task (resource, &task))
return -1;

usage_type = sql_string ("SELECT usage_type FROM tasks WHERE id = %llu",
task);
}

if (usage_type == NULL)
return -1;

int same_type = (strcmp (tag_type, type) == 0);

if (same_type && ((strcmp (usage_type, "audit") == 0)
|| (strcmp (usage_type, "policy") == 0)))
{
g_free (usage_type);
return 1;
}
if (!same_type && (strcmp (usage_type, "scan") == 0))
{
g_free (usage_type);
return 1;
}
g_free (usage_type);
}

return tag_add_resource (tag, type, uuid, resource, resource_location);
}

Expand All @@ -57061,24 +57102,29 @@ tag_add_resources_list (tag_t tag, const char *type, array_t *uuids,
gchar *resource_permission, *current_uuid;
int index;

gchar *resource_type = g_strdup (type);

if (type_is_info_subtype (type))
resource_permission = g_strdup ("get_info");
else if (type_is_asset_subtype (type))
resource_permission = g_strdup ("get_assets");
else if (type_is_report_subtype (type))
{
resource_permission = g_strdup ("get_reports");
type = g_strdup("report");
g_free (resource_type);
resource_type = g_strdup ("report");
timopollmeier marked this conversation as resolved.
Show resolved Hide resolved
}
else if (type_is_task_subtype (type))
{
resource_permission = g_strdup ("get_tasks");
type = g_strdup("task");
g_free (resource_type);
resource_type = g_strdup ("task");
}
else if (type_is_config_subtype (type))
{
resource_permission = g_strdup ("get_configs");
type = g_strdup("config");
g_free (resource_type);
resource_type = g_strdup ("config");
}
else
resource_permission = g_strdup_printf ("get_%ss", type);
Expand All @@ -57088,16 +57134,19 @@ tag_add_resources_list (tag_t tag, const char *type, array_t *uuids,
{
int ret;

ret = tag_add_resource_uuid (tag, type, current_uuid,
ret = tag_add_resource_uuid (tag, resource_type, type, current_uuid,
resource_permission);
if (ret)
{
g_free (resource_permission);
g_free (resource_type);
if (error_extra)
*error_extra = g_strdup (current_uuid);
return ret;
}
}
g_free (resource_permission);
g_free (resource_type);

return 0;
}
Expand Down Expand Up @@ -57907,9 +57956,7 @@ modify_tag (const char *tag_id, const char *name, const char *comment,
{ "resource_type", NULL, KEYWORD_TYPE_STRING }, \
{ "active", NULL, KEYWORD_TYPE_INTEGER }, \
{ "value", NULL, KEYWORD_TYPE_STRING }, \
{ "(SELECT count(*) FROM tag_resources" \
" WHERE tag = tags.id" \
" AND resource_location = " G_STRINGIFY (LOCATION_TABLE) ")", \
{ "tag_resources_count (tags.id, tags.resource_type)", \
"resources", KEYWORD_TYPE_INTEGER }, \
{ NULL, NULL, KEYWORD_TYPE_UNKNOWN } \
}
Expand All @@ -57923,8 +57970,7 @@ modify_tag (const char *tag_id, const char *name, const char *comment,
{ "resource_type", NULL, KEYWORD_TYPE_STRING }, \
{ "active", NULL, KEYWORD_TYPE_INTEGER }, \
{ "value", NULL, KEYWORD_TYPE_STRING }, \
{ "(SELECT count(*) FROM tag_resources_trash" \
" WHERE tag = tags_trash.id)", \
{ "tag_resources_trash_count (tags_trash.id, tags_trash.resource_type)", \
"resources", KEYWORD_TYPE_INTEGER }, \
{ NULL, NULL, KEYWORD_TYPE_UNKNOWN } \
}
Expand Down Expand Up @@ -58095,6 +58141,7 @@ init_resource_tag_iterator (iterator_t* iterator, const char* type,
{
get_data_t get;
gchar *owned_clause, *with_clause;
const char *parent_type;

assert (type);
assert (resource);
Expand All @@ -58104,11 +58151,21 @@ init_resource_tag_iterator (iterator_t* iterator, const char* type,
owned_clause = acl_where_owned ("tag", &get, 1, "any", 0, NULL, 0,
&with_clause);

if (type_is_report_subtype (type))
parent_type = "report";
else if (type_is_task_subtype (type))
parent_type = "task";
else if (type_is_config_subtype (type))
parent_type = "config";
else
parent_type = type;

init_iterator (iterator,
"%s"
" SELECT id, uuid, name, value, comment"
" FROM tags"
" WHERE EXISTS"
" WHERE resource_type = '%s'"
" AND EXISTS"
" (SELECT * FROM tag_resources"
" WHERE resource_type = '%s'"
" AND resource = %llu"
Expand All @@ -58119,6 +58176,7 @@ init_resource_tag_iterator (iterator_t* iterator, const char* type,
" ORDER BY %s %s;",
with_clause ? with_clause : "",
type,
parent_type,
resource,
LOCATION_TABLE,
active_only ? " AND active=1" : "",
Expand Down
Loading