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

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