polkitunixgroup.c 7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/*
 * 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 <davidz@redhat.com>
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <string.h>
27
#include <grp.h>
28
#include <errno.h>
29
#include "polkitunixgroup.h"
30
#include "polkitidentity.h"
31
#include "polkiterror.h"
32 33 34 35 36 37 38
#include "polkitprivate.h"

/**
 * SECTION:polkitunixgroup
 * @title: PolkitUnixGroup
 * @short_description: Unix groups
 *
David Zeuthen's avatar
David Zeuthen committed
39
 * An object representing a group identity on a UNIX system.
40 41
 */

David Zeuthen's avatar
David Zeuthen committed
42 43 44 45 46
/**
 * PolkitUnixGroup:
 *
 * The #PolkitUnixGroup struct should not be accessed directly.
 */
47 48 49 50
struct _PolkitUnixGroup
{
  GObject parent_instance;

51
  gint gid;
52 53 54 55 56 57 58 59 60 61 62 63 64
};

struct _PolkitUnixGroupClass
{
  GObjectClass parent_class;
};

enum
{
  PROP_0,
  PROP_GID,
};

65
static void identity_iface_init (PolkitIdentityIface *identity_iface);
66 67

G_DEFINE_TYPE_WITH_CODE (PolkitUnixGroup, polkit_unix_group, G_TYPE_OBJECT,
68
                         G_IMPLEMENT_INTERFACE (POLKIT_TYPE_IDENTITY, identity_iface_init)
69 70 71 72 73
                         );

static void
polkit_unix_group_init (PolkitUnixGroup *unix_group)
{
74
  unix_group->gid = -1;
75 76 77 78
}

static void
polkit_unix_group_get_property (GObject    *object,
79 80 81
                                guint       prop_id,
                                GValue     *value,
                                GParamSpec *pspec)
82 83 84 85 86 87
{
  PolkitUnixGroup *unix_group = POLKIT_UNIX_GROUP (object);

  switch (prop_id)
    {
    case PROP_GID:
88
      g_value_set_int (value, unix_group->gid);
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
      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);
104
  gint val;
105 106 107 108

  switch (prop_id)
    {
    case PROP_GID:
109 110 111
      val = g_value_get_int (value);
      g_return_if_fail (val != -1);
      unix_group->gid = val;
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
      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,
135 136 137
                                   g_param_spec_int ("gid",
                                                     "Group ID",
                                                     "The UNIX group ID",
138
                                                     G_MININT,
139
                                                     G_MAXINT,
140
                                                     -1,
141 142 143 144 145
                                                     G_PARAM_CONSTRUCT |
                                                     G_PARAM_READWRITE |
                                                     G_PARAM_STATIC_NAME |
                                                     G_PARAM_STATIC_BLURB |
                                                     G_PARAM_STATIC_NICK));
146 147 148

}

David Zeuthen's avatar
David Zeuthen committed
149 150 151 152 153 154 155 156
/**
 * polkit_unix_group_get_gid:
 * @group: A #PolkitUnixGroup.
 *
 * Gets the UNIX group id for @group.
 *
 * Returns: A UNIX group id.
 */
157
gint
158 159
polkit_unix_group_get_gid (PolkitUnixGroup *group)
{
160
  g_return_val_if_fail (POLKIT_IS_UNIX_GROUP (group), -1);
161 162 163
  return group->gid;
}

David Zeuthen's avatar
David Zeuthen committed
164 165 166 167 168 169 170
/**
 * polkit_unix_group_set_gid:
 * @group: A #PolkitUnixGroup.
 * @gid: A UNIX group id.
 *
 * Sets @gid for @group.
 */
171 172
void
polkit_unix_group_set_gid (PolkitUnixGroup *group,
173
                           gint gid)
174
{
175
  g_return_if_fail (POLKIT_IS_UNIX_GROUP (group));
176
  g_return_if_fail (gid != -1);
177 178 179
  group->gid = gid;
}

David Zeuthen's avatar
David Zeuthen committed
180 181 182 183 184 185
/**
 * polkit_unix_group_new:
 * @gid: A UNIX group id.
 *
 * Creates a new #PolkitUnixGroup object for @gid.
 *
186
 * Returns: (transfer full): A #PolkitUnixGroup object. Free with g_object_unref().
David Zeuthen's avatar
David Zeuthen committed
187
 */
188
PolkitIdentity *
189
polkit_unix_group_new (gint gid)
190
{
191 192
  g_return_val_if_fail (gid != -1, NULL);

193
  return POLKIT_IDENTITY (g_object_new (POLKIT_TYPE_UNIX_GROUP,
194 195 196 197
                                       "gid", gid,
                                       NULL));
}

David Zeuthen's avatar
David Zeuthen committed
198 199 200 201 202 203 204 205
/**
 * 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.
 *
206
 * Returns: (transfer full): (allow-none): A #PolkitUnixGroup object or %NULL if @error
David Zeuthen's avatar
David Zeuthen committed
207
 * is set.
David Zeuthen's avatar
David Zeuthen committed
208
 */
209
PolkitIdentity *
210 211 212 213
polkit_unix_group_new_for_name (const gchar    *name,
                                GError        **error)
{
  struct group *group;
214
  PolkitIdentity *identity;
215

216 217 218
  g_return_val_if_fail (name != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

219
  identity = NULL;
220 221 222 223 224 225 226

  group = getgrnam (name);
  if (group == NULL)
    {
      g_set_error (error,
                   POLKIT_ERROR,
                   POLKIT_ERROR_FAILED,
227 228 229
                   "No UNIX group with name %s: %s",
                   name,
                   g_strerror (errno));
230 231 232
      goto out;
    }

233
  identity = polkit_unix_group_new (group->gr_gid);
234 235

 out:
236
  return identity;
237 238
}

239 240 241 242 243 244 245 246 247 248
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));
}

249
static gboolean
250 251
polkit_unix_group_equal (PolkitIdentity *a,
                        PolkitIdentity *b)
252 253 254 255 256 257 258 259 260 261
{
  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;
}

262
static gchar *
263
polkit_unix_group_to_string (PolkitIdentity *identity)
264
{
265
  PolkitUnixGroup *group = POLKIT_UNIX_GROUP (identity);
266 267 268 269 270 271 272 273 274 275
  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);
}

276
static void
277
identity_iface_init (PolkitIdentityIface *identity_iface)
278
{
279
  identity_iface->hash      = polkit_unix_group_hash;
280 281
  identity_iface->equal     = polkit_unix_group_equal;
  identity_iface->to_string = polkit_unix_group_to_string;
282
}