Commit 229a7728 authored by Philip Withnall's avatar Philip Withnall Committed by Ray Strode

util: Split out helper method for getting admin group IDs

This introduces one small functional change: if any of the groups in
`EXTRA_ADMIN_GROUPS` can’t be resolved using `getgrnam()`, an error will
now be thrown. Previously, it would be ignored.

Other than that, this introduces no functional changes and is just
intended as a code cleanup.
Signed-off-by: Philip Withnall's avatarPhilip Withnall <withnall@endlessm.com>
parent dfecf170
Pipeline #141661 passed with stage
in 1 minute and 9 seconds
......@@ -1687,7 +1687,6 @@ user_change_account_type_authorized_cb (Daemon *daemon,
g_autofree gid_t *extra_admin_groups_gids = NULL;
gsize n_extra_admin_groups_gids = 0;
gid_t admin_gid;
struct group *grp;
gint i;
const gchar *argv[6];
......@@ -1698,25 +1697,10 @@ user_change_account_type_authorized_cb (Daemon *daemon,
accounts_user_get_uid (ACCOUNTS_USER (user)),
account_type);
grp = getgrnam (ADMIN_GROUP);
if (grp == NULL) {
if (!get_admin_groups (&admin_gid, &extra_admin_groups_gids, &n_extra_admin_groups_gids)) {
throw_error (context, ERROR_FAILED, "failed to set account type: " ADMIN_GROUP " group not found");
return;
}
admin_gid = grp->gr_gid;
extra_admin_groups = g_strsplit (EXTRA_ADMIN_GROUPS, ",", 0);
n_extra_admin_groups_gids = 0;
extra_admin_groups_gids = g_new0 (gid_t, g_strv_length (extra_admin_groups));
for (i = 0; extra_admin_groups[i] != NULL; i++) {
struct group *extra_group;
extra_group = getgrnam (extra_admin_groups[i]);
if (extra_group == NULL || extra_group->gr_gid == admin_gid)
continue;
extra_admin_groups_gids[n_extra_admin_groups_gids++] = extra_group->gr_gid;
}
ngroups = get_user_groups (accounts_user_get_user_name (ACCOUNTS_USER (user)), user->gid, &groups);
......
......@@ -257,6 +257,77 @@ get_user_groups (const gchar *user,
return res;
}
/**
* get_admin_groups:
* @admin_gid_out: (out caller-allocates) (optional): return location for the ID
* of the main admin group
* @groups_out: (out callee-allocates) (transfer container) (optional) (length=n_groups_out):
* return location for an array of the extra admin group IDs
* @n_groups_out: (out caller-allocates) (optional): return location for the
* number of elements in @group_out
*
* Get the GIDs of the admin groups on the system, as set at configure time for
* accountsservice. The main admin group ID (typically for the `sudo` or `wheel`
* group) will be returned in @admin_gid_out. Any group IDs for other admin
* groups (such as `lpadmin` or `systemd-journal`) will be returned in
* @groups_out, which should be freed by the caller using g_free().
*
* Returns: %TRUE on success, %FALSE if one or more of the groups could not be
* looked up
*/
gboolean
get_admin_groups (gid_t *admin_gid_out,
gid_t **groups_out,
gsize *n_groups_out)
{
g_auto(GStrv) extra_admin_groups = NULL;
g_autofree gid_t *extra_admin_groups_gids = NULL;
gsize n_extra_admin_groups_gids = 0;
gsize i;
gboolean retval = FALSE;
struct group *grp;
gid_t admin_gid = 0;
/* Get the main admin group ID. */
grp = getgrnam (ADMIN_GROUP);
if (grp == NULL)
goto out;
admin_gid = grp->gr_gid;
/* Get the extra admin group IDs. */
extra_admin_groups = g_strsplit (EXTRA_ADMIN_GROUPS, ",", 0);
n_extra_admin_groups_gids = 0;
extra_admin_groups_gids = g_new0 (gid_t, g_strv_length (extra_admin_groups));
for (i = 0; extra_admin_groups[i] != NULL; i++) {
struct group *extra_group;
extra_group = getgrnam (extra_admin_groups[i]);
if (extra_group == NULL)
goto out;
if (extra_group->gr_gid == admin_gid)
continue;
extra_admin_groups_gids[n_extra_admin_groups_gids++] = extra_group->gr_gid;
}
retval = TRUE;
out:
if (!retval) {
admin_gid = 0;
g_clear_pointer (&extra_admin_groups_gids, g_free);
n_extra_admin_groups_gids = 0;
}
if (admin_gid_out != NULL)
*admin_gid_out = admin_gid;
if (groups_out != NULL)
*groups_out = g_steal_pointer (&extra_admin_groups_gids);
if (n_groups_out != NULL)
*n_groups_out = n_extra_admin_groups_gids;
return retval;
}
gboolean
get_caller_uid (GDBusMethodInvocation *context,
......
......@@ -36,6 +36,10 @@ gboolean spawn_with_login_uid (GDBusMethodInvocation *context,
const gchar *argv[],
GError **error);
gboolean get_admin_groups (gid_t *admin_gid_out,
gid_t **groups_out,
gsize *n_groups_out);
gint get_user_groups (const gchar *username,
gid_t group,
gid_t **groups);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment