From 5a479c811e4e215091a86af1debfc200efd10e4d Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Fri, 16 Jan 2026 14:40:58 +0200 Subject: [PATCH 1/4] Change: move modify_user and copy_user to dedicated users files --- src/manage.h | 6 - src/manage_sql.c | 435 ----------------------------------------- src/manage_sql_users.c | 435 +++++++++++++++++++++++++++++++++++++++++ src/manage_users.h | 9 + 4 files changed, 444 insertions(+), 441 deletions(-) diff --git a/src/manage.h b/src/manage.h index d62d222ae..a18b4f359 100644 --- a/src/manage.h +++ b/src/manage.h @@ -3217,12 +3217,6 @@ copy_user (const char*, const char*, const char*, user_t*); gchar * keyfile_to_auth_conf_settings_xml (const gchar *); -int -modify_user (const gchar *, gchar **, const gchar *, const gchar *, - const gchar*, const gchar *, int, - const array_t *, array_t *, gchar **, array_t *, gchar **, - gchar **); - int user_count (const get_data_t*); diff --git a/src/manage_sql.c b/src/manage_sql.c index 8478bce1d..3ee63ff28 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -38172,441 +38172,6 @@ manage_set_password (GSList *log_config, const db_conn_info_t *database, return -1; } -/** - * @brief Create a user from an existing user. - * - * @param[in] name Name of new user. NULL to copy from existing. - * @param[in] comment Comment on new user. NULL to copy from existing. - * @param[in] user_id UUID of existing user. - * @param[out] new_user New user. - * - * @return 0 success, 1 user exists already, 2 failed to find existing - * user, 99 permission denied, -1 error. - */ -int -copy_user (const char* name, const char* comment, const char *user_id, - user_t* new_user) -{ - user_t user; - int ret; - gchar *quoted_uuid; - GArray *cache_users; - char *uuid; - - if (acl_user_can_super_everyone (user_id)) - return 99; - - sql_begin_immediate (); - - ret = copy_resource_lock ("user", name, comment, user_id, - "password, timezone, hosts, hosts_allow, method", - 1, &user, NULL); - if (ret) - { - sql_rollback (); - return ret; - } - - sql ("UPDATE users SET password = NULL WHERE id = %llu;", user); - - quoted_uuid = sql_quote (user_id); - - sql ("INSERT INTO group_users (\"user\", \"group\")" - " SELECT %llu, \"group\" FROM group_users" - " WHERE \"user\" = (SELECT id FROM users WHERE uuid = '%s');", - user, - quoted_uuid); - - sql ("INSERT INTO role_users (\"user\", role)" - " SELECT %llu, role FROM role_users" - " WHERE \"user\" = (SELECT id FROM users WHERE uuid = '%s');", - user, - quoted_uuid); - - g_free (quoted_uuid); - - /* Ensure the user can see themself. */ - - uuid = user_uuid (user); - if (uuid == NULL) - { - g_warning ("%s: Failed to allocate UUID", __func__); - sql_rollback (); - return -1; - } - - create_permission_internal (1, - "GET_USERS", - "Automatically created when adding user", - NULL, - uuid, - "user", - uuid, - NULL); - - free (uuid); - - /* Cache permissions. */ - - cache_users = g_array_new (TRUE, TRUE, sizeof (user_t)); - g_array_append_val (cache_users, user); - cache_all_permissions_for_users (cache_users); - g_free (g_array_free (cache_users, TRUE)); - - sql_commit (); - - if (new_user) - *new_user = user; - - return ret; -} - -/** - * @brief Modify a user. - * - * @param[in] user_id The UUID of the user. Overrides name. - * @param[in] name The name of the user. If NULL then set to name - * when return is 3 or 4. - * @param[in] new_name New name for the user. NULL to leave as is. - * @param[in] password The password of the user. NULL to leave as is. - * @param[in] comment The comment for the user. NULL to leave as is. - * @param[in] hosts The host the user is allowed/forbidden to scan. - * NULL to leave as is. - * @param[in] hosts_allow Whether hosts is allow or forbid. - * @param[in] allowed_methods Allowed login methods. - * @param[in] groups Groups. - * @param[out] group_id_return ID of group on "failed to find" error. - * @param[in] roles Roles. - * @param[out] role_id_return ID of role on "failed to find" error. - * @param[out] r_errdesc If not NULL the address of a variable to receive - * a malloced string with the error description. Will - * always be set to NULL on success. - * - * @return 0 if the user has been added successfully, 1 failed to find group, - * 2 failed to find user, 3 success and user gained admin, 4 success - * and user lost admin, 5 failed to find role, 6 syntax error in hosts, - * 7 syntax error in new name, 99 permission denied, -1 on error, - * -2 for an unknown role, -3 if wrong number of methods, -4 error in - * method. - */ -int -modify_user (const gchar * user_id, gchar **name, const gchar *new_name, - const gchar * password, const gchar * comment, - const gchar * hosts, int hosts_allow, - const array_t * allowed_methods, array_t *groups, - gchar **group_id_return, array_t *roles, gchar **role_id_return, - gchar **r_errdesc) -{ - char *errstr; - gchar *hash, *quoted_hosts, *quoted_method, *clean, *uuid; - gchar *quoted_new_name, *quoted_comment; - user_t user; - int max, was_admin, is_admin; - GArray *cache_users; - - if (r_errdesc) - *r_errdesc = NULL; - - /* allowed_methods is a NULL terminated array. */ - if (allowed_methods && (allowed_methods->len > 2)) - return -3; - - if (allowed_methods && (allowed_methods->len <= 1)) - allowed_methods = NULL; - - if (allowed_methods - && (strlen (g_ptr_array_index (allowed_methods, 0)) == 0)) - allowed_methods = NULL; - - if (allowed_methods - && (auth_method_name_valid (g_ptr_array_index (allowed_methods, 0)) - == 0)) - return -4; - - sql_begin_immediate (); - - if (acl_user_may ("modify_user") == 0) - { - sql_rollback (); - return 99; - } - - user = 0; - if (user_id) - { - if (find_user_with_permission (user_id, &user, "modify_user")) - { - sql_rollback (); - return -1; - } - } - else if (find_user_by_name_with_permission (*name, &user, "modify_user")) - { - sql_rollback (); - return -1; - } - if (user == 0) - { - sql_rollback (); - return 2; - } - - uuid = sql_string ("SELECT uuid FROM users WHERE id = %llu", - user); - - /* The only user that can edit a Super Admin is the Super Admin themself. */ - if (acl_user_can_super_everyone (uuid) && strcmp (uuid, current_credentials.uuid)) - { - g_free (uuid); - sql_rollback (); - return 99; - } - - was_admin = acl_user_is_admin (uuid); - - if (password) - { - char *user_name; - - user_name = sql_string ("SELECT name FROM users WHERE id = %llu", - user); - errstr = gvm_validate_password (password, user_name); - if (errstr) - { - g_warning ("new password for '%s' rejected: %s", user_name, errstr); - if (r_errdesc) - *r_errdesc = errstr; - else - g_free (errstr); - sql_rollback (); - g_free (user_name); - return -1; - } - g_free (user_name); - } - - /* Check hosts. */ - - max = manage_max_hosts (); - manage_set_max_hosts (MANAGE_USER_MAX_HOSTS); - if (hosts && (manage_count_hosts (hosts, NULL) < 0)) - { - manage_set_max_hosts (max); - sql_rollback (); - return 6; - } - manage_set_max_hosts (max); - - /* Check new name. */ - - if (new_name) - { - if (validate_username (new_name) != 0) - { - sql_rollback (); - return 7; - } - - if (strcmp (uuid, current_credentials.uuid) == 0) - { - sql_rollback (); - return 99; - } - - if (resource_with_name_exists_global (new_name, "user", user)) - { - sql_rollback (); - return 8; - } - quoted_new_name = sql_quote (new_name); - } - else - quoted_new_name = NULL; - - /* Get the password hashes. */ - - if (password) - hash = manage_authentication_hash (password); - else - hash = NULL; - - if (comment) - { - quoted_comment = sql_quote (comment); - } - else - { - quoted_comment = NULL; - } - - - /* Update the user in the database. */ - - clean = clean_hosts (hosts ? hosts : "", &max); - if ((hosts_allow == 0) && (max == 0)) - /* Convert "Deny none" to "Allow All". */ - hosts_allow = 2; - quoted_hosts = sql_quote (clean); - g_free (clean); - quoted_method = sql_quote (allowed_methods - ? g_ptr_array_index (allowed_methods, 0) - : ""); - sql ("UPDATE users" - " SET name = %s%s%s," - " comment = %s%s%s," - " hosts = '%s'," - " hosts_allow = '%i'," - " method = %s%s%s," - " modification_time = m_now ()" - " WHERE id = %llu;", - quoted_new_name ? "'" : "", - quoted_new_name ? quoted_new_name : "name", - quoted_new_name ? "'" : "", - quoted_comment ? "'" : "", - quoted_comment ? quoted_comment : "comment", - quoted_comment ? "'" : "", - quoted_hosts, - hosts_allow, - allowed_methods ? "'" : "", - allowed_methods ? quoted_method : "method", - allowed_methods ? "'" : "", - user); - g_free (quoted_new_name); - g_free (quoted_hosts); - g_free (quoted_method); - if (hash) - sql ("UPDATE users" - " SET password = '%s'" - " WHERE id = %llu;", - hash, - user); - g_free (hash); - - /* Update the user groups. */ - - if (groups) - { - int index; - - sql ("DELETE FROM group_users WHERE \"user\" = %llu;", user); - index = 0; - while (groups && (index < groups->len)) - { - gchar *group_id; - group_t group; - - group_id = (gchar*) g_ptr_array_index (groups, index); - if (strcmp (group_id, "0") == 0) - { - index++; - continue; - } - - if (find_group_with_permission (group_id, &group, "modify_group")) - { - sql_rollback (); - return -1; - } - - if (group == 0) - { - sql_rollback (); - if (group_id_return) *group_id_return = group_id; - return 1; - } - - sql ("INSERT INTO group_users (\"group\", \"user\")" - " VALUES (%llu, %llu);", - group, - user); - - index++; - } - } - - /* Update the user roles. */ - - if (roles) - { - int index; - - sql ("DELETE FROM role_users" - " WHERE \"user\" = %llu" - " AND role != (SELECT id from roles" - " WHERE uuid = '" ROLE_UUID_SUPER_ADMIN "');", - user); - index = 0; - while (roles && (index < roles->len)) - { - gchar *role_id; - role_t role; - - role_id = (gchar*) g_ptr_array_index (roles, index); - if (strcmp (role_id, "0") == 0) - { - index++; - continue; - } - - if (find_role_with_permission (role_id, &role, "get_roles")) - { - sql_rollback (); - return -1; - } - - if (role == 0) - { - sql_rollback (); - if (role_id_return) *role_id_return = role_id; - return 1; - } - - if (acl_role_can_super_everyone (role_id)) - { - sql_rollback (); - return 99; - } - - sql ("INSERT INTO role_users (role, \"user\") VALUES (%llu, %llu);", - role, - user); - - index++; - } - } - - cache_users = g_array_new (TRUE, TRUE, sizeof (user_t)); - g_array_append_val (cache_users, user); - cache_all_permissions_for_users (cache_users); - g_free (g_array_free (cache_users, TRUE)); - - sql_commit (); - - if (was_admin) - { - is_admin = acl_user_is_admin (uuid); - g_free (uuid); - if (is_admin) - return 0; - if (*name == NULL) - *name = sql_string ("SELECT name FROM users WHERE id = %llu", - user); - return 4; - } - - is_admin = acl_user_is_admin (uuid); - g_free (uuid); - if (is_admin) - { - if (*name == NULL) - *name = sql_string ("SELECT name FROM users WHERE id = %llu", - user); - return 3; - } - - return 0; -} - /** * @brief Filter columns for vuln iterator. */ diff --git a/src/manage_sql_users.c b/src/manage_sql_users.c index f7f5811c1..d40efe55e 100644 --- a/src/manage_sql_users.c +++ b/src/manage_sql_users.c @@ -1625,3 +1625,438 @@ delete_user (const char *user_id_arg, const char *name_arg, sql_commit (); return 0; } + +/** + * @brief Create a user from an existing user. + * + * @param[in] name Name of new user. NULL to copy from existing. + * @param[in] comment Comment on new user. NULL to copy from existing. + * @param[in] user_id UUID of existing user. + * @param[out] new_user New user. + * + * @return 0 success, 1 user exists already, 2 failed to find existing + * user, 99 permission denied, -1 error. + */ +int +copy_user (const char* name, const char* comment, const char *user_id, + user_t* new_user) +{ + user_t user; + int ret; + gchar *quoted_uuid; + GArray *cache_users; + char *uuid; + + if (acl_user_can_super_everyone (user_id)) + return 99; + + sql_begin_immediate (); + + ret = copy_resource_lock ("user", name, comment, user_id, + "password, timezone, hosts, hosts_allow, method", + 1, &user, NULL); + if (ret) + { + sql_rollback (); + return ret; + } + + sql ("UPDATE users SET password = NULL WHERE id = %llu;", user); + + quoted_uuid = sql_quote (user_id); + + sql ("INSERT INTO group_users (\"user\", \"group\")" + " SELECT %llu, \"group\" FROM group_users" + " WHERE \"user\" = (SELECT id FROM users WHERE uuid = '%s');", + user, + quoted_uuid); + + sql ("INSERT INTO role_users (\"user\", role)" + " SELECT %llu, role FROM role_users" + " WHERE \"user\" = (SELECT id FROM users WHERE uuid = '%s');", + user, + quoted_uuid); + + g_free (quoted_uuid); + + /* Ensure the user can see themself. */ + + uuid = user_uuid (user); + if (uuid == NULL) + { + g_warning ("%s: Failed to allocate UUID", __func__); + sql_rollback (); + return -1; + } + + create_permission_internal (1, + "GET_USERS", + "Automatically created when adding user", + NULL, + uuid, + "user", + uuid, + NULL); + + free (uuid); + + /* Cache permissions. */ + + cache_users = g_array_new (TRUE, TRUE, sizeof (user_t)); + g_array_append_val (cache_users, user); + cache_all_permissions_for_users (cache_users); + g_free (g_array_free (cache_users, TRUE)); + + sql_commit (); + + if (new_user) + *new_user = user; + + return ret; +} + +/** + * @brief Modify a user. + * + * @param[in] user_id The UUID of the user. Overrides name. + * @param[in] name The name of the user. If NULL then set to name + * when return is 3 or 4. + * @param[in] new_name New name for the user. NULL to leave as is. + * @param[in] password The password of the user. NULL to leave as is. + * @param[in] comment The comment for the user. NULL to leave as is. + * @param[in] hosts The host the user is allowed/forbidden to scan. + * NULL to leave as is. + * @param[in] hosts_allow Whether hosts is allow or forbid. + * @param[in] allowed_methods Allowed login methods. + * @param[in] groups Groups. + * @param[out] group_id_return ID of group on "failed to find" error. + * @param[in] roles Roles. + * @param[out] role_id_return ID of role on "failed to find" error. + * @param[out] r_errdesc If not NULL the address of a variable to receive + * a malloced string with the error description. Will + * always be set to NULL on success. + * + * @return 0 if the user has been added successfully, 1 failed to find group, + * 2 failed to find user, 3 success and user gained admin, 4 success + * and user lost admin, 5 failed to find role, 6 syntax error in hosts, + * 7 syntax error in new name, 99 permission denied, -1 on error, + * -2 for an unknown role, -3 if wrong number of methods, -4 error in + * method. + */ +int +modify_user (const gchar * user_id, gchar **name, const gchar *new_name, + const gchar * password, const gchar * comment, + const gchar * hosts, int hosts_allow, + const array_t * allowed_methods, array_t *groups, + gchar **group_id_return, array_t *roles, gchar **role_id_return, + gchar **r_errdesc) +{ + char *errstr; + gchar *hash, *quoted_hosts, *quoted_method, *clean, *uuid; + gchar *quoted_new_name, *quoted_comment; + user_t user; + int max, was_admin, is_admin; + GArray *cache_users; + + if (r_errdesc) + *r_errdesc = NULL; + + /* allowed_methods is a NULL terminated array. */ + if (allowed_methods && (allowed_methods->len > 2)) + return -3; + + if (allowed_methods && (allowed_methods->len <= 1)) + allowed_methods = NULL; + + if (allowed_methods + && (strlen (g_ptr_array_index (allowed_methods, 0)) == 0)) + allowed_methods = NULL; + + if (allowed_methods + && (auth_method_name_valid (g_ptr_array_index (allowed_methods, 0)) + == 0)) + return -4; + + sql_begin_immediate (); + + if (acl_user_may ("modify_user") == 0) + { + sql_rollback (); + return 99; + } + + user = 0; + if (user_id) + { + if (find_user_with_permission (user_id, &user, "modify_user")) + { + sql_rollback (); + return -1; + } + } + else if (find_user_by_name_with_permission (*name, &user, "modify_user")) + { + sql_rollback (); + return -1; + } + if (user == 0) + { + sql_rollback (); + return 2; + } + + uuid = sql_string ("SELECT uuid FROM users WHERE id = %llu", + user); + + /* The only user that can edit a Super Admin is the Super Admin themself. */ + if (acl_user_can_super_everyone (uuid) && strcmp (uuid, current_credentials.uuid)) + { + g_free (uuid); + sql_rollback (); + return 99; + } + + was_admin = acl_user_is_admin (uuid); + + if (password) + { + char *user_name; + + user_name = sql_string ("SELECT name FROM users WHERE id = %llu", + user); + errstr = gvm_validate_password (password, user_name); + if (errstr) + { + g_warning ("new password for '%s' rejected: %s", user_name, errstr); + if (r_errdesc) + *r_errdesc = errstr; + else + g_free (errstr); + sql_rollback (); + g_free (user_name); + return -1; + } + g_free (user_name); + } + + /* Check hosts. */ + + max = manage_max_hosts (); + manage_set_max_hosts (MANAGE_USER_MAX_HOSTS); + if (hosts && (manage_count_hosts (hosts, NULL) < 0)) + { + manage_set_max_hosts (max); + sql_rollback (); + return 6; + } + manage_set_max_hosts (max); + + /* Check new name. */ + + if (new_name) + { + if (validate_username (new_name) != 0) + { + sql_rollback (); + return 7; + } + + if (strcmp (uuid, current_credentials.uuid) == 0) + { + sql_rollback (); + return 99; + } + + if (resource_with_name_exists_global (new_name, "user", user)) + { + sql_rollback (); + return 8; + } + quoted_new_name = sql_quote (new_name); + } + else + quoted_new_name = NULL; + + /* Get the password hashes. */ + + if (password) + hash = manage_authentication_hash (password); + else + hash = NULL; + + if (comment) + { + quoted_comment = sql_quote (comment); + } + else + { + quoted_comment = NULL; + } + + + /* Update the user in the database. */ + + clean = clean_hosts (hosts ? hosts : "", &max); + if ((hosts_allow == 0) && (max == 0)) + /* Convert "Deny none" to "Allow All". */ + hosts_allow = 2; + quoted_hosts = sql_quote (clean); + g_free (clean); + quoted_method = sql_quote (allowed_methods + ? g_ptr_array_index (allowed_methods, 0) + : ""); + sql ("UPDATE users" + " SET name = %s%s%s," + " comment = %s%s%s," + " hosts = '%s'," + " hosts_allow = '%i'," + " method = %s%s%s," + " modification_time = m_now ()" + " WHERE id = %llu;", + quoted_new_name ? "'" : "", + quoted_new_name ? quoted_new_name : "name", + quoted_new_name ? "'" : "", + quoted_comment ? "'" : "", + quoted_comment ? quoted_comment : "comment", + quoted_comment ? "'" : "", + quoted_hosts, + hosts_allow, + allowed_methods ? "'" : "", + allowed_methods ? quoted_method : "method", + allowed_methods ? "'" : "", + user); + g_free (quoted_new_name); + g_free (quoted_hosts); + g_free (quoted_method); + if (hash) + sql ("UPDATE users" + " SET password = '%s'" + " WHERE id = %llu;", + hash, + user); + g_free (hash); + + /* Update the user groups. */ + + if (groups) + { + int index; + + sql ("DELETE FROM group_users WHERE \"user\" = %llu;", user); + index = 0; + while (groups && (index < groups->len)) + { + gchar *group_id; + group_t group; + + group_id = (gchar*) g_ptr_array_index (groups, index); + if (strcmp (group_id, "0") == 0) + { + index++; + continue; + } + + if (find_group_with_permission (group_id, &group, "modify_group")) + { + sql_rollback (); + return -1; + } + + if (group == 0) + { + sql_rollback (); + if (group_id_return) *group_id_return = group_id; + return 1; + } + + sql ("INSERT INTO group_users (\"group\", \"user\")" + " VALUES (%llu, %llu);", + group, + user); + + index++; + } + } + + /* Update the user roles. */ + + if (roles) + { + int index; + + sql ("DELETE FROM role_users" + " WHERE \"user\" = %llu" + " AND role != (SELECT id from roles" + " WHERE uuid = '" ROLE_UUID_SUPER_ADMIN "');", + user); + index = 0; + while (roles && (index < roles->len)) + { + gchar *role_id; + role_t role; + + role_id = (gchar*) g_ptr_array_index (roles, index); + if (strcmp (role_id, "0") == 0) + { + index++; + continue; + } + + if (find_role_with_permission (role_id, &role, "get_roles")) + { + sql_rollback (); + return -1; + } + + if (role == 0) + { + sql_rollback (); + if (role_id_return) *role_id_return = role_id; + return 1; + } + + if (acl_role_can_super_everyone (role_id)) + { + sql_rollback (); + return 99; + } + + sql ("INSERT INTO role_users (role, \"user\") VALUES (%llu, %llu);", + role, + user); + + index++; + } + } + + cache_users = g_array_new (TRUE, TRUE, sizeof (user_t)); + g_array_append_val (cache_users, user); + cache_all_permissions_for_users (cache_users); + g_free (g_array_free (cache_users, TRUE)); + + sql_commit (); + + if (was_admin) + { + is_admin = acl_user_is_admin (uuid); + g_free (uuid); + if (is_admin) + return 0; + if (*name == NULL) + *name = sql_string ("SELECT name FROM users WHERE id = %llu", + user); + return 4; + } + + is_admin = acl_user_is_admin (uuid); + g_free (uuid); + if (is_admin) + { + if (*name == NULL) + *name = sql_string ("SELECT name FROM users WHERE id = %llu", + user); + return 3; + } + + return 0; +} diff --git a/src/manage_users.h b/src/manage_users.h index 30974e777..4ee3f8024 100644 --- a/src/manage_users.h +++ b/src/manage_users.h @@ -80,4 +80,13 @@ create_user (const gchar *, const gchar *, const gchar *, const gchar *, int delete_user (const char *, const char *, int, const char *, const char *); +int +copy_user (const char *, const char *, const char *, user_t *); + +int +modify_user (const gchar *, gchar **, const gchar *, const gchar *, + const gchar *, const gchar *, int, + const array_t *, array_t *, gchar **, array_t *, gchar **, + gchar **); + #endif /* not _GVMD_MANAGE_USERS_H */ From f422f7069649332791a60591bfc7b089eb536a65 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Fri, 16 Jan 2026 14:50:42 +0200 Subject: [PATCH 2/4] Change: move the user option handlers to dedicated users files --- src/gvmd.c | 1 + src/manage.h | 15 -- src/manage_sql.c | 343 +---------------------------------------- src/manage_sql_users.c | 338 ++++++++++++++++++++++++++++++++++++++++ src/manage_sql_users.h | 3 + src/manage_users.h | 16 ++ 6 files changed, 359 insertions(+), 357 deletions(-) diff --git a/src/gvmd.c b/src/gvmd.c index 5faf0e330..eff55852f 100644 --- a/src/gvmd.c +++ b/src/gvmd.c @@ -97,6 +97,7 @@ #include "manage_runtime_flags.h" #include "manage_roles.h" #include "manage_scan_queue.h" +#include "manage_users.h" #include "gmpd.h" #include "utils.h" diff --git a/src/manage.h b/src/manage.h index a18b4f359..e8407083f 100644 --- a/src/manage.h +++ b/src/manage.h @@ -3193,21 +3193,6 @@ manage_default_ca_cert (); /* Users. */ -int -manage_create_user (GSList *, const db_conn_info_t *, const gchar *, - const gchar *, const gchar *); - -int -manage_delete_user (GSList *, const db_conn_info_t *, const gchar *, - const gchar *); - -int -manage_get_users (GSList *, const db_conn_info_t *, const gchar *, int); - -int -manage_set_password (GSList *, const db_conn_info_t *, const gchar *, - const gchar *); - gchar * manage_user_hash (const gchar *); diff --git a/src/manage_sql.c b/src/manage_sql.c index 3ee63ff28..e1f691134 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -210,9 +210,6 @@ task_owner_uuid (task_t); static int user_ensure_in_db (const gchar *, const gchar *); -static int -set_password (const gchar *, const gchar *, const gchar *, gchar **); - static resource_t permission_resource (permission_t); @@ -37832,345 +37829,7 @@ manage_default_ca_cert () } -/* Users. */ - -/** - * @brief Create the given user. - * - * @param[in] log_config Log configuration. - * @param[in] database Location of manage database. - * @param[in] name Name of user. - * @param[in] password Password for user. Autogenerated if NULL. - * @param[in] role_name Role of user. Admin if NULL. - * - * @return 0 success, -1 error, - * -2 database is too old, -3 database needs to be initialised - * from server, -5 database is too new. - */ -int -manage_create_user (GSList *log_config, const db_conn_info_t *database, - const gchar *name, const gchar *password, - const gchar *role_name) -{ - char *uuid; - array_t *roles; - int ret; - gchar *rejection_msg; - - g_info (" Creating user."); - - ret = manage_option_setup (log_config, database, - 0 /* avoid_db_check_inserts */); - if (ret) - return ret; - - roles = make_array (); - if (role_name) - { - role_t role; - if (find_role_by_name (role_name, &role)) - { - array_free (roles); - fprintf (stderr, "Internal Error.\n"); - manage_option_cleanup (); - return -1; - } - if (role == 0) - { - array_free (roles); - fprintf (stderr, "Failed to find role.\n"); - manage_option_cleanup (); - return -1; - } - array_add (roles, role_uuid (role)); - } - else - array_add (roles, g_strdup (ROLE_UUID_ADMIN)); - - if (password) - uuid = NULL; - else - uuid = gvm_uuid_make (); - - /* Setup a dummy user, so that create_user will work. */ - current_credentials.uuid = ""; - - ret = create_user (name, password ? password : uuid, "", NULL, 0, - NULL, NULL, NULL, roles, NULL, &rejection_msg, NULL, 0); - - switch (ret) - { - case 0: - if (password) - printf ("User created.\n"); - else - printf ("User created with password '%s'.\n", uuid); - break; - case -2: - fprintf (stderr, "User exists already.\n"); - break; - default: - if (rejection_msg) - { - fprintf (stderr, "Failed to create user: %s\n", rejection_msg); - } - else - fprintf (stderr, "Failed to create user.\n"); - break; - } - - current_credentials.uuid = NULL; - g_free (rejection_msg); - - array_free (roles); - free (uuid); - - manage_option_cleanup (); - - return ret; -} - -/** - * @brief Delete the given user. - * - * @param[in] log_config Log configuration. - * @param[in] database Location of manage database. - * @param[in] name Name of user. - * @param[in] inheritor_name Name of user that inherits user's resources. - * - * @return 0 success, 2 failed to find user, 4 user has active tasks, -1 error. - * -2 database is too old, -3 database needs to be initialised - * from server, -5 database is too new. - */ -int -manage_delete_user (GSList *log_config, const db_conn_info_t *database, - const gchar *name, const gchar *inheritor_name) -{ - int ret; - - g_info (" Deleting user."); - - ret = manage_option_setup (log_config, database, - 0 /* avoid_db_check_inserts */); - if (ret) - return ret; - - /* Setup a dummy user, so that delete_user will work. */ - current_credentials.uuid = ""; - - switch ((ret = delete_user (NULL, name, 0, NULL, inheritor_name))) - { - case 0: - printf ("User deleted.\n"); - break; - case 2: - fprintf (stderr, "Failed to find user.\n"); - break; - case 4: - fprintf (stderr, "User has active tasks.\n"); - break; - case 6: - fprintf (stderr, "Inheritor not found.\n"); - break; - case 7: - fprintf (stderr, "Inheritor same as deleted user.\n"); - break; - case 8: - fprintf (stderr, "Invalid inheritor.\n"); - break; - case 9: - fprintf (stderr, - "Resources owned by the user are still in use by others.\n"); - break; - case 10: - fprintf (stderr, "User is Feed Import Owner.\n"); - break; - default: - fprintf (stderr, "Internal Error.\n"); - break; - } - - current_credentials.uuid = NULL; - - manage_option_cleanup (); - - return ret; -} - -/** - * @brief List users. - * - * @param[in] log_config Log configuration. - * @param[in] database Location of manage database. - * @param[in] role_name Role name. - * @param[in] verbose Whether to print UUID. - * - * @return 0 success, -1 error. - */ -int -manage_get_users (GSList *log_config, const db_conn_info_t *database, - const gchar* role_name, int verbose) -{ - iterator_t users; - int ret; - - g_info (" Getting users."); - - ret = manage_option_setup (log_config, database, - 0 /* avoid_db_check_inserts */); - if (ret) - return ret; - - if (role_name) - { - role_t role; - if (find_role_by_name (role_name, &role)) - { - fprintf (stderr, "Internal Error.\n"); - manage_option_cleanup (); - return -1; - } - if (role == 0) - { - fprintf (stderr, "Failed to find role.\n"); - manage_option_cleanup (); - return -1; - } - init_iterator (&users, - "SELECT name, uuid FROM users" - " WHERE id IN (SELECT \"user\" FROM role_users" - " WHERE role = %llu);", - role); - } - else - init_iterator (&users, "SELECT name, uuid FROM users;"); - while (next (&users)) - if (verbose) - printf ("%s %s\n", iterator_string (&users, 0), iterator_string (&users, 1)); - else - printf ("%s\n", iterator_string (&users, 0)); - - cleanup_iterator (&users); - - manage_option_cleanup (); - - return 0; -} - -/** - * @brief Set the password of a user. - * - * @param[in] name Name of user. - * @param[in] uuid User UUID. - * @param[in] password New password. - * @param[out] r_errdesc Address to receive a malloced string with the error - * description, or NULL. - * - * @return 0 success, -1 error. - */ -static int -set_password (const gchar *name, const gchar *uuid, const gchar *password, - gchar **r_errdesc) -{ - gchar *errstr, *hash; - - assert (name && uuid); - - if ((errstr = gvm_validate_password (password, name))) - { - g_warning ("new password for '%s' rejected: %s", name, errstr); - if (r_errdesc) - *r_errdesc = errstr; - else - g_free (errstr); - return -1; - } - hash = manage_authentication_hash (password); - sql ("UPDATE users SET password = '%s', modification_time = m_now ()" - " WHERE uuid = '%s';", - hash, - uuid); - g_free (hash); - return 0; -} - -/** - * @brief Set the password of a user. - * - * @param[in] log_config Log configuration. - * @param[in] database Location of manage database. - * @param[in] name Name of user. - * @param[in] password New password. - * - * @return 0 success, -1 error. - */ -int -manage_set_password (GSList *log_config, const db_conn_info_t *database, - const gchar *name, const gchar *password) -{ - user_t user; - char *uuid; - int ret; - gchar *rejection_msg; - - g_info (" Modifying user password."); - - if (name == NULL) - { - fprintf (stderr, "--user required.\n"); - return -1; - } - - ret = manage_option_setup (log_config, database, - 0 /* avoid_db_check_inserts */); - if (ret) - return ret; - - sql_begin_immediate (); - - if (find_user_by_name (name, &user)) - { - fprintf (stderr, "Internal error.\n"); - goto fail; - } - - if (user == 0) - { - fprintf (stderr, "Failed to find user.\n"); - goto fail; - } - - uuid = user_uuid (user); - if (uuid == NULL) - { - fprintf (stderr, "Failed to allocate UUID.\n"); - goto fail; - } - - rejection_msg = NULL; - if (set_password (name, uuid, password, &rejection_msg)) - { - if (rejection_msg) - { - fprintf (stderr, "New password rejected: %s\n", rejection_msg); - g_free (rejection_msg); - } - else - fprintf (stderr, "New password rejected.\n"); - free (uuid); - goto fail; - } - - sql_commit (); - free (uuid); - manage_option_cleanup (); - return ret; - - fail: - sql_rollback (); - manage_option_cleanup (); - return -1; -} +/* Vulns. */ /** * @brief Filter columns for vuln iterator. diff --git a/src/manage_sql_users.c b/src/manage_sql_users.c index d40efe55e..36e5c3533 100644 --- a/src/manage_sql_users.c +++ b/src/manage_sql_users.c @@ -2060,3 +2060,341 @@ modify_user (const gchar * user_id, gchar **name, const gchar *new_name, return 0; } + +/** + * @brief Create the given user. + * + * @param[in] log_config Log configuration. + * @param[in] database Location of manage database. + * @param[in] name Name of user. + * @param[in] password Password for user. Autogenerated if NULL. + * @param[in] role_name Role of user. Admin if NULL. + * + * @return 0 success, -1 error, + * -2 database is too old, -3 database needs to be initialised + * from server, -5 database is too new. + */ +int +manage_create_user (GSList *log_config, const db_conn_info_t *database, + const gchar *name, const gchar *password, + const gchar *role_name) +{ + char *uuid; + array_t *roles; + int ret; + gchar *rejection_msg; + + g_info (" Creating user."); + + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); + if (ret) + return ret; + + roles = make_array (); + if (role_name) + { + role_t role; + if (find_role_by_name (role_name, &role)) + { + array_free (roles); + fprintf (stderr, "Internal Error.\n"); + manage_option_cleanup (); + return -1; + } + if (role == 0) + { + array_free (roles); + fprintf (stderr, "Failed to find role.\n"); + manage_option_cleanup (); + return -1; + } + array_add (roles, role_uuid (role)); + } + else + array_add (roles, g_strdup (ROLE_UUID_ADMIN)); + + if (password) + uuid = NULL; + else + uuid = gvm_uuid_make (); + + /* Setup a dummy user, so that create_user will work. */ + current_credentials.uuid = ""; + + ret = create_user (name, password ? password : uuid, "", NULL, 0, + NULL, NULL, NULL, roles, NULL, &rejection_msg, NULL, 0); + + switch (ret) + { + case 0: + if (password) + printf ("User created.\n"); + else + printf ("User created with password '%s'.\n", uuid); + break; + case -2: + fprintf (stderr, "User exists already.\n"); + break; + default: + if (rejection_msg) + { + fprintf (stderr, "Failed to create user: %s\n", rejection_msg); + } + else + fprintf (stderr, "Failed to create user.\n"); + break; + } + + current_credentials.uuid = NULL; + g_free (rejection_msg); + + array_free (roles); + free (uuid); + + manage_option_cleanup (); + + return ret; +} + +/** + * @brief Delete the given user. + * + * @param[in] log_config Log configuration. + * @param[in] database Location of manage database. + * @param[in] name Name of user. + * @param[in] inheritor_name Name of user that inherits user's resources. + * + * @return 0 success, 2 failed to find user, 4 user has active tasks, -1 error. + * -2 database is too old, -3 database needs to be initialised + * from server, -5 database is too new. + */ +int +manage_delete_user (GSList *log_config, const db_conn_info_t *database, + const gchar *name, const gchar *inheritor_name) +{ + int ret; + + g_info (" Deleting user."); + + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); + if (ret) + return ret; + + /* Setup a dummy user, so that delete_user will work. */ + current_credentials.uuid = ""; + + switch ((ret = delete_user (NULL, name, 0, NULL, inheritor_name))) + { + case 0: + printf ("User deleted.\n"); + break; + case 2: + fprintf (stderr, "Failed to find user.\n"); + break; + case 4: + fprintf (stderr, "User has active tasks.\n"); + break; + case 6: + fprintf (stderr, "Inheritor not found.\n"); + break; + case 7: + fprintf (stderr, "Inheritor same as deleted user.\n"); + break; + case 8: + fprintf (stderr, "Invalid inheritor.\n"); + break; + case 9: + fprintf (stderr, + "Resources owned by the user are still in use by others.\n"); + break; + case 10: + fprintf (stderr, "User is Feed Import Owner.\n"); + break; + default: + fprintf (stderr, "Internal Error.\n"); + break; + } + + current_credentials.uuid = NULL; + + manage_option_cleanup (); + + return ret; +} + +/** + * @brief List users. + * + * @param[in] log_config Log configuration. + * @param[in] database Location of manage database. + * @param[in] role_name Role name. + * @param[in] verbose Whether to print UUID. + * + * @return 0 success, -1 error. + */ +int +manage_get_users (GSList *log_config, const db_conn_info_t *database, + const gchar* role_name, int verbose) +{ + iterator_t users; + int ret; + + g_info (" Getting users."); + + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); + if (ret) + return ret; + + if (role_name) + { + role_t role; + if (find_role_by_name (role_name, &role)) + { + fprintf (stderr, "Internal Error.\n"); + manage_option_cleanup (); + return -1; + } + if (role == 0) + { + fprintf (stderr, "Failed to find role.\n"); + manage_option_cleanup (); + return -1; + } + init_iterator (&users, + "SELECT name, uuid FROM users" + " WHERE id IN (SELECT \"user\" FROM role_users" + " WHERE role = %llu);", + role); + } + else + init_iterator (&users, "SELECT name, uuid FROM users;"); + while (next (&users)) + if (verbose) + printf ("%s %s\n", iterator_string (&users, 0), iterator_string (&users, 1)); + else + printf ("%s\n", iterator_string (&users, 0)); + + cleanup_iterator (&users); + + manage_option_cleanup (); + + return 0; +} + +/** + * @brief Set the password of a user. + * + * @param[in] name Name of user. + * @param[in] uuid User UUID. + * @param[in] password New password. + * @param[out] r_errdesc Address to receive a malloced string with the error + * description, or NULL. + * + * @return 0 success, -1 error. + */ +int +set_password (const gchar *name, const gchar *uuid, const gchar *password, + gchar **r_errdesc) +{ + gchar *errstr, *hash; + + assert (name && uuid); + + if ((errstr = gvm_validate_password (password, name))) + { + g_warning ("new password for '%s' rejected: %s", name, errstr); + if (r_errdesc) + *r_errdesc = errstr; + else + g_free (errstr); + return -1; + } + hash = manage_authentication_hash (password); + sql ("UPDATE users SET password = '%s', modification_time = m_now ()" + " WHERE uuid = '%s';", + hash, + uuid); + g_free (hash); + return 0; +} + +/** + * @brief Set the password of a user. + * + * @param[in] log_config Log configuration. + * @param[in] database Location of manage database. + * @param[in] name Name of user. + * @param[in] password New password. + * + * @return 0 success, -1 error. + */ +int +manage_set_password (GSList *log_config, const db_conn_info_t *database, + const gchar *name, const gchar *password) +{ + user_t user; + char *uuid; + int ret; + gchar *rejection_msg; + + g_info (" Modifying user password."); + + if (name == NULL) + { + fprintf (stderr, "--user required.\n"); + return -1; + } + + ret = manage_option_setup (log_config, database, + 0 /* avoid_db_check_inserts */); + if (ret) + return ret; + + sql_begin_immediate (); + + if (find_user_by_name (name, &user)) + { + fprintf (stderr, "Internal error.\n"); + goto fail; + } + + if (user == 0) + { + fprintf (stderr, "Failed to find user.\n"); + goto fail; + } + + uuid = user_uuid (user); + if (uuid == NULL) + { + fprintf (stderr, "Failed to allocate UUID.\n"); + goto fail; + } + + rejection_msg = NULL; + if (set_password (name, uuid, password, &rejection_msg)) + { + if (rejection_msg) + { + fprintf (stderr, "New password rejected: %s\n", rejection_msg); + g_free (rejection_msg); + } + else + fprintf (stderr, "New password rejected.\n"); + free (uuid); + goto fail; + } + + sql_commit (); + free (uuid); + manage_option_cleanup (); + return ret; + + fail: + sql_rollback (); + manage_option_cleanup (); + return -1; +} diff --git a/src/manage_sql_users.h b/src/manage_sql_users.h index 6f1ae06a8..2cedb246b 100644 --- a/src/manage_sql_users.h +++ b/src/manage_sql_users.h @@ -85,6 +85,9 @@ user_uuid_any_method (const gchar *); int add_users (const gchar *, resource_t, const char *); +int +set_password (const gchar *, const gchar *, const gchar *, gchar **); + /* Defined in manage_users.c, but internal to libmanage. */ int diff --git a/src/manage_users.h b/src/manage_users.h index 4ee3f8024..11bea2e1e 100644 --- a/src/manage_users.h +++ b/src/manage_users.h @@ -8,6 +8,7 @@ #include "manage_get.h" #include "manage_resources.h" +#include "sql.h" // Sadly, for db_conn_info_t gchar * user_name (const char *); @@ -89,4 +90,19 @@ modify_user (const gchar *, gchar **, const gchar *, const gchar *, const array_t *, array_t *, gchar **, array_t *, gchar **, gchar **); +int +manage_create_user (GSList *, const db_conn_info_t *, const gchar *, + const gchar *, const gchar *); + +int +manage_delete_user (GSList *, const db_conn_info_t *, const gchar *, + const gchar *); + +int +manage_get_users (GSList *, const db_conn_info_t *, const gchar *, int); + +int +manage_set_password (GSList *, const db_conn_info_t *, const gchar *, + const gchar *); + #endif /* not _GVMD_MANAGE_USERS_H */ From 9f68c9b24d194f3d5af68dc853332132729c6af9 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Fri, 16 Jan 2026 14:56:17 +0200 Subject: [PATCH 3/4] Fix: remove stray headers from Users section keyfile_to_auth_conf_settings_xml was removed in a011b88538abba5f5860d530f33599d9e9901c3d in 2015. --- src/manage.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/manage.h b/src/manage.h index e8407083f..38ab31cab 100644 --- a/src/manage.h +++ b/src/manage.h @@ -3196,12 +3196,6 @@ manage_default_ca_cert (); gchar * manage_user_hash (const gchar *); -int -copy_user (const char*, const char*, const char*, user_t*); - -gchar * -keyfile_to_auth_conf_settings_xml (const gchar *); - int user_count (const get_data_t*); From fa7513d53d04e2d1d410fe179dc88ded461f90e3 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Fri, 16 Jan 2026 15:01:16 +0200 Subject: [PATCH 4/4] Change: clear last of Users section from header --- src/manage.h | 8 +------- src/manage_sql.c | 2 +- src/manage_users.h | 3 +++ 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/manage.h b/src/manage.h index 38ab31cab..926bd1555 100644 --- a/src/manage.h +++ b/src/manage.h @@ -3191,13 +3191,7 @@ char * manage_default_ca_cert (); -/* Users. */ - -gchar * -manage_user_hash (const gchar *); - -int -user_count (const get_data_t*); +/* Vulns. */ int init_vuln_iterator (iterator_t*, const get_data_t*); diff --git a/src/manage_sql.c b/src/manage_sql.c index e1f691134..9d8a506a6 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -5640,7 +5640,7 @@ manage_reset_currents () * * @return Hash. */ -gchar * +static gchar * manage_user_hash (const gchar *username) { gchar *hash, *quoted_username; diff --git a/src/manage_users.h b/src/manage_users.h index 11bea2e1e..defb9318c 100644 --- a/src/manage_users.h +++ b/src/manage_users.h @@ -34,6 +34,9 @@ user_hosts (const char *); int user_hosts_allow (const char *); +int +user_count (const get_data_t *); + int init_user_iterator (iterator_t *, get_data_t *);