1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>.
4 * Copyright (C) 2007-2008 William Jon McCann <mccann@jhu.edu>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include <config.h>
22
23 #include <float.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
28
29 #include <glib.h>
30 #include <glib/gi18n.h>
31 #include <gio/gio.h>
32
33 #include "act-user-private.h"
34 #include "accounts-user-generated.h"
35
36 /**
37 * SECTION:act-user
38 * @title: ActUser
39 * @short_description: information about a user account
40 *
41 * An ActUser object represents a user account on the system.
42 */
43
44 /**
45 * ActUser:
46 *
47 * Represents a user account on the system.
48 */
49
50 /**
51 * ActUserAccountType:
52 * @ACT_USER_ACCOUNT_TYPE_STANDARD: Normal non-administrative user
53 * @ACT_USER_ACCOUNT_TYPE_ADMINISTRATOR: Administrative user
54 *
55 * Type of user account
56 */
57
58 /**
59 * ActUserPasswordMode:
60 * @ACT_USER_PASSWORD_MODE_REGULAR: Password set normally
61 * @ACT_USER_PASSWORD_MODE_SET_AT_LOGIN: Password will be chosen at next login
62 * @ACT_USER_PASSWORD_MODE_NONE: No password set
63 *
64 * Mode for setting the user's password.
65 */
66
67 #define ACT_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ACT_TYPE_USER, ActUserClass))
68 #define ACT_IS_USER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ACT_TYPE_USER))
69 #define ACT_USER_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), ACT_TYPE_USER, ActUserClass))
70
71 #define ACCOUNTS_NAME "org.freedesktop.Accounts"
72 #define ACCOUNTS_USER_INTERFACE "org.freedesktop.Accounts.User"
73
74 enum {
75 PROP_0,
76 PROP_UID,
77 PROP_USER_NAME,
78 PROP_REAL_NAME,
79 PROP_ACCOUNT_TYPE,
80 PROP_PASSWORD_MODE,
81 PROP_PASSWORD_HINT,
82 PROP_HOME_DIR,
83 PROP_SHELL,
84 PROP_EMAIL,
85 PROP_LOCATION,
86 PROP_LOCKED,
87 PROP_AUTOMATIC_LOGIN,
88 PROP_SYSTEM_ACCOUNT,
89 PROP_NONEXISTENT,
90 PROP_LOCAL_ACCOUNT,
91 PROP_LOGIN_FREQUENCY,
92 PROP_LOGIN_TIME,
93 PROP_LOGIN_HISTORY,
94 PROP_ICON_FILE,
95 PROP_LANGUAGE,
96 PROP_X_SESSION,
97 PROP_IS_LOADED
98 };
99
100 enum {
101 CHANGED,
102 SESSIONS_CHANGED,
103 LAST_SIGNAL
104 };
105
106 struct _ActUser {
107 GObject parent;
108
109 GDBusConnection *connection;
110 AccountsUser *accounts_proxy;
111
112 GList *our_sessions;
113 GList *other_sessions;
114
115 guint is_loaded : 1;
116 guint nonexistent : 1;
117 };
118
119 struct _ActUserClass
120 {
121 GObjectClass parent_class;
122 };
123
124 static void act_user_finalize (GObject *object);
125
126 static guint signals[LAST_SIGNAL] = { 0 };
127
G_DEFINE_TYPE(ActUser,act_user,G_TYPE_OBJECT)128 G_DEFINE_TYPE (ActUser, act_user, G_TYPE_OBJECT)
129
130 static int
131 session_compare (const char *a,
132 const char *b)
133 {
134 if (a == NULL) {
135 return 1;
136 } else if (b == NULL) {
137 return -1;
138 }
139
140 return strcmp (a, b);
141 }
142
143 void
_act_user_add_session(ActUser * user,const char * ssid,gboolean is_ours)144 _act_user_add_session (ActUser *user,
145 const char *ssid,
146 gboolean is_ours)
147 {
148 GList *li;
149
150 g_return_if_fail (ACT_IS_USER (user));
151 g_return_if_fail (ssid != NULL);
152
153 li = g_list_find_custom (user->our_sessions, ssid, (GCompareFunc)session_compare);
154 if (li == NULL)
155 li = g_list_find_custom (user->other_sessions, ssid, (GCompareFunc)session_compare);
156
157 if (li == NULL) {
158 g_debug ("ActUser: adding session %s", ssid);
159 if (is_ours)
160 user->our_sessions = g_list_prepend (user->our_sessions, g_strdup (ssid));
161 else
162 user->other_sessions = g_list_prepend (user->other_sessions, g_strdup (ssid));
163 g_signal_emit (user, signals[SESSIONS_CHANGED], 0);
164 } else {
165 g_debug ("ActUser: session already present: %s", ssid);
166 }
167 }
168
169 void
_act_user_remove_session(ActUser * user,const char * ssid)170 _act_user_remove_session (ActUser *user,
171 const char *ssid)
172 {
173 GList *li, **headp;
174
175 g_return_if_fail (ACT_IS_USER (user));
176 g_return_if_fail (ssid != NULL);
177
178 headp = &(user->our_sessions);
179 li = g_list_find_custom (user->our_sessions, ssid, (GCompareFunc)session_compare);
180 if (li == NULL) {
181 headp = &(user->other_sessions);
182 li = g_list_find_custom (user->other_sessions, ssid, (GCompareFunc)session_compare);
183 }
184
185 if (li != NULL) {
186 g_debug ("ActUser: removing session %s", ssid);
187 g_free (li->data);
188 *headp = g_list_delete_link (*headp, li);
189 g_signal_emit (user, signals[SESSIONS_CHANGED], 0);
190 } else {
191 g_debug ("ActUser: session not found: %s", ssid);
192 }
193 }
194
195 /**
196 * act_user_get_num_sessions:
197 * @user: a user
198 *
199 * Get the number of sessions for a user that are graphical and on the
200 * same seat as the session of the calling process.
201 *
202 * Returns: the number of sessions
203 */
204 guint
act_user_get_num_sessions(ActUser * user)205 act_user_get_num_sessions (ActUser *user)
206 {
207 return g_list_length (user->our_sessions);
208 }
209
210 /**
211 * act_user_get_num_sessions_anywhere:
212 * @user: a user
213 *
214 * Get the number of sessions for a user on any seat of any type.
215 * See also act_user_get_num_sessions().
216 *
217 * (Currently, this function is only implemented for systemd-logind.
218 * For ConsoleKit, it is equivalent to act_user_get_num_sessions.)
219 *
220 * Returns: the number of sessions
221 */
222 guint
act_user_get_num_sessions_anywhere(ActUser * user)223 act_user_get_num_sessions_anywhere (ActUser *user)
224 {
225 return (g_list_length (user->our_sessions)
226 + g_list_length (user->other_sessions));
227 }
228
229 static void
act_user_get_property(GObject * object,guint param_id,GValue * value,GParamSpec * pspec)230 act_user_get_property (GObject *object,
231 guint param_id,
232 GValue *value,
233 GParamSpec *pspec)
234 {
235 ActUser *user;
236
237 user = ACT_USER (object);
238
239 switch (param_id) {
240 case PROP_NONEXISTENT:
241 g_value_set_boolean (value, user->nonexistent);
242 break;
243 case PROP_IS_LOADED:
244 g_value_set_boolean (value, user->is_loaded);
245 break;
246 default:
247 if (user->accounts_proxy != NULL) {
248 const char *property_name;
249
250 property_name = g_param_spec_get_name (pspec);
251
252 g_object_get_property (G_OBJECT (user->accounts_proxy), property_name, value);
253
254 }
255 break;
256 }
257 }
258
259
260 static void
act_user_class_init(ActUserClass * class)261 act_user_class_init (ActUserClass *class)
262 {
263 GObjectClass *gobject_class;
264
265 gobject_class = G_OBJECT_CLASS (class);
266
267 gobject_class->finalize = act_user_finalize;
268 gobject_class->get_property = act_user_get_property;
269
270 g_object_class_install_property (gobject_class,
271 PROP_REAL_NAME,
272 g_param_spec_string ("real-name",
273 "Real Name",
274 "The real name to display for this user.",
275 NULL,
276 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
277
278 g_object_class_install_property (gobject_class,
279 PROP_ACCOUNT_TYPE,
280 g_param_spec_int ("account-type",
281 "Account Type",
282 "The account type for this user.",
283 ACT_USER_ACCOUNT_TYPE_STANDARD,
284 ACT_USER_ACCOUNT_TYPE_ADMINISTRATOR,
285 ACT_USER_ACCOUNT_TYPE_STANDARD,
286 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
287 g_object_class_install_property (gobject_class,
288 PROP_PASSWORD_MODE,
289 g_param_spec_int ("password-mode",
290 "Password Mode",
291 "The password mode for this user.",
292 ACT_USER_PASSWORD_MODE_REGULAR,
293 ACT_USER_PASSWORD_MODE_NONE,
294 ACT_USER_PASSWORD_MODE_REGULAR,
295 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
296
297 g_object_class_install_property (gobject_class,
298 PROP_PASSWORD_HINT,
299 g_param_spec_string ("password-hint",
300 "Password Hint",
301 "Hint to help this user remember his password",
302 NULL,
303 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
304
305 g_object_class_install_property (gobject_class,
306 PROP_UID,
307 g_param_spec_int ("uid",
308 "User ID",
309 "The UID for this user.",
310 0, G_MAXINT, 0,
311 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
312 g_object_class_install_property (gobject_class,
313 PROP_USER_NAME,
314 g_param_spec_string ("user-name",
315 "User Name",
316 "The login name for this user.",
317 NULL,
318 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
319 g_object_class_install_property (gobject_class,
320 PROP_HOME_DIR,
321 g_param_spec_string ("home-directory",
322 "Home Directory",
323 "The home directory for this user.",
324 NULL,
325 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
326 g_object_class_install_property (gobject_class,
327 PROP_SHELL,
328 g_param_spec_string ("shell",
329 "Shell",
330 "The shell for this user.",
331 NULL,
332 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
333 g_object_class_install_property (gobject_class,
334 PROP_EMAIL,
335 g_param_spec_string ("email",
336 "Email",
337 "The email address for this user.",
338 NULL,
339 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
340 g_object_class_install_property (gobject_class,
341 PROP_LOCATION,
342 g_param_spec_string ("location",
343 "Location",
344 "The location of this user.",
345 NULL,
346 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
347 g_object_class_install_property (gobject_class,
348 PROP_LOGIN_FREQUENCY,
349 g_param_spec_int ("login-frequency",
350 "login frequency",
351 "login frequency",
352 0,
353 G_MAXINT,
354 0,
355 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
356 g_object_class_install_property (gobject_class,
357 PROP_LOGIN_TIME,
358 g_param_spec_int64 ("login-time",
359 "Login time",
360 "The last login time for this user.",
361 0,
362 G_MAXINT64,
363 0,
364 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
365 g_object_class_install_property (gobject_class,
366 PROP_LOGIN_HISTORY,
367 g_param_spec_variant ("login-history",
368 "Login history",
369 "The login history for this user.",
370 G_VARIANT_TYPE ("a(xxa{sv})"),
371 NULL,
372 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
373 g_object_class_install_property (gobject_class,
374 PROP_ICON_FILE,
375 g_param_spec_string ("icon-file",
376 "Icon File",
377 "The path to an icon for this user.",
378 NULL,
379 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
380 g_object_class_install_property (gobject_class,
381 PROP_LANGUAGE,
382 g_param_spec_string ("language",
383 "Language",
384 "User's locale.",
385 NULL,
386 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
387 g_object_class_install_property (gobject_class,
388 PROP_X_SESSION,
389 g_param_spec_string ("x-session",
390 "X session",
391 "User's X session.",
392 NULL,
393 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
394 g_object_class_install_property (gobject_class,
395 PROP_IS_LOADED,
396 g_param_spec_boolean ("is-loaded",
397 "Is loaded",
398 "Determines whether or not the user object is loaded and ready to read from.",
399 FALSE,
400 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
401 g_object_class_install_property (gobject_class,
402 PROP_NONEXISTENT,
403 g_param_spec_boolean ("nonexistent",
404 "Doesn't exist",
405 "Determines whether or not the user object represents a valid user account.",
406 FALSE,
407 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
408 g_object_class_install_property (gobject_class,
409 PROP_LOCKED,
410 g_param_spec_boolean ("locked",
411 "Locked",
412 "Locked",
413 FALSE,
414 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
415
416 g_object_class_install_property (gobject_class,
417 PROP_AUTOMATIC_LOGIN,
418 g_param_spec_boolean ("automatic-login",
419 "Automatic Login",
420 "Automatic Login",
421 FALSE,
422 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
423
424 g_object_class_install_property (gobject_class,
425 PROP_LOCAL_ACCOUNT,
426 g_param_spec_boolean ("local-account",
427 "Local Account",
428 "Local Account",
429 FALSE,
430 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
431
432 g_object_class_install_property (gobject_class,
433 PROP_SYSTEM_ACCOUNT,
434 g_param_spec_boolean ("system-account",
435 "System Account",
436 "System Account",
437 FALSE,
438 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
439
440
441 /**
442 * ActUser::changed:
443 *
444 * Emitted when the user accounts changes in some way.
445 */
446 signals [CHANGED] =
447 g_signal_new ("changed",
448 G_TYPE_FROM_CLASS (class),
449 G_SIGNAL_RUN_LAST,
450 0,
451 NULL, NULL,
452 g_cclosure_marshal_VOID__VOID,
453 G_TYPE_NONE, 0);
454 /**
455 * ActUser::sessions-changed:
456 *
457 * Emitted when the list of sessions for this user changes.
458 */
459 signals [SESSIONS_CHANGED] =
460 g_signal_new ("sessions-changed",
461 G_TYPE_FROM_CLASS (class),
462 G_SIGNAL_RUN_LAST,
463 0,
464 NULL, NULL,
465 g_cclosure_marshal_VOID__VOID,
466 G_TYPE_NONE, 0);
467 }
468
469 static void
act_user_init(ActUser * user)470 act_user_init (ActUser *user)
471 {
472 g_autoptr(GError) error = NULL;
473
474 user->our_sessions = NULL;
475 user->other_sessions = NULL;
476
477 user->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
478 if (user->connection == NULL) {
479 g_warning ("Couldn't connect to system bus: %s", error->message);
480 }
481 }
482
483 static void
act_user_finalize(GObject * object)484 act_user_finalize (GObject *object)
485 {
486 ActUser *user;
487
488 user = ACT_USER (object);
489
490 if (user->accounts_proxy != NULL) {
491 g_object_unref (user->accounts_proxy);
492 }
493
494 if (user->connection != NULL) {
495 g_object_unref (user->connection);
496 }
497
498 if (G_OBJECT_CLASS (act_user_parent_class)->finalize)
499 (*G_OBJECT_CLASS (act_user_parent_class)->finalize) (object);
500 }
501
502 static void
set_is_loaded(ActUser * user,gboolean is_loaded)503 set_is_loaded (ActUser *user,
504 gboolean is_loaded)
505 {
506 if (user->is_loaded != is_loaded) {
507 user->is_loaded = is_loaded;
508 g_object_notify (G_OBJECT (user), "is-loaded");
509 }
510 }
511
512 /**
513 * act_user_get_uid:
514 * @user: the user object to examine.
515 *
516 * Retrieves the ID of @user.
517 *
518 * Returns: a pointer to an array of characters which must not be modified or
519 * freed, or %NULL.
520 **/
521
522 uid_t
act_user_get_uid(ActUser * user)523 act_user_get_uid (ActUser *user)
524 {
525 g_return_val_if_fail (ACT_IS_USER (user), -1);
526
527 if (user->accounts_proxy == NULL)
528 return -1;
529
530 return accounts_user_get_uid (user->accounts_proxy);
531 }
532
533 /**
534 * act_user_get_real_name:
535 * @user: the user object to examine.
536 *
537 * Retrieves the display name of @user.
538 *
539 * Returns: (transfer none): a pointer to an array of characters which must not be modified or
540 * freed, or %NULL.
541 **/
542 const char *
act_user_get_real_name(ActUser * user)543 act_user_get_real_name (ActUser *user)
544 {
545 const char *real_name = NULL;
546
547 g_return_val_if_fail (ACT_IS_USER (user), NULL);
548
549 if (user->accounts_proxy == NULL)
550 return NULL;
551
552 real_name = accounts_user_get_real_name (user->accounts_proxy);
553
554 if (real_name == NULL || real_name[0] == '\0') {
555 real_name = accounts_user_get_user_name (user->accounts_proxy);
556 }
557
558 return real_name;
559 }
560
561 /**
562 * act_user_get_account_type:
563 * @user: the user object to examine.
564 *
565 * Retrieves the account type of @user.
566 *
567 * Returns: a #ActUserAccountType
568 **/
569 ActUserAccountType
act_user_get_account_type(ActUser * user)570 act_user_get_account_type (ActUser *user)
571 {
572 g_return_val_if_fail (ACT_IS_USER (user), ACT_USER_ACCOUNT_TYPE_STANDARD);
573
574 if (user->accounts_proxy == NULL)
575 return ACT_USER_ACCOUNT_TYPE_STANDARD;
576
577 return accounts_user_get_account_type (user->accounts_proxy);
578 }
579
580 /**
581 * act_user_get_password_mode:
582 * @user: the user object to examine.
583 *
584 * Retrieves the password mode of @user.
585 *
586 * Returns: a #ActUserPasswordMode
587 **/
588 ActUserPasswordMode
act_user_get_password_mode(ActUser * user)589 act_user_get_password_mode (ActUser *user)
590 {
591 g_return_val_if_fail (ACT_IS_USER (user), ACT_USER_PASSWORD_MODE_REGULAR);
592
593 if (user->accounts_proxy == NULL)
594 return ACT_USER_PASSWORD_MODE_REGULAR;
595
596 return accounts_user_get_password_mode (user->accounts_proxy);
597 }
598
599 /**
600 * act_user_get_password_hint:
601 * @user: the user object to examine.
602 *
603 * Retrieves the password hint set by @user.
604 *
605 * Returns: (transfer none): a pointer to an array of characters which must not be modified or
606 * freed, or %NULL.
607 **/
608 const char *
act_user_get_password_hint(ActUser * user)609 act_user_get_password_hint (ActUser *user)
610 {
611 g_return_val_if_fail (ACT_IS_USER (user), NULL);
612
613 if (user->accounts_proxy == NULL)
614 return NULL;
615
616 return accounts_user_get_password_hint (user->accounts_proxy);
617 }
618
619 /**
620 * act_user_get_home_dir:
621 * @user: the user object to examine.
622 *
623 * Retrieves the home directory for @user.
624 *
625 * Returns: (transfer none): a pointer to an array of characters which must not be modified or
626 * freed, or %NULL.
627 **/
628 const char *
act_user_get_home_dir(ActUser * user)629 act_user_get_home_dir (ActUser *user)
630 {
631 g_return_val_if_fail (ACT_IS_USER (user), NULL);
632
633 if (user->accounts_proxy == NULL)
634 return NULL;
635
636 return accounts_user_get_home_directory (user->accounts_proxy);
637 }
638
639 /**
640 * act_user_get_shell:
641 * @user: the user object to examine.
642 *
643 * Retrieves the shell assigned to @user.
644 *
645 * Returns: (transfer none): a pointer to an array of characters which must not be modified or
646 * freed, or %NULL.
647 **/
648 const char *
act_user_get_shell(ActUser * user)649 act_user_get_shell (ActUser *user)
650 {
651 g_return_val_if_fail (ACT_IS_USER (user), NULL);
652
653 if (user->accounts_proxy == NULL)
654 return NULL;
655
656 return accounts_user_get_shell (user->accounts_proxy);
657 }
658
659 /**
660 * act_user_get_email:
661 * @user: the user object to examine.
662 *
663 * Retrieves the email address set by @user.
664 *
665 * Returns: (transfer none): a pointer to an array of characters which must not be modified or
666 * freed, or %NULL.
667 **/
668 const char *
act_user_get_email(ActUser * user)669 act_user_get_email (ActUser *user)
670 {
671 g_return_val_if_fail (ACT_IS_USER (user), NULL);
672
673 if (user->accounts_proxy == NULL)
674 return NULL;
675
676 return accounts_user_get_email (user->accounts_proxy);
677 }
678
679 /**
680 * act_user_get_location:
681 * @user: the user object to examine.
682 *
683 * Retrieves the location set by @user.
684 *
685 * Returns: (transfer none): a pointer to an array of characters which must not be modified or
686 * freed, or %NULL.
687 **/
688 const char *
act_user_get_location(ActUser * user)689 act_user_get_location (ActUser *user)
690 {
691 g_return_val_if_fail (ACT_IS_USER (user), NULL);
692
693 if (user->accounts_proxy == NULL)
694 return NULL;
695
696 return accounts_user_get_location (user->accounts_proxy);
697 }
698
699 /**
700 * act_user_get_user_name:
701 * @user: the user object to examine.
702 *
703 * Retrieves the login name of @user.
704 *
705 * Returns: (transfer none): a pointer to an array of characters which must not be modified or
706 * freed, or %NULL.
707 **/
708
709 const char *
act_user_get_user_name(ActUser * user)710 act_user_get_user_name (ActUser *user)
711 {
712 g_return_val_if_fail (ACT_IS_USER (user), NULL);
713
714 if (user->accounts_proxy == NULL)
715 return NULL;
716
717 return accounts_user_get_user_name (user->accounts_proxy);
718 }
719
720 /**
721 * act_user_get_login_frequency:
722 * @user: a #ActUser
723 *
724 * Returns the number of times @user has logged in.
725 *
726 * Returns: the login frequency
727 */
728 int
act_user_get_login_frequency(ActUser * user)729 act_user_get_login_frequency (ActUser *user)
730 {
731 g_return_val_if_fail (ACT_IS_USER (user), 0);
732
733 if (user->accounts_proxy == NULL)
734 return 1;
735
736 return accounts_user_get_login_frequency (user->accounts_proxy);
737 }
738
739 /**
740 * act_user_get_login_time:
741 * @user: a #ActUser
742 *
743 * Returns the last login time for @user.
744 *
745 * Returns: the login time
746 */
747 gint64
act_user_get_login_time(ActUser * user)748 act_user_get_login_time (ActUser *user)
749 {
750 g_return_val_if_fail (ACT_IS_USER (user), 0);
751
752 if (user->accounts_proxy == NULL)
753 return 0;
754
755 return accounts_user_get_login_time (user->accounts_proxy);
756 }
757
758 /**
759 * act_user_get_login_history:
760 * @user: a #ActUser
761 *
762 * Returns the login history for @user.
763 *
764 * Returns: (transfer none): a pointer to GVariant of type "a(xxa{sv})"
765 * which must not be modified or freed, or %NULL.
766 */
767 const GVariant *
act_user_get_login_history(ActUser * user)768 act_user_get_login_history (ActUser *user)
769 {
770 g_return_val_if_fail (ACT_IS_USER (user), NULL);
771
772 if (user->accounts_proxy == NULL)
773 return NULL;
774
775 return accounts_user_get_login_history (user->accounts_proxy);
776 }
777
778 /**
779 * act_user_collate:
780 * @user1: a user
781 * @user2: a user
782 *
783 * Organize the user by login frequency and names.
784 *
785 * Returns: negative if @user1 is before @user2, zero if equal
786 * or positive if @user1 is after @user2
787 */
788 int
act_user_collate(ActUser * user1,ActUser * user2)789 act_user_collate (ActUser *user1,
790 ActUser *user2)
791 {
792 const char *str1;
793 const char *str2;
794 int num1;
795 int num2;
796 guint len1;
797 guint len2;
798
799 g_return_val_if_fail (ACT_IS_USER (user1), 0);
800 g_return_val_if_fail (ACT_IS_USER (user2), 0);
801
802 num1 = act_user_get_login_frequency (user1);
803 num2 = act_user_get_login_frequency (user2);
804
805 if (num1 > num2) {
806 return -1;
807 }
808
809 if (num1 < num2) {
810 return 1;
811 }
812
813
814 len1 = g_list_length (user1->our_sessions);
815 len2 = g_list_length (user2->our_sessions);
816
817 if (len1 > len2) {
818 return -1;
819 }
820
821 if (len1 < len2) {
822 return 1;
823 }
824
825 /* if login frequency is equal try names */
826 str1 = act_user_get_real_name (user1);
827 str2 = act_user_get_real_name (user2);
828
829 if (str1 == NULL && str2 != NULL) {
830 return -1;
831 }
832
833 if (str1 != NULL && str2 == NULL) {
834 return 1;
835 }
836
837 if (str1 == NULL && str2 == NULL) {
838 return 0;
839 }
840
841 return g_utf8_collate (str1, str2);
842 }
843
844 /**
845 * act_user_is_logged_in:
846 * @user: a #ActUser
847 *
848 * Returns whether or not #ActUser is currently graphically logged in
849 * on the same seat as the seat of the session of the calling process.
850 *
851 * Returns: %TRUE or %FALSE
852 */
853 gboolean
act_user_is_logged_in(ActUser * user)854 act_user_is_logged_in (ActUser *user)
855 {
856 return user->our_sessions != NULL;
857 }
858
859 /**
860 * act_user_is_logged_in_anywhere:
861 * @user: a #ActUser
862 *
863 * Returns whether or not #ActUser is currently logged in in any way
864 * whatsoever. See also act_user_is_logged_in().
865 *
866 * (Currently, this function is only implemented for systemd-logind.
867 * For ConsoleKit, it is equivalent to act_user_is_logged_in.)
868 *
869 * Returns: %TRUE or %FALSE
870 */
871 gboolean
act_user_is_logged_in_anywhere(ActUser * user)872 act_user_is_logged_in_anywhere (ActUser *user)
873 {
874 return user->our_sessions != NULL || user->other_sessions != NULL;
875 }
876
877 /**
878 * act_user_get_saved:
879 * @user: a #ActUser
880 *
881 * Returns whether or not the #ActUser account has retained state in accountsservice.
882 *
883 * Returns: %TRUE or %FALSE
884 */
885 gboolean
act_user_get_saved(ActUser * user)886 act_user_get_saved (ActUser *user)
887 {
888 g_return_val_if_fail (ACT_IS_USER (user), TRUE);
889
890 if (user->accounts_proxy == NULL)
891 return FALSE;
892
893 return accounts_user_get_saved (user->accounts_proxy);
894 }
895
896 /**
897 * act_user_get_locked:
898 * @user: a #ActUser
899 *
900 * Returns whether or not the #ActUser account is locked.
901 *
902 * Returns: %TRUE or %FALSE
903 */
904 gboolean
act_user_get_locked(ActUser * user)905 act_user_get_locked (ActUser *user)
906 {
907 g_return_val_if_fail (ACT_IS_USER (user), TRUE);
908
909 if (user->accounts_proxy == NULL)
910 return TRUE;
911
912 return accounts_user_get_locked (user->accounts_proxy);
913 }
914
915 /**
916 * act_user_get_automatic_login:
917 * @user: a #ActUser
918 *
919 * Returns whether or not #ActUser is automatically logged in at boot time.
920 *
921 * Returns: %TRUE or %FALSE
922 */
923 gboolean
act_user_get_automatic_login(ActUser * user)924 act_user_get_automatic_login (ActUser *user)
925 {
926 g_return_val_if_fail (ACT_IS_USER (user), FALSE);
927
928 if (user->accounts_proxy == NULL)
929 return FALSE;
930
931 return accounts_user_get_automatic_login (user->accounts_proxy);
932 }
933
934 /**
935 * act_user_is_system_account:
936 * @user: a #ActUser
937 *
938 * Returns whether or not #ActUser represents a 'system account' like
939 * 'root' or 'nobody'.
940 *
941 * Returns: %TRUE or %FALSE
942 */
943 gboolean
act_user_is_system_account(ActUser * user)944 act_user_is_system_account (ActUser *user)
945 {
946 g_return_val_if_fail (ACT_IS_USER (user), TRUE);
947
948 if (user->accounts_proxy == NULL)
949 return TRUE;
950
951 return accounts_user_get_system_account (user->accounts_proxy);
952 }
953
954 /**
955 * act_user_is_local_account:
956 * @user: the user object to examine.
957 *
958 * Retrieves whether the user is a local account or not.
959 *
960 * Returns: %TRUE if the user is local
961 **/
962 gboolean
act_user_is_local_account(ActUser * user)963 act_user_is_local_account (ActUser *user)
964 {
965 g_return_val_if_fail (ACT_IS_USER (user), FALSE);
966
967 if (user->accounts_proxy == NULL)
968 return FALSE;
969
970 return accounts_user_get_local_account (user->accounts_proxy);
971 }
972
973 /**
974 * act_user_is_nonexistent:
975 * @user: the user object to examine.
976 *
977 * Retrieves whether the user is nonexistent or not.
978 *
979 * Returns: %TRUE if the user is nonexistent
980 **/
981 gboolean
act_user_is_nonexistent(ActUser * user)982 act_user_is_nonexistent (ActUser *user)
983 {
984 g_return_val_if_fail (ACT_IS_USER (user), FALSE);
985
986 return user->nonexistent;
987 }
988
989 /**
990 * act_user_get_icon_file:
991 * @user: a #ActUser
992 *
993 * Returns the path to the account icon belonging to @user.
994 *
995 * Returns: (transfer none): a path to an icon
996 */
997 const char *
act_user_get_icon_file(ActUser * user)998 act_user_get_icon_file (ActUser *user)
999 {
1000 g_return_val_if_fail (ACT_IS_USER (user), NULL);
1001
1002 if (user->accounts_proxy == NULL)
1003 return NULL;
1004
1005 return accounts_user_get_icon_file (user->accounts_proxy);
1006 }
1007
1008 /**
1009 * act_user_get_language:
1010 * @user: a #ActUser
1011 *
1012 * Returns the path to the configured locale of @user.
1013 *
1014 * Returns: (transfer none): a path to an icon
1015 */
1016 const char *
act_user_get_language(ActUser * user)1017 act_user_get_language (ActUser *user)
1018 {
1019 g_return_val_if_fail (ACT_IS_USER (user), NULL);
1020
1021 if (user->accounts_proxy == NULL)
1022 return NULL;
1023
1024 return accounts_user_get_language (user->accounts_proxy);
1025 }
1026
1027 /**
1028 * act_user_get_x_session:
1029 * @user: a #ActUser
1030 *
1031 * Returns the path to the configured X session for @user.
1032 *
1033 * Returns: (transfer none): a path to an icon
1034 */
1035 const char *
act_user_get_x_session(ActUser * user)1036 act_user_get_x_session (ActUser *user)
1037 {
1038 g_return_val_if_fail (ACT_IS_USER (user), NULL);
1039
1040 if (user->accounts_proxy == NULL)
1041 return NULL;
1042
1043 return accounts_user_get_xsession (user->accounts_proxy);
1044 }
1045
1046 /**
1047 * act_user_get_session:
1048 * @user: a #ActUser
1049 *
1050 * Returns the path to the configured session for @user.
1051 *
1052 * Returns: (transfer none): a path to an icon
1053 */
1054 const char *
act_user_get_session(ActUser * user)1055 act_user_get_session (ActUser *user)
1056 {
1057 g_return_val_if_fail (ACT_IS_USER (user), NULL);
1058
1059 if (user->accounts_proxy == NULL)
1060 return NULL;
1061
1062 return accounts_user_get_session (user->accounts_proxy);
1063 }
1064
1065 /**
1066 * act_user_get_session_type:
1067 * @user: a #ActUser
1068 *
1069 * Returns the type of the configured session for @user.
1070 *
1071 * Returns: (transfer none): a path to an icon
1072 */
1073 const char *
act_user_get_session_type(ActUser * user)1074 act_user_get_session_type (ActUser *user)
1075 {
1076 g_return_val_if_fail (ACT_IS_USER (user), NULL);
1077
1078 if (user->accounts_proxy == NULL)
1079 return NULL;
1080
1081 return accounts_user_get_session_type (user->accounts_proxy);
1082 }
1083
1084 /**
1085 * act_user_get_object_path:
1086 * @user: a #ActUser
1087 *
1088 * Returns the user accounts service object path of @user,
1089 * or %NULL if @user doesn't have an object path associated
1090 * with it.
1091 *
1092 * Returns: (transfer none): the object path of the user
1093 */
1094 const char *
act_user_get_object_path(ActUser * user)1095 act_user_get_object_path (ActUser *user)
1096 {
1097 g_return_val_if_fail (ACT_IS_USER (user), NULL);
1098
1099 if (user->accounts_proxy == NULL)
1100 return NULL;
1101
1102 return g_dbus_proxy_get_object_path (G_DBUS_PROXY (user->accounts_proxy));
1103 }
1104
1105 /**
1106 * act_user_get_primary_session_id:
1107 * @user: a #ActUser
1108 *
1109 * Returns the id of the primary session of @user, or %NULL if @user
1110 * has no primary session. The primary session will always be
1111 * graphical and will be chosen from the sessions on the same seat as
1112 * the seat of the session of the calling process.
1113 *
1114 * Returns: (transfer none): the id of the primary session of the user
1115 */
1116 const char *
act_user_get_primary_session_id(ActUser * user)1117 act_user_get_primary_session_id (ActUser *user)
1118 {
1119 if (user->our_sessions == NULL) {
1120 g_debug ("User %s is not logged in here, so has no primary session",
1121 act_user_get_user_name (user));
1122 return NULL;
1123 }
1124
1125 /* FIXME: better way to choose? */
1126 return user->our_sessions->data;
1127 }
1128
1129 /**
1130 * _act_user_update_as_nonexistent:
1131 * @user: the user object to update.
1132 *
1133 * Set's the 'non-existent' property of @user to #TRUE
1134 * Can only be called before the user is loaded.
1135 **/
1136 void
_act_user_update_as_nonexistent(ActUser * user)1137 _act_user_update_as_nonexistent (ActUser *user)
1138 {
1139 g_return_if_fail (ACT_IS_USER (user));
1140 g_return_if_fail (!act_user_is_loaded (user));
1141 g_return_if_fail (act_user_get_object_path (user) == NULL);
1142
1143 user->nonexistent = TRUE;
1144 g_object_notify (G_OBJECT (user), "nonexistent");
1145
1146 set_is_loaded (user, TRUE);
1147 }
1148
1149 static void
on_accounts_proxy_changed(ActUser * user)1150 on_accounts_proxy_changed (ActUser *user)
1151 {
1152 g_signal_emit (user, signals[CHANGED], 0);
1153 }
1154
1155 /**
1156 * _act_user_update_from_object_path:
1157 * @user: the user object to update.
1158 * @object_path: the object path of the user to use.
1159 *
1160 * Updates the properties of @user from the accounts service via
1161 * the object path in @object_path.
1162 **/
1163 void
_act_user_update_from_object_path(ActUser * user,const char * object_path)1164 _act_user_update_from_object_path (ActUser *user,
1165 const char *object_path)
1166 {
1167 AccountsUser *accounts_proxy;
1168 g_autoptr(GError) error = NULL;
1169
1170 g_return_if_fail (ACT_IS_USER (user));
1171 g_return_if_fail (object_path != NULL);
1172 g_return_if_fail (act_user_get_object_path (user) == NULL);
1173
1174 accounts_proxy = accounts_user_proxy_new_sync (user->connection,
1175 G_DBUS_PROXY_FLAGS_NONE,
1176 ACCOUNTS_NAME,
1177 object_path,
1178 NULL,
1179 &error);
1180 if (!accounts_proxy) {
1181 g_warning ("Couldn't create accounts proxy: %s", error->message);
1182 return;
1183 }
1184
1185 user->accounts_proxy = accounts_proxy;
1186
1187 g_signal_connect_object (user->accounts_proxy,
1188 "changed",
1189 G_CALLBACK (on_accounts_proxy_changed),
1190 user,
1191 G_CONNECT_SWAPPED);
1192
1193 g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (user->accounts_proxy), INT_MAX);
1194
1195 set_is_loaded (user, TRUE);
1196 }
1197
1198 void
_act_user_update_login_frequency(ActUser * user,int login_frequency)1199 _act_user_update_login_frequency (ActUser *user,
1200 int login_frequency)
1201 {
1202 if (act_user_get_login_frequency (user) == login_frequency) {
1203 return;
1204 }
1205
1206 accounts_user_set_login_frequency (user->accounts_proxy,
1207 login_frequency);
1208 }
1209
1210 static void
copy_sessions_lists(ActUser * user,ActUser * user_to_copy)1211 copy_sessions_lists (ActUser *user,
1212 ActUser *user_to_copy)
1213 {
1214 GList *node;
1215
1216 for (node = g_list_last (user_to_copy->our_sessions);
1217 node != NULL;
1218 node = node->prev) {
1219 user->our_sessions = g_list_prepend (user->our_sessions, g_strdup (node->data));
1220 }
1221
1222 for (node = g_list_last (user_to_copy->other_sessions);
1223 node != NULL;
1224 node = node->prev) {
1225 user->other_sessions = g_list_prepend (user->other_sessions, g_strdup (node->data));
1226 }
1227 }
1228
1229 void
_act_user_load_from_user(ActUser * user,ActUser * user_to_copy)1230 _act_user_load_from_user (ActUser *user,
1231 ActUser *user_to_copy)
1232 {
1233 if (!user_to_copy->is_loaded) {
1234 return;
1235 }
1236
1237 user->accounts_proxy = g_object_ref (user_to_copy->accounts_proxy);
1238
1239 g_signal_connect_object (user->accounts_proxy,
1240 "changed",
1241 G_CALLBACK (on_accounts_proxy_changed),
1242 user,
1243 G_CONNECT_SWAPPED);
1244
1245 if (user->our_sessions == NULL && user->other_sessions == NULL) {
1246 copy_sessions_lists (user, user_to_copy);
1247 g_signal_emit (user, signals[SESSIONS_CHANGED], 0);
1248 }
1249
1250 set_is_loaded (user, TRUE);
1251 }
1252
1253 /**
1254 * act_user_is_loaded:
1255 * @user: a #ActUser
1256 *
1257 * Determines whether or not the user object is loaded and ready to read from.
1258 * #ActUserManager:is-loaded property must be %TRUE before calling
1259 * act_user_manager_list_users()
1260 *
1261 * Returns: %TRUE or %FALSE
1262 */
1263 gboolean
act_user_is_loaded(ActUser * user)1264 act_user_is_loaded (ActUser *user)
1265 {
1266 return user->is_loaded;
1267 }
1268
1269 /**
1270 * act_user_get_password_expiration_policy:
1271 * @user: the user object to query.
1272 * @expiration_time: location to write time users password expires
1273 * @last_change_time: location to write time users password was last changed.
1274 * @min_days_between_changes: location to write minimum number of days needed between password changes.
1275 * @max_days_between_changes: location to write maximum number of days password can stay unchanged.
1276 * @days_to_warn: location to write number of days to warn user password is about to expire.
1277 * @days_after_expiration_until_lock: location to write number of days account will be locked after password expires.
1278 *
1279 * Get the password expiration policy for a user.
1280 *
1281 * Note this function is synchronous and ignores errors.
1282 **/
1283 void
act_user_get_password_expiration_policy(ActUser * user,gint64 * expiration_time,gint64 * last_change_time,gint64 * min_days_between_changes,gint64 * max_days_between_changes,gint64 * days_to_warn,gint64 * days_after_expiration_until_lock)1284 act_user_get_password_expiration_policy (ActUser *user,
1285 gint64 *expiration_time,
1286 gint64 *last_change_time,
1287 gint64 *min_days_between_changes,
1288 gint64 *max_days_between_changes,
1289 gint64 *days_to_warn,
1290 gint64 *days_after_expiration_until_lock)
1291 {
1292 g_autoptr(GError) error = NULL;
1293
1294 g_return_if_fail (ACT_IS_USER (user));
1295 g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
1296
1297 if (!accounts_user_call_get_password_expiration_policy_sync (user->accounts_proxy,
1298 expiration_time,
1299 last_change_time,
1300 min_days_between_changes,
1301 max_days_between_changes,
1302 days_to_warn,
1303 days_after_expiration_until_lock,
1304 NULL,
1305 &error)) {
1306 g_warning ("GetPasswordExpirationPolicy call failed: %s", error->message);
1307 return;
1308 }
1309 }
1310
1311 /**
1312 * act_user_set_email:
1313 * @user: the user object to alter.
1314 * @email: an email address
1315 *
1316 * Assigns a new email to @user.
1317 *
1318 * Note this function is synchronous and ignores errors.
1319 **/
1320 void
act_user_set_email(ActUser * user,const char * email)1321 act_user_set_email (ActUser *user,
1322 const char *email)
1323 {
1324 g_autoptr(GError) error = NULL;
1325
1326 g_return_if_fail (ACT_IS_USER (user));
1327 g_return_if_fail (email != NULL);
1328 g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
1329
1330 if (!accounts_user_call_set_email_sync (user->accounts_proxy,
1331 email,
1332 NULL,
1333 &error)) {
1334 g_warning ("SetEmail call failed: %s", error->message);
1335 return;
1336 }
1337 }
1338
1339 /**
1340 * act_user_set_language:
1341 * @user: the user object to alter.
1342 * @language: a locale (e.g. en_US.utf8)
1343 *
1344 * Assigns a new locale for @user.
1345 *
1346 * Note this function is synchronous and ignores errors.
1347 **/
1348 void
act_user_set_language(ActUser * user,const char * language)1349 act_user_set_language (ActUser *user,
1350 const char *language)
1351 {
1352 g_autoptr(GError) error = NULL;
1353
1354 g_return_if_fail (ACT_IS_USER (user));
1355 g_return_if_fail (language != NULL);
1356 g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
1357
1358 if (!accounts_user_call_set_language_sync (user->accounts_proxy,
1359 language,
1360 NULL,
1361 &error)) {
1362 g_warning ("SetLanguage for language %s failed: %s", language, error->message);
1363 return;
1364 }
1365 }
1366
1367 /**
1368 * act_user_set_x_session:
1369 * @user: the user object to alter.
1370 * @x_session: an x session (e.g. gnome)
1371 *
1372 * Assigns a new x session for @user.
1373 *
1374 * Note this function is synchronous and ignores errors.
1375 **/
1376 void
act_user_set_x_session(ActUser * user,const char * x_session)1377 act_user_set_x_session (ActUser *user,
1378 const char *x_session)
1379 {
1380 g_autoptr(GError) error = NULL;
1381
1382 g_return_if_fail (ACT_IS_USER (user));
1383 g_return_if_fail (x_session != NULL);
1384 g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
1385
1386 if (!accounts_user_call_set_xsession_sync (user->accounts_proxy,
1387 x_session,
1388 NULL,
1389 &error)) {
1390 g_warning ("SetXSession call failed: %s", error->message);
1391 return;
1392 }
1393 }
1394
1395 /**
1396 * act_user_set_session:
1397 * @user: the user object to alter.
1398 * @session: a session (e.g. gnome)
1399 *
1400 * Assigns a new session for @user.
1401 *
1402 * Note this function is synchronous and ignores errors.
1403 **/
1404 void
act_user_set_session(ActUser * user,const char * session)1405 act_user_set_session (ActUser *user,
1406 const char *session)
1407 {
1408 g_autoptr(GError) error = NULL;
1409
1410 g_return_if_fail (ACT_IS_USER (user));
1411 g_return_if_fail (session != NULL);
1412 g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
1413
1414 if (!accounts_user_call_set_session_sync (user->accounts_proxy,
1415 session,
1416 NULL,
1417 &error)) {
1418 g_warning ("SetSession call failed: %s", error->message);
1419 return;
1420 }
1421 }
1422
1423 /**
1424 * act_user_set_session_type:
1425 * @user: the user object to alter.
1426 * @session_type: a type of session (e.g. "wayland" or "x11")
1427 *
1428 * Assigns a type to the session for @user.
1429 *
1430 * Note this function is synchronous and ignores errors.
1431 **/
1432 void
act_user_set_session_type(ActUser * user,const char * session_type)1433 act_user_set_session_type (ActUser *user,
1434 const char *session_type)
1435 {
1436 g_autoptr(GError) error = NULL;
1437
1438 g_return_if_fail (ACT_IS_USER (user));
1439 g_return_if_fail (session_type != NULL);
1440 g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
1441
1442 if (!accounts_user_call_set_session_type_sync (user->accounts_proxy,
1443 session_type,
1444 NULL,
1445 &error)) {
1446 g_warning ("SetSessionType call failed: %s", error->message);
1447 return;
1448 }
1449 }
1450
1451 /**
1452 * act_user_set_location:
1453 * @user: the user object to alter.
1454 * @location: a location
1455 *
1456 * Assigns a new location for @user.
1457 *
1458 * Note this function is synchronous and ignores errors.
1459 **/
1460 void
act_user_set_location(ActUser * user,const char * location)1461 act_user_set_location (ActUser *user,
1462 const char *location)
1463 {
1464 g_autoptr(GError) error = NULL;
1465
1466 g_return_if_fail (ACT_IS_USER (user));
1467 g_return_if_fail (location != NULL);
1468 g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
1469
1470 if (!accounts_user_call_set_location_sync (user->accounts_proxy,
1471 location,
1472 NULL,
1473 &error)) {
1474 g_warning ("SetLocation call failed: %s", error->message);
1475 return;
1476 }
1477 }
1478
1479 /**
1480 * act_user_set_user_name:
1481 * @user: the user object to alter.
1482 * @user_name: a new user name
1483 *
1484 * Assigns a new username for @user.
1485 *
1486 * Note this function is synchronous and ignores errors.
1487 **/
1488 void
act_user_set_user_name(ActUser * user,const char * user_name)1489 act_user_set_user_name (ActUser *user,
1490 const char *user_name)
1491 {
1492 g_autoptr(GError) error = NULL;
1493
1494 g_return_if_fail (ACT_IS_USER (user));
1495 g_return_if_fail (user_name != NULL);
1496 g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
1497
1498 if (!accounts_user_call_set_user_name_sync (user->accounts_proxy,
1499 user_name,
1500 NULL,
1501 &error)) {
1502 g_warning ("SetUserName call failed: %s", error->message);
1503 return;
1504 }
1505 }
1506
1507 /**
1508 * act_user_set_real_name:
1509 * @user: the user object to alter.
1510 * @real_name: a new name
1511 *
1512 * Assigns a new name for @user.
1513 *
1514 * Note this function is synchronous and ignores errors.
1515 **/
1516 void
act_user_set_real_name(ActUser * user,const char * real_name)1517 act_user_set_real_name (ActUser *user,
1518 const char *real_name)
1519 {
1520 g_autoptr(GError) error = NULL;
1521
1522 g_return_if_fail (ACT_IS_USER (user));
1523 g_return_if_fail (real_name != NULL);
1524 g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
1525
1526 if (!accounts_user_call_set_real_name_sync (user->accounts_proxy,
1527 real_name,
1528 NULL,
1529 &error)) {
1530 g_warning ("SetRealName call failed: %s", error->message);
1531 return;
1532 }
1533 }
1534
1535 /**
1536 * act_user_set_icon_file:
1537 * @user: the user object to alter.
1538 * @icon_file: path to an icon
1539 *
1540 * Assigns a new icon for @user.
1541 *
1542 * Note this function is synchronous and ignores errors.
1543 **/
1544 void
act_user_set_icon_file(ActUser * user,const char * icon_file)1545 act_user_set_icon_file (ActUser *user,
1546 const char *icon_file)
1547 {
1548 g_autoptr(GError) error = NULL;
1549
1550 g_return_if_fail (ACT_IS_USER (user));
1551 g_return_if_fail (icon_file != NULL);
1552 g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
1553
1554 if (!accounts_user_call_set_icon_file_sync (user->accounts_proxy,
1555 icon_file,
1556 NULL,
1557 &error)) {
1558 g_warning ("SetIconFile call failed: %s", error->message);
1559 return;
1560 }
1561 }
1562
1563 /**
1564 * act_user_set_account_type:
1565 * @user: the user object to alter.
1566 * @account_type: a #ActUserAccountType
1567 *
1568 * Changes the account type of @user.
1569 *
1570 * Note this function is synchronous and ignores errors.
1571 **/
1572 void
act_user_set_account_type(ActUser * user,ActUserAccountType account_type)1573 act_user_set_account_type (ActUser *user,
1574 ActUserAccountType account_type)
1575 {
1576 g_autoptr(GError) error = NULL;
1577
1578 g_return_if_fail (ACT_IS_USER (user));
1579 g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
1580
1581 if (!accounts_user_call_set_account_type_sync (user->accounts_proxy,
1582 account_type,
1583 NULL,
1584 &error)) {
1585 g_warning ("SetAccountType call failed: %s", error->message);
1586 return;
1587 }
1588 }
1589
1590 static gchar
salt_char(GRand * rand)1591 salt_char (GRand *rand)
1592 {
1593 gchar salt[] = "ABCDEFGHIJKLMNOPQRSTUVXYZ"
1594 "abcdefghijklmnopqrstuvxyz"
1595 "./0123456789";
1596
1597 return salt[g_rand_int_range (rand, 0, G_N_ELEMENTS (salt))];
1598 }
1599
1600 static gchar *
make_crypted(const gchar * plain)1601 make_crypted (const gchar *plain)
1602 {
1603 g_autoptr(GString) salt = NULL;
1604 g_autoptr(GRand) rand = NULL;
1605 gint i;
1606
1607 rand = g_rand_new ();
1608 salt = g_string_sized_new (21);
1609
1610 /* SHA 256 */
1611 g_string_append (salt, "$6$");
1612 for (i = 0; i < 16; i++) {
1613 g_string_append_c (salt, salt_char (rand));
1614 }
1615 g_string_append_c (salt, '$');
1616
1617 return g_strdup (crypt (plain, salt->str));
1618 }
1619
1620 /**
1621 * act_user_set_password:
1622 * @user: the user object to alter.
1623 * @password: a password
1624 * @hint: a hint to help user recall password
1625 *
1626 * Changes the password of @user to @password.
1627 * @hint is displayed to the user if they forget the password.
1628 *
1629 * Note this function is synchronous and ignores errors.
1630 **/
1631 void
act_user_set_password(ActUser * user,const gchar * password,const gchar * hint)1632 act_user_set_password (ActUser *user,
1633 const gchar *password,
1634 const gchar *hint)
1635 {
1636 g_autoptr(GError) error = NULL;
1637 g_autofree gchar *crypted = NULL;
1638
1639 g_return_if_fail (ACT_IS_USER (user));
1640 g_return_if_fail (password != NULL);
1641 g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
1642
1643 crypted = make_crypted (password);
1644 if (!accounts_user_call_set_password_sync (user->accounts_proxy,
1645 crypted,
1646 hint,
1647 NULL,
1648 &error)) {
1649 g_warning ("SetPassword call failed: %s", error->message);
1650 }
1651 memset (crypted, 0, strlen (crypted));
1652 }
1653
1654 /**
1655 * act_uset_set_password_hint:
1656 * @user: the user object to alter.
1657 * @hint: a hint to help user recall password
1658 *
1659 * Sets the password hint of @user.
1660 * @hint is displayed to the user if they forget the password.
1661 *
1662 * Note this function is synchronous and ignores errors.
1663 **/
1664 void
act_user_set_password_hint(ActUser * user,const gchar * hint)1665 act_user_set_password_hint (ActUser *user,
1666 const gchar *hint)
1667 {
1668 g_autoptr(GError) error = NULL;
1669
1670 g_return_if_fail (ACT_IS_USER (user));
1671 g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
1672
1673 if (!accounts_user_call_set_password_hint_sync (user->accounts_proxy,
1674 hint,
1675 NULL,
1676 &error)) {
1677 g_warning ("SetPasswordHint call failed: %s", error->message);
1678 }
1679 }
1680
1681 /**
1682 * act_user_set_password_mode:
1683 * @user: the user object to alter.
1684 * @password_mode: a #ActUserPasswordMode
1685 *
1686 * Changes the password of @user. If @password_mode is
1687 * ACT_USER_PASSWORD_MODE_SET_AT_LOGIN then the user will
1688 * be asked for a new password at the next login. If @password_mode
1689 * is ACT_USER_PASSWORD_MODE_NONE then the user will not require
1690 * a password to log in.
1691 *
1692 * Note this function is synchronous and ignores errors.
1693 **/
1694 void
act_user_set_password_mode(ActUser * user,ActUserPasswordMode password_mode)1695 act_user_set_password_mode (ActUser *user,
1696 ActUserPasswordMode password_mode)
1697 {
1698 g_autoptr(GError) error = NULL;
1699
1700 g_return_if_fail (ACT_IS_USER (user));
1701 g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
1702
1703 if (!accounts_user_call_set_password_mode_sync (user->accounts_proxy,
1704 (gint) password_mode,
1705 NULL,
1706 &error)) {
1707 g_warning ("SetPasswordMode call failed: %s", error->message);
1708 }
1709 }
1710
1711 /**
1712 * act_user_set_locked:
1713 * @user: the user object to alter.
1714 * @locked: whether or not the account is locked
1715 *
1716 * Note this function is synchronous and ignores errors.
1717 **/
1718 void
act_user_set_locked(ActUser * user,gboolean locked)1719 act_user_set_locked (ActUser *user,
1720 gboolean locked)
1721 {
1722 g_autoptr(GError) error = NULL;
1723
1724 g_return_if_fail (ACT_IS_USER (user));
1725 g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
1726
1727 if (!accounts_user_call_set_locked_sync (user->accounts_proxy,
1728 locked,
1729 NULL,
1730 &error)) {
1731 g_warning ("SetLocked call failed: %s", error->message);
1732 }
1733 }
1734
1735 /**
1736 * act_user_set_automatic_login:
1737 * @user: the user object to alter
1738 * @enabled: whether or not to autologin for user.
1739 *
1740 * If enabled is set to %TRUE then this user will automatically be logged in
1741 * at boot up time. Only one user can be configured to auto login at any given
1742 * time, so subsequent calls to act_user_set_automatic_login() override previous
1743 * calls.
1744 *
1745 * Note this function is synchronous and ignores errors.
1746 **/
1747 void
act_user_set_automatic_login(ActUser * user,gboolean enabled)1748 act_user_set_automatic_login (ActUser *user,
1749 gboolean enabled)
1750 {
1751 g_autoptr(GError) error = NULL;
1752
1753 g_return_if_fail (ACT_IS_USER (user));
1754 g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
1755
1756 if (!accounts_user_call_set_automatic_login_sync (user->accounts_proxy,
1757 enabled,
1758 NULL,
1759 &error)) {
1760 g_warning ("SetAutomaticLogin call failed: %s", error->message);
1761 }
1762 }
1763