Skip to content
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
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ include(CPack)

## Variables

set(GVMD_DATABASE_VERSION 268)
set(GVMD_DATABASE_VERSION 269)

set(GVMD_SCAP_DATABASE_VERSION 22)

Expand Down
12 changes: 12 additions & 0 deletions src/gmp_agent_groups.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,12 @@ create_agent_group_run (gmp_parser_t *gmp_parser, GError **error)
log_event_fail ("agent_group", "Agent Group", NULL, "created");
break;

case AGENT_GROUP_RESP_GROUP_NAME_EXISTS:
SEND_TO_CLIENT_OR_FAIL (
XML_ERROR_SYNTAX ("create_agent_group", "Agent Group name exists"));
log_event_fail ("agent_group", "Agent Group", NULL, "created");
break;

case AGENT_GROUP_RESP_INTERNAL_ERROR:
default:
SEND_TO_CLIENT_OR_FAIL (XML_INTERNAL_ERROR ("create_agent_group"));
Expand Down Expand Up @@ -753,6 +759,12 @@ modify_agent_group_run (gmp_parser_t *gmp_parser, GError **error)
log_event_fail ("agent_group", "Agent Group", NULL, "modified");
break;

case AGENT_GROUP_RESP_GROUP_NAME_EXISTS:
SEND_TO_CLIENT_OR_FAIL (
XML_ERROR_SYNTAX ("modify_agent_group", "Agent Group name exists"));
log_event_fail ("agent_group", "Agent Group", NULL, "modified");
break;

case AGENT_GROUP_RESP_INTERNAL_ERROR:
default:
SEND_TO_CLIENT_OR_FAIL (XML_INTERNAL_ERROR ("modify_agent_group"));
Expand Down
3 changes: 2 additions & 1 deletion src/manage_agent_groups.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ typedef enum {
AGENT_GROUP_RESP_INVALID_ARGUMENT = -5, ///< Failed invalid argument
AGENT_GROUP_RESP_AGENT_NOT_FOUND = -6, ///< Failed getting agent id
AGENT_GROUP_RESP_INTERNAL_ERROR = -7, ///< Internal error
AGENT_GROUP_RESP_AGENT_UNAUTHORIZED = -8 ///< Failed to create group with unauthorized agent
AGENT_GROUP_RESP_AGENT_UNAUTHORIZED = -8, ///< Failed to create group with unauthorized agent
AGENT_GROUP_RESP_GROUP_NAME_EXISTS = -9 ///< Failed to create group for name exists
} agent_group_resp_t;

agent_group_data_t
Expand Down
81 changes: 80 additions & 1 deletion src/manage_migrators.c
Original file line number Diff line number Diff line change
Expand Up @@ -3560,7 +3560,7 @@ migrate_266_to_267 ()
}

/**
* @brief Migrate the database from version 265 to version 266.
* @brief Migrate the database from version 267 to version 268.
*
* @return 0 success, -1 error.
*/
Expand Down Expand Up @@ -3599,6 +3599,84 @@ migrate_267_to_268 ()
return 0;
}

/**
* @brief Migrate the database from version 268 to version 269.
*
* @return 0 success, -1 error.
*/
int
migrate_268_to_269 ()
{
sql_begin_immediate ();

/* Ensure that the database is currently version 268. */

if (manage_db_version () != 268)
{
sql_rollback ();
return -1;
}
/* Check table exists */
const char *schema = sql_schema ();
int ag_exists = (sql_table_exists (schema, "agent_groups") == 1);
int ag_trash_exists = (sql_table_exists (schema, "agent_groups_trash") == 1);

if (ag_exists)
{
/* Update the database. */
// Before adding unique constraint migrate all agent group names
// name -> name - id
sql (
"UPDATE agent_groups SET name = name || '-' || id::text;"
);

// According to the manual, ADD CONSTRAINT IF NOT EXISTS does not work
// Instead use drop and create new constraint
//ref: https://www.postgresql.org/docs/current/sql-altertable.html#SQL-ALTERTABLE-DESC-DROP-CONSTRAINT
// Drop unique constraints if exists
sql (
"ALTER TABLE agent_groups"
" DROP CONSTRAINT IF EXISTS agent_groups_name_key;"
);

// Add unique constraints for agent group name
sql (
"ALTER TABLE agent_groups "
" ADD CONSTRAINT agent_groups_name_key UNIQUE (name);"
);
}

if (ag_trash_exists)
{
/* Update the database. */
// Before adding unique constraint migrate all agent group names
// name -> name - id
sql (
"UPDATE agent_groups_trash SET name = name || '-' || id::text;"
);

// Drop unique constraints if exists
sql (
"ALTER TABLE agent_groups_trash"
" DROP CONSTRAINT IF EXISTS agent_groups_trash_name_key;"
);

// Add unique constraints for agent group name
sql (
"ALTER TABLE agent_groups_trash "
" ADD CONSTRAINT agent_groups_trash_name_key UNIQUE (name);"
);
}

/* Set the database version to 269. */

set_db_version (269);

sql_commit ();

return 0;
}

#undef UPDATE_DASHBOARD_SETTINGS

/**
Expand Down Expand Up @@ -3673,6 +3751,7 @@ static migrator_t database_migrators[] = {
{266, migrate_265_to_266},
{267, migrate_266_to_267},
{268, migrate_267_to_268},
{269, migrate_268_to_269},
/* End marker. */
{-1, NULL}};

Expand Down
4 changes: 2 additions & 2 deletions src/manage_pg.c
Original file line number Diff line number Diff line change
Expand Up @@ -2882,7 +2882,7 @@ create_tables ()
sql ("CREATE TABLE IF NOT EXISTS agent_groups"
" (id SERIAL PRIMARY KEY,"
" uuid TEXT NOT NULL UNIQUE,"
" name TEXT NOT NULL,"
" name TEXT UNIQUE NOT NULL,"
" scanner INTEGER NOT NULL REFERENCES scanners (id) ON DELETE RESTRICT,"
" owner INTEGER REFERENCES users (id) ON DELETE RESTRICT,"
" comment TEXT,"
Expand All @@ -2899,7 +2899,7 @@ create_tables ()
" uuid text UNIQUE NOT NULL,"
" owner integer REFERENCES users (id) ON DELETE RESTRICT,"
" scanner INTEGER NOT NULL REFERENCES scanners (id) ON DELETE RESTRICT,"
" name text NOT NULL,"
" name text UNIQUE NOT NULL,"
" comment text,"
" creation_time integer,"
" modification_time integer);");
Expand Down
88 changes: 57 additions & 31 deletions src/manage_sql_agent_groups.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,34 @@ agent_group_in_use_in_hidden_task (agent_group_t agent_group)
agent_group);
}

/**
* @brief Check if an agent group name already exists.
* in agent_groups and agent_groups_trash table.
*
* @param name The agent group name to check.
*
* @return 1 if the name exists in either agent_groups
* or agent_groups_trash, 0 otherwise.
*/
static int
agent_group_name_exists (const gchar *name)
{
int count = sql_int_ps (
"SELECT COUNT(*) FROM agent_groups WHERE name = $1;",
SQL_STR_PARAM (name),
NULL);

if (count > 0)
return 1;

count = sql_int_ps (
"SELECT COUNT(*) FROM agent_groups_trash WHERE name = $1;",
SQL_STR_PARAM (name),
NULL);

return (count > 0) ? 1 : 0;
}

/**
* @brief Count the number of agent groups based on filter criteria.
*
Expand Down Expand Up @@ -215,30 +243,27 @@ create_agent_group (agent_group_data_t group_data,
return AGENT_GROUP_RESP_INTERNAL_ERROR;
}

gchar *quoted_uuid = sql_quote (group_data->uuid);
gchar *quoted_name = sql_quote (group_data->name);
gchar *quoted_comment = sql_quote (group_data->comment);
gchar *quoted_user_uuid = sql_quote (current_credentials.uuid);
if (agent_group_name_exists (group_data->name))
{
g_debug ("%s: agent group name already exists", __func__);
return AGENT_GROUP_RESP_GROUP_NAME_EXISTS;
}

sql_begin_immediate ();

// Insert into agent_groups (scanner added)
sql ("INSERT INTO agent_groups (uuid, name, comment, scanner, owner, creation_time, modification_time) "
"VALUES ('%s', '%s', '%s', %llu, "
" (SELECT id FROM users WHERE uuid = '%s'),"
" %ld, %ld);",
quoted_uuid,
quoted_name,
quoted_comment,
group_data->scanner,
quoted_user_uuid,
group_data->creation_time,
group_data->modification_time);

g_free (quoted_uuid);
g_free (quoted_name);
g_free (quoted_comment);
g_free (quoted_user_uuid);
sql_ps ("INSERT INTO agent_groups (uuid, name, comment, scanner, owner, creation_time, modification_time) "
"VALUES ($1, $2, $3, $4, "
" (SELECT id FROM users WHERE uuid = $5),"
" $6, $7);",
SQL_STR_PARAM (group_data->uuid),
SQL_STR_PARAM (group_data->name),
SQL_STR_PARAM (group_data->comment),
SQL_RESOURCE_PARAM (group_data->scanner),
SQL_STR_PARAM (current_credentials.uuid),
SQL_INT_PARAM (group_data->creation_time),
SQL_INT_PARAM (group_data->modification_time),
NULL);

agent_group_t new_agent_group = sql_last_insert_id ();
if (new_agent_group == 0)
Expand Down Expand Up @@ -300,20 +325,21 @@ modify_agent_group (agent_group_t agent_group,
agent_group_data_t group_data,
agent_uuid_list_t agent_uuids)
{
gchar *quoted_name = sql_quote (group_data->name);
gchar *quoted_comment = sql_quote (group_data->comment);

if (agent_group_name_exists (group_data->name))
{
g_debug ("%s: agent group name already exists", __func__);
return AGENT_GROUP_RESP_GROUP_NAME_EXISTS;
}
sql_begin_immediate ();

sql ("UPDATE agent_groups SET name = '%s', comment = '%s', "
"modification_time = %ld WHERE id = %llu;",
quoted_name,
quoted_comment,
group_data->modification_time,
agent_group);

g_free (quoted_name);
g_free (quoted_comment);
sql_ps ("UPDATE agent_groups SET name = $1, comment = $2, "
"modification_time = $3 WHERE id = $4;",
SQL_STR_PARAM (group_data->name),
SQL_STR_PARAM (group_data->comment),
SQL_INT_PARAM (group_data->modification_time),
SQL_RESOURCE_PARAM (agent_group),
NULL);

if (!agent_uuids || agent_uuids->count == 0)
{
Expand Down
3 changes: 3 additions & 0 deletions src/sql.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ sql_int64_0_ps (const char *sql, ...);
int
sql_cancel_internal ();

int
sql_table_exists (const gchar *, const gchar *);

/* Transactions. */

void
Expand Down
26 changes: 26 additions & 0 deletions src/sql_pg.c
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,32 @@ sql_cancel_internal ()
return 0;
}

/**
* @brief Check whether a table exists in a schema.
*
* @return 1 if exists, 0 if not exists, -1 on error.
*/
int
sql_table_exists (const gchar *schema, const gchar *table)
{
const gchar *schema_name;

if (table == NULL || *table == '\0')
return -1;

schema_name = (schema && *schema) ? schema : sql_schema ();

return sql_int_ps (
"SELECT EXISTS ("
" SELECT 1"
" FROM pg_catalog.pg_tables"
" WHERE schemaname = $1 AND tablename = $2"
");",
SQL_STR_PARAM (schema_name),
SQL_STR_PARAM (table),
NULL);
}

/**
* @brief Tries to transfer data for a COPY ... FROM STDIN statement.
*
Expand Down
Loading