/* * Copyright (C) 2008 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. * * Author: David Zeuthen */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include "polkitunixgroup.h" #include "polkitidentity.h" #include "polkiterror.h" #include "polkitprivate.h" /** * SECTION:polkitunixgroup * @title: PolkitUnixGroup * @short_description: Unix groups * * An object representing a group identity on a UNIX system. */ /** * PolkitUnixGroup: * * The #PolkitUnixGroup struct should not be accessed directly. */ struct _PolkitUnixGroup { GObject parent_instance; gint gid; }; struct _PolkitUnixGroupClass { GObjectClass parent_class; }; enum { PROP_0, PROP_GID, }; static void identity_iface_init (PolkitIdentityIface *identity_iface); G_DEFINE_TYPE_WITH_CODE (PolkitUnixGroup, polkit_unix_group, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (POLKIT_TYPE_IDENTITY, identity_iface_init) ); static void polkit_unix_group_init (PolkitUnixGroup *unix_group) { unix_group->gid = -1; /* (gid_t) -1 is not a valid GID under Linux */ } static void polkit_unix_group_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { PolkitUnixGroup *unix_group = POLKIT_UNIX_GROUP (object); switch (prop_id) { case PROP_GID: g_value_set_int (value, unix_group->gid); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void polkit_unix_group_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { PolkitUnixGroup *unix_group = POLKIT_UNIX_GROUP (object); gint val; switch (prop_id) { case PROP_GID: val = g_value_get_int (value); g_return_if_fail (val != -1); unix_group->gid = val; break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void polkit_unix_group_class_init (PolkitUnixGroupClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->get_property = polkit_unix_group_get_property; gobject_class->set_property = polkit_unix_group_set_property; /** * PolkitUnixGroup:gid: * * The UNIX group id. */ g_object_class_install_property (gobject_class, PROP_GID, g_param_spec_int ("gid", "Group ID", "The UNIX group ID", G_MININT, G_MAXINT, -1, G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK)); } /** * polkit_unix_group_get_gid: * @group: A #PolkitUnixGroup. * * Gets the UNIX group id for @group. * * Returns: A UNIX group id. */ gint polkit_unix_group_get_gid (PolkitUnixGroup *group) { g_return_val_if_fail (POLKIT_IS_UNIX_GROUP (group), -1); return group->gid; } /** * polkit_unix_group_set_gid: * @group: A #PolkitUnixGroup. * @gid: A UNIX group id. * * Sets @gid for @group. */ void polkit_unix_group_set_gid (PolkitUnixGroup *group, gint gid) { g_return_if_fail (POLKIT_IS_UNIX_GROUP (group)); g_return_if_fail (gid != -1); group->gid = gid; } /** * polkit_unix_group_new: * @gid: A UNIX group id. * * Creates a new #PolkitUnixGroup object for @gid. * * Returns: (transfer full): A #PolkitUnixGroup object. Free with g_object_unref(). */ PolkitIdentity * polkit_unix_group_new (gint gid) { g_return_val_if_fail (gid != -1, NULL); return POLKIT_IDENTITY (g_object_new (POLKIT_TYPE_UNIX_GROUP, "gid", gid, NULL)); } /** * polkit_unix_group_new_for_name: * @name: A UNIX group name. * @error: Return location for error. * * Creates a new #PolkitUnixGroup object for a group with the group name * @name. * * Returns: (transfer full) (allow-none): A #PolkitUnixGroup object or %NULL if @error * is set. */ PolkitIdentity * polkit_unix_group_new_for_name (const gchar *name, GError **error) { struct group *group; PolkitIdentity *identity; g_return_val_if_fail (name != NULL, NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); identity = NULL; group = getgrnam (name); if (group == NULL) { g_set_error (error, POLKIT_ERROR, POLKIT_ERROR_FAILED, "No UNIX group with name %s: %s", name, g_strerror (errno)); goto out; } identity = polkit_unix_group_new (group->gr_gid); out: return identity; } static guint polkit_unix_group_hash (PolkitIdentity *identity) { PolkitUnixGroup *group; group = POLKIT_UNIX_GROUP (identity); return g_direct_hash (GINT_TO_POINTER (((gint) (group->gid)) * 2 + 1)); } static gboolean polkit_unix_group_equal (PolkitIdentity *a, PolkitIdentity *b) { PolkitUnixGroup *group_a; PolkitUnixGroup *group_b; group_a = POLKIT_UNIX_GROUP (a); group_b = POLKIT_UNIX_GROUP (b); return group_a->gid == group_b->gid; } static gchar * polkit_unix_group_to_string (PolkitIdentity *identity) { PolkitUnixGroup *group = POLKIT_UNIX_GROUP (identity); struct group *gr; gr = getgrgid (group->gid); if (gr == NULL) return g_strdup_printf ("unix-group:%d", group->gid); else return g_strdup_printf ("unix-group:%s", gr->gr_name); } static void identity_iface_init (PolkitIdentityIface *identity_iface) { identity_iface->hash = polkit_unix_group_hash; identity_iface->equal = polkit_unix_group_equal; identity_iface->to_string = polkit_unix_group_to_string; }