15
14
#include <stdlib.h>
18
16
#include "accounts.h"
17
#include "user-list.h"
26
/* Accounts interface proxy */
35
/* GECOS information */
39
gchar *home_directory;
21
/* Internal user object */
22
CommonUser *common_user;
51
25
G_DEFINE_TYPE (User, user, G_TYPE_OBJECT);
53
/* Connection to AccountsService */
54
static GDBusProxy *accounts_service_proxy = NULL;
55
static gboolean have_accounts_service_proxy = FALSE;
58
call_method (GDBusProxy *proxy, const gchar *method, GVariant *args,
59
const gchar *expected, GVariant **result)
67
answer = g_dbus_proxy_call_sync (proxy,
70
G_DBUS_CALL_FLAGS_NONE,
75
g_warning ("Could not call %s: %s", method, error->message);
76
g_clear_error (&error);
81
if (!g_variant_is_of_type (answer, G_VARIANT_TYPE (expected)))
83
g_warning ("Unexpected response from %s: %s",
84
method, g_variant_get_type_string (answer));
85
g_variant_unref (answer);
92
g_variant_unref (answer);
98
get_property (GDBusProxy *proxy, const gchar *property,
99
const gchar *expected, GVariant **result)
103
answer = g_dbus_proxy_get_cached_property (proxy, property);
107
g_warning ("Could not get accounts property %s", property);
111
if (!g_variant_is_of_type (answer, G_VARIANT_TYPE (expected)))
113
g_warning ("Unexpected accounts property type for %s: %s",
114
property, g_variant_get_type_string (answer));
115
g_variant_unref (answer);
122
g_variant_unref (answer);
127
save_string_to_dmrc (const gchar *username, const gchar *group,
128
const gchar *key, const gchar *value)
132
dmrc = dmrc_load (username);
133
g_key_file_set_string (dmrc, group, key, value);
134
dmrc_save (dmrc, username);
136
g_key_file_free (dmrc);
140
get_string_from_dmrc (const gchar *username, const gchar *group,
146
dmrc = dmrc_load (username);
147
value = g_key_file_get_string (dmrc, group, key, NULL);
149
g_key_file_free (dmrc);
154
get_accounts_service_proxy (void)
156
GError *error = NULL;
158
if (have_accounts_service_proxy)
159
return accounts_service_proxy;
161
have_accounts_service_proxy = TRUE;
162
accounts_service_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
163
G_DBUS_PROXY_FLAGS_NONE,
165
"org.freedesktop.Accounts",
166
"/org/freedesktop/Accounts",
167
"org.freedesktop.Accounts",
170
g_warning ("Could not get accounts proxy: %s", error->message);
171
g_clear_error (&error);
173
if (accounts_service_proxy)
176
name = g_dbus_proxy_get_name_owner (accounts_service_proxy);
179
g_debug ("org.freedesktop.Accounts does not exist, falling back to passwd file");
180
g_object_unref (accounts_service_proxy);
181
accounts_service_proxy = NULL;
186
return accounts_service_proxy;
190
get_accounts_proxy_for_user (const gchar *user)
193
GError *error = NULL;
196
gchar *user_path = NULL;
198
g_return_val_if_fail (user != NULL, NULL);
200
proxy = get_accounts_service_proxy ();
204
success = call_method (proxy, "FindUserByName", g_variant_new ("(s)", user), "(o)", &result);
209
g_variant_get (result, "(o)", &user_path);
210
g_variant_unref (result);
215
proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
216
G_DBUS_PROXY_FLAGS_NONE,
218
"org.freedesktop.Accounts",
220
"org.freedesktop.Accounts.User",
223
g_warning ("Could not get accounts user proxy: %s", error->message);
224
g_clear_error (&error);
231
user_from_passwd (struct passwd *user_info)
235
user = g_object_new (USER_TYPE, NULL);
236
user->priv->name = g_strdup (user_info->pw_name);
237
user->priv->uid = user_info->pw_uid;
238
user->priv->gid = user_info->pw_gid;
239
user->priv->gecos = g_strdup (user_info->pw_gecos);
240
user->priv->home_directory = g_strdup (user_info->pw_dir);
241
user->priv->shell = g_strdup (user_info->pw_shell);
242
user->priv->proxy = get_accounts_proxy_for_user (user->priv->name);
248
28
accounts_get_user_by_name (const gchar *username)
250
struct passwd *user_info;
251
30
User *user = NULL;
31
CommonUser *common_user;
253
33
g_return_val_if_fail (username != NULL, NULL);
256
user_info = getpwnam (username);
258
user = user_from_passwd (user_info);
260
if (!user && errno != 0)
261
g_warning ("Unable to get information on user %s: %s", username, strerror (errno));
267
accounts_get_user_by_uid (uid_t uid)
272
struct passwd *user_info;
274
user_info = getpwuid (uid);
276
user = user_from_passwd (user_info);
278
if (!user && errno != 0)
279
g_warning ("Unable to get information on user %d: %s", uid, strerror (errno));
35
common_user = common_user_list_get_user_by_name (common_user_list_get_instance (), username);
36
if (common_user != NULL)
38
user = g_object_new (USER_TYPE, NULL);
39
user->priv->common_user = common_user;
285
46
accounts_get_current_user ()
287
return user_from_passwd (getpwuid (getuid ()));
48
struct passwd *entry = getpwuid (getuid ());
50
return accounts_get_user_by_name (entry->pw_name);
291
56
user_get_name (User *user)
293
58
g_return_val_if_fail (user != NULL, NULL);
294
return user->priv->name;
59
return common_user_get_name (user->priv->common_user);
298
63
user_get_uid (User *user)
300
65
g_return_val_if_fail (user != NULL, 0);
301
return user->priv->uid;
66
return common_user_get_uid (user->priv->common_user);
305
70
user_get_gid (User *user)
307
72
g_return_val_if_fail (user != NULL, 0);
308
return user->priv->gid;
312
user_get_gecos (User *user)
314
g_return_val_if_fail (user != NULL, NULL);
315
return user->priv->gecos;
73
return common_user_get_gid (user->priv->common_user);
319
77
user_get_home_directory (User *user)
321
79
g_return_val_if_fail (user != NULL, NULL);
322
return user->priv->home_directory;
80
return common_user_get_home_directory (user->priv->common_user);
326
84
user_get_shell (User *user)
328
86
g_return_val_if_fail (user != NULL, NULL);
329
return user->priv->shell;
87
return common_user_get_shell (user->priv->common_user);
333
91
user_set_language (User *user, const gchar *language)
335
93
g_return_if_fail (user != NULL);
337
call_method (user->priv->proxy, "SetLanguage", g_variant_new ("(s)", language), "()", NULL);
338
save_string_to_dmrc (user->priv->name, "Desktop", "Language", language);
94
common_user_set_language (user->priv->common_user, language);
342
98
user_get_language (User *user)
344
GVariant *variant, *inner;
347
100
g_return_val_if_fail (user != NULL, NULL);
349
g_free (user->priv->language);
350
if (user->priv->proxy)
352
/* the "Language" property cannot be retrieved with get_property () here since it
353
* uses g_dbus_proxy_get_cached_property () which would return the previous (cached) value
354
* of the "Language" property
356
success = call_method (user->priv->proxy, "org.freedesktop.DBus.Properties.Get", g_variant_new ("(ss)", g_dbus_proxy_get_interface_name(user->priv->proxy), "Language"), "(v)", &variant);
359
g_variant_get (variant, "(v)", &inner);
360
user->priv->language = g_variant_dup_string (inner, NULL);
361
g_variant_unref (inner);
362
g_variant_unref (variant);
365
user->priv->language = NULL;
368
user->priv->language = get_string_from_dmrc (user->priv->name, "Desktop", "Language");
370
/* Treat a blank language as unset */
371
if (g_strcmp0 (user->priv->language, "") == 0)
373
g_free (user->priv->language);
374
user->priv->language = NULL;
377
return user->priv->language;
101
return common_user_get_language (user->priv->common_user);
381
105
user_set_xsession (User *user, const gchar *xsession)
383
107
g_return_if_fail (user != NULL);
385
call_method (user->priv->proxy, "SetXSession", g_variant_new ("(s)", xsession), "()", NULL);
386
save_string_to_dmrc (user->priv->name, "Desktop", "Session", xsession);
108
common_user_set_session (user->priv->common_user, xsession);
390
112
user_get_xsession (User *user)
394
114
g_return_val_if_fail (user != NULL, NULL);
396
g_free (user->priv->xsession);
397
if (user->priv->proxy)
399
if (get_property (user->priv->proxy, "XSession", "s", &result))
401
g_variant_get (result, "s", &user->priv->xsession);
402
g_variant_unref (result);
405
user->priv->xsession = NULL;
408
user->priv->xsession = get_string_from_dmrc (user->priv->name, "Desktop", "Session");
410
if (g_strcmp0 (user->priv->xsession, "") == 0)
412
g_free (user->priv->xsession);
413
user->priv->xsession = NULL;
416
return user->priv->xsession;
115
return common_user_get_session (user->priv->common_user);
430
129
self = USER (object);
432
if (self->priv->proxy)
434
g_object_unref (self->priv->proxy);
435
self->priv->proxy = NULL;
131
if (self->priv->common_user)
132
g_object_unref (self->priv->common_user);
133
self->priv->common_user = NULL;
438
135
G_OBJECT_CLASS (user_parent_class)->dispose (object);
442
user_finalize (GObject *object)
446
self = USER (object);
448
g_free (self->priv->name);
449
g_free (self->priv->gecos);
450
g_free (self->priv->home_directory);
451
g_free (self->priv->shell);
452
g_free (self->priv->language);
454
G_OBJECT_CLASS (user_parent_class)->finalize (object);
458
139
user_class_init (UserClass *klass)
460
141
GObjectClass *object_class = G_OBJECT_CLASS (klass);
462
143
object_class->dispose = user_dispose;
463
object_class->finalize = user_finalize;
465
145
g_type_class_add_private (klass, sizeof (UserPrivate));