Merge lp:~mterry/lightdm/refactor-accounts into lp:lightdm
- refactor-accounts
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Robert Ancell |
Approved revision: | 1881 |
Merged at revision: | 1892 |
Proposed branch: | lp:~mterry/lightdm/refactor-accounts |
Merge into: | lp:lightdm |
Diff against target: |
3540 lines (+1558/-785) 20 files modified
Makefile.am (+1/-1) common/Makefile.am (+23/-0) common/dmrc.c (+20/-43) common/dmrc.h (+3/-2) common/privileges.c (+9/-9) common/privileges.h (+2/-2) common/user-list.c (+580/-351) common/user-list.h (+111/-0) configure.ac (+1/-0) debian/patches/01_transition_ubuntu2d_ubuntu_desktop.patch (+6/-6) liblightdm-gobject/Makefile.am (+4/-1) liblightdm-gobject/session.c (+5/-6) liblightdm-gobject/user.c (+736/-0) src/Makefile.am (+2/-6) src/accounts.c (+27/-347) src/accounts.h (+0/-4) src/lightdm.c (+8/-3) src/session-child.c (+2/-2) tests/src/test-gobject-greeter.c (+3/-2) tests/src/test-runner.c (+15/-0) |
To merge this branch: | bzr merge lp:~mterry/lightdm/refactor-accounts |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Robert Ancell | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
Review via email: mp+205422@code.launchpad.net |
Commit message
Refactor LightDMUser and User classes to use the same code internally
Description of the change
I was starting work on the shared user data directories feature (bug 1263418), when I realized I needed to do a bit of refactoring. I wanted to add knowledge to the lightdm daemon of the list of users on the system and to pay attention to user adds and removals.
But there was already a bit of overlap between liblightdm-
So I've added a common/ directory with a static libcommon.a, used by liblightdm-gobject and the lightdm daemon. I realize "common" is a dumb name. But since LightDMUser and User were already claimed by other internal objects, I didn't feel like being overly clever with the naming. So CommonUser it was. I will change the namespace to whatever you like.
I've switched LightDMUser and User to internally use CommonUser without changing their own APIs. That was necessary for LightDMUser and a matter of convenience for User. A few small classes have moved from src/ to common/ to support CommonUser (I didn't bother Common-namespacing those small classes since they didn't conflict with other code).
Moving the Configuration class into common/ let me re-use it in liblightdm-gobject, where the same job was being done manually (not much of a savings in my branch right now, but that section of code should be changed to look in lightdm.conf.d as well as just lightdm.conf, and using Configuration will make that future FIXME much easier to solve).
This branch means that the lightdm daemon relies on AccountsService a bit more than it used to (its previous primary lookup for user info was passwd, whereas this branch now prefers AS with a fallback to passwd). So I had to build out a few pieces of the test framework to emulate AS a bit better.
This branch may be overkill to land before my shared data branch (as it means the lightdm daemon is monitoring the user list needlessly). But it doesn't hurt to start reviewing it. I've also changed the Session monitoring to be started lazily; only if the API consumer asks whether a user is logged in do we start monitoring (i.e. the lightdm daemon won't be monitoring Sessions needlessly).
- 1879. By Michael Terry
-
Merge from trunk
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1879
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Robert Ancell (robert-ancell) wrote : | # |
Looks good.
The amount of shared code regarding users has been something that has felt inefficient so this approach seems good.
I've also had a slight concern that the daemon relying too heavily on accounts service might be a reliability issue, but I guess we just need to see how that goes. Also wondering how much accounts service would lean towards reporting "real" user accounts and not the system accounts we require.
Obviously the patch is enormous, but is mostly just moving / renaming so I'll rely heavily on the regression tests picking out any mistakes.
Also worth considering is if LightDM moves early into the boot when A-S is not available / not applicable what the daemon should do (switch passwd to a-s part after start? Restart from light to full mode?). This can be tackled if/when we cross that bridge though.
I'm not sure
I'll review more closely when I get back from travelling.
Michael Terry (mterry) wrote : | # |
Regarding your concern about AS not reporting the system users we need... the current daemon code actually only ever calls common_
So common_
- 1880. By Michael Terry
-
Add better cleanup as lightdm daemon closes
- 1881. By Michael Terry
-
Update patches
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1881
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1882. By Michael Terry
-
Add shared data manager and test
Robert Ancell (robert-ancell) : | # |
Preview Diff
1 | === modified file 'Makefile.am' |
2 | --- Makefile.am 2013-11-07 07:54:55 +0000 |
3 | +++ Makefile.am 2014-02-08 22:36:44 +0000 |
4 | @@ -1,4 +1,4 @@ |
5 | -SUBDIRS = |
6 | +SUBDIRS = common |
7 | if COMPILE_LIBLIGHTDM_GOBJECT |
8 | SUBDIRS += liblightdm-gobject |
9 | endif |
10 | |
11 | === added directory 'common' |
12 | === added file 'common/Makefile.am' |
13 | --- common/Makefile.am 1970-01-01 00:00:00 +0000 |
14 | +++ common/Makefile.am 2014-02-08 22:36:44 +0000 |
15 | @@ -0,0 +1,23 @@ |
16 | +# -*- Mode: Automake; indent-tabs-mode: t; tab-width: 4 -*- |
17 | + |
18 | +noinst_LTLIBRARIES = libcommon.la |
19 | + |
20 | +libcommon_la_SOURCES = \ |
21 | + configuration.c \ |
22 | + configuration.h \ |
23 | + dmrc.c \ |
24 | + dmrc.h \ |
25 | + privileges.c \ |
26 | + privileges.h \ |
27 | + user-list.c \ |
28 | + user-list.h |
29 | + |
30 | +libcommon_la_CFLAGS = \ |
31 | + $(WARN_CFLAGS) \ |
32 | + $(GLIB_CFLAGS) |
33 | + |
34 | +libcommon_la_LIBADD = \ |
35 | + $(GLIB_LDFLAGS) |
36 | + |
37 | +DISTCLEANFILES = \ |
38 | + Makefile.in |
39 | |
40 | === renamed file 'src/configuration.c' => 'common/configuration.c' |
41 | === renamed file 'src/configuration.h' => 'common/configuration.h' |
42 | === renamed file 'src/dmrc.c' => 'common/dmrc.c' |
43 | --- src/dmrc.c 2013-06-13 03:17:43 +0000 |
44 | +++ common/dmrc.c 2014-02-08 22:36:44 +0000 |
45 | @@ -15,34 +15,26 @@ |
46 | |
47 | #include "dmrc.h" |
48 | #include "configuration.h" |
49 | -#include "accounts.h" |
50 | #include "privileges.h" |
51 | +#include "user-list.h" |
52 | |
53 | GKeyFile * |
54 | -dmrc_load (const gchar *username) |
55 | +dmrc_load (CommonUser *user) |
56 | { |
57 | - User *user; |
58 | GKeyFile *dmrc_file; |
59 | gchar *path; |
60 | gboolean have_dmrc, drop_privileges; |
61 | |
62 | dmrc_file = g_key_file_new (); |
63 | |
64 | - user = accounts_get_user_by_name (username); |
65 | - if (!user) |
66 | - { |
67 | - g_warning ("Cannot load .dmrc file, unable to get information on user %s", username); |
68 | - return dmrc_file; |
69 | - } |
70 | - |
71 | /* Load from the user directory, if this fails (e.g. the user directory |
72 | * is not yet mounted) then load from the cache */ |
73 | - path = g_build_filename (user_get_home_directory (user), ".dmrc", NULL); |
74 | + path = g_build_filename (common_user_get_home_directory (user), ".dmrc", NULL); |
75 | |
76 | /* Guard against privilege escalation through symlinks, etc. */ |
77 | drop_privileges = geteuid () == 0; |
78 | if (drop_privileges) |
79 | - privileges_drop (user); |
80 | + privileges_drop (common_user_get_uid (user), common_user_get_gid (user)); |
81 | have_dmrc = g_key_file_load_from_file (dmrc_file, path, G_KEY_FILE_KEEP_COMMENTS, NULL); |
82 | if (drop_privileges) |
83 | privileges_reclaim (); |
84 | @@ -53,7 +45,7 @@ |
85 | { |
86 | gchar *filename, *cache_dir; |
87 | |
88 | - filename = g_strdup_printf ("%s.dmrc", user_get_name (user)); |
89 | + filename = g_strdup_printf ("%s.dmrc", common_user_get_name (user)); |
90 | cache_dir = config_get_string (config_get_instance (), "LightDM", "cache-directory"); |
91 | path = g_build_filename (cache_dir, "dmrc", filename, NULL); |
92 | g_free (filename); |
93 | @@ -63,46 +55,32 @@ |
94 | g_free (path); |
95 | } |
96 | |
97 | - g_object_unref (user); |
98 | - |
99 | return dmrc_file; |
100 | } |
101 | |
102 | void |
103 | -dmrc_save (GKeyFile *dmrc_file, const gchar *username) |
104 | +dmrc_save (GKeyFile *dmrc_file, CommonUser *user) |
105 | { |
106 | - User *user; |
107 | gchar *path, *filename, *cache_dir, *dmrc_cache_dir; |
108 | gchar *data; |
109 | gsize length; |
110 | - |
111 | - user = accounts_get_user_by_name (username); |
112 | - if (!user) |
113 | - { |
114 | - g_warning ("Not saving DMRC file - unable to get information on user %s", username); |
115 | - return; |
116 | - } |
117 | + gboolean drop_privileges; |
118 | |
119 | data = g_key_file_to_data (dmrc_file, &length, NULL); |
120 | |
121 | /* Update the users .dmrc */ |
122 | - if (user) |
123 | - { |
124 | - gboolean drop_privileges; |
125 | - |
126 | - path = g_build_filename (user_get_home_directory (user), ".dmrc", NULL); |
127 | - |
128 | - /* Guard against privilege escalation through symlinks, etc. */ |
129 | - drop_privileges = geteuid () == 0; |
130 | - if (drop_privileges) |
131 | - privileges_drop (user); |
132 | - g_debug ("Writing %s", path); |
133 | - g_file_set_contents (path, data, length, NULL); |
134 | - if (drop_privileges) |
135 | - privileges_reclaim (); |
136 | - |
137 | - g_free (path); |
138 | - } |
139 | + path = g_build_filename (common_user_get_home_directory (user), ".dmrc", NULL); |
140 | + |
141 | + /* Guard against privilege escalation through symlinks, etc. */ |
142 | + drop_privileges = geteuid () == 0; |
143 | + if (drop_privileges) |
144 | + privileges_drop (common_user_get_uid (user), common_user_get_gid (user)); |
145 | + g_debug ("Writing %s", path); |
146 | + g_file_set_contents (path, data, length, NULL); |
147 | + if (drop_privileges) |
148 | + privileges_reclaim (); |
149 | + |
150 | + g_free (path); |
151 | |
152 | /* Update the .dmrc cache */ |
153 | cache_dir = config_get_string (config_get_instance (), "LightDM", "cache-directory"); |
154 | @@ -110,12 +88,11 @@ |
155 | if (g_mkdir_with_parents (dmrc_cache_dir, 0700) < 0) |
156 | g_warning ("Failed to make DMRC cache directory %s: %s", dmrc_cache_dir, strerror (errno)); |
157 | |
158 | - filename = g_strdup_printf ("%s.dmrc", username); |
159 | + filename = g_strdup_printf ("%s.dmrc", common_user_get_name (user)); |
160 | path = g_build_filename (dmrc_cache_dir, filename, NULL); |
161 | g_file_set_contents (path, data, length, NULL); |
162 | |
163 | g_free (dmrc_cache_dir); |
164 | g_free (path); |
165 | g_free (filename); |
166 | - g_object_unref (user); |
167 | } |
168 | |
169 | === renamed file 'src/dmrc.h' => 'common/dmrc.h' |
170 | --- src/dmrc.h 2013-04-23 03:07:03 +0000 |
171 | +++ common/dmrc.h 2014-02-08 22:36:44 +0000 |
172 | @@ -13,12 +13,13 @@ |
173 | #define DMRC_H_ |
174 | |
175 | #include <glib.h> |
176 | +#include "user-list.h" |
177 | |
178 | G_BEGIN_DECLS |
179 | |
180 | -GKeyFile *dmrc_load (const gchar *username); |
181 | +GKeyFile *dmrc_load (CommonUser *user); |
182 | |
183 | -void dmrc_save (GKeyFile *dmrc_file, const gchar *username); |
184 | +void dmrc_save (GKeyFile *dmrc_file, CommonUser *user); |
185 | |
186 | G_END_DECLS |
187 | |
188 | |
189 | === renamed file 'src/privileges.c' => 'common/privileges.c' |
190 | --- src/privileges.c 2013-08-26 00:58:45 +0000 |
191 | +++ common/privileges.c 2014-02-08 22:36:44 +0000 |
192 | @@ -13,24 +13,24 @@ |
193 | #define _GNU_SOURCE |
194 | |
195 | #include <config.h> |
196 | +#include <glib.h> |
197 | +#include <unistd.h> |
198 | #include "privileges.h" |
199 | |
200 | void |
201 | -privileges_drop (User *user) |
202 | +privileges_drop (uid_t uid, gid_t gid) |
203 | { |
204 | - g_return_if_fail (user != NULL); |
205 | - |
206 | #ifdef HAVE_SETRESGID |
207 | - g_assert (setresgid (user_get_gid (user), user_get_gid (user), -1) == 0); |
208 | + g_assert (setresgid (gid, gid, -1) == 0); |
209 | #else |
210 | - g_assert (setgid (user_get_gid (user)) == 0); |
211 | - g_assert (setegid (user_get_gid (user)) == 0); |
212 | + g_assert (setgid (gid) == 0); |
213 | + g_assert (setegid (gid) == 0); |
214 | #endif |
215 | #ifdef HAVE_SETRESUID |
216 | - g_assert (setresuid (user_get_uid (user), user_get_uid (user), -1) == 0); |
217 | + g_assert (setresuid (uid, uid, -1) == 0); |
218 | #else |
219 | - g_assert (setuid (user_get_uid (user)) == 0); |
220 | - g_assert (seteuid (user_get_uid (user)) == 0); |
221 | + g_assert (setuid (uid) == 0); |
222 | + g_assert (seteuid (uid) == 0); |
223 | #endif |
224 | } |
225 | |
226 | |
227 | === renamed file 'src/privileges.h' => 'common/privileges.h' |
228 | --- src/privileges.h 2013-04-23 03:07:03 +0000 |
229 | +++ common/privileges.h 2014-02-08 22:36:44 +0000 |
230 | @@ -12,9 +12,9 @@ |
231 | #ifndef PRIVILEGES_H_ |
232 | #define PRIVILEGES_H_ |
233 | |
234 | -#include "accounts.h" |
235 | +#include <sys/types.h> |
236 | |
237 | -void privileges_drop (User *user); |
238 | +void privileges_drop (uid_t uid, gid_t gid); |
239 | |
240 | void privileges_reclaim (void); |
241 | |
242 | |
243 | === renamed file 'liblightdm-gobject/user.c' => 'common/user-list.c' |
244 | --- liblightdm-gobject/user.c 2013-12-12 20:32:47 +0000 |
245 | +++ common/user-list.c 2014-02-08 22:36:44 +0000 |
246 | @@ -1,7 +1,9 @@ |
247 | /* -*- Mode: C; indent-tabs-mode:nil; tab-width:4 -*- |
248 | * |
249 | * Copyright (C) 2010 Robert Ancell. |
250 | - * Author: Robert Ancell <robert.ancell@canonical.com> |
251 | + * Copyright (C) 2014 Canonical, Ltd. |
252 | + * Authors: Robert Ancell <robert.ancell@canonical.com> |
253 | + * Michael Terry <michael.terry@canonical.com> |
254 | * |
255 | * This library is free software; you can redistribute it and/or modify it under |
256 | * the terms of the GNU Lesser General Public License as published by the Free |
257 | @@ -17,7 +19,8 @@ |
258 | #include <pwd.h> |
259 | #include <gio/gio.h> |
260 | |
261 | -#include "lightdm/user.h" |
262 | +#include "dmrc.h" |
263 | +#include "user-list.h" |
264 | |
265 | enum |
266 | { |
267 | @@ -33,6 +36,7 @@ |
268 | USER_PROP_REAL_NAME, |
269 | USER_PROP_DISPLAY_NAME, |
270 | USER_PROP_HOME_DIRECTORY, |
271 | + USER_PROP_SHELL, |
272 | USER_PROP_IMAGE, |
273 | USER_PROP_BACKGROUND, |
274 | USER_PROP_LANGUAGE, |
275 | @@ -40,7 +44,9 @@ |
276 | USER_PROP_LAYOUTS, |
277 | USER_PROP_SESSION, |
278 | USER_PROP_LOGGED_IN, |
279 | - USER_PROP_HAS_MESSAGES |
280 | + USER_PROP_HAS_MESSAGES, |
281 | + USER_PROP_UID, |
282 | + USER_PROP_GID, |
283 | }; |
284 | |
285 | enum |
286 | @@ -83,12 +89,12 @@ |
287 | |
288 | /* List of sessions */ |
289 | GList *sessions; |
290 | -} LightDMUserListPrivate; |
291 | +} CommonUserListPrivate; |
292 | |
293 | typedef struct |
294 | { |
295 | /* User list this user is part of */ |
296 | - LightDMUserList *user_list; |
297 | + CommonUserList *user_list; |
298 | |
299 | /* TRUE if have loaded user properties */ |
300 | gboolean loaded_values; |
301 | @@ -96,9 +102,6 @@ |
302 | /* Accounts service path */ |
303 | gchar *path; |
304 | |
305 | - /* DMRC file */ |
306 | - GKeyFile *dmrc_file; |
307 | - |
308 | /* Update signal from accounts service */ |
309 | guint changed_signal; |
310 | |
311 | @@ -111,6 +114,9 @@ |
312 | /* Home directory of user */ |
313 | gchar *home_directory; |
314 | |
315 | + /* Shell for user */ |
316 | + gchar *shell; |
317 | + |
318 | /* Image for user */ |
319 | gchar *image; |
320 | |
321 | @@ -120,6 +126,12 @@ |
322 | /* TRUE if this user has messages available */ |
323 | gboolean has_messages; |
324 | |
325 | + /* UID of user */ |
326 | + guint64 uid; |
327 | + |
328 | + /* GID of user */ |
329 | + guint64 gid; |
330 | + |
331 | /* User chosen language */ |
332 | gchar *language; |
333 | |
334 | @@ -128,74 +140,82 @@ |
335 | |
336 | /* User default session */ |
337 | gchar *session; |
338 | -} LightDMUserPrivate; |
339 | +} CommonUserPrivate; |
340 | |
341 | typedef struct |
342 | { |
343 | GObject parent_instance; |
344 | gchar *path; |
345 | gchar *username; |
346 | -} Session; |
347 | +} CommonSession; |
348 | |
349 | typedef struct |
350 | { |
351 | GObjectClass parent_class; |
352 | -} SessionClass; |
353 | - |
354 | -G_DEFINE_TYPE (LightDMUserList, lightdm_user_list, G_TYPE_OBJECT); |
355 | -G_DEFINE_TYPE (LightDMUser, lightdm_user, G_TYPE_OBJECT); |
356 | -#define SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), session_get_type (), Session)) |
357 | -GType session_get_type (void); |
358 | -G_DEFINE_TYPE (Session, session, G_TYPE_OBJECT); |
359 | - |
360 | -#define GET_LIST_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_USER_LIST, LightDMUserListPrivate) |
361 | -#define GET_USER_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_USER, LightDMUserPrivate) |
362 | +} CommonSessionClass; |
363 | + |
364 | +G_DEFINE_TYPE (CommonUserList, common_user_list, G_TYPE_OBJECT); |
365 | +G_DEFINE_TYPE (CommonUser, common_user, G_TYPE_OBJECT); |
366 | +#define COMMON_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), common_session_get_type (), CommonSession)) |
367 | +GType common_session_get_type (void); |
368 | +G_DEFINE_TYPE (CommonSession, common_session, G_TYPE_OBJECT); |
369 | + |
370 | +#define GET_LIST_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), COMMON_TYPE_USER_LIST, CommonUserListPrivate) |
371 | +#define GET_USER_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), COMMON_TYPE_USER, CommonUserPrivate) |
372 | |
373 | #define PASSWD_FILE "/etc/passwd" |
374 | #define USER_CONFIG_FILE "/etc/lightdm/users.conf" |
375 | |
376 | -static LightDMUserList *singleton = NULL; |
377 | +static CommonUserList *singleton = NULL; |
378 | |
379 | /** |
380 | - * lightdm_user_list_get_instance: |
381 | + * common_user_list_get_instance: |
382 | * |
383 | * Get the user list. |
384 | * |
385 | - * Return value: (transfer none): the #LightDMUserList |
386 | + * Return value: (transfer none): the #CommonUserList |
387 | **/ |
388 | -LightDMUserList * |
389 | -lightdm_user_list_get_instance (void) |
390 | +CommonUserList * |
391 | +common_user_list_get_instance (void) |
392 | { |
393 | if (!singleton) |
394 | - singleton = g_object_new (LIGHTDM_TYPE_USER_LIST, NULL); |
395 | + singleton = g_object_new (COMMON_TYPE_USER_LIST, NULL); |
396 | return singleton; |
397 | } |
398 | |
399 | -static LightDMUser * |
400 | -get_user_by_name (LightDMUserList *user_list, const gchar *username) |
401 | -{ |
402 | - LightDMUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
403 | +void |
404 | +common_user_list_cleanup (void) |
405 | +{ |
406 | + if (singleton) |
407 | + g_object_unref (singleton); |
408 | + singleton = NULL; |
409 | +} |
410 | + |
411 | +static CommonUser * |
412 | +get_user_by_name (CommonUserList *user_list, const gchar *username) |
413 | +{ |
414 | + CommonUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
415 | GList *link; |
416 | |
417 | for (link = priv->users; link; link = link->next) |
418 | { |
419 | - LightDMUser *user = link->data; |
420 | - if (g_strcmp0 (lightdm_user_get_name (user), username) == 0) |
421 | + CommonUser *user = link->data; |
422 | + if (g_strcmp0 (common_user_get_name (user), username) == 0) |
423 | return user; |
424 | } |
425 | |
426 | return NULL; |
427 | } |
428 | |
429 | -static LightDMUser * |
430 | -get_user_by_path (LightDMUserList *user_list, const gchar *path) |
431 | +static CommonUser * |
432 | +get_user_by_path (CommonUserList *user_list, const gchar *path) |
433 | { |
434 | - LightDMUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
435 | + CommonUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
436 | GList *link; |
437 | |
438 | for (link = priv->users; link; link = link->next) |
439 | { |
440 | - LightDMUser *user = link->data; |
441 | + CommonUser *user = link->data; |
442 | if (g_strcmp0 (GET_USER_PRIVATE (user)->path, path) == 0) |
443 | return user; |
444 | } |
445 | @@ -206,25 +226,28 @@ |
446 | static gint |
447 | compare_user (gconstpointer a, gconstpointer b) |
448 | { |
449 | - LightDMUser *user_a = (LightDMUser *) a, *user_b = (LightDMUser *) b; |
450 | - return g_strcmp0 (lightdm_user_get_display_name (user_a), lightdm_user_get_display_name (user_b)); |
451 | + CommonUser *user_a = (CommonUser *) a, *user_b = (CommonUser *) b; |
452 | + return g_strcmp0 (common_user_get_display_name (user_a), common_user_get_display_name (user_b)); |
453 | } |
454 | |
455 | static gboolean |
456 | -update_passwd_user (LightDMUser *user, const gchar *real_name, const gchar *home_directory, const gchar *image) |
457 | +update_passwd_user (CommonUser *user, const gchar *real_name, const gchar *home_directory, const gchar *shell, const gchar *image) |
458 | { |
459 | - LightDMUserPrivate *priv = GET_USER_PRIVATE (user); |
460 | + CommonUserPrivate *priv = GET_USER_PRIVATE (user); |
461 | |
462 | /* Skip if already set to this */ |
463 | - if (g_strcmp0 (lightdm_user_get_real_name (user), real_name) == 0 && |
464 | - g_strcmp0 (lightdm_user_get_home_directory (user), home_directory) == 0 && |
465 | - g_strcmp0 (lightdm_user_get_image (user), image) == 0) |
466 | + if (g_strcmp0 (common_user_get_real_name (user), real_name) == 0 && |
467 | + g_strcmp0 (common_user_get_home_directory (user), home_directory) == 0 && |
468 | + g_strcmp0 (common_user_get_shell (user), shell) == 0 && |
469 | + g_strcmp0 (common_user_get_image (user), image) == 0) |
470 | return FALSE; |
471 | |
472 | g_free (priv->real_name); |
473 | priv->real_name = g_strdup (real_name); |
474 | g_free (priv->home_directory); |
475 | priv->home_directory = g_strdup (home_directory); |
476 | + g_free (priv->shell); |
477 | + priv->shell = g_strdup (shell); |
478 | g_free (priv->image); |
479 | priv->image = g_strdup (image); |
480 | |
481 | @@ -232,15 +255,54 @@ |
482 | } |
483 | |
484 | static void |
485 | -user_changed_cb (LightDMUser *user) |
486 | +user_changed_cb (CommonUser *user) |
487 | { |
488 | g_signal_emit (GET_USER_PRIVATE (user)->user_list, list_signals[USER_CHANGED], 0, user); |
489 | } |
490 | |
491 | +static CommonUser * |
492 | +make_passwd_user (CommonUserList *user_list, struct passwd *entry) |
493 | +{ |
494 | + CommonUser *user = g_object_new (COMMON_TYPE_USER, NULL); |
495 | + CommonUserPrivate *priv = GET_USER_PRIVATE (user); |
496 | + char **tokens; |
497 | + gchar *real_name, *image; |
498 | + |
499 | + tokens = g_strsplit (entry->pw_gecos, ",", -1); |
500 | + if (tokens[0] != NULL && tokens[0][0] != '\0') |
501 | + real_name = g_strdup (tokens[0]); |
502 | + else |
503 | + real_name = g_strdup (""); |
504 | + g_strfreev (tokens); |
505 | + |
506 | + image = g_build_filename (entry->pw_dir, ".face", NULL); |
507 | + if (!g_file_test (image, G_FILE_TEST_EXISTS)) |
508 | + { |
509 | + g_free (image); |
510 | + image = g_build_filename (entry->pw_dir, ".face.icon", NULL); |
511 | + if (!g_file_test (image, G_FILE_TEST_EXISTS)) |
512 | + { |
513 | + g_free (image); |
514 | + image = NULL; |
515 | + } |
516 | + } |
517 | + |
518 | + priv->user_list = user_list; |
519 | + priv->name = g_strdup (entry->pw_name); |
520 | + priv->real_name = real_name; |
521 | + priv->home_directory = g_strdup (entry->pw_dir); |
522 | + priv->shell = g_strdup (entry->pw_shell); |
523 | + priv->image = image; |
524 | + priv->uid = entry->pw_uid; |
525 | + priv->gid = entry->pw_gid; |
526 | + |
527 | + return user; |
528 | +} |
529 | + |
530 | static void |
531 | -load_passwd_file (LightDMUserList *user_list, gboolean emit_add_signal) |
532 | +load_passwd_file (CommonUserList *user_list, gboolean emit_add_signal) |
533 | { |
534 | - LightDMUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
535 | + CommonUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
536 | GKeyFile *config; |
537 | gchar *value; |
538 | gint minimum_uid; |
539 | @@ -280,10 +342,7 @@ |
540 | while (TRUE) |
541 | { |
542 | struct passwd *entry; |
543 | - LightDMUser *user; |
544 | - LightDMUserPrivate *user_priv; |
545 | - char **tokens; |
546 | - gchar *real_name, *image; |
547 | + CommonUser *user; |
548 | int i; |
549 | |
550 | errno = 0; |
551 | @@ -308,44 +367,15 @@ |
552 | if (hidden_users[i]) |
553 | continue; |
554 | |
555 | - tokens = g_strsplit (entry->pw_gecos, ",", -1); |
556 | - if (tokens[0] != NULL && tokens[0][0] != '\0') |
557 | - real_name = g_strdup (tokens[0]); |
558 | - else |
559 | - real_name = g_strdup (""); |
560 | - g_strfreev (tokens); |
561 | - |
562 | - image = g_build_filename (entry->pw_dir, ".face", NULL); |
563 | - if (!g_file_test (image, G_FILE_TEST_EXISTS)) |
564 | - { |
565 | - g_free (image); |
566 | - image = g_build_filename (entry->pw_dir, ".face.icon", NULL); |
567 | - if (!g_file_test (image, G_FILE_TEST_EXISTS)) |
568 | - { |
569 | - g_free (image); |
570 | - image = NULL; |
571 | - } |
572 | - } |
573 | - |
574 | - user = g_object_new (LIGHTDM_TYPE_USER, NULL); |
575 | - user_priv = GET_USER_PRIVATE (user); |
576 | - user_priv->user_list = user_list; |
577 | - g_free (user_priv->name); |
578 | - user_priv->name = g_strdup (entry->pw_name); |
579 | - g_free (user_priv->real_name); |
580 | - user_priv->real_name = real_name; |
581 | - g_free (user_priv->home_directory); |
582 | - user_priv->home_directory = g_strdup (entry->pw_dir); |
583 | - g_free (user_priv->image); |
584 | - user_priv->image = image; |
585 | + user = make_passwd_user (user_list, entry); |
586 | |
587 | /* Update existing users if have them */ |
588 | for (link = priv->users; link; link = link->next) |
589 | { |
590 | - LightDMUser *info = link->data; |
591 | - if (strcmp (lightdm_user_get_name (info), lightdm_user_get_name (user)) == 0) |
592 | + CommonUser *info = link->data; |
593 | + if (strcmp (common_user_get_name (info), common_user_get_name (user)) == 0) |
594 | { |
595 | - if (update_passwd_user (info, lightdm_user_get_real_name (user), lightdm_user_get_home_directory (user), lightdm_user_get_image (user))) |
596 | + if (update_passwd_user (info, common_user_get_real_name (user), common_user_get_home_directory (user), common_user_get_shell (user), common_user_get_image (user))) |
597 | changed_users = g_list_insert_sorted (changed_users, info, compare_user); |
598 | g_object_unref (user); |
599 | user = info; |
600 | @@ -375,8 +405,8 @@ |
601 | /* Notify of changes */ |
602 | for (link = new_users; link; link = link->next) |
603 | { |
604 | - LightDMUser *info = link->data; |
605 | - g_debug ("User %s added", lightdm_user_get_name (info)); |
606 | + CommonUser *info = link->data; |
607 | + g_debug ("User %s added", common_user_get_name (info)); |
608 | g_signal_connect (info, "changed", G_CALLBACK (user_changed_cb), NULL); |
609 | if (emit_add_signal) |
610 | g_signal_emit (user_list, list_signals[USER_ADDED], 0, info); |
611 | @@ -384,8 +414,8 @@ |
612 | g_list_free (new_users); |
613 | for (link = changed_users; link; link = link->next) |
614 | { |
615 | - LightDMUser *info = link->data; |
616 | - g_debug ("User %s changed", lightdm_user_get_name (info)); |
617 | + CommonUser *info = link->data; |
618 | + g_debug ("User %s changed", common_user_get_name (info)); |
619 | g_signal_emit (info, user_signals[CHANGED], 0); |
620 | } |
621 | g_list_free (changed_users); |
622 | @@ -402,8 +432,8 @@ |
623 | |
624 | if (!new_link) |
625 | { |
626 | - LightDMUser *info = link->data; |
627 | - g_debug ("User %s removed", lightdm_user_get_name (info)); |
628 | + CommonUser *info = link->data; |
629 | + g_debug ("User %s removed", common_user_get_name (info)); |
630 | g_signal_emit (user_list, list_signals[USER_REMOVED], 0, info); |
631 | g_object_unref (info); |
632 | } |
633 | @@ -412,7 +442,7 @@ |
634 | } |
635 | |
636 | static void |
637 | -passwd_changed_cb (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, LightDMUserList *user_list) |
638 | +passwd_changed_cb (GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, CommonUserList *user_list) |
639 | { |
640 | if (event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT) |
641 | { |
642 | @@ -421,7 +451,7 @@ |
643 | } |
644 | } |
645 | |
646 | -static gboolean load_accounts_user (LightDMUser *user); |
647 | +static gboolean load_accounts_user (CommonUser *user); |
648 | |
649 | static void |
650 | accounts_user_changed_cb (GDBusConnection *connection, |
651 | @@ -432,8 +462,8 @@ |
652 | GVariant *parameters, |
653 | gpointer data) |
654 | { |
655 | - LightDMUser *user = data; |
656 | - LightDMUserPrivate *priv = GET_USER_PRIVATE (user); |
657 | + CommonUser *user = data; |
658 | + CommonUserPrivate *priv = GET_USER_PRIVATE (user); |
659 | |
660 | g_debug ("User %s changed", priv->path); |
661 | if (load_accounts_user (user)) |
662 | @@ -441,9 +471,9 @@ |
663 | } |
664 | |
665 | static gboolean |
666 | -load_accounts_user (LightDMUser *user) |
667 | +load_accounts_user (CommonUser *user) |
668 | { |
669 | - LightDMUserPrivate *priv = GET_USER_PRIVATE (user); |
670 | + CommonUserPrivate *priv = GET_USER_PRIVATE (user); |
671 | GVariant *result, *value; |
672 | GVariantIter *iter; |
673 | gchar *name; |
674 | @@ -498,6 +528,11 @@ |
675 | g_free (priv->home_directory); |
676 | priv->home_directory = g_variant_dup_string (value, NULL); |
677 | } |
678 | + else if (strcmp (name, "Shell") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) |
679 | + { |
680 | + g_free (priv->shell); |
681 | + priv->shell = g_variant_dup_string (value, NULL); |
682 | + } |
683 | else if (strcmp (name, "SystemAccount") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)) |
684 | system_account = g_variant_get_boolean (value); |
685 | else if (strcmp (name, "Language") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) |
686 | @@ -543,6 +578,8 @@ |
687 | } |
688 | else if (strcmp (name, "XHasMessages") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)) |
689 | priv->has_messages = g_variant_get_boolean (value); |
690 | + else if (strcmp (name, "Uid") == 0 && g_variant_is_of_type (value, G_VARIANT_TYPE_UINT64)) |
691 | + priv->uid = g_variant_get_uint64 (value); |
692 | } |
693 | g_variant_iter_free (iter); |
694 | |
695 | @@ -554,13 +591,13 @@ |
696 | } |
697 | |
698 | static void |
699 | -add_accounts_user (LightDMUserList *user_list, const gchar *path, gboolean emit_signal) |
700 | +add_accounts_user (CommonUserList *user_list, const gchar *path, gboolean emit_signal) |
701 | { |
702 | - LightDMUserListPrivate *list_priv = GET_LIST_PRIVATE (user_list); |
703 | - LightDMUser *user; |
704 | - LightDMUserPrivate *priv; |
705 | + CommonUserListPrivate *list_priv = GET_LIST_PRIVATE (user_list); |
706 | + CommonUser *user; |
707 | + CommonUserPrivate *priv; |
708 | |
709 | - user = g_object_new (LIGHTDM_TYPE_USER, NULL); |
710 | + user = g_object_new (COMMON_TYPE_USER, NULL); |
711 | priv = GET_USER_PRIVATE (user); |
712 | |
713 | g_debug ("User %s added", path); |
714 | @@ -586,9 +623,9 @@ |
715 | GVariant *parameters, |
716 | gpointer data) |
717 | { |
718 | - LightDMUserList *user_list = data; |
719 | + CommonUserList *user_list = data; |
720 | gchar *path; |
721 | - LightDMUser *user; |
722 | + CommonUser *user; |
723 | |
724 | if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(o)"))) |
725 | { |
726 | @@ -613,10 +650,10 @@ |
727 | GVariant *parameters, |
728 | gpointer data) |
729 | { |
730 | - LightDMUserList *user_list = data; |
731 | - LightDMUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
732 | + CommonUserList *user_list = data; |
733 | + CommonUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
734 | gchar *path; |
735 | - LightDMUser *user; |
736 | + CommonUser *user; |
737 | |
738 | if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(o)"))) |
739 | { |
740 | @@ -639,11 +676,11 @@ |
741 | } |
742 | } |
743 | |
744 | -static Session * |
745 | -load_session (LightDMUserList *user_list, const gchar *path) |
746 | +static CommonSession * |
747 | +load_session (CommonUserList *user_list, const gchar *path) |
748 | { |
749 | - LightDMUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
750 | - Session *session = NULL; |
751 | + CommonUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
752 | + CommonSession *session = NULL; |
753 | GVariant *result, *username; |
754 | GError *error = NULL; |
755 | |
756 | @@ -672,7 +709,7 @@ |
757 | g_variant_get (username, "&s", &name); |
758 | |
759 | g_debug ("Loaded session %s (%s)", path, name); |
760 | - session = g_object_new (session_get_type (), NULL); |
761 | + session = g_object_new (common_session_get_type (), NULL); |
762 | session->username = g_strdup (name); |
763 | session->path = g_strdup (path); |
764 | priv->sessions = g_list_append (priv->sessions, session); |
765 | @@ -692,10 +729,10 @@ |
766 | GVariant *parameters, |
767 | gpointer data) |
768 | { |
769 | - LightDMUserList *user_list = data; |
770 | + CommonUserList *user_list = data; |
771 | gchar *path; |
772 | - Session *session; |
773 | - LightDMUser *user = NULL; |
774 | + CommonSession *session; |
775 | + CommonUser *user = NULL; |
776 | |
777 | if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(o)"))) |
778 | { |
779 | @@ -720,8 +757,8 @@ |
780 | GVariant *parameters, |
781 | gpointer data) |
782 | { |
783 | - LightDMUserList *user_list = data; |
784 | - LightDMUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
785 | + CommonUserList *user_list = data; |
786 | + CommonUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
787 | gchar *path; |
788 | GList *link; |
789 | |
790 | @@ -735,10 +772,10 @@ |
791 | |
792 | for (link = priv->sessions; link; link = link->next) |
793 | { |
794 | - Session *session = link->data; |
795 | + CommonSession *session = link->data; |
796 | if (strcmp (session->path, path) == 0) |
797 | { |
798 | - LightDMUser *user; |
799 | + CommonUser *user; |
800 | |
801 | g_debug ("Session %s removed", path); |
802 | priv->sessions = g_list_remove_link (priv->sessions, link); |
803 | @@ -752,9 +789,75 @@ |
804 | } |
805 | |
806 | static void |
807 | -load_users (LightDMUserList *user_list) |
808 | -{ |
809 | - LightDMUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
810 | +load_sessions (CommonUserList *user_list) |
811 | +{ |
812 | + CommonUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
813 | + GVariant *result; |
814 | + GError *error = NULL; |
815 | + |
816 | + priv->session_added_signal = g_dbus_connection_signal_subscribe (priv->bus, |
817 | + "org.freedesktop.DisplayManager", |
818 | + "org.freedesktop.DisplayManager", |
819 | + "SessionAdded", |
820 | + "/org/freedesktop/DisplayManager", |
821 | + NULL, |
822 | + G_DBUS_SIGNAL_FLAGS_NONE, |
823 | + session_added_cb, |
824 | + user_list, |
825 | + NULL); |
826 | + priv->session_removed_signal = g_dbus_connection_signal_subscribe (priv->bus, |
827 | + "org.freedesktop.DisplayManager", |
828 | + "org.freedesktop.DisplayManager", |
829 | + "SessionRemoved", |
830 | + "/org/freedesktop/DisplayManager", |
831 | + NULL, |
832 | + G_DBUS_SIGNAL_FLAGS_NONE, |
833 | + session_removed_cb, |
834 | + user_list, |
835 | + NULL); |
836 | + result = g_dbus_connection_call_sync (priv->bus, |
837 | + "org.freedesktop.DisplayManager", |
838 | + "/org/freedesktop/DisplayManager", |
839 | + "org.freedesktop.DBus.Properties", |
840 | + "Get", |
841 | + g_variant_new ("(ss)", "org.freedesktop.DisplayManager", "Sessions"), |
842 | + G_VARIANT_TYPE ("(v)"), |
843 | + G_DBUS_CALL_FLAGS_NONE, |
844 | + -1, |
845 | + NULL, |
846 | + &error); |
847 | + if (error) |
848 | + g_warning ("Error getting session list from org.freedesktop.DisplayManager: %s", error->message); |
849 | + g_clear_error (&error); |
850 | + if (result) |
851 | + { |
852 | + if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(v)"))) |
853 | + { |
854 | + GVariant *value; |
855 | + GVariantIter *iter; |
856 | + const gchar *path; |
857 | + |
858 | + g_variant_get (result, "(v)", &value); |
859 | + |
860 | + g_debug ("Loading sessions from org.freedesktop.DisplayManager"); |
861 | + g_variant_get (value, "ao", &iter); |
862 | + while (g_variant_iter_loop (iter, "&o", &path)) |
863 | + load_session (user_list, path); |
864 | + g_variant_iter_free (iter); |
865 | + |
866 | + g_variant_unref (value); |
867 | + } |
868 | + else |
869 | + g_warning ("Unexpected type from org.freedesktop.DisplayManager.Sessions: %s", g_variant_get_type_string (result)); |
870 | + |
871 | + g_variant_unref (result); |
872 | + } |
873 | +} |
874 | + |
875 | +static void |
876 | +load_users (CommonUserList *user_list) |
877 | +{ |
878 | + CommonUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
879 | GVariant *result; |
880 | GError *error = NULL; |
881 | |
882 | @@ -831,128 +934,83 @@ |
883 | g_signal_connect (priv->passwd_monitor, "changed", G_CALLBACK (passwd_changed_cb), user_list); |
884 | g_clear_error (&error); |
885 | } |
886 | - |
887 | - priv->session_added_signal = g_dbus_connection_signal_subscribe (priv->bus, |
888 | - "org.freedesktop.DisplayManager", |
889 | - "org.freedesktop.DisplayManager", |
890 | - "SessionAdded", |
891 | - "/org/freedesktop/DisplayManager", |
892 | - NULL, |
893 | - G_DBUS_SIGNAL_FLAGS_NONE, |
894 | - session_added_cb, |
895 | - user_list, |
896 | - NULL); |
897 | - priv->session_removed_signal = g_dbus_connection_signal_subscribe (priv->bus, |
898 | - "org.freedesktop.DisplayManager", |
899 | - "org.freedesktop.DisplayManager", |
900 | - "SessionRemoved", |
901 | - "/org/freedesktop/DisplayManager", |
902 | - NULL, |
903 | - G_DBUS_SIGNAL_FLAGS_NONE, |
904 | - session_removed_cb, |
905 | - |
906 | - user_list, |
907 | - NULL); |
908 | - result = g_dbus_connection_call_sync (priv->bus, |
909 | - "org.freedesktop.DisplayManager", |
910 | - "/org/freedesktop/DisplayManager", |
911 | - "org.freedesktop.DBus.Properties", |
912 | - "Get", |
913 | - g_variant_new ("(ss)", "org.freedesktop.DisplayManager", "Sessions"), |
914 | - G_VARIANT_TYPE ("(v)"), |
915 | - G_DBUS_CALL_FLAGS_NONE, |
916 | - -1, |
917 | - NULL, |
918 | - &error); |
919 | - if (error) |
920 | - g_warning ("Error getting session list from org.freedesktop.DisplayManager: %s", error->message); |
921 | - g_clear_error (&error); |
922 | - if (result) |
923 | - { |
924 | - if (g_variant_is_of_type (result, G_VARIANT_TYPE ("(v)"))) |
925 | - { |
926 | - GVariant *value; |
927 | - GVariantIter *iter; |
928 | - const gchar *path; |
929 | - |
930 | - g_variant_get (result, "(v)", &value); |
931 | - |
932 | - g_debug ("Loading sessions from org.freedesktop.DisplayManager"); |
933 | - g_variant_get (value, "ao", &iter); |
934 | - while (g_variant_iter_loop (iter, "&o", &path)) |
935 | - load_session (user_list, path); |
936 | - g_variant_iter_free (iter); |
937 | - |
938 | - g_variant_unref (value); |
939 | - } |
940 | - else |
941 | - g_warning ("Unexpected type from org.freedesktop.DisplayManager.Sessions: %s", g_variant_get_type_string (result)); |
942 | - |
943 | - g_variant_unref (result); |
944 | - } |
945 | } |
946 | |
947 | /** |
948 | - * lightdm_user_list_get_length: |
949 | - * @user_list: a #LightDMUserList |
950 | + * common_user_list_get_length: |
951 | + * @user_list: a #CommonUserList |
952 | * |
953 | * Return value: The number of users able to log in |
954 | **/ |
955 | gint |
956 | -lightdm_user_list_get_length (LightDMUserList *user_list) |
957 | +common_user_list_get_length (CommonUserList *user_list) |
958 | { |
959 | - g_return_val_if_fail (LIGHTDM_IS_USER_LIST (user_list), 0); |
960 | + g_return_val_if_fail (COMMON_IS_USER_LIST (user_list), 0); |
961 | load_users (user_list); |
962 | return g_list_length (GET_LIST_PRIVATE (user_list)->users); |
963 | } |
964 | |
965 | /** |
966 | - * lightdm_user_list_get_users: |
967 | - * @user_list: A #LightDMUserList |
968 | + * common_user_list_get_users: |
969 | + * @user_list: A #CommonUserList |
970 | * |
971 | * Get a list of users to present to the user. This list may be a subset of the |
972 | * available users and may be empty depending on the server configuration. |
973 | * |
974 | - * Return value: (element-type LightDMUser) (transfer none): A list of #LightDMUser that should be presented to the user. |
975 | + * Return value: (element-type CommonUser) (transfer none): A list of #CommonUser that should be presented to the user. |
976 | **/ |
977 | GList * |
978 | -lightdm_user_list_get_users (LightDMUserList *user_list) |
979 | +common_user_list_get_users (CommonUserList *user_list) |
980 | { |
981 | - g_return_val_if_fail (LIGHTDM_IS_USER_LIST (user_list), NULL); |
982 | + g_return_val_if_fail (COMMON_IS_USER_LIST (user_list), NULL); |
983 | load_users (user_list); |
984 | return GET_LIST_PRIVATE (user_list)->users; |
985 | } |
986 | |
987 | /** |
988 | - * lightdm_user_list_get_user_by_name: |
989 | - * @user_list: A #LightDMUserList |
990 | + * common_user_list_get_user_by_name: |
991 | + * @user_list: A #CommonUserList |
992 | * @username: Name of user to get. |
993 | * |
994 | * Get infomation about a given user or #NULL if this user doesn't exist. |
995 | + * Includes hidden and system users, unlike the list from |
996 | + * common_user_list_get_users. |
997 | * |
998 | - * Return value: (transfer none): A #LightDMUser entry for the given user. |
999 | + * Return value: (transfer full): A #CommonUser entry for the given user. |
1000 | **/ |
1001 | -LightDMUser * |
1002 | -lightdm_user_list_get_user_by_name (LightDMUserList *user_list, const gchar *username) |
1003 | +CommonUser * |
1004 | +common_user_list_get_user_by_name (CommonUserList *user_list, const gchar *username) |
1005 | { |
1006 | - g_return_val_if_fail (LIGHTDM_IS_USER_LIST (user_list), NULL); |
1007 | + g_return_val_if_fail (COMMON_IS_USER_LIST (user_list), NULL); |
1008 | g_return_val_if_fail (username != NULL, NULL); |
1009 | |
1010 | load_users (user_list); |
1011 | |
1012 | - return get_user_by_name (user_list, username); |
1013 | + CommonUser *user = get_user_by_name (user_list, username); |
1014 | + if (user) |
1015 | + return g_object_ref (user); |
1016 | + |
1017 | + /* Sometimes we need to look up users that aren't in AccountsService. |
1018 | + Notably we need to look up the user that the greeter runs as, which |
1019 | + is usually 'lightdm'. For such cases, we manually create a one-off |
1020 | + CommonUser object and pre-seed with passwd info. */ |
1021 | + struct passwd *entry = getpwnam (username); |
1022 | + if (entry != NULL) |
1023 | + return make_passwd_user (user_list, entry); |
1024 | + |
1025 | + return NULL; |
1026 | } |
1027 | |
1028 | static void |
1029 | -lightdm_user_list_init (LightDMUserList *user_list) |
1030 | +common_user_list_init (CommonUserList *user_list) |
1031 | { |
1032 | - LightDMUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
1033 | + CommonUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
1034 | |
1035 | priv->bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); |
1036 | } |
1037 | |
1038 | static void |
1039 | -lightdm_user_list_set_property (GObject *object, |
1040 | +common_user_list_set_property (GObject *object, |
1041 | guint prop_id, |
1042 | const GValue *value, |
1043 | GParamSpec *pspec) |
1044 | @@ -961,19 +1019,19 @@ |
1045 | } |
1046 | |
1047 | static void |
1048 | -lightdm_user_list_get_property (GObject *object, |
1049 | +common_user_list_get_property (GObject *object, |
1050 | guint prop_id, |
1051 | GValue *value, |
1052 | GParamSpec *pspec) |
1053 | { |
1054 | - LightDMUserList *self; |
1055 | + CommonUserList *self; |
1056 | |
1057 | - self = LIGHTDM_USER_LIST (object); |
1058 | + self = COMMON_USER_LIST (object); |
1059 | |
1060 | switch (prop_id) |
1061 | { |
1062 | case LIST_PROP_NUM_USERS: |
1063 | - g_value_set_int (value, lightdm_user_list_get_length (self)); |
1064 | + g_value_set_int (value, common_user_list_get_length (self)); |
1065 | break; |
1066 | default: |
1067 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
1068 | @@ -982,10 +1040,10 @@ |
1069 | } |
1070 | |
1071 | static void |
1072 | -lightdm_user_list_finalize (GObject *object) |
1073 | +common_user_list_finalize (GObject *object) |
1074 | { |
1075 | - LightDMUserList *self = LIGHTDM_USER_LIST (object); |
1076 | - LightDMUserListPrivate *priv = GET_LIST_PRIVATE (self); |
1077 | + CommonUserList *self = COMMON_USER_LIST (object); |
1078 | + CommonUserListPrivate *priv = GET_LIST_PRIVATE (self); |
1079 | |
1080 | /* Remove children first, they might access us */ |
1081 | g_list_free_full (priv->users, g_object_unref); |
1082 | @@ -1003,19 +1061,19 @@ |
1083 | if (priv->passwd_monitor) |
1084 | g_object_unref (priv->passwd_monitor); |
1085 | |
1086 | - G_OBJECT_CLASS (lightdm_user_list_parent_class)->finalize (object); |
1087 | + G_OBJECT_CLASS (common_user_list_parent_class)->finalize (object); |
1088 | } |
1089 | |
1090 | static void |
1091 | -lightdm_user_list_class_init (LightDMUserListClass *klass) |
1092 | +common_user_list_class_init (CommonUserListClass *klass) |
1093 | { |
1094 | GObjectClass *object_class = G_OBJECT_CLASS (klass); |
1095 | |
1096 | - g_type_class_add_private (klass, sizeof (LightDMUserListPrivate)); |
1097 | + g_type_class_add_private (klass, sizeof (CommonUserListPrivate)); |
1098 | |
1099 | - object_class->set_property = lightdm_user_list_set_property; |
1100 | - object_class->get_property = lightdm_user_list_get_property; |
1101 | - object_class->finalize = lightdm_user_list_finalize; |
1102 | + object_class->set_property = common_user_list_set_property; |
1103 | + object_class->get_property = common_user_list_get_property; |
1104 | + object_class->finalize = common_user_list_finalize; |
1105 | |
1106 | g_object_class_install_property (object_class, |
1107 | LIST_PROP_NUM_USERS, |
1108 | @@ -1025,9 +1083,9 @@ |
1109 | 0, G_MAXINT, 0, |
1110 | G_PARAM_READABLE)); |
1111 | /** |
1112 | - * LightDMUserList::user-added: |
1113 | - * @user_list: A #LightDMUserList |
1114 | - * @user: The #LightDM user that has been added. |
1115 | + * CommonUserList::user-added: |
1116 | + * @user_list: A #CommonUserList |
1117 | + * @user: The #CommonUser that has been added. |
1118 | * |
1119 | * The ::user-added signal gets emitted when a user account is created. |
1120 | **/ |
1121 | @@ -1035,15 +1093,15 @@ |
1122 | g_signal_new ("user-added", |
1123 | G_TYPE_FROM_CLASS (klass), |
1124 | G_SIGNAL_RUN_LAST, |
1125 | - G_STRUCT_OFFSET (LightDMUserListClass, user_added), |
1126 | + G_STRUCT_OFFSET (CommonUserListClass, user_added), |
1127 | NULL, NULL, |
1128 | NULL, |
1129 | - G_TYPE_NONE, 1, LIGHTDM_TYPE_USER); |
1130 | + G_TYPE_NONE, 1, COMMON_TYPE_USER); |
1131 | |
1132 | /** |
1133 | - * LightDMUserList::user-changed: |
1134 | - * @user_list: A #LightDMUserList |
1135 | - * @user: The #LightDM user that has been changed. |
1136 | + * CommonUserList::user-changed: |
1137 | + * @user_list: A #CommonUserList |
1138 | + * @user: The #CommonUser that has been changed. |
1139 | * |
1140 | * The ::user-changed signal gets emitted when a user account is modified. |
1141 | **/ |
1142 | @@ -1051,15 +1109,15 @@ |
1143 | g_signal_new ("user-changed", |
1144 | G_TYPE_FROM_CLASS (klass), |
1145 | G_SIGNAL_RUN_LAST, |
1146 | - G_STRUCT_OFFSET (LightDMUserListClass, user_changed), |
1147 | + G_STRUCT_OFFSET (CommonUserListClass, user_changed), |
1148 | NULL, NULL, |
1149 | NULL, |
1150 | - G_TYPE_NONE, 1, LIGHTDM_TYPE_USER); |
1151 | + G_TYPE_NONE, 1, COMMON_TYPE_USER); |
1152 | |
1153 | /** |
1154 | - * LightDMUserList::user-removed: |
1155 | - * @user_list: A #LightDMUserList |
1156 | - * @user: The #LightDM user that has been removed. |
1157 | + * CommonUserList::user-removed: |
1158 | + * @user_list: A #CommonUserList |
1159 | + * @user: The #CommonUser that has been removed. |
1160 | * |
1161 | * The ::user-removed signal gets emitted when a user account is removed. |
1162 | **/ |
1163 | @@ -1067,55 +1125,93 @@ |
1164 | g_signal_new ("user-removed", |
1165 | G_TYPE_FROM_CLASS (klass), |
1166 | G_SIGNAL_RUN_LAST, |
1167 | - G_STRUCT_OFFSET (LightDMUserListClass, user_removed), |
1168 | + G_STRUCT_OFFSET (CommonUserListClass, user_removed), |
1169 | NULL, NULL, |
1170 | NULL, |
1171 | - G_TYPE_NONE, 1, LIGHTDM_TYPE_USER); |
1172 | -} |
1173 | - |
1174 | -static void |
1175 | -load_dmrc (LightDMUser *user) |
1176 | -{ |
1177 | - LightDMUserPrivate *priv = GET_USER_PRIVATE (user); |
1178 | - gchar *path; |
1179 | - //gboolean have_dmrc; |
1180 | - |
1181 | - if (!priv->dmrc_file) |
1182 | - priv->dmrc_file = g_key_file_new (); |
1183 | - |
1184 | - /* Load from the user directory */ |
1185 | - path = g_build_filename (priv->home_directory, ".dmrc", NULL); |
1186 | - /*have_dmrc = */g_key_file_load_from_file (priv->dmrc_file, path, G_KEY_FILE_KEEP_COMMENTS, NULL); |
1187 | - g_free (path); |
1188 | - |
1189 | - /* If no ~/.dmrc, then load from the cache */ |
1190 | - // FIXME |
1191 | + G_TYPE_NONE, 1, COMMON_TYPE_USER); |
1192 | +} |
1193 | + |
1194 | +static gboolean |
1195 | +call_method (CommonUser *user, const gchar *method, GVariant *args, |
1196 | + const gchar *expected, GVariant **result) |
1197 | +{ |
1198 | + GVariant *answer; |
1199 | + GError *error = NULL; |
1200 | + CommonUserPrivate *user_priv = GET_USER_PRIVATE (user); |
1201 | + CommonUserListPrivate *list_priv = GET_LIST_PRIVATE (user_priv->user_list); |
1202 | + |
1203 | + answer = g_dbus_connection_call_sync (list_priv->bus, |
1204 | + "org.freedesktop.Accounts", |
1205 | + user_priv->path, |
1206 | + "org.freedesktop.Accounts.User", |
1207 | + method, |
1208 | + args, |
1209 | + G_VARIANT_TYPE (expected), |
1210 | + G_DBUS_CALL_FLAGS_NONE, |
1211 | + -1, |
1212 | + NULL, |
1213 | + &error); |
1214 | + if (error) |
1215 | + g_warning ("Could not call %s: %s", method, error->message); |
1216 | + g_clear_error (&error); |
1217 | + |
1218 | + if (!answer) |
1219 | + return FALSE; |
1220 | + |
1221 | + if (result) |
1222 | + *result = answer; |
1223 | + else |
1224 | + g_variant_unref (answer); |
1225 | + |
1226 | + return TRUE; |
1227 | +} |
1228 | + |
1229 | +static void |
1230 | +save_string_to_dmrc (CommonUser *user, const gchar *group, |
1231 | + const gchar *key, const gchar *value) |
1232 | +{ |
1233 | + GKeyFile *dmrc; |
1234 | + |
1235 | + dmrc = dmrc_load (user); |
1236 | + g_key_file_set_string (dmrc, group, key, value); |
1237 | + dmrc_save (dmrc, user); |
1238 | + |
1239 | + g_key_file_free (dmrc); |
1240 | +} |
1241 | + |
1242 | +static void |
1243 | +load_dmrc (CommonUser *user) |
1244 | +{ |
1245 | + CommonUserPrivate *priv = GET_USER_PRIVATE (user); |
1246 | + GKeyFile *dmrc; |
1247 | + |
1248 | + dmrc = dmrc_load (user); |
1249 | |
1250 | // FIXME: Watch for changes |
1251 | |
1252 | /* The Language field contains the locale */ |
1253 | - if (priv->language) |
1254 | - g_free (priv->language); |
1255 | - priv->language = g_key_file_get_string (priv->dmrc_file, "Desktop", "Language", NULL); |
1256 | + g_free (priv->language); |
1257 | + priv->language = g_key_file_get_string (dmrc, "Desktop", "Language", NULL); |
1258 | |
1259 | - if (g_key_file_has_key (priv->dmrc_file, "Desktop", "Layout", NULL)) |
1260 | + if (g_key_file_has_key (dmrc, "Desktop", "Layout", NULL)) |
1261 | { |
1262 | g_strfreev (priv->layouts); |
1263 | priv->layouts = g_malloc (sizeof (gchar *) * 2); |
1264 | - priv->layouts[0] = g_key_file_get_string (priv->dmrc_file, "Desktop", "Layout", NULL); |
1265 | + priv->layouts[0] = g_key_file_get_string (dmrc, "Desktop", "Layout", NULL); |
1266 | priv->layouts[1] = NULL; |
1267 | } |
1268 | |
1269 | - if (priv->session) |
1270 | - g_free (priv->session); |
1271 | - priv->session = g_key_file_get_string (priv->dmrc_file, "Desktop", "Session", NULL); |
1272 | + g_free (priv->session); |
1273 | + priv->session = g_key_file_get_string (dmrc, "Desktop", "Session", NULL); |
1274 | + |
1275 | + g_key_file_free (dmrc); |
1276 | } |
1277 | |
1278 | /* Loads language/layout/session info for user */ |
1279 | static void |
1280 | -load_user_values (LightDMUser *user) |
1281 | +load_user_values (CommonUser *user) |
1282 | { |
1283 | - LightDMUserPrivate *priv = GET_USER_PRIVATE (user); |
1284 | + CommonUserPrivate *priv = GET_USER_PRIVATE (user); |
1285 | |
1286 | if (priv->loaded_values) |
1287 | return; |
1288 | @@ -1126,51 +1222,51 @@ |
1289 | } |
1290 | |
1291 | /** |
1292 | - * lightdm_user_get_name: |
1293 | - * @user: A #LightDMUser |
1294 | + * common_user_get_name: |
1295 | + * @user: A #CommonUser |
1296 | * |
1297 | * Get the name of a user. |
1298 | * |
1299 | * Return value: The name of the given user |
1300 | **/ |
1301 | const gchar * |
1302 | -lightdm_user_get_name (LightDMUser *user) |
1303 | +common_user_get_name (CommonUser *user) |
1304 | { |
1305 | - g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
1306 | + g_return_val_if_fail (COMMON_IS_USER (user), NULL); |
1307 | load_user_values (user); |
1308 | return GET_USER_PRIVATE (user)->name; |
1309 | } |
1310 | |
1311 | /** |
1312 | - * lightdm_user_get_real_name: |
1313 | - * @user: A #LightDMUser |
1314 | + * common_user_get_real_name: |
1315 | + * @user: A #CommonUser |
1316 | * |
1317 | * Get the real name of a user. |
1318 | * |
1319 | * Return value: The real name of the given user |
1320 | **/ |
1321 | const gchar * |
1322 | -lightdm_user_get_real_name (LightDMUser *user) |
1323 | +common_user_get_real_name (CommonUser *user) |
1324 | { |
1325 | - g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
1326 | + g_return_val_if_fail (COMMON_IS_USER (user), NULL); |
1327 | load_user_values (user); |
1328 | return GET_USER_PRIVATE (user)->real_name; |
1329 | } |
1330 | |
1331 | /** |
1332 | - * lightdm_user_get_display_name: |
1333 | - * @user: A #LightDMUser |
1334 | + * common_user_get_display_name: |
1335 | + * @user: A #CommonUser |
1336 | * |
1337 | * Get the display name of a user. |
1338 | * |
1339 | * Return value: The display name of the given user |
1340 | **/ |
1341 | const gchar * |
1342 | -lightdm_user_get_display_name (LightDMUser *user) |
1343 | +common_user_get_display_name (CommonUser *user) |
1344 | { |
1345 | - LightDMUserPrivate *priv; |
1346 | + CommonUserPrivate *priv; |
1347 | |
1348 | - g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
1349 | + g_return_val_if_fail (COMMON_IS_USER (user), NULL); |
1350 | |
1351 | load_user_values (user); |
1352 | |
1353 | @@ -1182,140 +1278,198 @@ |
1354 | } |
1355 | |
1356 | /** |
1357 | - * lightdm_user_get_home_directory: |
1358 | - * @user: A #LightDMUser |
1359 | + * common_user_get_home_directory: |
1360 | + * @user: A #CommonUser |
1361 | * |
1362 | * Get the home directory for a user. |
1363 | * |
1364 | * Return value: The users home directory |
1365 | */ |
1366 | const gchar * |
1367 | -lightdm_user_get_home_directory (LightDMUser *user) |
1368 | +common_user_get_home_directory (CommonUser *user) |
1369 | { |
1370 | - g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
1371 | + g_return_val_if_fail (COMMON_IS_USER (user), NULL); |
1372 | load_user_values (user); |
1373 | return GET_USER_PRIVATE (user)->home_directory; |
1374 | } |
1375 | |
1376 | /** |
1377 | - * lightdm_user_get_image: |
1378 | - * @user: A #LightDMUser |
1379 | + * common_user_get_shell: |
1380 | + * @user: A #CommonUser |
1381 | + * |
1382 | + * Get the shell for a user. |
1383 | + * |
1384 | + * Return value: The user's shell |
1385 | + */ |
1386 | +const gchar * |
1387 | +common_user_get_shell (CommonUser *user) |
1388 | +{ |
1389 | + g_return_val_if_fail (COMMON_IS_USER (user), NULL); |
1390 | + load_user_values (user); |
1391 | + return GET_USER_PRIVATE (user)->shell; |
1392 | +} |
1393 | + |
1394 | +/** |
1395 | + * common_user_get_image: |
1396 | + * @user: A #CommonUser |
1397 | * |
1398 | * Get the image URI for a user. |
1399 | * |
1400 | * Return value: The image URI for the given user or #NULL if no URI |
1401 | **/ |
1402 | const gchar * |
1403 | -lightdm_user_get_image (LightDMUser *user) |
1404 | +common_user_get_image (CommonUser *user) |
1405 | { |
1406 | - g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
1407 | + g_return_val_if_fail (COMMON_IS_USER (user), NULL); |
1408 | load_user_values (user); |
1409 | return GET_USER_PRIVATE (user)->image; |
1410 | } |
1411 | |
1412 | /** |
1413 | - * lightdm_user_get_background: |
1414 | - * @user: A #LightDMUser |
1415 | + * common_user_get_background: |
1416 | + * @user: A #CommonUser |
1417 | * |
1418 | * Get the background file path for a user. |
1419 | * |
1420 | * Return value: The background file path for the given user or #NULL if no path |
1421 | **/ |
1422 | const gchar * |
1423 | -lightdm_user_get_background (LightDMUser *user) |
1424 | +common_user_get_background (CommonUser *user) |
1425 | { |
1426 | - g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
1427 | + g_return_val_if_fail (COMMON_IS_USER (user), NULL); |
1428 | load_user_values (user); |
1429 | return GET_USER_PRIVATE (user)->background; |
1430 | } |
1431 | |
1432 | /** |
1433 | - * lightdm_user_get_language: |
1434 | - * @user: A #LightDMUser |
1435 | + * common_user_get_language: |
1436 | + * @user: A #CommonUser |
1437 | * |
1438 | * Get the language for a user. |
1439 | * |
1440 | * Return value: The language in the form of a local specification (e.g. "de_DE.UTF-8") for the given user or #NULL if using the system default locale. |
1441 | **/ |
1442 | const gchar * |
1443 | -lightdm_user_get_language (LightDMUser *user) |
1444 | +common_user_get_language (CommonUser *user) |
1445 | { |
1446 | - g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
1447 | + g_return_val_if_fail (COMMON_IS_USER (user), NULL); |
1448 | load_user_values (user); |
1449 | - return GET_USER_PRIVATE (user)->language; |
1450 | -} |
1451 | - |
1452 | -/** |
1453 | - * lightdm_user_get_layout: |
1454 | - * @user: A #LightDMUser |
1455 | + const gchar *language = GET_USER_PRIVATE (user)->language; |
1456 | + return (language && language[0] == 0) ? NULL : language; /* Treat "" as NULL */ |
1457 | +} |
1458 | + |
1459 | +/** |
1460 | + * common_user_set_language: |
1461 | + * @user: A #CommonUser |
1462 | + * @language: The user's new language |
1463 | + * |
1464 | + * Set the language for a user. |
1465 | + **/ |
1466 | +void |
1467 | +common_user_set_language (CommonUser *user, const gchar *language) |
1468 | +{ |
1469 | + g_return_if_fail (COMMON_IS_USER (user)); |
1470 | + if (g_strcmp0 (common_user_get_language (user), language) != 0) |
1471 | + { |
1472 | + call_method (user, "SetLanguage", g_variant_new ("(s)", language), "()", NULL); |
1473 | + save_string_to_dmrc (user, "Desktop", "Language", language); |
1474 | + } |
1475 | +} |
1476 | + |
1477 | +/** |
1478 | + * common_user_get_layout: |
1479 | + * @user: A #CommonUser |
1480 | * |
1481 | * Get the keyboard layout for a user. |
1482 | * |
1483 | * Return value: The keyboard layout for the given user or #NULL if using system defaults. Copy the value if you want to use it long term. |
1484 | **/ |
1485 | const gchar * |
1486 | -lightdm_user_get_layout (LightDMUser *user) |
1487 | +common_user_get_layout (CommonUser *user) |
1488 | { |
1489 | - g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
1490 | + g_return_val_if_fail (COMMON_IS_USER (user), NULL); |
1491 | load_user_values (user); |
1492 | return GET_USER_PRIVATE (user)->layouts[0]; |
1493 | } |
1494 | |
1495 | /** |
1496 | - * lightdm_user_get_layouts: |
1497 | - * @user: A #LightDMUser |
1498 | + * common_user_get_layouts: |
1499 | + * @user: A #CommonUser |
1500 | * |
1501 | * Get the configured keyboard layouts for a user. |
1502 | * |
1503 | * Return value: (transfer none): A NULL-terminated array of keyboard layouts for the given user. Copy the values if you want to use them long term. |
1504 | **/ |
1505 | const gchar * const * |
1506 | -lightdm_user_get_layouts (LightDMUser *user) |
1507 | +common_user_get_layouts (CommonUser *user) |
1508 | { |
1509 | - g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
1510 | + g_return_val_if_fail (COMMON_IS_USER (user), NULL); |
1511 | load_user_values (user); |
1512 | return (const gchar * const *) GET_USER_PRIVATE (user)->layouts; |
1513 | } |
1514 | |
1515 | /** |
1516 | - * lightdm_user_get_session: |
1517 | - * @user: A #LightDMUser |
1518 | + * common_user_get_session: |
1519 | + * @user: A #CommonUser |
1520 | * |
1521 | * Get the session for a user. |
1522 | * |
1523 | * Return value: The session for the given user or #NULL if using system defaults. |
1524 | **/ |
1525 | const gchar * |
1526 | -lightdm_user_get_session (LightDMUser *user) |
1527 | +common_user_get_session (CommonUser *user) |
1528 | { |
1529 | - g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
1530 | + g_return_val_if_fail (COMMON_IS_USER (user), NULL); |
1531 | load_user_values (user); |
1532 | - return GET_USER_PRIVATE (user)->session; |
1533 | -} |
1534 | - |
1535 | -/** |
1536 | - * lightdm_user_get_logged_in: |
1537 | - * @user: A #LightDMUser |
1538 | + const gchar *session = GET_USER_PRIVATE (user)->session; |
1539 | + return (session && session[0] == 0) ? NULL : session; /* Treat "" as NULL */ |
1540 | +} |
1541 | + |
1542 | +/** |
1543 | + * common_user_set_session: |
1544 | + * @user: A #CommonUser |
1545 | + * @language: The user's new session |
1546 | + * |
1547 | + * Set the session for a user. |
1548 | + **/ |
1549 | +void |
1550 | +common_user_set_session (CommonUser *user, const gchar *session) |
1551 | +{ |
1552 | + g_return_if_fail (COMMON_IS_USER (user)); |
1553 | + if (g_strcmp0 (common_user_get_session (user), session) != 0) |
1554 | + { |
1555 | + call_method (user, "SetXSession", g_variant_new ("(s)", session), "()", NULL); |
1556 | + save_string_to_dmrc (user, "Desktop", "Session", session); |
1557 | + } |
1558 | +} |
1559 | + |
1560 | +/** |
1561 | + * common_user_get_logged_in: |
1562 | + * @user: A #CommonUser |
1563 | * |
1564 | * Check if a user is logged in. |
1565 | * |
1566 | * Return value: #TRUE if the user is currently logged in. |
1567 | **/ |
1568 | gboolean |
1569 | -lightdm_user_get_logged_in (LightDMUser *user) |
1570 | +common_user_get_logged_in (CommonUser *user) |
1571 | { |
1572 | - LightDMUserPrivate *priv; |
1573 | - LightDMUserListPrivate *list_priv; |
1574 | + CommonUserPrivate *priv; |
1575 | + CommonUserListPrivate *list_priv; |
1576 | GList *link; |
1577 | |
1578 | - g_return_val_if_fail (LIGHTDM_IS_USER (user), FALSE); |
1579 | + g_return_val_if_fail (COMMON_IS_USER (user), FALSE); |
1580 | |
1581 | priv = GET_USER_PRIVATE (user); |
1582 | list_priv = GET_LIST_PRIVATE (priv->user_list); |
1583 | |
1584 | + // Lazily decide to load/listen to sessions |
1585 | + if (list_priv->session_added_signal == 0) |
1586 | + load_sessions (priv->user_list); |
1587 | + |
1588 | for (link = list_priv->sessions; link; link = link->next) |
1589 | { |
1590 | - Session *session = link->data; |
1591 | + CommonSession *session = link->data; |
1592 | if (strcmp (session->username, priv->name) == 0) |
1593 | return TRUE; |
1594 | } |
1595 | @@ -1324,31 +1478,73 @@ |
1596 | } |
1597 | |
1598 | /** |
1599 | - * lightdm_user_get_has_messages: |
1600 | - * @user: A #LightDMUser |
1601 | + * common_user_get_has_messages: |
1602 | + * @user: A #CommonUser |
1603 | * |
1604 | * Check if a user has waiting messages. |
1605 | * |
1606 | * Return value: #TRUE if the user has waiting messages. |
1607 | **/ |
1608 | gboolean |
1609 | -lightdm_user_get_has_messages (LightDMUser *user) |
1610 | +common_user_get_has_messages (CommonUser *user) |
1611 | { |
1612 | - g_return_val_if_fail (LIGHTDM_IS_USER (user), FALSE); |
1613 | + g_return_val_if_fail (COMMON_IS_USER (user), FALSE); |
1614 | load_user_values (user); |
1615 | return GET_USER_PRIVATE (user)->has_messages; |
1616 | } |
1617 | |
1618 | +/** |
1619 | + * common_user_get_uid: |
1620 | + * @user: A #CommonUser |
1621 | + * |
1622 | + * Get the uid of a user |
1623 | + * |
1624 | + * Return value: The user's uid |
1625 | + **/ |
1626 | +uid_t |
1627 | +common_user_get_uid (CommonUser *user) |
1628 | +{ |
1629 | + g_return_val_if_fail (COMMON_IS_USER (user), 0); |
1630 | + load_user_values (user); |
1631 | + return GET_USER_PRIVATE (user)->uid; |
1632 | +} |
1633 | + |
1634 | +/** |
1635 | + * common_user_get_gid: |
1636 | + * @user: A #CommonUser |
1637 | + * |
1638 | + * Get the gid of a user |
1639 | + * |
1640 | + * Return value: The user's gid |
1641 | + **/ |
1642 | +gid_t |
1643 | +common_user_get_gid (CommonUser *user) |
1644 | +{ |
1645 | + g_return_val_if_fail (COMMON_IS_USER (user), 0); |
1646 | + load_user_values (user); |
1647 | + /* gid is not actually stored in AccountsService, so if our user is from |
1648 | + AccountsService, we have to look up manually in passwd. gid won't |
1649 | + change, so just look up the first time we're asked and never again. */ |
1650 | + CommonUserPrivate *priv = GET_USER_PRIVATE (user); |
1651 | + if (priv->uid != 0 && priv->gid == 0) |
1652 | + { |
1653 | + struct passwd *entry = getpwuid (priv->uid); |
1654 | + if (entry != NULL) |
1655 | + priv->gid = entry->pw_gid; |
1656 | + } |
1657 | + return priv->gid; |
1658 | +} |
1659 | + |
1660 | static void |
1661 | -lightdm_user_init (LightDMUser *user) |
1662 | +common_user_init (CommonUser *user) |
1663 | { |
1664 | - LightDMUserPrivate *priv = GET_USER_PRIVATE (user); |
1665 | + CommonUserPrivate *priv = GET_USER_PRIVATE (user); |
1666 | priv->layouts = g_malloc (sizeof (gchar *) * 1); |
1667 | priv->layouts[0] = NULL; |
1668 | } |
1669 | |
1670 | static void |
1671 | -lightdm_user_set_property (GObject *object, |
1672 | +common_user_set_property (GObject *object, |
1673 | guint prop_id, |
1674 | const GValue *value, |
1675 | GParamSpec *pspec) |
1676 | @@ -1357,52 +1553,61 @@ |
1677 | } |
1678 | |
1679 | static void |
1680 | -lightdm_user_get_property (GObject *object, |
1681 | +common_user_get_property (GObject *object, |
1682 | guint prop_id, |
1683 | GValue *value, |
1684 | GParamSpec *pspec) |
1685 | { |
1686 | - LightDMUser *self; |
1687 | + CommonUser *self; |
1688 | |
1689 | - self = LIGHTDM_USER (object); |
1690 | + self = COMMON_USER (object); |
1691 | |
1692 | switch (prop_id) |
1693 | { |
1694 | case USER_PROP_NAME: |
1695 | - g_value_set_string (value, lightdm_user_get_name (self)); |
1696 | + g_value_set_string (value, common_user_get_name (self)); |
1697 | break; |
1698 | case USER_PROP_REAL_NAME: |
1699 | - g_value_set_string (value, lightdm_user_get_real_name (self)); |
1700 | + g_value_set_string (value, common_user_get_real_name (self)); |
1701 | break; |
1702 | case USER_PROP_DISPLAY_NAME: |
1703 | - g_value_set_string (value, lightdm_user_get_display_name (self)); |
1704 | + g_value_set_string (value, common_user_get_display_name (self)); |
1705 | break; |
1706 | case USER_PROP_HOME_DIRECTORY: |
1707 | - g_value_set_string (value, lightdm_user_get_home_directory (self)); |
1708 | + g_value_set_string (value, common_user_get_home_directory (self)); |
1709 | + break; |
1710 | + case USER_PROP_SHELL: |
1711 | + g_value_set_string (value, common_user_get_shell (self)); |
1712 | break; |
1713 | case USER_PROP_IMAGE: |
1714 | - g_value_set_string (value, lightdm_user_get_image (self)); |
1715 | + g_value_set_string (value, common_user_get_image (self)); |
1716 | break; |
1717 | case USER_PROP_BACKGROUND: |
1718 | - g_value_set_string (value, lightdm_user_get_background (self)); |
1719 | + g_value_set_string (value, common_user_get_background (self)); |
1720 | break; |
1721 | case USER_PROP_LANGUAGE: |
1722 | - g_value_set_string (value, lightdm_user_get_language (self)); |
1723 | + g_value_set_string (value, common_user_get_language (self)); |
1724 | break; |
1725 | case USER_PROP_LAYOUT: |
1726 | - g_value_set_string (value, lightdm_user_get_layout (self)); |
1727 | + g_value_set_string (value, common_user_get_layout (self)); |
1728 | break; |
1729 | case USER_PROP_LAYOUTS: |
1730 | - g_value_set_boxed (value, g_strdupv ((gchar **) lightdm_user_get_layouts (self))); |
1731 | + g_value_set_boxed (value, g_strdupv ((gchar **) common_user_get_layouts (self))); |
1732 | break; |
1733 | case USER_PROP_SESSION: |
1734 | - g_value_set_string (value, lightdm_user_get_session (self)); |
1735 | + g_value_set_string (value, common_user_get_session (self)); |
1736 | break; |
1737 | case USER_PROP_LOGGED_IN: |
1738 | - g_value_set_boolean (value, lightdm_user_get_logged_in (self)); |
1739 | + g_value_set_boolean (value, common_user_get_logged_in (self)); |
1740 | break; |
1741 | case USER_PROP_HAS_MESSAGES: |
1742 | - g_value_set_boolean (value, lightdm_user_get_has_messages (self)); |
1743 | + g_value_set_boolean (value, common_user_get_has_messages (self)); |
1744 | + break; |
1745 | + case USER_PROP_UID: |
1746 | + g_value_set_uint64 (value, common_user_get_uid (self)); |
1747 | + break; |
1748 | + case USER_PROP_GID: |
1749 | + g_value_set_uint64 (value, common_user_get_gid (self)); |
1750 | break; |
1751 | default: |
1752 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
1753 | @@ -1411,10 +1616,10 @@ |
1754 | } |
1755 | |
1756 | static void |
1757 | -lightdm_user_finalize (GObject *object) |
1758 | +common_user_finalize (GObject *object) |
1759 | { |
1760 | - LightDMUser *self = LIGHTDM_USER (object); |
1761 | - LightDMUserPrivate *priv = GET_USER_PRIVATE (self); |
1762 | + CommonUser *self = COMMON_USER (object); |
1763 | + CommonUserPrivate *priv = GET_USER_PRIVATE (self); |
1764 | |
1765 | g_free (priv->path); |
1766 | if (priv->changed_signal) |
1767 | @@ -1422,23 +1627,22 @@ |
1768 | g_free (priv->name); |
1769 | g_free (priv->real_name); |
1770 | g_free (priv->home_directory); |
1771 | + g_free (priv->shell); |
1772 | g_free (priv->image); |
1773 | g_free (priv->background); |
1774 | g_strfreev (priv->layouts); |
1775 | - if (priv->dmrc_file) |
1776 | - g_key_file_free (priv->dmrc_file); |
1777 | } |
1778 | |
1779 | static void |
1780 | -lightdm_user_class_init (LightDMUserClass *klass) |
1781 | +common_user_class_init (CommonUserClass *klass) |
1782 | { |
1783 | GObjectClass *object_class = G_OBJECT_CLASS (klass); |
1784 | |
1785 | - g_type_class_add_private (klass, sizeof (LightDMUserPrivate)); |
1786 | + g_type_class_add_private (klass, sizeof (CommonUserPrivate)); |
1787 | |
1788 | - object_class->set_property = lightdm_user_set_property; |
1789 | - object_class->get_property = lightdm_user_get_property; |
1790 | - object_class->finalize = lightdm_user_finalize; |
1791 | + object_class->set_property = common_user_set_property; |
1792 | + object_class->get_property = common_user_get_property; |
1793 | + object_class->finalize = common_user_finalize; |
1794 | |
1795 | g_object_class_install_property (object_class, |
1796 | USER_PROP_NAME, |
1797 | @@ -1469,6 +1673,13 @@ |
1798 | NULL, |
1799 | G_PARAM_READWRITE)); |
1800 | g_object_class_install_property (object_class, |
1801 | + USER_PROP_SHELL, |
1802 | + g_param_spec_string ("shell", |
1803 | + "shell", |
1804 | + "Shell", |
1805 | + NULL, |
1806 | + G_PARAM_READWRITE)); |
1807 | + g_object_class_install_property (object_class, |
1808 | USER_PROP_IMAGE, |
1809 | g_param_spec_string ("image", |
1810 | "image", |
1811 | @@ -1524,10 +1735,28 @@ |
1812 | "TRUE if the user is has waiting messages", |
1813 | FALSE, |
1814 | G_PARAM_READWRITE)); |
1815 | + g_object_class_install_property (object_class, |
1816 | + USER_PROP_UID, |
1817 | + g_param_spec_uint64 ("uid", |
1818 | + "uid", |
1819 | + "Uid", |
1820 | + 0, |
1821 | + G_MAXUINT64, |
1822 | + 0, |
1823 | + G_PARAM_READWRITE)); |
1824 | + g_object_class_install_property (object_class, |
1825 | + USER_PROP_GID, |
1826 | + g_param_spec_uint64 ("gd", |
1827 | + "gid", |
1828 | + "Gid", |
1829 | + 0, |
1830 | + G_MAXUINT64, |
1831 | + 0, |
1832 | + G_PARAM_READWRITE)); |
1833 | |
1834 | /** |
1835 | - * LightDMUser::changed: |
1836 | - * @user: A #LightDMUser |
1837 | + * CommonUser::changed: |
1838 | + * @user: A #CommonUser |
1839 | * |
1840 | * The ::changed signal gets emitted this user account is modified. |
1841 | **/ |
1842 | @@ -1535,29 +1764,29 @@ |
1843 | g_signal_new ("changed", |
1844 | G_TYPE_FROM_CLASS (klass), |
1845 | G_SIGNAL_RUN_LAST, |
1846 | - G_STRUCT_OFFSET (LightDMUserClass, changed), |
1847 | + G_STRUCT_OFFSET (CommonUserClass, changed), |
1848 | NULL, NULL, |
1849 | NULL, |
1850 | G_TYPE_NONE, 0); |
1851 | } |
1852 | |
1853 | static void |
1854 | -session_init (Session *session) |
1855 | +common_session_init (CommonSession *common_session) |
1856 | { |
1857 | } |
1858 | |
1859 | static void |
1860 | -session_finalize (GObject *object) |
1861 | +common_session_finalize (GObject *object) |
1862 | { |
1863 | - Session *self = SESSION (object); |
1864 | + CommonSession *self = COMMON_SESSION (object); |
1865 | |
1866 | g_free (self->path); |
1867 | g_free (self->username); |
1868 | } |
1869 | |
1870 | static void |
1871 | -session_class_init (SessionClass *klass) |
1872 | +common_session_class_init (CommonSessionClass *klass) |
1873 | { |
1874 | GObjectClass *object_class = G_OBJECT_CLASS (klass); |
1875 | - object_class->finalize = session_finalize; |
1876 | + object_class->finalize = common_session_finalize; |
1877 | } |
1878 | |
1879 | === added file 'common/user-list.h' |
1880 | --- common/user-list.h 1970-01-01 00:00:00 +0000 |
1881 | +++ common/user-list.h 2014-02-08 22:36:44 +0000 |
1882 | @@ -0,0 +1,111 @@ |
1883 | +/* |
1884 | + * Copyright (C) 2010 Robert Ancell. |
1885 | + * Copyright (C) 2014 Canonical, Ltd. |
1886 | + * Authors: Robert Ancell <robert.ancell@canonical.com> |
1887 | + * Michael Terry <michael.terry@canonical.com> |
1888 | + * |
1889 | + * This library is free software; you can redistribute it and/or modify it under |
1890 | + * the terms of the GNU Lesser General Public License as published by the Free |
1891 | + * Software Foundation; either version 2 or version 3 of the License. |
1892 | + * See http://www.gnu.org/copyleft/lgpl.html the full text of the license. |
1893 | + */ |
1894 | + |
1895 | +#ifndef COMMON_USER_LIST_H_ |
1896 | +#define COMMON_USER_LIST_H_ |
1897 | + |
1898 | +#include <glib-object.h> |
1899 | +#include <sys/types.h> |
1900 | + |
1901 | +G_BEGIN_DECLS |
1902 | + |
1903 | +#define COMMON_TYPE_USER_LIST (common_user_list_get_type()) |
1904 | +#define COMMON_USER_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COMMON_TYPE_USER_LIST, CommonUserList)); |
1905 | +#define COMMON_USER_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COMMON_TYPE_USER_LIST, CommonUserListClass)) |
1906 | +#define COMMON_IS_USER_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COMMON_TYPE_USER_LIST)) |
1907 | +#define COMMON_IS_USER_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COMMON_TYPE_USER_LIST)) |
1908 | +#define COMMON_USER_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COMMON_TYPE_USER_LIST, CommonUserListClass)) |
1909 | + |
1910 | +#define COMMON_TYPE_USER (common_user_get_type()) |
1911 | +#define COMMON_USER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COMMON_TYPE_USER, CommonUser)); |
1912 | +#define COMMON_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), COMMON_TYPE_USER, CommonUserClass)) |
1913 | +#define COMMON_IS_USER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), COMMON_TYPE_USER)) |
1914 | +#define COMMON_IS_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), COMMON_TYPE_USER)) |
1915 | +#define COMMON_USER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), COMMON_TYPE_USER, CommonUserClass)) |
1916 | + |
1917 | +typedef struct |
1918 | +{ |
1919 | + GObject parent_instance; |
1920 | +} CommonUser; |
1921 | + |
1922 | +typedef struct |
1923 | +{ |
1924 | + GObjectClass parent_class; |
1925 | + |
1926 | + void (*changed)(CommonUser *user); |
1927 | +} CommonUserClass; |
1928 | + |
1929 | +typedef struct |
1930 | +{ |
1931 | + GObject parent_instance; |
1932 | +} CommonUserList; |
1933 | + |
1934 | +typedef struct |
1935 | +{ |
1936 | + GObjectClass parent_class; |
1937 | + |
1938 | + void (*user_added)(CommonUserList *user_list, CommonUser *user); |
1939 | + void (*user_changed)(CommonUserList *user_list, CommonUser *user); |
1940 | + void (*user_removed)(CommonUserList *user_list, CommonUser *user); |
1941 | +} CommonUserListClass; |
1942 | + |
1943 | +GType common_user_list_get_type (void); |
1944 | + |
1945 | +GType common_user_get_type (void); |
1946 | + |
1947 | +CommonUserList *common_user_list_get_instance (void); |
1948 | + |
1949 | +void common_user_list_cleanup (void); |
1950 | + |
1951 | +gint common_user_list_get_length (CommonUserList *user_list); |
1952 | + |
1953 | +CommonUser *common_user_list_get_user_by_name (CommonUserList *user_list, const gchar *username); |
1954 | + |
1955 | +GList *common_user_list_get_users (CommonUserList *user_list); |
1956 | + |
1957 | +const gchar *common_user_get_name (CommonUser *user); |
1958 | + |
1959 | +const gchar *common_user_get_real_name (CommonUser *user); |
1960 | + |
1961 | +const gchar *common_user_get_display_name (CommonUser *user); |
1962 | + |
1963 | +const gchar *common_user_get_home_directory (CommonUser *user); |
1964 | + |
1965 | +const gchar *common_user_get_shell (CommonUser *user); |
1966 | + |
1967 | +const gchar *common_user_get_image (CommonUser *user); |
1968 | + |
1969 | +const gchar *common_user_get_background (CommonUser *user); |
1970 | + |
1971 | +const gchar *common_user_get_language (CommonUser *user); |
1972 | + |
1973 | +void common_user_set_language (CommonUser *user, const gchar *language); |
1974 | + |
1975 | +const gchar *common_user_get_layout (CommonUser *user); |
1976 | + |
1977 | +const gchar * const *common_user_get_layouts (CommonUser *user); |
1978 | + |
1979 | +const gchar *common_user_get_session (CommonUser *user); |
1980 | + |
1981 | +void common_user_set_session (CommonUser *user, const gchar *session); |
1982 | + |
1983 | +gboolean common_user_get_logged_in (CommonUser *user); |
1984 | + |
1985 | +gboolean common_user_get_has_messages (CommonUser *user); |
1986 | + |
1987 | +uid_t common_user_get_uid (CommonUser *user); |
1988 | + |
1989 | +gid_t common_user_get_gid (CommonUser *user); |
1990 | + |
1991 | +G_END_DECLS |
1992 | + |
1993 | +#endif /* COMMON_USER_LIST_H_ */ |
1994 | |
1995 | === modified file 'configure.ac' |
1996 | --- configure.ac 2014-02-06 15:35:02 +0000 |
1997 | +++ configure.ac 2014-02-08 22:36:44 +0000 |
1998 | @@ -211,6 +211,7 @@ |
1999 | |
2000 | AC_CONFIG_FILES([ |
2001 | Makefile |
2002 | +common/Makefile |
2003 | data/Makefile |
2004 | doc/Makefile |
2005 | help/Makefile |
2006 | |
2007 | === modified file 'debian/patches/01_transition_ubuntu2d_ubuntu_desktop.patch' |
2008 | --- debian/patches/01_transition_ubuntu2d_ubuntu_desktop.patch 2013-12-09 04:14:30 +0000 |
2009 | +++ debian/patches/01_transition_ubuntu2d_ubuntu_desktop.patch 2014-02-08 22:36:44 +0000 |
2010 | @@ -1,16 +1,16 @@ |
2011 | # Description: Remove unity-2d (not anymore supported) and transition to unity |
2012 | # starting from quantal. llvmpipe is used in case no hardware |
2013 | # acceleration is available. |
2014 | -=== modified file 'liblightdm-gobject/user.c' |
2015 | -Index: trunk/liblightdm-gobject/user.c |
2016 | +=== modified file 'common/user-list.c' |
2017 | +Index: trunk/common/user-list.c |
2018 | =================================================================== |
2019 | ---- trunk.orig/liblightdm-gobject/user.c 2013-12-09 17:13:47.918244873 +1300 |
2020 | -+++ trunk/liblightdm-gobject/user.c 2013-12-09 17:13:47.910244873 +1300 |
2021 | -@@ -1123,6 +1123,12 @@ |
2022 | +--- trunk.orig/common/user-list.c 2014-02-08 17:09:03.157580601 -0500 |
2023 | ++++ trunk/common/user-list.c 2014-02-08 17:34:52.897555476 -0500 |
2024 | +@@ -1219,6 +1219,12 @@ |
2025 | |
2026 | if (!priv->path) |
2027 | load_dmrc (user); |
2028 | -+ |
2029 | ++ |
2030 | + if (g_strcmp0 (priv->session, "ubuntu-2d") == 0) |
2031 | + { |
2032 | + g_free(priv->session); |
2033 | |
2034 | === modified file 'liblightdm-gobject/Makefile.am' |
2035 | --- liblightdm-gobject/Makefile.am 2013-07-23 02:24:45 +0000 |
2036 | +++ liblightdm-gobject/Makefile.am 2014-02-08 22:36:44 +0000 |
2037 | @@ -1,9 +1,12 @@ |
2038 | lib_LTLIBRARIES = liblightdm-gobject-1.la |
2039 | |
2040 | liblightdm_gobject_1_la_LDFLAGS = -export-symbols-regex \^lightdm_.* |
2041 | -liblightdm_gobject_1_la_LIBADD = $(LIBLIGHTDM_GOBJECT_LIBS) |
2042 | +liblightdm_gobject_1_la_LIBADD = \ |
2043 | + $(LIBLIGHTDM_GOBJECT_LIBS) \ |
2044 | + $(top_builddir)/common/libcommon.la |
2045 | liblightdm_gobject_1_la_CFLAGS = $(LIBLIGHTDM_GOBJECT_CFLAGS) \ |
2046 | $(WARN_CFLAGS) \ |
2047 | + -I"$(top_srcdir)/common" \ |
2048 | -DCONFIG_DIR=\"$(sysconfdir)/lightdm\" \ |
2049 | -DSESSIONS_DIR=\"$(pkgdatadir)/sessions:$(datadir)/xsessions\" \ |
2050 | -DREMOTE_SESSIONS_DIR=\"$(pkgdatadir)/remote-sessions\" |
2051 | |
2052 | === modified file 'liblightdm-gobject/session.c' |
2053 | --- liblightdm-gobject/session.c 2013-12-12 20:32:47 +0000 |
2054 | +++ liblightdm-gobject/session.c 2014-02-08 22:36:44 +0000 |
2055 | @@ -11,6 +11,7 @@ |
2056 | #include <string.h> |
2057 | #include <gio/gdesktopappinfo.h> |
2058 | |
2059 | +#include "configuration.h" |
2060 | #include "lightdm/session.h" |
2061 | |
2062 | enum { |
2063 | @@ -191,7 +192,6 @@ |
2064 | static void |
2065 | update_sessions (void) |
2066 | { |
2067 | - GKeyFile *config_key_file = NULL; |
2068 | gchar *config_path = NULL; |
2069 | gchar *sessions_dir; |
2070 | gchar *remote_sessions_dir; |
2071 | @@ -207,8 +207,8 @@ |
2072 | /* Use session directory from configuration */ |
2073 | /* FIXME: This should be sent in the greeter connection */ |
2074 | config_path = g_build_filename (CONFIG_DIR, "lightdm.conf", NULL); |
2075 | - config_key_file = g_key_file_new (); |
2076 | - result = g_key_file_load_from_file (config_key_file, config_path, G_KEY_FILE_NONE, &error); |
2077 | + /* FIXME: This should load from lightdm.conf.d as well */ |
2078 | + result = config_load_from_file (config_get_instance (), config_path, &error); |
2079 | if (error && !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) |
2080 | g_warning ("Failed to open configuration file: %s", error->message); |
2081 | g_clear_error (&error); |
2082 | @@ -216,21 +216,20 @@ |
2083 | { |
2084 | gchar *value; |
2085 | |
2086 | - value = g_key_file_get_string (config_key_file, "LightDM", "sessions-directory", NULL); |
2087 | + value = config_get_string (config_get_instance (), "LightDM", "sessions-directory"); |
2088 | if (value) |
2089 | { |
2090 | g_free (sessions_dir); |
2091 | sessions_dir = value; |
2092 | } |
2093 | |
2094 | - value = g_key_file_get_string (config_key_file, "LightDM", "remote-sessions-directory", NULL); |
2095 | + value = config_get_string (config_get_instance (), "LightDM", "remote-sessions-directory"); |
2096 | if (value) |
2097 | { |
2098 | g_free (remote_sessions_dir); |
2099 | remote_sessions_dir = value; |
2100 | } |
2101 | } |
2102 | - g_key_file_free (config_key_file); |
2103 | g_free (config_path); |
2104 | |
2105 | local_sessions = load_sessions (sessions_dir); |
2106 | |
2107 | === added file 'liblightdm-gobject/user.c' |
2108 | --- liblightdm-gobject/user.c 1970-01-01 00:00:00 +0000 |
2109 | +++ liblightdm-gobject/user.c 2014-02-08 22:36:44 +0000 |
2110 | @@ -0,0 +1,736 @@ |
2111 | +/* -*- Mode: C; indent-tabs-mode:nil; tab-width:4 -*- |
2112 | + * |
2113 | + * Copyright (C) 2010 Robert Ancell. |
2114 | + * Copyright (C) 2014 Canonical, Ltd. |
2115 | + * Authors: Robert Ancell <robert.ancell@canonical.com> |
2116 | + * Michael Terry <michael.terry@canonical.com> |
2117 | + * |
2118 | + * This library is free software; you can redistribute it and/or modify it under |
2119 | + * the terms of the GNU Lesser General Public License as published by the Free |
2120 | + * Software Foundation; either version 2 or version 3 of the License. |
2121 | + * See http://www.gnu.org/copyleft/lgpl.html the full text of the license. |
2122 | + */ |
2123 | + |
2124 | +#include <config.h> |
2125 | + |
2126 | +#include "user-list.h" |
2127 | +#include "lightdm/user.h" |
2128 | + |
2129 | +enum |
2130 | +{ |
2131 | + LIST_PROP_0, |
2132 | + LIST_PROP_NUM_USERS, |
2133 | + LIST_PROP_USERS, |
2134 | +}; |
2135 | + |
2136 | +enum |
2137 | +{ |
2138 | + USER_PROP_0, |
2139 | + USER_PROP_COMMON_USER, |
2140 | + USER_PROP_NAME, |
2141 | + USER_PROP_REAL_NAME, |
2142 | + USER_PROP_DISPLAY_NAME, |
2143 | + USER_PROP_HOME_DIRECTORY, |
2144 | + USER_PROP_IMAGE, |
2145 | + USER_PROP_BACKGROUND, |
2146 | + USER_PROP_LANGUAGE, |
2147 | + USER_PROP_LAYOUT, |
2148 | + USER_PROP_LAYOUTS, |
2149 | + USER_PROP_SESSION, |
2150 | + USER_PROP_LOGGED_IN, |
2151 | + USER_PROP_HAS_MESSAGES |
2152 | +}; |
2153 | + |
2154 | +enum |
2155 | +{ |
2156 | + USER_ADDED, |
2157 | + USER_CHANGED, |
2158 | + USER_REMOVED, |
2159 | + LAST_LIST_SIGNAL |
2160 | +}; |
2161 | +static guint list_signals[LAST_LIST_SIGNAL] = { 0 }; |
2162 | + |
2163 | +enum |
2164 | +{ |
2165 | + CHANGED, |
2166 | + LAST_USER_SIGNAL |
2167 | +}; |
2168 | +static guint user_signals[LAST_USER_SIGNAL] = { 0 }; |
2169 | + |
2170 | +typedef struct |
2171 | +{ |
2172 | + gboolean initialized; |
2173 | + |
2174 | + /* Wrapper list, kept locally to preserve transfer-none promises */ |
2175 | + GList *lightdm_list; |
2176 | +} LightDMUserListPrivate; |
2177 | + |
2178 | +typedef struct |
2179 | +{ |
2180 | + CommonUser *common_user; |
2181 | +} LightDMUserPrivate; |
2182 | + |
2183 | +G_DEFINE_TYPE (LightDMUserList, lightdm_user_list, G_TYPE_OBJECT); |
2184 | +G_DEFINE_TYPE (LightDMUser, lightdm_user, G_TYPE_OBJECT); |
2185 | + |
2186 | +#define GET_LIST_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_USER_LIST, LightDMUserListPrivate) |
2187 | +#define GET_USER_PRIVATE(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), LIGHTDM_TYPE_USER, LightDMUserPrivate) |
2188 | + |
2189 | +static LightDMUserList *singleton = NULL; |
2190 | + |
2191 | +/** |
2192 | + * lightdm_user_list_get_instance: |
2193 | + * |
2194 | + * Get the user list. |
2195 | + * |
2196 | + * Return value: (transfer none): the #LightDMUserList |
2197 | + **/ |
2198 | +LightDMUserList * |
2199 | +lightdm_user_list_get_instance (void) |
2200 | +{ |
2201 | + if (!singleton) |
2202 | + singleton = g_object_new (LIGHTDM_TYPE_USER_LIST, NULL); |
2203 | + return singleton; |
2204 | +} |
2205 | + |
2206 | +static void |
2207 | +user_changed_cb (CommonUser *common_user, LightDMUser *lightdm_user) |
2208 | +{ |
2209 | + g_signal_emit (lightdm_user, user_signals[CHANGED], 0); |
2210 | +} |
2211 | + |
2212 | +static LightDMUser * |
2213 | +wrap_common_user (CommonUser *user) |
2214 | +{ |
2215 | + LightDMUser *lightdm_user = g_object_new (LIGHTDM_TYPE_USER, "common-user", user, NULL); |
2216 | + g_signal_connect (user, "changed", G_CALLBACK (user_changed_cb), lightdm_user); |
2217 | + return lightdm_user; |
2218 | +} |
2219 | + |
2220 | +static void |
2221 | +user_list_added_cb (CommonUserList *common_list, CommonUser *common_user, LightDMUserList *user_list) |
2222 | +{ |
2223 | + LightDMUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
2224 | + GList *common_users = common_user_list_get_users (common_list); |
2225 | + LightDMUser *lightdm_user = wrap_common_user (common_user); |
2226 | + priv->lightdm_list = g_list_insert (priv->lightdm_list, lightdm_user, g_list_index (common_users, common_user)); |
2227 | + g_signal_emit (user_list, list_signals[USER_ADDED], 0, lightdm_user); |
2228 | +} |
2229 | + |
2230 | +static void |
2231 | +user_list_changed_cb (CommonUserList *common_list, CommonUser *common_user, LightDMUserList *user_list) |
2232 | +{ |
2233 | + LightDMUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
2234 | + GList *common_users = common_user_list_get_users (common_list); |
2235 | + LightDMUser *lightdm_user = g_list_nth_data (priv->lightdm_list, g_list_index (common_users, common_user)); |
2236 | + g_signal_emit (user_list, list_signals[USER_CHANGED], 0, lightdm_user); |
2237 | +} |
2238 | + |
2239 | +static void |
2240 | +user_list_removed_cb (CommonUserList *common_list, CommonUser *common_user, LightDMUserList *user_list) |
2241 | +{ |
2242 | + LightDMUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
2243 | + GList *link; |
2244 | + |
2245 | + for (link = priv->lightdm_list; link; link = link->next) |
2246 | + { |
2247 | + LightDMUser *lightdm_user = link->data; |
2248 | + LightDMUserPrivate *user_priv = GET_USER_PRIVATE (lightdm_user); |
2249 | + if (user_priv->common_user == common_user) |
2250 | + { |
2251 | + priv->lightdm_list = g_list_delete_link (priv->lightdm_list, link); |
2252 | + g_signal_emit (user_list, list_signals[USER_REMOVED], 0, lightdm_user); |
2253 | + g_object_unref (lightdm_user); |
2254 | + break; |
2255 | + } |
2256 | + } |
2257 | +} |
2258 | + |
2259 | +static void |
2260 | +initialize_user_list_if_needed (LightDMUserList *user_list) |
2261 | +{ |
2262 | + LightDMUserListPrivate *priv = GET_LIST_PRIVATE (user_list); |
2263 | + GList *common_users; |
2264 | + GList *link; |
2265 | + |
2266 | + if (priv->initialized) |
2267 | + return; |
2268 | + |
2269 | + common_users = common_user_list_get_users (common_user_list_get_instance ()); |
2270 | + for (link = common_users; link; link = link->next) |
2271 | + { |
2272 | + CommonUser *user = link->data; |
2273 | + LightDMUser *lightdm_user = wrap_common_user (user); |
2274 | + priv->lightdm_list = g_list_prepend (priv->lightdm_list, lightdm_user); |
2275 | + } |
2276 | + priv->lightdm_list = g_list_reverse (priv->lightdm_list); |
2277 | + |
2278 | + CommonUserList *common_list = common_user_list_get_instance (); |
2279 | + g_signal_connect (common_list, "user-added", G_CALLBACK (user_list_added_cb), user_list); |
2280 | + g_signal_connect (common_list, "user-changed", G_CALLBACK (user_list_changed_cb), user_list); |
2281 | + g_signal_connect (common_list, "user-removed", G_CALLBACK (user_list_removed_cb), user_list); |
2282 | + |
2283 | + priv->initialized = TRUE; |
2284 | +} |
2285 | + |
2286 | +/** |
2287 | + * lightdm_user_list_get_length: |
2288 | + * @user_list: a #LightDMUserList |
2289 | + * |
2290 | + * Return value: The number of users able to log in |
2291 | + **/ |
2292 | +gint |
2293 | +lightdm_user_list_get_length (LightDMUserList *user_list) |
2294 | +{ |
2295 | + g_return_val_if_fail (LIGHTDM_IS_USER_LIST (user_list), 0); |
2296 | + initialize_user_list_if_needed (user_list); |
2297 | + return g_list_length (GET_LIST_PRIVATE (user_list)->lightdm_list); |
2298 | +} |
2299 | + |
2300 | +/** |
2301 | + * lightdm_user_list_get_users: |
2302 | + * @user_list: A #LightDMUserList |
2303 | + * |
2304 | + * Get a list of users to present to the user. This list may be a subset of the |
2305 | + * available users and may be empty depending on the server configuration. |
2306 | + * |
2307 | + * Return value: (element-type LightDMUser) (transfer none): A list of #LightDMUser that should be presented to the user. |
2308 | + **/ |
2309 | +GList * |
2310 | +lightdm_user_list_get_users (LightDMUserList *user_list) |
2311 | +{ |
2312 | + g_return_val_if_fail (LIGHTDM_IS_USER_LIST (user_list), NULL); |
2313 | + initialize_user_list_if_needed (user_list); |
2314 | + return GET_LIST_PRIVATE (user_list)->lightdm_list; |
2315 | +} |
2316 | + |
2317 | +/** |
2318 | + * lightdm_user_list_get_user_by_name: |
2319 | + * @user_list: A #LightDMUserList |
2320 | + * @username: Name of user to get. |
2321 | + * |
2322 | + * Get infomation about a given user or #NULL if this user doesn't exist. |
2323 | + * |
2324 | + * Return value: (transfer none): A #LightDMUser entry for the given user. |
2325 | + **/ |
2326 | +LightDMUser * |
2327 | +lightdm_user_list_get_user_by_name (LightDMUserList *user_list, const gchar *username) |
2328 | +{ |
2329 | + GList *link; |
2330 | + |
2331 | + g_return_val_if_fail (LIGHTDM_IS_USER_LIST (user_list), NULL); |
2332 | + g_return_val_if_fail (username != NULL, NULL); |
2333 | + |
2334 | + initialize_user_list_if_needed (user_list); |
2335 | + |
2336 | + for (link = GET_LIST_PRIVATE (user_list)->lightdm_list; link; link = link->next) |
2337 | + { |
2338 | + LightDMUser *user = link->data; |
2339 | + if (g_strcmp0 (lightdm_user_get_name (user), username) == 0) |
2340 | + return user; |
2341 | + } |
2342 | + |
2343 | + return NULL; |
2344 | +} |
2345 | + |
2346 | +static void |
2347 | +lightdm_user_list_init (LightDMUserList *user_list) |
2348 | +{ |
2349 | +} |
2350 | + |
2351 | +static void |
2352 | +lightdm_user_list_set_property (GObject *object, |
2353 | + guint prop_id, |
2354 | + const GValue *value, |
2355 | + GParamSpec *pspec) |
2356 | +{ |
2357 | + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
2358 | +} |
2359 | + |
2360 | +static void |
2361 | +lightdm_user_list_get_property (GObject *object, |
2362 | + guint prop_id, |
2363 | + GValue *value, |
2364 | + GParamSpec *pspec) |
2365 | +{ |
2366 | + LightDMUserList *self; |
2367 | + |
2368 | + self = LIGHTDM_USER_LIST (object); |
2369 | + |
2370 | + switch (prop_id) |
2371 | + { |
2372 | + case LIST_PROP_NUM_USERS: |
2373 | + g_value_set_int (value, lightdm_user_list_get_length (self)); |
2374 | + break; |
2375 | + default: |
2376 | + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
2377 | + break; |
2378 | + } |
2379 | +} |
2380 | + |
2381 | +static void |
2382 | +lightdm_user_list_finalize (GObject *object) |
2383 | +{ |
2384 | + LightDMUserList *self = LIGHTDM_USER_LIST (object); |
2385 | + LightDMUserListPrivate *priv = GET_LIST_PRIVATE (self); |
2386 | + |
2387 | + g_list_free_full (priv->lightdm_list, g_object_unref); |
2388 | + |
2389 | + G_OBJECT_CLASS (lightdm_user_list_parent_class)->finalize (object); |
2390 | +} |
2391 | + |
2392 | +static void |
2393 | +lightdm_user_list_class_init (LightDMUserListClass *klass) |
2394 | +{ |
2395 | + GObjectClass *object_class = G_OBJECT_CLASS (klass); |
2396 | + |
2397 | + g_type_class_add_private (klass, sizeof (LightDMUserListPrivate)); |
2398 | + |
2399 | + object_class->set_property = lightdm_user_list_set_property; |
2400 | + object_class->get_property = lightdm_user_list_get_property; |
2401 | + object_class->finalize = lightdm_user_list_finalize; |
2402 | + |
2403 | + g_object_class_install_property (object_class, |
2404 | + LIST_PROP_NUM_USERS, |
2405 | + g_param_spec_int ("num-users", |
2406 | + "num-users", |
2407 | + "Number of login users", |
2408 | + 0, G_MAXINT, 0, |
2409 | + G_PARAM_READABLE)); |
2410 | + /** |
2411 | + * LightDMUserList::user-added: |
2412 | + * @user_list: A #LightDMUserList |
2413 | + * @user: The #LightDM user that has been added. |
2414 | + * |
2415 | + * The ::user-added signal gets emitted when a user account is created. |
2416 | + **/ |
2417 | + list_signals[USER_ADDED] = |
2418 | + g_signal_new ("user-added", |
2419 | + G_TYPE_FROM_CLASS (klass), |
2420 | + G_SIGNAL_RUN_LAST, |
2421 | + G_STRUCT_OFFSET (LightDMUserListClass, user_added), |
2422 | + NULL, NULL, |
2423 | + NULL, |
2424 | + G_TYPE_NONE, 1, LIGHTDM_TYPE_USER); |
2425 | + |
2426 | + /** |
2427 | + * LightDMUserList::user-changed: |
2428 | + * @user_list: A #LightDMUserList |
2429 | + * @user: The #LightDM user that has been changed. |
2430 | + * |
2431 | + * The ::user-changed signal gets emitted when a user account is modified. |
2432 | + **/ |
2433 | + list_signals[USER_CHANGED] = |
2434 | + g_signal_new ("user-changed", |
2435 | + G_TYPE_FROM_CLASS (klass), |
2436 | + G_SIGNAL_RUN_LAST, |
2437 | + G_STRUCT_OFFSET (LightDMUserListClass, user_changed), |
2438 | + NULL, NULL, |
2439 | + NULL, |
2440 | + G_TYPE_NONE, 1, LIGHTDM_TYPE_USER); |
2441 | + |
2442 | + /** |
2443 | + * LightDMUserList::user-removed: |
2444 | + * @user_list: A #LightDMUserList |
2445 | + * @user: The #LightDM user that has been removed. |
2446 | + * |
2447 | + * The ::user-removed signal gets emitted when a user account is removed. |
2448 | + **/ |
2449 | + list_signals[USER_REMOVED] = |
2450 | + g_signal_new ("user-removed", |
2451 | + G_TYPE_FROM_CLASS (klass), |
2452 | + G_SIGNAL_RUN_LAST, |
2453 | + G_STRUCT_OFFSET (LightDMUserListClass, user_removed), |
2454 | + NULL, NULL, |
2455 | + NULL, |
2456 | + G_TYPE_NONE, 1, LIGHTDM_TYPE_USER); |
2457 | +} |
2458 | + |
2459 | +/** |
2460 | + * lightdm_user_get_name: |
2461 | + * @user: A #LightDMUser |
2462 | + * |
2463 | + * Get the name of a user. |
2464 | + * |
2465 | + * Return value: The name of the given user |
2466 | + **/ |
2467 | +const gchar * |
2468 | +lightdm_user_get_name (LightDMUser *user) |
2469 | +{ |
2470 | + g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
2471 | + return common_user_get_name (GET_USER_PRIVATE (user)->common_user); |
2472 | +} |
2473 | + |
2474 | +/** |
2475 | + * lightdm_user_get_real_name: |
2476 | + * @user: A #LightDMUser |
2477 | + * |
2478 | + * Get the real name of a user. |
2479 | + * |
2480 | + * Return value: The real name of the given user |
2481 | + **/ |
2482 | +const gchar * |
2483 | +lightdm_user_get_real_name (LightDMUser *user) |
2484 | +{ |
2485 | + g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
2486 | + return common_user_get_real_name (GET_USER_PRIVATE (user)->common_user); |
2487 | +} |
2488 | + |
2489 | +/** |
2490 | + * lightdm_user_get_display_name: |
2491 | + * @user: A #LightDMUser |
2492 | + * |
2493 | + * Get the display name of a user. |
2494 | + * |
2495 | + * Return value: The display name of the given user |
2496 | + **/ |
2497 | +const gchar * |
2498 | +lightdm_user_get_display_name (LightDMUser *user) |
2499 | +{ |
2500 | + g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
2501 | + return common_user_get_display_name (GET_USER_PRIVATE (user)->common_user); |
2502 | +} |
2503 | + |
2504 | +/** |
2505 | + * lightdm_user_get_home_directory: |
2506 | + * @user: A #LightDMUser |
2507 | + * |
2508 | + * Get the home directory for a user. |
2509 | + * |
2510 | + * Return value: The users home directory |
2511 | + */ |
2512 | +const gchar * |
2513 | +lightdm_user_get_home_directory (LightDMUser *user) |
2514 | +{ |
2515 | + g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
2516 | + return common_user_get_home_directory (GET_USER_PRIVATE (user)->common_user); |
2517 | +} |
2518 | + |
2519 | +/** |
2520 | + * lightdm_user_get_image: |
2521 | + * @user: A #LightDMUser |
2522 | + * |
2523 | + * Get the image URI for a user. |
2524 | + * |
2525 | + * Return value: The image URI for the given user or #NULL if no URI |
2526 | + **/ |
2527 | +const gchar * |
2528 | +lightdm_user_get_image (LightDMUser *user) |
2529 | +{ |
2530 | + g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
2531 | + return common_user_get_image (GET_USER_PRIVATE (user)->common_user); |
2532 | +} |
2533 | + |
2534 | +/** |
2535 | + * lightdm_user_get_background: |
2536 | + * @user: A #LightDMUser |
2537 | + * |
2538 | + * Get the background file path for a user. |
2539 | + * |
2540 | + * Return value: The background file path for the given user or #NULL if no path |
2541 | + **/ |
2542 | +const gchar * |
2543 | +lightdm_user_get_background (LightDMUser *user) |
2544 | +{ |
2545 | + g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
2546 | + return common_user_get_background (GET_USER_PRIVATE (user)->common_user); |
2547 | +} |
2548 | + |
2549 | +/** |
2550 | + * lightdm_user_get_language: |
2551 | + * @user: A #LightDMUser |
2552 | + * |
2553 | + * Get the language for a user. |
2554 | + * |
2555 | + * Return value: The language in the form of a local specification (e.g. "de_DE.UTF-8") for the given user or #NULL if using the system default locale. |
2556 | + **/ |
2557 | +const gchar * |
2558 | +lightdm_user_get_language (LightDMUser *user) |
2559 | +{ |
2560 | + g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
2561 | + return common_user_get_language (GET_USER_PRIVATE (user)->common_user); |
2562 | +} |
2563 | + |
2564 | +/** |
2565 | + * lightdm_user_get_layout: |
2566 | + * @user: A #LightDMUser |
2567 | + * |
2568 | + * Get the keyboard layout for a user. |
2569 | + * |
2570 | + * Return value: The keyboard layout for the given user or #NULL if using system defaults. Copy the value if you want to use it long term. |
2571 | + **/ |
2572 | +const gchar * |
2573 | +lightdm_user_get_layout (LightDMUser *user) |
2574 | +{ |
2575 | + g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
2576 | + return common_user_get_layout (GET_USER_PRIVATE (user)->common_user); |
2577 | +} |
2578 | + |
2579 | +/** |
2580 | + * lightdm_user_get_layouts: |
2581 | + * @user: A #LightDMUser |
2582 | + * |
2583 | + * Get the configured keyboard layouts for a user. |
2584 | + * |
2585 | + * Return value: (transfer none): A NULL-terminated array of keyboard layouts for the given user. Copy the values if you want to use them long term. |
2586 | + **/ |
2587 | +const gchar * const * |
2588 | +lightdm_user_get_layouts (LightDMUser *user) |
2589 | +{ |
2590 | + g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
2591 | + return common_user_get_layouts (GET_USER_PRIVATE (user)->common_user); |
2592 | +} |
2593 | + |
2594 | +/** |
2595 | + * lightdm_user_get_session: |
2596 | + * @user: A #LightDMUser |
2597 | + * |
2598 | + * Get the session for a user. |
2599 | + * |
2600 | + * Return value: The session for the given user or #NULL if using system defaults. |
2601 | + **/ |
2602 | +const gchar * |
2603 | +lightdm_user_get_session (LightDMUser *user) |
2604 | +{ |
2605 | + g_return_val_if_fail (LIGHTDM_IS_USER (user), NULL); |
2606 | + return common_user_get_session (GET_USER_PRIVATE (user)->common_user); |
2607 | +} |
2608 | + |
2609 | +/** |
2610 | + * lightdm_user_get_logged_in: |
2611 | + * @user: A #LightDMUser |
2612 | + * |
2613 | + * Check if a user is logged in. |
2614 | + * |
2615 | + * Return value: #TRUE if the user is currently logged in. |
2616 | + **/ |
2617 | +gboolean |
2618 | +lightdm_user_get_logged_in (LightDMUser *user) |
2619 | +{ |
2620 | + g_return_val_if_fail (LIGHTDM_IS_USER (user), FALSE); |
2621 | + return common_user_get_logged_in (GET_USER_PRIVATE (user)->common_user); |
2622 | +} |
2623 | + |
2624 | +/** |
2625 | + * lightdm_user_get_has_messages: |
2626 | + * @user: A #LightDMUser |
2627 | + * |
2628 | + * Check if a user has waiting messages. |
2629 | + * |
2630 | + * Return value: #TRUE if the user has waiting messages. |
2631 | + **/ |
2632 | +gboolean |
2633 | +lightdm_user_get_has_messages (LightDMUser *user) |
2634 | +{ |
2635 | + g_return_val_if_fail (LIGHTDM_IS_USER (user), FALSE); |
2636 | + return common_user_get_has_messages (GET_USER_PRIVATE (user)->common_user); |
2637 | +} |
2638 | + |
2639 | +static void |
2640 | +lightdm_user_init (LightDMUser *user) |
2641 | +{ |
2642 | +} |
2643 | + |
2644 | +static void |
2645 | +lightdm_user_set_property (GObject *object, |
2646 | + guint prop_id, |
2647 | + const GValue *value, |
2648 | + GParamSpec *pspec) |
2649 | +{ |
2650 | + LightDMUser *self = LIGHTDM_USER (object); |
2651 | + LightDMUserPrivate *priv = GET_USER_PRIVATE (self); |
2652 | + |
2653 | + switch (prop_id) |
2654 | + { |
2655 | + case USER_PROP_COMMON_USER: |
2656 | + priv->common_user = g_value_dup_object (value); |
2657 | + break; |
2658 | + default: |
2659 | + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
2660 | + break; |
2661 | + } |
2662 | +} |
2663 | + |
2664 | +static void |
2665 | +lightdm_user_get_property (GObject *object, |
2666 | + guint prop_id, |
2667 | + GValue *value, |
2668 | + GParamSpec *pspec) |
2669 | +{ |
2670 | + LightDMUser *self; |
2671 | + |
2672 | + self = LIGHTDM_USER (object); |
2673 | + |
2674 | + switch (prop_id) |
2675 | + { |
2676 | + case USER_PROP_NAME: |
2677 | + g_value_set_string (value, lightdm_user_get_name (self)); |
2678 | + break; |
2679 | + case USER_PROP_REAL_NAME: |
2680 | + g_value_set_string (value, lightdm_user_get_real_name (self)); |
2681 | + break; |
2682 | + case USER_PROP_DISPLAY_NAME: |
2683 | + g_value_set_string (value, lightdm_user_get_display_name (self)); |
2684 | + break; |
2685 | + case USER_PROP_HOME_DIRECTORY: |
2686 | + g_value_set_string (value, lightdm_user_get_home_directory (self)); |
2687 | + break; |
2688 | + case USER_PROP_IMAGE: |
2689 | + g_value_set_string (value, lightdm_user_get_image (self)); |
2690 | + break; |
2691 | + case USER_PROP_BACKGROUND: |
2692 | + g_value_set_string (value, lightdm_user_get_background (self)); |
2693 | + break; |
2694 | + case USER_PROP_LANGUAGE: |
2695 | + g_value_set_string (value, lightdm_user_get_language (self)); |
2696 | + break; |
2697 | + case USER_PROP_LAYOUT: |
2698 | + g_value_set_string (value, lightdm_user_get_layout (self)); |
2699 | + break; |
2700 | + case USER_PROP_LAYOUTS: |
2701 | + g_value_set_boxed (value, g_strdupv ((gchar **) lightdm_user_get_layouts (self))); |
2702 | + break; |
2703 | + case USER_PROP_SESSION: |
2704 | + g_value_set_string (value, lightdm_user_get_session (self)); |
2705 | + break; |
2706 | + case USER_PROP_LOGGED_IN: |
2707 | + g_value_set_boolean (value, lightdm_user_get_logged_in (self)); |
2708 | + break; |
2709 | + case USER_PROP_HAS_MESSAGES: |
2710 | + g_value_set_boolean (value, lightdm_user_get_has_messages (self)); |
2711 | + break; |
2712 | + default: |
2713 | + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
2714 | + break; |
2715 | + } |
2716 | +} |
2717 | + |
2718 | +static void |
2719 | +lightdm_user_finalize (GObject *object) |
2720 | +{ |
2721 | + LightDMUser *self = LIGHTDM_USER (object); |
2722 | + LightDMUserPrivate *priv = GET_USER_PRIVATE (self); |
2723 | + |
2724 | + g_object_unref (priv->common_user); |
2725 | + |
2726 | + G_OBJECT_CLASS (lightdm_user_parent_class)->finalize (object); |
2727 | +} |
2728 | + |
2729 | +static void |
2730 | +lightdm_user_class_init (LightDMUserClass *klass) |
2731 | +{ |
2732 | + GObjectClass *object_class = G_OBJECT_CLASS (klass); |
2733 | + |
2734 | + g_type_class_add_private (klass, sizeof (LightDMUserPrivate)); |
2735 | + |
2736 | + object_class->set_property = lightdm_user_set_property; |
2737 | + object_class->get_property = lightdm_user_get_property; |
2738 | + object_class->finalize = lightdm_user_finalize; |
2739 | + |
2740 | + g_object_class_install_property (object_class, |
2741 | + USER_PROP_COMMON_USER, |
2742 | + g_param_spec_object ("common-user", |
2743 | + "common-user", |
2744 | + "Internal user object", |
2745 | + COMMON_TYPE_USER, |
2746 | + G_PARAM_PRIVATE|G_PARAM_CONSTRUCT_ONLY|G_PARAM_WRITABLE)); |
2747 | + g_object_class_install_property (object_class, |
2748 | + USER_PROP_NAME, |
2749 | + g_param_spec_string ("name", |
2750 | + "name", |
2751 | + "Username", |
2752 | + NULL, |
2753 | + G_PARAM_READWRITE)); |
2754 | + g_object_class_install_property (object_class, |
2755 | + USER_PROP_REAL_NAME, |
2756 | + g_param_spec_string ("real-name", |
2757 | + "real-name", |
2758 | + "Users real name", |
2759 | + NULL, |
2760 | + G_PARAM_READWRITE)); |
2761 | + g_object_class_install_property (object_class, |
2762 | + USER_PROP_DISPLAY_NAME, |
2763 | + g_param_spec_string ("display-name", |
2764 | + "display-name", |
2765 | + "Users display name", |
2766 | + NULL, |
2767 | + G_PARAM_READABLE)); |
2768 | + g_object_class_install_property (object_class, |
2769 | + USER_PROP_HOME_DIRECTORY, |
2770 | + g_param_spec_string ("home-directory", |
2771 | + "home-directory", |
2772 | + "Home directory", |
2773 | + NULL, |
2774 | + G_PARAM_READWRITE)); |
2775 | + g_object_class_install_property (object_class, |
2776 | + USER_PROP_IMAGE, |
2777 | + g_param_spec_string ("image", |
2778 | + "image", |
2779 | + "Avatar image", |
2780 | + NULL, |
2781 | + G_PARAM_READWRITE)); |
2782 | + g_object_class_install_property (object_class, |
2783 | + USER_PROP_BACKGROUND, |
2784 | + g_param_spec_string ("background", |
2785 | + "background", |
2786 | + "User background", |
2787 | + NULL, |
2788 | + G_PARAM_READWRITE)); |
2789 | + g_object_class_install_property (object_class, |
2790 | + USER_PROP_LANGUAGE, |
2791 | + g_param_spec_string ("language", |
2792 | + "language", |
2793 | + "Language used by this user", |
2794 | + NULL, |
2795 | + G_PARAM_READABLE)); |
2796 | + g_object_class_install_property (object_class, |
2797 | + USER_PROP_LAYOUT, |
2798 | + g_param_spec_string ("layout", |
2799 | + "layout", |
2800 | + "Keyboard layout used by this user", |
2801 | + NULL, |
2802 | + G_PARAM_READABLE)); |
2803 | + g_object_class_install_property (object_class, |
2804 | + USER_PROP_LAYOUTS, |
2805 | + g_param_spec_boxed ("layouts", |
2806 | + "layouts", |
2807 | + "Keyboard layouts used by this user", |
2808 | + G_TYPE_STRV, |
2809 | + G_PARAM_READABLE)); |
2810 | + g_object_class_install_property (object_class, |
2811 | + USER_PROP_SESSION, |
2812 | + g_param_spec_string ("session", |
2813 | + "session", |
2814 | + "Session used by this user", |
2815 | + NULL, |
2816 | + G_PARAM_READABLE)); |
2817 | + g_object_class_install_property (object_class, |
2818 | + USER_PROP_LOGGED_IN, |
2819 | + g_param_spec_boolean ("logged-in", |
2820 | + "logged-in", |
2821 | + "TRUE if the user is currently in a session", |
2822 | + FALSE, |
2823 | + G_PARAM_READWRITE)); |
2824 | + g_object_class_install_property (object_class, |
2825 | + USER_PROP_LOGGED_IN, |
2826 | + g_param_spec_boolean ("has-messages", |
2827 | + "has-messages", |
2828 | + "TRUE if the user is has waiting messages", |
2829 | + FALSE, |
2830 | + G_PARAM_READWRITE)); |
2831 | + |
2832 | + /** |
2833 | + * LightDMUser::changed: |
2834 | + * @user: A #LightDMUser |
2835 | + * |
2836 | + * The ::changed signal gets emitted this user account is modified. |
2837 | + **/ |
2838 | + user_signals[CHANGED] = |
2839 | + g_signal_new ("changed", |
2840 | + G_TYPE_FROM_CLASS (klass), |
2841 | + G_SIGNAL_RUN_LAST, |
2842 | + G_STRUCT_OFFSET (LightDMUserClass, changed), |
2843 | + NULL, NULL, |
2844 | + NULL, |
2845 | + G_TYPE_NONE, 0); |
2846 | +} |
2847 | |
2848 | === modified file 'src/Makefile.am' |
2849 | --- src/Makefile.am 2014-02-06 15:35:02 +0000 |
2850 | +++ src/Makefile.am 2014-02-08 22:36:44 +0000 |
2851 | @@ -4,16 +4,12 @@ |
2852 | lightdm_SOURCES = \ |
2853 | accounts.c \ |
2854 | accounts.h \ |
2855 | - configuration.c \ |
2856 | - configuration.h \ |
2857 | console-kit.c \ |
2858 | console-kit.h \ |
2859 | display-manager.c \ |
2860 | display-manager.h \ |
2861 | display-server.c \ |
2862 | display-server.h \ |
2863 | - dmrc.c \ |
2864 | - dmrc.h \ |
2865 | greeter.c \ |
2866 | greeter.h \ |
2867 | guest-account.c \ |
2868 | @@ -27,8 +23,6 @@ |
2869 | mir-server.h \ |
2870 | plymouth.c \ |
2871 | plymouth.h \ |
2872 | - privileges.c \ |
2873 | - privileges.h \ |
2874 | process.c \ |
2875 | process.h \ |
2876 | seat.c \ |
2877 | @@ -80,6 +74,7 @@ |
2878 | lightdm_CFLAGS = \ |
2879 | $(WARN_CFLAGS) \ |
2880 | $(LIGHTDM_CFLAGS) \ |
2881 | + -I"$(top_srcdir)/common" \ |
2882 | -DSBIN_DIR=\"$(sbindir)\" \ |
2883 | -DCONFIG_DIR=\"$(sysconfdir)/lightdm\" \ |
2884 | -DLOG_DIR=\"$(localstatedir)/log/lightdm\" \ |
2885 | @@ -92,6 +87,7 @@ |
2886 | |
2887 | lightdm_LDADD = \ |
2888 | $(LIGHTDM_LIBS) \ |
2889 | + $(top_builddir)/common/libcommon.la \ |
2890 | -lgcrypt \ |
2891 | -lpam |
2892 | |
2893 | |
2894 | === modified file 'src/accounts.c' |
2895 | --- src/accounts.c 2013-06-17 23:14:43 +0000 |
2896 | +++ src/accounts.c 2014-02-08 22:36:44 +0000 |
2897 | @@ -10,273 +10,34 @@ |
2898 | * license. |
2899 | */ |
2900 | |
2901 | -#include <errno.h> |
2902 | #include <pwd.h> |
2903 | #include <stdlib.h> |
2904 | -#include <string.h> |
2905 | |
2906 | #include "accounts.h" |
2907 | -#include "dmrc.h" |
2908 | +#include "user-list.h" |
2909 | |
2910 | struct UserPrivate |
2911 | { |
2912 | - /* Name of user */ |
2913 | - gchar *name; |
2914 | - |
2915 | - /* Accounts interface proxy */ |
2916 | - GDBusProxy *proxy; |
2917 | - |
2918 | - /* User ID */ |
2919 | - uid_t uid; |
2920 | - |
2921 | - /* Group ID */ |
2922 | - gid_t gid; |
2923 | - |
2924 | - /* GECOS information */ |
2925 | - gchar *gecos; |
2926 | - |
2927 | - /* Home directory */ |
2928 | - gchar *home_directory; |
2929 | - |
2930 | - /* Shell */ |
2931 | - gchar *shell; |
2932 | - |
2933 | - /* Language */ |
2934 | - gchar *language; |
2935 | - |
2936 | - /* X session */ |
2937 | - gchar *xsession; |
2938 | + /* Internal user object */ |
2939 | + CommonUser *common_user; |
2940 | }; |
2941 | |
2942 | G_DEFINE_TYPE (User, user, G_TYPE_OBJECT); |
2943 | |
2944 | -/* Connection to AccountsService */ |
2945 | -static GDBusProxy *accounts_service_proxy = NULL; |
2946 | -static gboolean have_accounts_service_proxy = FALSE; |
2947 | - |
2948 | -static gboolean |
2949 | -call_method (GDBusProxy *proxy, const gchar *method, GVariant *args, |
2950 | - const gchar *expected, GVariant **result) |
2951 | -{ |
2952 | - GVariant *answer; |
2953 | - GError *error = NULL; |
2954 | - |
2955 | - if (!proxy) |
2956 | - return FALSE; |
2957 | - |
2958 | - answer = g_dbus_proxy_call_sync (proxy, |
2959 | - method, |
2960 | - args, |
2961 | - G_DBUS_CALL_FLAGS_NONE, |
2962 | - -1, |
2963 | - NULL, |
2964 | - &error); |
2965 | - if (error) |
2966 | - g_warning ("Could not call %s: %s", method, error->message); |
2967 | - g_clear_error (&error); |
2968 | - |
2969 | - if (!answer) |
2970 | - return FALSE; |
2971 | - |
2972 | - if (!g_variant_is_of_type (answer, G_VARIANT_TYPE (expected))) |
2973 | - { |
2974 | - g_warning ("Unexpected response from %s: %s", |
2975 | - method, g_variant_get_type_string (answer)); |
2976 | - g_variant_unref (answer); |
2977 | - return FALSE; |
2978 | - } |
2979 | - |
2980 | - if (result) |
2981 | - *result = answer; |
2982 | - else |
2983 | - g_variant_unref (answer); |
2984 | - |
2985 | - return TRUE; |
2986 | -} |
2987 | - |
2988 | -static gboolean |
2989 | -get_property (GDBusProxy *proxy, const gchar *property, |
2990 | - const gchar *expected, GVariant **result) |
2991 | -{ |
2992 | - GVariant *answer; |
2993 | - |
2994 | - answer = g_dbus_proxy_get_cached_property (proxy, property); |
2995 | - |
2996 | - if (!answer) |
2997 | - { |
2998 | - g_warning ("Could not get accounts property %s", property); |
2999 | - return FALSE; |
3000 | - } |
3001 | - |
3002 | - if (!g_variant_is_of_type (answer, G_VARIANT_TYPE (expected))) |
3003 | - { |
3004 | - g_warning ("Unexpected accounts property type for %s: %s", |
3005 | - property, g_variant_get_type_string (answer)); |
3006 | - g_variant_unref (answer); |
3007 | - return FALSE; |
3008 | - } |
3009 | - |
3010 | - if (result) |
3011 | - *result = answer; |
3012 | - else |
3013 | - g_variant_unref (answer); |
3014 | - return TRUE; |
3015 | -} |
3016 | - |
3017 | -static void |
3018 | -save_string_to_dmrc (const gchar *username, const gchar *group, |
3019 | - const gchar *key, const gchar *value) |
3020 | -{ |
3021 | - GKeyFile *dmrc; |
3022 | - |
3023 | - dmrc = dmrc_load (username); |
3024 | - g_key_file_set_string (dmrc, group, key, value); |
3025 | - dmrc_save (dmrc, username); |
3026 | - |
3027 | - g_key_file_free (dmrc); |
3028 | -} |
3029 | - |
3030 | -static gchar * |
3031 | -get_string_from_dmrc (const gchar *username, const gchar *group, |
3032 | - const gchar *key) |
3033 | -{ |
3034 | - GKeyFile *dmrc; |
3035 | - gchar *value; |
3036 | - |
3037 | - dmrc = dmrc_load (username); |
3038 | - value = g_key_file_get_string (dmrc, group, key, NULL); |
3039 | - |
3040 | - g_key_file_free (dmrc); |
3041 | - return value; |
3042 | -} |
3043 | - |
3044 | -static GDBusProxy * |
3045 | -get_accounts_service_proxy (void) |
3046 | -{ |
3047 | - GError *error = NULL; |
3048 | - |
3049 | - if (have_accounts_service_proxy) |
3050 | - return accounts_service_proxy; |
3051 | - |
3052 | - have_accounts_service_proxy = TRUE; |
3053 | - accounts_service_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, |
3054 | - G_DBUS_PROXY_FLAGS_NONE, |
3055 | - NULL, |
3056 | - "org.freedesktop.Accounts", |
3057 | - "/org/freedesktop/Accounts", |
3058 | - "org.freedesktop.Accounts", |
3059 | - NULL, &error); |
3060 | - if (error) |
3061 | - g_warning ("Could not get accounts proxy: %s", error->message); |
3062 | - g_clear_error (&error); |
3063 | - |
3064 | - if (accounts_service_proxy) |
3065 | - { |
3066 | - gchar *name; |
3067 | - name = g_dbus_proxy_get_name_owner (accounts_service_proxy); |
3068 | - if (!name) |
3069 | - { |
3070 | - g_debug ("org.freedesktop.Accounts does not exist, falling back to passwd file"); |
3071 | - g_object_unref (accounts_service_proxy); |
3072 | - accounts_service_proxy = NULL; |
3073 | - } |
3074 | - g_free (name); |
3075 | - } |
3076 | - |
3077 | - return accounts_service_proxy; |
3078 | -} |
3079 | - |
3080 | -static GDBusProxy * |
3081 | -get_accounts_proxy_for_user (const gchar *user) |
3082 | -{ |
3083 | - GDBusProxy *proxy; |
3084 | - GError *error = NULL; |
3085 | - GVariant *result; |
3086 | - gboolean success; |
3087 | - gchar *user_path = NULL; |
3088 | - |
3089 | - g_return_val_if_fail (user != NULL, NULL); |
3090 | - |
3091 | - proxy = get_accounts_service_proxy (); |
3092 | - if (!proxy) |
3093 | - return NULL; |
3094 | - |
3095 | - success = call_method (proxy, "FindUserByName", g_variant_new ("(s)", user), "(o)", &result); |
3096 | - |
3097 | - if (!success) |
3098 | - return NULL; |
3099 | - |
3100 | - g_variant_get (result, "(o)", &user_path); |
3101 | - g_variant_unref (result); |
3102 | - |
3103 | - if (!user_path) |
3104 | - return NULL; |
3105 | - |
3106 | - proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, |
3107 | - G_DBUS_PROXY_FLAGS_NONE, |
3108 | - NULL, |
3109 | - "org.freedesktop.Accounts", |
3110 | - user_path, |
3111 | - "org.freedesktop.Accounts.User", |
3112 | - NULL, &error); |
3113 | - if (error) |
3114 | - g_warning ("Could not get accounts user proxy: %s", error->message); |
3115 | - g_clear_error (&error); |
3116 | - g_free (user_path); |
3117 | - |
3118 | - return proxy; |
3119 | -} |
3120 | - |
3121 | -static User * |
3122 | -user_from_passwd (struct passwd *user_info) |
3123 | -{ |
3124 | - User *user; |
3125 | - |
3126 | - user = g_object_new (USER_TYPE, NULL); |
3127 | - user->priv->name = g_strdup (user_info->pw_name); |
3128 | - user->priv->uid = user_info->pw_uid; |
3129 | - user->priv->gid = user_info->pw_gid; |
3130 | - user->priv->gecos = g_strdup (user_info->pw_gecos); |
3131 | - user->priv->home_directory = g_strdup (user_info->pw_dir); |
3132 | - user->priv->shell = g_strdup (user_info->pw_shell); |
3133 | - user->priv->proxy = get_accounts_proxy_for_user (user->priv->name); |
3134 | - |
3135 | - return user; |
3136 | -} |
3137 | - |
3138 | User * |
3139 | accounts_get_user_by_name (const gchar *username) |
3140 | { |
3141 | - struct passwd *user_info; |
3142 | User *user = NULL; |
3143 | + CommonUser *common_user; |
3144 | |
3145 | g_return_val_if_fail (username != NULL, NULL); |
3146 | |
3147 | - errno = 0; |
3148 | - user_info = getpwnam (username); |
3149 | - if (user_info) |
3150 | - user = user_from_passwd (user_info); |
3151 | - |
3152 | - if (!user && errno != 0) |
3153 | - g_warning ("Unable to get information on user %s: %s", username, strerror (errno)); |
3154 | - |
3155 | - return user; |
3156 | -} |
3157 | - |
3158 | -User * |
3159 | -accounts_get_user_by_uid (uid_t uid) |
3160 | -{ |
3161 | - User *user = NULL; |
3162 | - |
3163 | - errno = 0; |
3164 | - struct passwd *user_info; |
3165 | - |
3166 | - user_info = getpwuid (uid); |
3167 | - if (user_info) |
3168 | - user = user_from_passwd (user_info); |
3169 | - |
3170 | - if (!user && errno != 0) |
3171 | - g_warning ("Unable to get information on user %d: %s", uid, strerror (errno)); |
3172 | + common_user = common_user_list_get_user_by_name (common_user_list_get_instance (), username); |
3173 | + if (common_user != NULL) |
3174 | + { |
3175 | + user = g_object_new (USER_TYPE, NULL); |
3176 | + user->priv->common_user = common_user; |
3177 | + } |
3178 | |
3179 | return user; |
3180 | } |
3181 | @@ -284,136 +45,74 @@ |
3182 | User * |
3183 | accounts_get_current_user () |
3184 | { |
3185 | - return user_from_passwd (getpwuid (getuid ())); |
3186 | + struct passwd *entry = getpwuid (getuid ()); |
3187 | + if (entry != NULL) |
3188 | + return accounts_get_user_by_name (entry->pw_name); |
3189 | + else |
3190 | + return NULL; |
3191 | } |
3192 | |
3193 | const gchar * |
3194 | user_get_name (User *user) |
3195 | { |
3196 | g_return_val_if_fail (user != NULL, NULL); |
3197 | - return user->priv->name; |
3198 | + return common_user_get_name (user->priv->common_user); |
3199 | } |
3200 | |
3201 | uid_t |
3202 | user_get_uid (User *user) |
3203 | { |
3204 | g_return_val_if_fail (user != NULL, 0); |
3205 | - return user->priv->uid; |
3206 | + return common_user_get_uid (user->priv->common_user); |
3207 | } |
3208 | |
3209 | gid_t |
3210 | user_get_gid (User *user) |
3211 | { |
3212 | g_return_val_if_fail (user != NULL, 0); |
3213 | - return user->priv->gid; |
3214 | -} |
3215 | - |
3216 | -const gchar * |
3217 | -user_get_gecos (User *user) |
3218 | -{ |
3219 | - g_return_val_if_fail (user != NULL, NULL); |
3220 | - return user->priv->gecos; |
3221 | + return common_user_get_gid (user->priv->common_user); |
3222 | } |
3223 | |
3224 | const gchar * |
3225 | user_get_home_directory (User *user) |
3226 | { |
3227 | g_return_val_if_fail (user != NULL, NULL); |
3228 | - return user->priv->home_directory; |
3229 | + return common_user_get_home_directory (user->priv->common_user); |
3230 | } |
3231 | |
3232 | const gchar * |
3233 | user_get_shell (User *user) |
3234 | { |
3235 | g_return_val_if_fail (user != NULL, NULL); |
3236 | - return user->priv->shell; |
3237 | + return common_user_get_shell (user->priv->common_user); |
3238 | } |
3239 | |
3240 | void |
3241 | user_set_language (User *user, const gchar *language) |
3242 | { |
3243 | g_return_if_fail (user != NULL); |
3244 | - |
3245 | - call_method (user->priv->proxy, "SetLanguage", g_variant_new ("(s)", language), "()", NULL); |
3246 | - save_string_to_dmrc (user->priv->name, "Desktop", "Language", language); |
3247 | + common_user_set_language (user->priv->common_user, language); |
3248 | } |
3249 | |
3250 | const gchar * |
3251 | user_get_language (User *user) |
3252 | { |
3253 | - GVariant *variant, *inner; |
3254 | - gboolean success; |
3255 | - |
3256 | g_return_val_if_fail (user != NULL, NULL); |
3257 | - |
3258 | - g_free (user->priv->language); |
3259 | - if (user->priv->proxy) |
3260 | - { |
3261 | - /* the "Language" property cannot be retrieved with get_property () here since it |
3262 | - * uses g_dbus_proxy_get_cached_property () which would return the previous (cached) value |
3263 | - * of the "Language" property |
3264 | - */ |
3265 | - 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); |
3266 | - if (success) |
3267 | - { |
3268 | - g_variant_get (variant, "(v)", &inner); |
3269 | - user->priv->language = g_variant_dup_string (inner, NULL); |
3270 | - g_variant_unref (inner); |
3271 | - g_variant_unref (variant); |
3272 | - } |
3273 | - else |
3274 | - user->priv->language = NULL; |
3275 | - } |
3276 | - else |
3277 | - user->priv->language = get_string_from_dmrc (user->priv->name, "Desktop", "Language"); |
3278 | - |
3279 | - /* Treat a blank language as unset */ |
3280 | - if (g_strcmp0 (user->priv->language, "") == 0) |
3281 | - { |
3282 | - g_free (user->priv->language); |
3283 | - user->priv->language = NULL; |
3284 | - } |
3285 | - |
3286 | - return user->priv->language; |
3287 | + return common_user_get_language (user->priv->common_user); |
3288 | } |
3289 | |
3290 | void |
3291 | user_set_xsession (User *user, const gchar *xsession) |
3292 | { |
3293 | g_return_if_fail (user != NULL); |
3294 | - |
3295 | - call_method (user->priv->proxy, "SetXSession", g_variant_new ("(s)", xsession), "()", NULL); |
3296 | - save_string_to_dmrc (user->priv->name, "Desktop", "Session", xsession); |
3297 | + common_user_set_session (user->priv->common_user, xsession); |
3298 | } |
3299 | |
3300 | const gchar * |
3301 | user_get_xsession (User *user) |
3302 | { |
3303 | - GVariant *result; |
3304 | - |
3305 | g_return_val_if_fail (user != NULL, NULL); |
3306 | - |
3307 | - g_free (user->priv->xsession); |
3308 | - if (user->priv->proxy) |
3309 | - { |
3310 | - if (get_property (user->priv->proxy, "XSession", "s", &result)) |
3311 | - { |
3312 | - g_variant_get (result, "s", &user->priv->xsession); |
3313 | - g_variant_unref (result); |
3314 | - } |
3315 | - else |
3316 | - user->priv->xsession = NULL; |
3317 | - } |
3318 | - else |
3319 | - user->priv->xsession = get_string_from_dmrc (user->priv->name, "Desktop", "Session"); |
3320 | - |
3321 | - if (g_strcmp0 (user->priv->xsession, "") == 0) |
3322 | - { |
3323 | - g_free (user->priv->xsession); |
3324 | - user->priv->xsession = NULL; |
3325 | - } |
3326 | - |
3327 | - return user->priv->xsession; |
3328 | + return common_user_get_session (user->priv->common_user); |
3329 | } |
3330 | |
3331 | static void |
3332 | @@ -429,38 +128,19 @@ |
3333 | |
3334 | self = USER (object); |
3335 | |
3336 | - if (self->priv->proxy) |
3337 | - { |
3338 | - g_object_unref (self->priv->proxy); |
3339 | - self->priv->proxy = NULL; |
3340 | - } |
3341 | + if (self->priv->common_user) |
3342 | + g_object_unref (self->priv->common_user); |
3343 | + self->priv->common_user = NULL; |
3344 | |
3345 | G_OBJECT_CLASS (user_parent_class)->dispose (object); |
3346 | } |
3347 | |
3348 | static void |
3349 | -user_finalize (GObject *object) |
3350 | -{ |
3351 | - User *self; |
3352 | - |
3353 | - self = USER (object); |
3354 | - |
3355 | - g_free (self->priv->name); |
3356 | - g_free (self->priv->gecos); |
3357 | - g_free (self->priv->home_directory); |
3358 | - g_free (self->priv->shell); |
3359 | - g_free (self->priv->language); |
3360 | - |
3361 | - G_OBJECT_CLASS (user_parent_class)->finalize (object); |
3362 | -} |
3363 | - |
3364 | -static void |
3365 | user_class_init (UserClass *klass) |
3366 | { |
3367 | GObjectClass *object_class = G_OBJECT_CLASS (klass); |
3368 | |
3369 | object_class->dispose = user_dispose; |
3370 | - object_class->finalize = user_finalize; |
3371 | |
3372 | g_type_class_add_private (klass, sizeof (UserPrivate)); |
3373 | } |
3374 | |
3375 | === modified file 'src/accounts.h' |
3376 | --- src/accounts.h 2013-04-24 01:51:02 +0000 |
3377 | +++ src/accounts.h 2014-02-08 22:36:44 +0000 |
3378 | @@ -36,8 +36,6 @@ |
3379 | |
3380 | User *accounts_get_user_by_name (const gchar *username); |
3381 | |
3382 | -User *accounts_get_user_by_uid (uid_t uid); |
3383 | - |
3384 | User *accounts_get_current_user (void); |
3385 | |
3386 | GType user_get_type (void); |
3387 | @@ -48,8 +46,6 @@ |
3388 | |
3389 | gid_t user_get_gid (User *user); |
3390 | |
3391 | -const gchar *user_get_gecos (User *user); |
3392 | - |
3393 | const gchar *user_get_home_directory (User *user); |
3394 | |
3395 | const gchar *user_get_shell (User *user); |
3396 | |
3397 | === modified file 'src/lightdm.c' |
3398 | --- src/lightdm.c 2013-11-25 21:40:16 +0000 |
3399 | +++ src/lightdm.c 2014-02-08 22:36:44 +0000 |
3400 | @@ -30,6 +30,7 @@ |
3401 | #include "x-server.h" |
3402 | #include "process.h" |
3403 | #include "session-child.h" |
3404 | +#include "user-list.h" |
3405 | |
3406 | static gchar *config_path = NULL; |
3407 | static GMainLoop *loop = NULL; |
3408 | @@ -42,7 +43,7 @@ |
3409 | static VNCServer *vnc_server = NULL; |
3410 | static guint bus_id = 0; |
3411 | static GDBusConnection *bus = NULL; |
3412 | -static guint bus_id; |
3413 | +static guint reg_id = 0; |
3414 | static GDBusNodeInfo *seat_info; |
3415 | static GHashTable *seat_bus_entries = NULL; |
3416 | static guint seat_index = 0; |
3417 | @@ -787,13 +788,13 @@ |
3418 | session_info = g_dbus_node_info_new_for_xml (session_interface, NULL); |
3419 | g_assert (session_info != NULL); |
3420 | |
3421 | - bus_id = g_dbus_connection_register_object (connection, |
3422 | + reg_id = g_dbus_connection_register_object (connection, |
3423 | "/org/freedesktop/DisplayManager", |
3424 | display_manager_info->interfaces[0], |
3425 | &display_manager_vtable, |
3426 | NULL, NULL, |
3427 | &error); |
3428 | - if (bus_id == 0) |
3429 | + if (reg_id == 0) |
3430 | g_warning ("Failed to register display manager: %s", error->message); |
3431 | g_clear_error (&error); |
3432 | g_dbus_node_info_unref (display_manager_info); |
3433 | @@ -1319,11 +1320,15 @@ |
3434 | |
3435 | g_main_loop_run (loop); |
3436 | |
3437 | + /* Clean up user list */ |
3438 | + common_user_list_cleanup (); |
3439 | + |
3440 | /* Clean up display manager */ |
3441 | g_object_unref (display_manager); |
3442 | display_manager = NULL; |
3443 | |
3444 | /* Remove D-Bus interface */ |
3445 | + g_dbus_connection_unregister_object (bus, reg_id); |
3446 | g_bus_unown_name (bus_id); |
3447 | if (seat_bus_entries) |
3448 | g_hash_table_unref (seat_bus_entries); |
3449 | |
3450 | === modified file 'src/session-child.c' |
3451 | --- src/session-child.c 2014-02-06 15:04:11 +0000 |
3452 | +++ src/session-child.c 2014-02-08 22:36:44 +0000 |
3453 | @@ -512,7 +512,7 @@ |
3454 | |
3455 | drop_privileges = geteuid () == 0; |
3456 | if (drop_privileges) |
3457 | - privileges_drop (user); |
3458 | + privileges_drop (user_get_uid (user), user_get_gid (user)); |
3459 | result = x_authority_write (x_authority, XAUTH_WRITE_MODE_REPLACE, x_authority_filename, &error); |
3460 | if (drop_privileges) |
3461 | privileges_reclaim (); |
3462 | @@ -660,7 +660,7 @@ |
3463 | |
3464 | drop_privileges = geteuid () == 0; |
3465 | if (drop_privileges) |
3466 | - privileges_drop (user); |
3467 | + privileges_drop (user_get_uid (user), user_get_gid (user)); |
3468 | result = x_authority_write (x_authority, XAUTH_WRITE_MODE_REMOVE, x_authority_filename, &error); |
3469 | if (drop_privileges) |
3470 | privileges_reclaim (); |
3471 | |
3472 | === modified file 'tests/src/test-gobject-greeter.c' |
3473 | --- tests/src/test-gobject-greeter.c 2013-10-30 17:30:12 +0000 |
3474 | +++ tests/src/test-gobject-greeter.c 2014-02-08 22:36:44 +0000 |
3475 | @@ -218,7 +218,7 @@ |
3476 | if (strcmp (name, "LOG-USER") == 0) |
3477 | { |
3478 | LightDMUser *user; |
3479 | - const gchar *username, *image, *background, *layout, *session; |
3480 | + const gchar *username, *image, *background, *language, *layout, *session; |
3481 | const gchar * const * layouts; |
3482 | gchar **fields = NULL; |
3483 | gchar *layouts_text; |
3484 | @@ -237,6 +237,7 @@ |
3485 | user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username); |
3486 | image = lightdm_user_get_image (user); |
3487 | background = lightdm_user_get_background (user); |
3488 | + language = lightdm_user_get_language (user); |
3489 | layout = lightdm_user_get_layout (user); |
3490 | layouts = lightdm_user_get_layouts (user); |
3491 | layouts_text = g_strjoinv (";", (gchar **) layouts); |
3492 | @@ -255,7 +256,7 @@ |
3493 | else if (strcmp (fields[i], "BACKGROUND") == 0) |
3494 | g_string_append_printf (status_text, " BACKGROUND=%s", background ? background : ""); |
3495 | else if (strcmp (fields[i], "LANGUAGE") == 0) |
3496 | - g_string_append_printf (status_text, " LANGUAGE=%s", lightdm_user_get_language (user)); |
3497 | + g_string_append_printf (status_text, " LANGUAGE=%s", language ? language : ""); |
3498 | else if (strcmp (fields[i], "LAYOUT") == 0) |
3499 | g_string_append_printf (status_text, " LAYOUT=%s", layout ? layout : ""); |
3500 | else if (strcmp (fields[i], "LAYOUTS") == 0) |
3501 | |
3502 | === modified file 'tests/src/test-runner.c' |
3503 | --- tests/src/test-runner.c 2013-11-07 00:37:07 +0000 |
3504 | +++ tests/src/test-runner.c 2014-02-08 22:36:44 +0000 |
3505 | @@ -1715,6 +1715,15 @@ |
3506 | user->xsession = g_strdup (xsession); |
3507 | |
3508 | g_dbus_method_invocation_return_value (invocation, g_variant_new ("()")); |
3509 | + |
3510 | + /* And notify others that it took */ |
3511 | + g_dbus_connection_emit_signal (accounts_connection, |
3512 | + NULL, |
3513 | + user->path, |
3514 | + "org.freedesktop.Accounts.User", |
3515 | + "Changed", |
3516 | + g_variant_new ("()"), |
3517 | + NULL); |
3518 | } |
3519 | else |
3520 | g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "No such method: %s", method_name); |
3521 | @@ -1745,6 +1754,10 @@ |
3522 | return g_variant_new_string (user->language ? user->language : ""); |
3523 | else if (strcmp (property_name, "IconFile") == 0) |
3524 | return g_variant_new_string (user->image ? user->image : ""); |
3525 | + else if (strcmp (property_name, "Shell") == 0) |
3526 | + return g_variant_new_string ("/bin/sh"); |
3527 | + else if (strcmp (property_name, "Uid") == 0) |
3528 | + return g_variant_new_uint64 (user->uid); |
3529 | else if (strcmp (property_name, "XSession") == 0) |
3530 | return g_variant_new_string (user->xsession ? user->xsession : ""); |
3531 | else if (strcmp (property_name, "XKeyboardLayouts") == 0) |
3532 | @@ -1800,6 +1813,8 @@ |
3533 | " <property name='BackgroundFile' type='s' access='read'/>" |
3534 | " <property name='Language' type='s' access='read'/>" |
3535 | " <property name='IconFile' type='s' access='read'/>" |
3536 | + " <property name='Shell' type='s' access='read'/>" |
3537 | + " <property name='Uid' type='t' access='read'/>" |
3538 | " <property name='XSession' type='s' access='read'/>" |
3539 | " <property name='XKeyboardLayouts' type='as' access='read'/>" |
3540 | " <property name='XHasMessages' type='b' access='read'/>" |
FAILED: Continuous integration, rev:1878 jenkins. qa.ubuntu. com/job/ lightdm- ci/234/ jenkins. qa.ubuntu. com/job/ lightdm- trusty- amd64-ci/ 28/console jenkins. qa.ubuntu. com/job/ lightdm- trusty- armhf-ci/ 28/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/lightdm- ci/234/ rebuild
http://