Blame SOURCES/0016-daemon-don-t-return-account-expiration-policy-if-not.patch

6f965c
From 7facd87e8ba34654fc9c46b4a42943e92acafffb Mon Sep 17 00:00:00 2001
6f965c
From: Ray Strode <rstrode@redhat.com>
6f965c
Date: Wed, 7 Feb 2018 11:03:21 -0500
6f965c
Subject: [PATCH 16/16] daemon: don't return account expiration policy if not
6f965c
 known
6f965c
6f965c
Right now we assume the user's shadow entry will always be available.
6f965c
If it's not available, we return fields from it initialized to 0.
6f965c
6f965c
That leads to spurious password expired notifications in GNOME.
6f965c
6f965c
This commit throws a NOT_SUPPORTED error if the shadow file is off
6f965c
limits.
6f965c
---
6f965c
 src/user.c | 7 +++++++
6f965c
 1 file changed, 7 insertions(+)
6f965c
6f965c
diff --git a/src/user.c b/src/user.c
6f965c
index a83cfe4..cf7eb26 100644
6f965c
--- a/src/user.c
6f965c
+++ b/src/user.c
6f965c
@@ -79,60 +79,61 @@ struct User {
6f965c
         gchar *object_path;
6f965c
 
6f965c
         Daemon       *daemon;
6f965c
 
6f965c
         GKeyFile     *keyfile;
6f965c
 
6f965c
         uid_t         uid;
6f965c
         gid_t         gid;
6f965c
         gchar        *user_name;
6f965c
         gchar        *real_name;
6f965c
         AccountType   account_type;
6f965c
         PasswordMode  password_mode;
6f965c
         gchar        *password_hint;
6f965c
         gchar        *home_dir;
6f965c
         gchar        *shell;
6f965c
         gchar        *email;
6f965c
         gchar        *language;
6f965c
         gchar        *x_session;
6f965c
         gchar        *location;
6f965c
         guint64       login_frequency;
6f965c
         gint64        login_time;
6f965c
         gint64        expiration_time;
6f965c
         gint64        last_change_time;
6f965c
         gint64        min_days_between_changes;
6f965c
         gint64        max_days_between_changes;
6f965c
         gint64        days_to_warn;
6f965c
         gint64        days_after_expiration_until_lock;
6f965c
         GVariant     *login_history;
6f965c
         gchar        *icon_file;
6f965c
         gchar        *default_icon_file;
6f965c
+        gboolean      account_expiration_policy_known;
6f965c
         gboolean      locked;
6f965c
         gboolean      automatic_login;
6f965c
         gboolean      system_account;
6f965c
         gboolean      local_account;
6f965c
         gboolean      cached;
6f965c
 
6f965c
         guint        *extension_ids;
6f965c
         guint         n_extension_ids;
6f965c
 };
6f965c
 
6f965c
 typedef struct UserClass
6f965c
 {
6f965c
         AccountsUserSkeletonClass parent_class;
6f965c
 } UserClass;
6f965c
 
6f965c
 static void user_accounts_user_iface_init (AccountsUserIface *iface);
6f965c
 
6f965c
 G_DEFINE_TYPE_WITH_CODE (User, user, ACCOUNTS_TYPE_USER_SKELETON, G_IMPLEMENT_INTERFACE (ACCOUNTS_TYPE_USER, user_accounts_user_iface_init));
6f965c
 
6f965c
 static gint
6f965c
 account_type_from_pwent (struct passwd *pwent)
6f965c
 {
6f965c
         struct group *grp;
6f965c
         gint i;
6f965c
 
6f965c
         if (pwent->pw_uid == 0) {
6f965c
                 g_debug ("user is root so account type is administrator");
6f965c
                 return ACCOUNT_TYPE_ADMINISTRATOR;
6f965c
         }
6f965c
 
6f965c
@@ -261,60 +262,61 @@ user_update_from_pwent (User          *user,
6f965c
                 locked = TRUE;
6f965c
         }
6f965c
         else {
6f965c
                 locked = FALSE;
6f965c
         }
6f965c
 
6f965c
         if (user->locked != locked) {
6f965c
                 user->locked = locked;
6f965c
                 changed = TRUE;
6f965c
                 g_object_notify (G_OBJECT (user), "locked");
6f965c
         }
6f965c
 
6f965c
         if (passwd == NULL || passwd[0] != 0) {
6f965c
                 mode = PASSWORD_MODE_REGULAR;
6f965c
         }
6f965c
         else {
6f965c
                 mode = PASSWORD_MODE_NONE;
6f965c
         }
6f965c
 
6f965c
         if (spent) {
6f965c
                 if (spent->sp_lstchg == 0) {
6f965c
                         mode = PASSWORD_MODE_SET_AT_LOGIN;
6f965c
                 }
6f965c
 
6f965c
                 user->expiration_time = spent->sp_expire;
6f965c
                 user->last_change_time  = spent->sp_lstchg;
6f965c
                 user->min_days_between_changes = spent->sp_min;
6f965c
                 user->max_days_between_changes = spent->sp_max;
6f965c
                 user->days_to_warn  = spent->sp_warn;
6f965c
                 user->days_after_expiration_until_lock = spent->sp_inact;
6f965c
+                user->account_expiration_policy_known = TRUE;
6f965c
         }
6f965c
 
6f965c
         if (user->password_mode != mode) {
6f965c
                 user->password_mode = mode;
6f965c
                 changed = TRUE;
6f965c
                 g_object_notify (G_OBJECT (user), "password-mode");
6f965c
         }
6f965c
 
6f965c
         user->system_account = !user_classify_is_human (user->uid, user->user_name, pwent->pw_shell, passwd);
6f965c
 
6f965c
         g_object_thaw_notify (G_OBJECT (user));
6f965c
 
6f965c
         if (changed)
6f965c
                 accounts_user_emit_changed (ACCOUNTS_USER (user));
6f965c
 }
6f965c
 
6f965c
 void
6f965c
 user_update_from_keyfile (User     *user,
6f965c
                           GKeyFile *keyfile)
6f965c
 {
6f965c
         gchar *s;
6f965c
 
6f965c
         g_object_freeze_notify (G_OBJECT (user));
6f965c
 
6f965c
         s = g_key_file_get_string (keyfile, "User", "Language", NULL);
6f965c
         if (s != NULL) {
6f965c
                 /* TODO: validate / normalize */
6f965c
                 g_free (user->language);
6f965c
                 user->language = s;
6f965c
                 g_object_notify (G_OBJECT (user), "language");
6f965c
@@ -1154,60 +1156,65 @@ user_set_x_session (AccountsUser          *auser,
6f965c
 
6f965c
         if (!get_caller_uid (context, &uid)) {
6f965c
                 throw_error (context, ERROR_FAILED, "identifying caller failed");
6f965c
                 return FALSE;
6f965c
         }
6f965c
 
6f965c
         if (user->uid == (uid_t) uid)
6f965c
                 action_id = "org.freedesktop.accounts.change-own-user-data";
6f965c
         else
6f965c
                 action_id = "org.freedesktop.accounts.user-administration";
6f965c
 
6f965c
         daemon_local_check_auth (user->daemon,
6f965c
                                  user,
6f965c
                                  action_id,
6f965c
                                  TRUE,
6f965c
                                  user_change_x_session_authorized_cb,
6f965c
                                  context,
6f965c
                                  g_strdup (x_session),
6f965c
                                  (GDestroyNotify) g_free);
6f965c
 
6f965c
         return TRUE;
6f965c
 }
6f965c
 
6f965c
 static void
6f965c
 user_get_password_expiration_policy_authorized_cb (Daemon                *daemon,
6f965c
                                                    User                  *user,
6f965c
                                                    GDBusMethodInvocation *context,
6f965c
                                                    gpointer               data)
6f965c
 
6f965c
 {
6f965c
+        if (!user->account_expiration_policy_known) {
6f965c
+                throw_error (context, ERROR_NOT_SUPPORTED, "account expiration policy unknown to accounts service");
6f965c
+                return;
6f965c
+        }
6f965c
+
6f965c
         accounts_user_complete_get_password_expiration_policy (ACCOUNTS_USER (user),
6f965c
                                                                context,
6f965c
                                                                user->expiration_time,
6f965c
                                                                user->last_change_time,
6f965c
                                                                user->min_days_between_changes,
6f965c
                                                                user->max_days_between_changes,
6f965c
                                                                user->days_to_warn,
6f965c
                                                                user->days_after_expiration_until_lock);
6f965c
 }
6f965c
 
6f965c
 static gboolean
6f965c
 user_get_password_expiration_policy (AccountsUser          *auser,
6f965c
                                      GDBusMethodInvocation *context)
6f965c
 {
6f965c
         User *user = (User*)auser;
6f965c
         int uid;
6f965c
         const gchar *action_id;
6f965c
 
6f965c
         if (!get_caller_uid (context, &uid)) {
6f965c
                 throw_error (context, ERROR_FAILED, "identifying caller failed");
6f965c
                 return FALSE;
6f965c
         }
6f965c
 
6f965c
         if (user->uid == (uid_t) uid)
6f965c
                 action_id = "org.freedesktop.accounts.change-own-user-data";
6f965c
         else
6f965c
                 action_id = "org.freedesktop.accounts.user-administration";
6f965c
 
6f965c
         daemon_local_check_auth (user->daemon,
6f965c
                                  user,
6f965c
-- 
6f965c
2.14.3
6f965c