]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blobdiff - src/accounts.c
Releasing 1.20.0
[sojka/lightdm.git] / src / accounts.c
index e974c543f187913919e54bd1de71161779f131ab..77cfdf5effe4703789797a3500af56fa987448f7 100644 (file)
@@ -2,7 +2,7 @@
  *
  * Copyright (C) 2010-2011 Robert Ancell.
  * Author: Robert Ancell <robert.ancell@canonical.com>
- * 
+ *
  * This program is free software: you can redistribute it and/or modify it under
  * the terms of the GNU General Public License as published by the Free Software
  * Foundation, either version 3 of the License, or (at your option) any later
  * license.
  */
 
-#include <errno.h>
 #include <pwd.h>
 #include <stdlib.h>
-#include <string.h>
 
 #include "accounts.h"
-#include "dmrc.h"
+#include "user-list.h"
 
 struct UserPrivate
 {
-    /* Name of user */
-    gchar *name;
-
-    /* Accounts interface proxy */
-    GDBusProxy *proxy;
-
-    /* User ID */
-    uid_t uid;
-
-    /* Group ID */
-    gid_t gid;
-
-    /* GECOS information */
-    gchar *gecos;
-
-    /* Home directory */
-    gchar *home_directory;
-
-    /* Shell */
-    gchar *shell;
-
-    /* Language */
-    gchar *language;
-
-    /* Locale */
-    gchar *locale;
-
-    /* X session */
-    gchar *xsession;
+    /* Internal user object */
+    CommonUser *common_user;
 };
 
 G_DEFINE_TYPE (User, user, G_TYPE_OBJECT);
 
-/* Connection to AccountsService */
-static GDBusProxy *accounts_service_proxy = NULL;
-static gboolean have_accounts_service_proxy = FALSE;
-
-static gboolean
-call_method (GDBusProxy *proxy, const gchar *method, GVariant *args,
-             const gchar *expected, GVariant **result)
-{
-    GVariant *answer;
-    GError *error = NULL;
-
-    if (!proxy)
-        return FALSE;
-
-    answer = g_dbus_proxy_call_sync (proxy,
-                                     method,
-                                     args,
-                                     G_DBUS_CALL_FLAGS_NONE,
-                                     -1,
-                                     NULL,
-                                     &error);
-    if (error)
-        g_warning ("Could not call %s: %s", method, error->message);
-    g_clear_error (&error);
-
-    if (!answer)
-        return FALSE;
-
-    if (!g_variant_is_of_type (answer, G_VARIANT_TYPE (expected)))
-    {
-        g_warning ("Unexpected response from %s: %s",
-                   method, g_variant_get_type_string (answer));
-        g_variant_unref (answer);
-        return FALSE;
-    }
-
-    if (result)
-        *result = answer;
-    else
-        g_variant_unref (answer);
-
-    return TRUE;
-}
-
-static gboolean
-get_property (GDBusProxy *proxy, const gchar *property,
-              const gchar *expected, GVariant **result)
-{
-    GVariant *answer;
-
-    answer = g_dbus_proxy_get_cached_property (proxy, property);
-
-    if (!answer)
-    {
-        g_warning ("Could not get accounts property %s", property);
-        return FALSE;
-    }
-
-    if (!g_variant_is_of_type (answer, G_VARIANT_TYPE (expected)))
-    {
-        g_warning ("Unexpected accounts property type for %s: %s",
-                   property, g_variant_get_type_string (answer));
-        g_variant_unref (answer);
-        return FALSE;
-    }
-
-    if (result)
-        *result = answer;
-    else
-        g_variant_unref (answer);
-    return TRUE;
-}
-
-static void
-save_string_to_dmrc (const gchar *username, const gchar *group,
-                     const gchar *key, const gchar *value)
-{
-    GKeyFile *dmrc;
-
-    dmrc = dmrc_load (username);
-    g_key_file_set_string (dmrc, group, key, value);
-    dmrc_save (dmrc, username);
-
-    g_key_file_free (dmrc);
-}
-
-static gchar *
-get_string_from_dmrc (const gchar *username, const gchar *group,
-                      const gchar *key)
-{
-    GKeyFile *dmrc;
-    gchar *value;
-
-    dmrc = dmrc_load (username);
-    value = g_key_file_get_string (dmrc, group, key, NULL);
-
-    g_key_file_free (dmrc);
-    return value;
-}
-
-static GDBusProxy *
-get_accounts_service_proxy ()
-{
-    GError *error = NULL;
-
-    if (have_accounts_service_proxy)
-        return accounts_service_proxy;
-
-    have_accounts_service_proxy = TRUE;
-    accounts_service_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
-                                                            G_DBUS_PROXY_FLAGS_NONE,
-                                                            NULL,
-                                                            "org.freedesktop.Accounts",
-                                                            "/org/freedesktop/Accounts",
-                                                            "org.freedesktop.Accounts",
-                                                            NULL, &error);
-    if (error)
-        g_warning ("Could not get accounts proxy: %s", error->message);
-    g_clear_error (&error);
-
-    if (accounts_service_proxy)
-    {
-        gchar *name;
-        name = g_dbus_proxy_get_name_owner (accounts_service_proxy);
-        if (!name)
-        {
-            g_debug ("org.freedesktop.Accounts does not exist, falling back to passwd file");
-            g_object_unref (accounts_service_proxy);
-            accounts_service_proxy = NULL;
-        }
-        g_free (name);
-    }  
-
-    return accounts_service_proxy;
-}
-
-static GDBusProxy *
-get_accounts_proxy_for_user (const gchar *user)
-{
-    GDBusProxy *proxy;
-    GError *error = NULL;
-    GVariant *result;
-    gboolean success;
-    gchar *user_path = NULL;
-
-    g_return_val_if_fail (user != NULL, NULL);  
-
-    proxy = get_accounts_service_proxy ();
-    if (!proxy)
-        return NULL;
-
-    success = call_method (proxy, "FindUserByName", g_variant_new ("(s)", user), "(o)", &result);
-
-    if (!success)
-        return NULL;
-
-    g_variant_get (result, "(o)", &user_path);
-    g_variant_unref (result);
-
-    if (!user_path)
-        return NULL;
-  
-    proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
-                                           G_DBUS_PROXY_FLAGS_NONE,
-                                           NULL,
-                                           "org.freedesktop.Accounts",
-                                           user_path,
-                                           "org.freedesktop.Accounts.User",
-                                           NULL, &error);
-    if (error)
-        g_warning ("Could not get accounts user proxy: %s", error->message);
-    g_clear_error (&error);
-    g_free (user_path);
-
-    return proxy;
-}
-
-static User *
-user_from_passwd (struct passwd *user_info)
-{
-    User *user;
-
-    user = g_object_new (USER_TYPE, NULL);
-    user->priv->name = g_strdup (user_info->pw_name);
-    user->priv->uid = user_info->pw_uid;
-    user->priv->gid = user_info->pw_gid;
-    user->priv->gecos = g_strdup (user_info->pw_gecos);
-    user->priv->home_directory = g_strdup (user_info->pw_dir);
-    user->priv->shell = g_strdup (user_info->pw_shell);
-    user->priv->proxy = get_accounts_proxy_for_user (user->priv->name);
-
-    return user;
-}
-
 User *
 accounts_get_user_by_name (const gchar *username)
 {
-    struct passwd *user_info;
     User *user = NULL;
+    CommonUser *common_user;
 
     g_return_val_if_fail (username != NULL, NULL);
 
-    errno = 0;
-    user_info = getpwnam (username);
-    if (user_info)
-        user = user_from_passwd (user_info);
-
-    if (!user && errno != 0)
-        g_warning ("Unable to get information on user %s: %s", username, strerror (errno));
-
-    return user;
-}
-
-User *
-accounts_get_user_by_uid (uid_t uid)
-{
-    User *user = NULL;
-
-    errno = 0;
-    struct passwd *user_info;
-
-    user_info = getpwuid (uid);
-    if (user_info)
-        user = user_from_passwd (user_info);
-
-    if (!user && errno != 0)
-        g_warning ("Unable to get information on user %d: %s", uid, strerror (errno));
+    common_user = common_user_list_get_user_by_name (common_user_list_get_instance (), username);
+    if (common_user != NULL)
+    {
+        user = g_object_new (USER_TYPE, NULL);
+        user->priv->common_user = common_user;
+    }
 
     return user;
 }
@@ -287,120 +45,74 @@ accounts_get_user_by_uid (uid_t uid)
 User *
 accounts_get_current_user ()
 {
-    return user_from_passwd (getpwuid (getuid ()));
+    struct passwd *entry = getpwuid (getuid ());
+    if (entry != NULL)
+        return accounts_get_user_by_name (entry->pw_name);
+    else
+        return NULL;
 }
 
 const gchar *
 user_get_name (User *user)
 {
     g_return_val_if_fail (user != NULL, NULL);
-    return user->priv->name;
+    return common_user_get_name (user->priv->common_user);
 }
 
 uid_t
 user_get_uid (User *user)
 {
     g_return_val_if_fail (user != NULL, 0);
-    return user->priv->uid;
+    return common_user_get_uid (user->priv->common_user);
 }
 
 gid_t
 user_get_gid (User *user)
 {
     g_return_val_if_fail (user != NULL, 0);
-    return user->priv->gid;
-}
-
-const gchar *
-user_get_gecos (User *user)
-{
-    g_return_val_if_fail (user != NULL, NULL);
-    return user->priv->gecos;
+    return common_user_get_gid (user->priv->common_user);
 }
 
 const gchar *
 user_get_home_directory (User *user)
 {
     g_return_val_if_fail (user != NULL, NULL);
-    return user->priv->home_directory;
+    return common_user_get_home_directory (user->priv->common_user);
 }
 
 const gchar *
 user_get_shell (User *user)
 {
     g_return_val_if_fail (user != NULL, NULL);
-    return user->priv->shell;
-}
-
-const gchar *
-user_get_locale (User *user)
-{
-    g_return_val_if_fail (user != NULL, NULL);
-
-    g_free (user->priv->locale);
-    if (user->priv->proxy)
-        user->priv->locale = NULL;
-    else
-        user->priv->locale = get_string_from_dmrc (user->priv->name, "Desktop", "Language");
-
-    /* Treat a blank locale as unset */
-    if (g_strcmp0 (user->priv->locale, "") == 0)
-    {
-        g_free (user->priv->locale);
-        user->priv->locale = NULL;
-    }
-
-    return user->priv->locale;
+    return common_user_get_shell (user->priv->common_user);
 }
 
 void
 user_set_language (User *user, const gchar *language)
 {
     g_return_if_fail (user != NULL);
+    common_user_set_language (user->priv->common_user, language);
+}
 
-    if (user->priv->proxy)
-        call_method (user->priv->proxy, "SetLanguage", g_variant_new ("(s)", language), "()", NULL);
-    else
-        save_string_to_dmrc (user->priv->name, "Desktop", "Language", language);
+const gchar *
+user_get_language (User *user)
+{
+    g_return_val_if_fail (user != NULL, NULL);
+    return common_user_get_language (user->priv->common_user);
 }
 
 void
 user_set_xsession (User *user, const gchar *xsession)
 {
     g_return_if_fail (user != NULL);
-
-    call_method (user->priv->proxy, "SetXSession", g_variant_new ("(s)", xsession), "()", NULL);
-    save_string_to_dmrc (user->priv->name, "Desktop", "Session", xsession);
+    common_user_set_session (user->priv->common_user, xsession);
 }
 
 const gchar *
 user_get_xsession (User *user)
 {
-    GVariant *result;
-
     g_return_val_if_fail (user != NULL, NULL);
-
-    g_free (user->priv->xsession);
-    if (user->priv->proxy)
-    {
-        if (get_property (user->priv->proxy, "XSession", "s", &result))
-        {
-            g_variant_get (result, "s", &user->priv->xsession);
-            g_variant_unref (result);
-        }
-        else
-            user->priv->xsession = NULL;
-    }
-    else
-        user->priv->xsession = get_string_from_dmrc (user->priv->name, "Desktop", "Session");
-
-    if (g_strcmp0 (user->priv->xsession, "") == 0)
-    {
-        g_free (user->priv->xsession);
-        user->priv->xsession = NULL;
-    }
-
-    return user->priv->xsession;
+    return common_user_get_session (user->priv->common_user);
 }
 
 static void
@@ -409,35 +121,14 @@ user_init (User *user)
     user->priv = G_TYPE_INSTANCE_GET_PRIVATE (user, USER_TYPE, UserPrivate);
 }
 
-static void
-user_dispose (GObject *object)
-{
-    User *self;
-
-    self = USER (object);
-
-    if (self->priv->proxy)
-    {
-        g_object_unref (self->priv->proxy);
-        self->priv->proxy = NULL;
-    }
-
-    G_OBJECT_CLASS (user_parent_class)->dispose (object);
-}
-
 static void
 user_finalize (GObject *object)
 {
-    User *self;
-
-    self = USER (object);
+    User *self = USER (object);
 
-    g_free (self->priv->name);
-    g_free (self->priv->gecos);
-    g_free (self->priv->home_directory);
-    g_free (self->priv->shell);
+    g_clear_object (&self->priv->common_user);
 
-    G_OBJECT_CLASS (user_parent_class)->finalize (object);  
+    G_OBJECT_CLASS (user_parent_class)->finalize (object);
 }
 
 static void
@@ -445,8 +136,7 @@ user_class_init (UserClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-    object_class->dispose = user_dispose;
-    object_class->finalize = user_finalize;  
+    object_class->finalize = user_finalize;
 
     g_type_class_add_private (klass, sizeof (UserPrivate));
 }