~tatokis/unity/gcc-72-errors

« back to all changes in this revision

Viewing changes to lockscreen/UserAuthenticatorPam.cpp

  • Committer: Bileto Bot
  • Author(s): Andrea Azzarone
  • Date: 2017-09-25 16:03:52 UTC
  • mfrom: (4253.3.3 fix-missing-entry-lockscreen)
  • Revision ID: ci-train-bot@canonical.com-20170925160352-kqd3v7i3wdwhixjn
Refactor the way UserAuthenticator is created and passed around. Handle failures to create new threads and fallback to a "Switch to greeter..." button in case of failure. (LP: #1311316)

Approved by: Marco Trevisan (Treviño)

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
#include "UserAuthenticatorPam.h"
25
25
#include "unity-shared/UnitySettings.h"
 
26
#include "UnityCore/GLibWrapper.h"
26
27
 
27
28
#include <cstring>
28
29
#include <security/pam_appl.h>
36
37
bool UserAuthenticatorPam::AuthenticateStart(std::string const& username,
37
38
                                             AuthenticateEndCallback const& authenticate_cb)
38
39
{
 
40
  if (pam_handle_)
 
41
    return false;
 
42
 
39
43
  first_prompt_ = true;
40
44
  username_ = username;
41
45
  authenticate_cb_ = authenticate_cb;
42
 
  pam_handle_ = nullptr;
43
 
 
44
 
  if (!InitPam() || !pam_handle_)
45
 
    return false;
46
 
 
47
 
  glib::Object<GTask> task(g_task_new(nullptr, cancellable_, [] (GObject*, GAsyncResult*, gpointer data) {
48
 
    auto self = static_cast<UserAuthenticatorPam*>(data);
49
 
    pam_end(self->pam_handle_, self->status_);
50
 
    self->authenticate_cb_(self->status_ == PAM_SUCCESS);
51
 
  }, this));
52
 
 
53
 
  g_task_set_task_data(task, this, nullptr);
54
 
 
55
 
  g_task_run_in_thread(task, [] (GTask* task, gpointer, gpointer data, GCancellable*) {
56
 
    auto self = static_cast<UserAuthenticatorPam*>(data);
57
 
 
58
 
    self->status_ = pam_authenticate(self->pam_handle_, 0);
59
 
 
60
 
    if (self->status_ == PAM_SUCCESS)
61
 
    {
62
 
      int status2 = pam_acct_mgmt(self->pam_handle_, 0);
63
 
 
64
 
      if (status2 == PAM_NEW_AUTHTOK_REQD)
65
 
        status2 = pam_chauthtok(self->pam_handle_, PAM_CHANGE_EXPIRED_AUTHTOK);
66
 
 
67
 
      if (unity::Settings::Instance().pam_check_account_type())
68
 
        self->status_ = status2;
69
 
 
70
 
      pam_setcred(self->pam_handle_, PAM_REINITIALIZE_CRED);
71
 
    }
72
 
  });
73
 
 
74
 
  return true;
 
46
 
 
47
  glib::Error error;
 
48
  g_thread_try_new(nullptr, AuthenticationThreadFunc, this, &error);
 
49
 
 
50
  return !error;
 
51
}
 
52
 
 
53
gpointer UserAuthenticatorPam::AuthenticationThreadFunc(gpointer data)
 
54
{
 
55
  auto self = static_cast<UserAuthenticatorPam*>(data);
 
56
 
 
57
  if (!self->InitPam() || !self->pam_handle_)
 
58
  {
 
59
    self->pam_handle_ = nullptr;
 
60
    self->source_manager_.AddTimeout(0, [self] { self->start_failed.emit(); return false; });
 
61
    return nullptr;
 
62
  }
 
63
 
 
64
  self->status_ = pam_authenticate(self->pam_handle_, 0);
 
65
 
 
66
  if (self->status_ == PAM_SUCCESS)
 
67
  {
 
68
    int status2 = pam_acct_mgmt(self->pam_handle_, 0);
 
69
 
 
70
    if (status2 == PAM_NEW_AUTHTOK_REQD)
 
71
      status2 = pam_chauthtok(self->pam_handle_, PAM_CHANGE_EXPIRED_AUTHTOK);
 
72
 
 
73
    if (unity::Settings::Instance().pam_check_account_type())
 
74
      self->status_ = status2;
 
75
 
 
76
    pam_setcred(self->pam_handle_, PAM_REINITIALIZE_CRED);
 
77
  }
 
78
 
 
79
  pam_end(self->pam_handle_, self->status_);
 
80
  self->pam_handle_ = nullptr;
 
81
  self->source_manager_.AddTimeout(0, [self] {   self->authenticate_cb_(self->status_ == PAM_SUCCESS); return false; });
 
82
  return nullptr;
75
83
}
76
84
 
77
85
bool UserAuthenticatorPam::InitPam()