diff --git a/CHANGELOG.md b/CHANGELOG.md index ace594174..ab025542c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Improve SCP username and destination path handling [#1350](https://github.com/greenbone/gvmd/pull/1350) - Fix response memory handling in handle_osp_scan [#1364](https://github.com/greenbone/gvmd/pull/1364) - Allow config to sync even if NVT family is not available [#1366](https://github.com/greenbone/gvmd/pull/1366) +- Delete report format dirs last when deleting a user [#1368](https://github.com/greenbone/gvmd/pull/1368) ### Removed - Remove DROP from vulns creation [#1281](http://github.com/greenbone/gvmd/pull/1281) diff --git a/src/manage_sql.c b/src/manage_sql.c index 87033c15d..d7c73ceb4 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -52146,6 +52146,9 @@ delete_user (const char *user_id_arg, const char *name_arg, int ultimate, user_t user, inheritor; get_data_t get; char *current_uuid, *feed_owner_id; + gboolean has_rows; + iterator_t rows; + gchar *deleted_user_id; assert (user_id_arg || name_arg); @@ -52310,7 +52313,7 @@ delete_user (const char *user_id_arg, const char *name_arg, int ultimate, if (inheritor) { - gchar *deleted_user_id, *deleted_user_name; + gchar *deleted_user_name; gchar *real_inheritor_id, *real_inheritor_name; /* Transfer ownership of objects to the inheritor. */ @@ -52346,7 +52349,6 @@ delete_user (const char *user_id_arg, const char *name_arg, int ultimate, real_inheritor_name, real_inheritor_id, deleted_user_name, deleted_user_id); - g_free (deleted_user_id); g_free (deleted_user_name); g_free (real_inheritor_id); g_free (real_inheritor_name); @@ -52385,7 +52387,6 @@ delete_user (const char *user_id_arg, const char *name_arg, int ultimate, inheritor, user); inherit_port_lists (user, inheritor); - inherit_report_formats (user, inheritor); sql ("UPDATE reports SET owner = %llu WHERE owner = %llu;", inheritor, user); @@ -52446,6 +52447,10 @@ delete_user (const char *user_id_arg, const char *name_arg, int ultimate, sql ("UPDATE roles_trash SET owner = %llu WHERE owner = %llu;", inheritor, user); + /* Report Formats. */ + + has_rows = inherit_report_formats (user, inheritor, &rows); + /* Delete user. */ sql ("DELETE FROM group_users WHERE \"user\" = %llu;", user); @@ -52458,6 +52463,21 @@ delete_user (const char *user_id_arg, const char *name_arg, int ultimate, sql ("DELETE FROM settings WHERE owner = %llu;", user); sql ("DELETE FROM users WHERE id = %llu;", user); + /* Very last: report formats dirs. */ + + if (deleted_user_id == NULL) + g_warning ("%s: deleted_user_id NULL, skipping dirs", __func__); + else if (has_rows) + do + { + inherit_report_format_dir (iterator_string (&rows, 0), + deleted_user_id, + inheritor); + } while (next (&rows)); + + g_free (deleted_user_id); + cleanup_iterator (&rows); + sql_commit (); return 0; @@ -52687,7 +52707,7 @@ delete_user (const char *user_id_arg, const char *name_arg, int ultimate, return 9; } - /* Report formats (used by alerts). */ + /* Check report formats (used by alerts). */ if (user_resources_in_use (user, "report_formats", report_format_in_use, @@ -52697,7 +52717,6 @@ delete_user (const char *user_id_arg, const char *name_arg, int ultimate, sql_rollback (); return 9; } - delete_report_formats_user (user); /* Delete credentials last because they can be used in various places */ @@ -52761,10 +52780,24 @@ delete_user (const char *user_id_arg, const char *name_arg, int ultimate, sql ("DELETE FROM role_users WHERE \"user\" = %llu;", user); sql ("DELETE FROM role_users_trash WHERE \"user\" = %llu;", user); + /* Delete report formats. */ + + has_rows = delete_report_formats_user (user, &rows); + /* Delete user. */ + deleted_user_id = user_uuid (user); + sql ("DELETE FROM users WHERE id = %llu;", user); + /* Delete report format dirs. */ + + if (deleted_user_id) + delete_report_format_dirs_user (deleted_user_id, has_rows ? &rows : NULL); + else + g_warning ("%s: deleted_user_id NULL, skipping removal of report formats dir", + __func__); + sql_commit (); return 0; } diff --git a/src/manage_sql_report_formats.c b/src/manage_sql_report_formats.c index b5897628e..9f1a95a06 100644 --- a/src/manage_sql_report_formats.c +++ b/src/manage_sql_report_formats.c @@ -3953,25 +3953,18 @@ empty_trashcan_report_formats () * @brief Change ownership of report formats, for user deletion. * * @param[in] report_format_id UUID of report format. - * @param[in] user Current owner. + * @param[in] user_id UUID of current owner. * @param[in] inheritor New owner. */ -static void -inherit_report_format_dir (const gchar *report_format_id, user_t user, +void +inherit_report_format_dir (const gchar *report_format_id, const gchar *user_id, user_t inheritor) { - gchar *user_id, *inheritor_id, *old_dir, *new_dir; + gchar *inheritor_id, *old_dir, *new_dir; - g_debug ("%s: %s from %llu to %llu", __func__, report_format_id, user, + g_debug ("%s: %s from %s to %llu", __func__, report_format_id, user_id, inheritor); - user_id = user_uuid (user); - if (user_id == NULL) - { - g_warning ("%s: user_id NULL, skipping report format dir", __func__); - return; - } - inheritor_id = user_uuid (inheritor); if (inheritor_id == NULL) { @@ -3991,7 +3984,6 @@ inherit_report_format_dir (const gchar *report_format_id, user_t user, report_format_id, NULL); - g_free (user_id); g_free (inheritor_id); if (move_report_format_dir (old_dir, new_dir)) @@ -4008,58 +4000,38 @@ inherit_report_format_dir (const gchar *report_format_id, user_t user, * * @param[in] user Current owner. * @param[in] inheritor New owner. + * @param[in] rows Iterator for inherited report formats, with next + * already called. + * + * @return TRUE if there is a row available, else FALSE. */ -void -inherit_report_formats (user_t user, user_t inheritor) +gboolean +inherit_report_formats (user_t user, user_t inheritor, iterator_t *rows) { - iterator_t rows; - - if (user == inheritor) - return; + sql ("UPDATE report_formats_trash SET owner = %llu WHERE owner = %llu;", + inheritor, user); - init_iterator (&rows, + init_iterator (rows, "UPDATE report_formats SET owner = %llu" " WHERE owner = %llu" " RETURNING uuid;", inheritor, user); - while (next (&rows)) - inherit_report_format_dir (iterator_string (&rows, 0), user, inheritor); - cleanup_iterator (&rows); - sql ("UPDATE report_formats_trash SET owner = %llu WHERE owner = %llu;", - inheritor, user); + /* This executes the SQL. */ + return next (rows); } /** * @brief Delete all report formats owned by a user. * * @param[in] user The user. + * @param[in] rows Trash report format ids. + * + * @return TURE if there are rows in rows, else FALSE. */ -void -delete_report_formats_user (user_t user) +gboolean +delete_report_formats_user (user_t user, iterator_t *rows) { - gchar *dir, *user_id; - iterator_t rows; - - /* Remove trash report formats from trash directory. */ - - init_iterator (&rows, - "SELECT id FROM report_formats_trash WHERE owner = %llu;", - user); - while (next (&rows)) - { - gchar *id; - - id = g_strdup_printf ("%llu", iterator_int64 (&rows, 0)); - dir = report_format_trash_dir (id); - g_free (id); - if (gvm_file_remove_recurse (dir)) - g_warning ("%s: failed to remove dir %s, continuing anyway", - __func__, dir); - g_free (dir); - } - cleanup_iterator (&rows); - /* Remove report formats from db. */ sql ("DELETE FROM report_format_param_options" @@ -4086,20 +4058,52 @@ delete_report_formats_user (user_t user) " WHERE owner = %llu);", user); sql ("DELETE FROM report_formats WHERE owner = %llu;", user); - sql ("DELETE FROM report_formats_trash WHERE owner = %llu;", user); + init_iterator (rows, + "DELETE FROM report_formats_trash WHERE owner = %llu" + " RETURNING id;", + user); - /* Remove user's regular report formats directory. */ + /* This executes the SQL. */ + return next (rows); +} - user_id = user_uuid (user); - if (user_id == NULL) - g_warning ("%s: user_id NULL, skipping removal of report formats dir", - __func__); +/** + * @brief Delete all report formats owned by a user. + * + * @param[in] user_id UUID of user. + * @param[in] rows Trash report format ids if any, else NULL. Cleaned up + * before returning. + */ +void +delete_report_format_dirs_user (const gchar *user_id, iterator_t *rows) +{ + gchar *dir; + + /* Remove trash report formats from trash directory. */ + + if (rows) + { + do + { + gchar *id; + + id = g_strdup_printf ("%llu", iterator_int64 (rows, 0)); + dir = report_format_trash_dir (id); + g_free (id); + if (gvm_file_remove_recurse (dir)) + g_warning ("%s: failed to remove dir %s, continuing anyway", + __func__, dir); + g_free (dir); + } while (next (rows)); + cleanup_iterator (rows); + } + + /* Remove user's regular report formats directory. */ dir = g_build_filename (GVMD_STATE_DIR, "report_formats", user_id, NULL); - g_free (user_id); if (g_file_test (dir, G_FILE_TEST_EXISTS) && gvm_file_remove_recurse (dir)) diff --git a/src/manage_sql_report_formats.h b/src/manage_sql_report_formats.h index 4de735e40..d44d48667 100644 --- a/src/manage_sql_report_formats.h +++ b/src/manage_sql_report_formats.h @@ -52,14 +52,20 @@ gchar * apply_report_format (gchar *, gchar *, gchar *, gchar *, GList **); +gboolean +delete_report_formats_user (user_t, iterator_t *); + void -delete_report_formats_user (user_t); +delete_report_format_dirs_user (const gchar *, iterator_t *); int empty_trashcan_report_formats (); +gboolean +inherit_report_formats (user_t, user_t, iterator_t *); + void -inherit_report_formats (user_t, user_t); +inherit_report_format_dir (const gchar *, const gchar *, user_t); void update_report_format (report_format_t, const gchar *, const gchar *,