polkitunixuser.c 7.66 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 <pwd.h>
28
#include <errno.h>
29
#include "polkitunixuser.h"
30
#include "polkitidentity.h"
31
#include "polkiterror.h"
32 33 34 35 36 37 38
#include "polkitprivate.h"

/**
 * SECTION:polkitunixuser
 * @title: PolkitUnixUser
 * @short_description: Unix users
 *
David Zeuthen's avatar
David Zeuthen committed
39
 * An object representing a user identity on a UNIX system.
40 41
 */

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

51
  gint uid;
52
  gchar *name;
53 54 55 56 57 58 59 60 61 62 63 64 65
};

struct _PolkitUnixUserClass
{
  GObjectClass parent_class;
};

enum
{
  PROP_0,
  PROP_UID,
};

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

G_DEFINE_TYPE_WITH_CODE (PolkitUnixUser, polkit_unix_user, G_TYPE_OBJECT,
69
                         G_IMPLEMENT_INTERFACE (POLKIT_TYPE_IDENTITY, identity_iface_init)
70 71 72 73 74
                         );

static void
polkit_unix_user_init (PolkitUnixUser *unix_user)
{
75
  unix_user->uid = -1;
76 77 78 79 80 81 82 83 84 85 86
  unix_user->name = NULL;
}

static void
polkit_unix_user_finalize (GObject *object)
{
  PolkitUnixUser *unix_user = POLKIT_UNIX_USER (object);

  g_free(unix_user->name);

  G_OBJECT_CLASS (polkit_unix_user_parent_class)->finalize (object);
87 88 89 90 91 92 93 94 95 96 97 98 99
}

static void
polkit_unix_user_get_property (GObject    *object,
                               guint       prop_id,
                               GValue     *value,
                               GParamSpec *pspec)
{
  PolkitUnixUser *unix_user = POLKIT_UNIX_USER (object);

  switch (prop_id)
    {
    case PROP_UID:
100
      g_value_set_int (value, unix_user->uid);
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
polkit_unix_user_set_property (GObject      *object,
                               guint         prop_id,
                               const GValue *value,
                               GParamSpec   *pspec)
{
  PolkitUnixUser *unix_user = POLKIT_UNIX_USER (object);
116
  gint val;
117 118 119 120

  switch (prop_id)
    {
    case PROP_UID:
121 122 123
      val = g_value_get_int (value);
      g_return_if_fail (val != -1);
      unix_user->uid = val;
124 125 126 127 128 129 130 131 132 133 134 135 136
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
polkit_unix_user_class_init (PolkitUnixUserClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

137
  gobject_class->finalize = polkit_unix_user_finalize;
138 139 140 141 142 143 144 145 146 147
  gobject_class->get_property = polkit_unix_user_get_property;
  gobject_class->set_property = polkit_unix_user_set_property;

  /**
   * PolkitUnixUser:uid:
   *
   * The UNIX user id.
   */
  g_object_class_install_property (gobject_class,
                                   PROP_UID,
148 149 150
                                   g_param_spec_int ("uid",
                                                     "User ID",
                                                     "The UNIX user ID",
151
                                                     G_MININT,
152
                                                     G_MAXINT,
153
                                                     -1,
154 155 156 157 158
                                                     G_PARAM_CONSTRUCT |
                                                     G_PARAM_READWRITE |
                                                     G_PARAM_STATIC_NAME |
                                                     G_PARAM_STATIC_BLURB |
                                                     G_PARAM_STATIC_NICK));
159 160 161

}

David Zeuthen's avatar
David Zeuthen committed
162 163 164 165 166 167 168 169
/**
 * polkit_unix_user_get_uid:
 * @user: A #PolkitUnixUser.
 *
 * Gets the UNIX user id for @user.
 *
 * Returns: A UNIX user id.
 */
170
gint
171 172
polkit_unix_user_get_uid (PolkitUnixUser *user)
{
173
  g_return_val_if_fail (POLKIT_IS_UNIX_USER (user), -1);
174 175 176
  return user->uid;
}

David Zeuthen's avatar
David Zeuthen committed
177 178 179 180 181 182 183
/**
 * polkit_unix_user_set_uid:
 * @user: A #PolkitUnixUser.
 * @uid: A UNIX user id.
 *
 * Sets @uid for @user.
 */
184 185
void
polkit_unix_user_set_uid (PolkitUnixUser *user,
186
                          gint uid)
187
{
188
  g_return_if_fail (POLKIT_IS_UNIX_USER (user));
189
  g_return_if_fail (uid != -1);
190 191 192
  user->uid = uid;
}

David Zeuthen's avatar
David Zeuthen committed
193 194 195 196 197 198
/**
 * polkit_unix_user_new:
 * @uid: A UNIX user id.
 *
 * Creates a new #PolkitUnixUser object for @uid.
 *
199
 * Returns: (transfer full): A #PolkitUnixUser object. Free with g_object_unref().
David Zeuthen's avatar
David Zeuthen committed
200
 */
201
PolkitIdentity *
202
polkit_unix_user_new (gint uid)
203
{
204 205
  g_return_val_if_fail (uid != -1, NULL);

206 207 208
  return POLKIT_IDENTITY (g_object_new (POLKIT_TYPE_UNIX_USER,
                                        "uid", uid,
                                        NULL));
209 210
}

David Zeuthen's avatar
David Zeuthen committed
211 212 213 214 215 216 217 218
/**
 * polkit_unix_user_new_for_name:
 * @name: A UNIX user name.
 * @error: Return location for error.
 *
 * Creates a new #PolkitUnixUser object for a user with the user name
 * @name.
 *
219
 * Returns: (allow-none) (transfer full): A #PolkitUnixUser object or %NULL if @error is set.
David Zeuthen's avatar
David Zeuthen committed
220
 */
221
PolkitIdentity *
222 223 224 225
polkit_unix_user_new_for_name (const gchar    *name,
                               GError        **error)
{
  struct passwd *passwd;
226
  PolkitIdentity *identity;
227

228 229 230
  g_return_val_if_fail (name != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

231
  identity = NULL;
232 233 234 235 236 237 238

  passwd = getpwnam (name);
  if (passwd == NULL)
    {
      g_set_error (error,
                   POLKIT_ERROR,
                   POLKIT_ERROR_FAILED,
239 240 241
                   "No UNIX user with name %s: %s",
                   name,
                   g_strerror (errno));
242 243 244
      goto out;
    }

245
  identity = polkit_unix_user_new (passwd->pw_uid);
246 247

 out:
248
  return identity;
249 250
}

251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
/**
 * polkit_unix_user_get_name:
 * @user: A #PolkitUnixUser.
 *
 * Get the user's name.
 *
 * Returns: (allow-none) (transfer none): User name string or %NULL if user uid not found.
 */
const gchar *
polkit_unix_user_get_name (PolkitUnixUser *user)
{
  if (user->name == NULL)
    {
      struct passwd *passwd;
      passwd = getpwuid (user->uid);

      if (passwd != NULL)
        user->name = g_strdup(passwd->pw_name);
    }

  return user->name;
}

274
static gboolean
275 276
polkit_unix_user_equal (PolkitIdentity *a,
                        PolkitIdentity *b)
277 278 279 280 281 282 283 284 285 286
{
  PolkitUnixUser *user_a;
  PolkitUnixUser *user_b;

  user_a = POLKIT_UNIX_USER (a);
  user_b = POLKIT_UNIX_USER (b);

  return user_a->uid == user_b->uid;
}

287 288 289 290 291 292 293 294 295 296
static guint
polkit_unix_user_hash (PolkitIdentity *identity)
{
  PolkitUnixUser *user;

  user = POLKIT_UNIX_USER (identity);

  return g_direct_hash (GINT_TO_POINTER (((gint) (user->uid)) * 2));
}

297
static gchar *
298
polkit_unix_user_to_string (PolkitIdentity *identity)
299
{
300
  PolkitUnixUser *user = POLKIT_UNIX_USER (identity);
301
  const gchar *user_name = polkit_unix_user_get_name(user);
302

303 304
  if (user_name != NULL)
    return g_strdup_printf ("unix-user:%s", user_name);
305
  else
306
    return g_strdup_printf ("unix-user:%d", user->uid);
307 308
}

309
static void
310
identity_iface_init (PolkitIdentityIface *identity_iface)
311
{
312
  identity_iface->hash      = polkit_unix_user_hash;
313 314
  identity_iface->equal     = polkit_unix_user_equal;
  identity_iface->to_string = polkit_unix_user_to_string;
315
}