summaryrefslogtreecommitdiff
path: root/src/pam_plugin/pam-key-manager-plugin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/pam_plugin/pam-key-manager-plugin.cpp')
-rw-r--r--src/pam_plugin/pam-key-manager-plugin.cpp248
1 files changed, 136 insertions, 112 deletions
diff --git a/src/pam_plugin/pam-key-manager-plugin.cpp b/src/pam_plugin/pam-key-manager-plugin.cpp
index 792e6aec..74a1d252 100644
--- a/src/pam_plugin/pam-key-manager-plugin.cpp
+++ b/src/pam_plugin/pam-key-manager-plugin.cpp
@@ -40,133 +40,157 @@ namespace {
#define PASSWORD_SHADOWED "x"
std::string old_password;
-bool identify_user_pwd(pam_handle_t *pamh, uid_t & uid, std::string & passwd)
+bool identify_user_pwd(pam_handle_t *pamh, uid_t &uid, std::string &passwd)
{
- int pam_err;
- const char *user;
- if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS)
- return true;
- struct passwd *pwd;
- if ((pwd = getpwnam(user)) == NULL)
- return true;
- if (strcmp(pwd->pw_passwd, PASSWORD_SHADOWED) == 0) {
- struct spwd *pwd_sh;
- if ((pwd_sh = getspnam(user)) == NULL)
- return true;
- passwd = std::string(pwd_sh->sp_pwdp);
- } else {
- passwd = std::string(pwd->pw_passwd);
- }
- uid = pwd->pw_uid;
- return false;
+ int pam_err;
+ const char *user;
+
+ if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS)
+ return true;
+
+ struct passwd *pwd;
+
+ if ((pwd = getpwnam(user)) == NULL)
+ return true;
+
+ if (strcmp(pwd->pw_passwd, PASSWORD_SHADOWED) == 0) {
+ struct spwd *pwd_sh;
+
+ if ((pwd_sh = getspnam(user)) == NULL)
+ return true;
+
+ passwd = std::string(pwd_sh->sp_pwdp);
+ } else {
+ passwd = std::string(pwd->pw_passwd);
+ }
+
+ uid = pwd->pw_uid;
+ return false;
}
}
COMMON_API PAM_EXTERN int
-pam_sm_open_session(pam_handle_t *pamh, int /*flags*/, int /*argc*/, const char **/*argv*/)
+pam_sm_open_session(pam_handle_t *pamh, int /*flags*/, int /*argc*/,
+ const char **/*argv*/)
{
- // identify user
- uid_t uid = -1;
- std::string passwd;
- if (identify_user_pwd(pamh, uid, passwd))
- return PAM_SESSION_ERR;
-
- auto control = CKM::Control::create();
- int ec = control->unlockUserKey(uid, passwd.c_str());
- if (ec == CKM_API_SUCCESS)
- return PAM_SUCCESS;
-
- if (ec == CKM_API_ERROR_AUTHENTICATION_FAILED) {
- pam_syslog(pamh, LOG_ERR, "key-manager and system password desynchronized,"
- "removing key-manager database for user: %d\n", uid);
-
- // key-manager<->system password desync
- // remove the user content
- ec = control->removeUserData(uid);
- if (ec == CKM_API_SUCCESS) {
- ec = CKM::Control::create()->unlockUserKey(uid, passwd.c_str());
- if (ec == CKM_API_SUCCESS)
- return PAM_SUCCESS;
- pam_syslog(pamh, LOG_ERR, "key-manager and system password desynchronized,"
- "attempt to create new database failed: %d\n", ec);
- } else {
- pam_syslog(pamh, LOG_ERR, "key-manager and system password desynchronized and"
- "recovery attempt to remove broken database failed: %d\n", ec);
- }
- }
-
- return PAM_SESSION_ERR;
+ // identify user
+ uid_t uid = -1;
+ std::string passwd;
+
+ if (identify_user_pwd(pamh, uid, passwd))
+ return PAM_SESSION_ERR;
+
+ auto control = CKM::Control::create();
+ int ec = control->unlockUserKey(uid, passwd.c_str());
+
+ if (ec == CKM_API_SUCCESS)
+ return PAM_SUCCESS;
+
+ if (ec == CKM_API_ERROR_AUTHENTICATION_FAILED) {
+ pam_syslog(pamh, LOG_ERR, "key-manager and system password desynchronized,"
+ "removing key-manager database for user: %d\n", uid);
+
+ // key-manager<->system password desync
+ // remove the user content
+ ec = control->removeUserData(uid);
+
+ if (ec == CKM_API_SUCCESS) {
+ ec = CKM::Control::create()->unlockUserKey(uid, passwd.c_str());
+
+ if (ec == CKM_API_SUCCESS)
+ return PAM_SUCCESS;
+
+ pam_syslog(pamh, LOG_ERR, "key-manager and system password desynchronized,"
+ "attempt to create new database failed: %d\n", ec);
+ } else {
+ pam_syslog(pamh, LOG_ERR, "key-manager and system password desynchronized and"
+ "recovery attempt to remove broken database failed: %d\n", ec);
+ }
+ }
+
+ return PAM_SESSION_ERR;
}
COMMON_API PAM_EXTERN int
-pam_sm_close_session(pam_handle_t *pamh, int /*flags*/, int /*argc*/, const char **/*argv*/)
+pam_sm_close_session(pam_handle_t *pamh, int /*flags*/, int /*argc*/,
+ const char **/*argv*/)
{
- // identify user
- uid_t uid = -1;
- std::string passwd;
- if (identify_user_pwd(pamh, uid, passwd))
- return PAM_SESSION_ERR;
+ // identify user
+ uid_t uid = -1;
+ std::string passwd;
+
+ if (identify_user_pwd(pamh, uid, passwd))
+ return PAM_SESSION_ERR;
- if (CKM::Control::create()->lockUserKey(uid) == CKM_API_SUCCESS)
- return PAM_SUCCESS;
+ if (CKM::Control::create()->lockUserKey(uid) == CKM_API_SUCCESS)
+ return PAM_SUCCESS;
- return PAM_SESSION_ERR;
+ return PAM_SESSION_ERR;
}
COMMON_API PAM_EXTERN int
pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
- if (argc == 0) {
- pam_syslog(pamh, LOG_ERR, "key-manager plugin called with inappropriate arguments\n");
- return PAM_SERVICE_ERR;
- }
-
- // identify user
- uid_t uid = -1;
- std::string passwd;
- if (identify_user_pwd(pamh, uid, passwd))
- return PAM_USER_UNKNOWN;
-
- // attention: argv[0] is the argument, not the binary/so name
- // args are in arg_name=value format
- if (strstr(argv[0], "change_step")) {
- if (strstr(argv[0], "before")) {
- if (!(flags & PAM_PRELIM_CHECK))
- old_password = passwd;
- return PAM_SUCCESS;
- } else if (strstr(argv[0], "after")) {
- if (flags & PAM_PRELIM_CHECK)
- return PAM_SUCCESS;
-
- if (old_password.size() == 0) {
- pam_syslog(pamh, LOG_ERR, "attempt to change key-manager password w/o old password\n");
- return PAM_SERVICE_ERR;
- }
- std::string local_old_pwd = old_password;
- old_password.clear();
-
- // CKM does not allow to change user password if database does
- // not exists. We must create database before change password.
- auto ctrl = CKM::Control::create();
- int ec = ctrl->unlockUserKey(uid, local_old_pwd.c_str());
- if (CKM_API_SUCCESS != ec) {
- // no DB reset here: somebody else might have changed password in mean time
- // if desync happened, next login attempt will remove the DB
- pam_syslog(pamh, LOG_ERR, "attempt to change key-manager password failed:"
- "can not open/create the database, ec: %d\n", ec);
- return PAM_SERVICE_ERR;
- }
-
- ec = ctrl->changeUserPassword(uid, local_old_pwd.c_str(), passwd.c_str());
- if (CKM_API_SUCCESS != ec) {
- pam_syslog(pamh, LOG_ERR, "attempt to change key-manager password ec: %d\n", ec);
- return PAM_SERVICE_ERR;
- }
-
- return PAM_SUCCESS;
- }
- }
-
- pam_syslog(pamh, LOG_ERR, "key-manager plugin called with no valid \"change_step\" option setting\n");
- return PAM_SERVICE_ERR;
+ if (argc == 0) {
+ pam_syslog(pamh, LOG_ERR,
+ "key-manager plugin called with inappropriate arguments\n");
+ return PAM_SERVICE_ERR;
+ }
+
+ // identify user
+ uid_t uid = -1;
+ std::string passwd;
+
+ if (identify_user_pwd(pamh, uid, passwd))
+ return PAM_USER_UNKNOWN;
+
+ // attention: argv[0] is the argument, not the binary/so name
+ // args are in arg_name=value format
+ if (strstr(argv[0], "change_step")) {
+ if (strstr(argv[0], "before")) {
+ if (!(flags & PAM_PRELIM_CHECK))
+ old_password = passwd;
+
+ return PAM_SUCCESS;
+ } else if (strstr(argv[0], "after")) {
+ if (flags & PAM_PRELIM_CHECK)
+ return PAM_SUCCESS;
+
+ if (old_password.size() == 0) {
+ pam_syslog(pamh, LOG_ERR,
+ "attempt to change key-manager password w/o old password\n");
+ return PAM_SERVICE_ERR;
+ }
+
+ std::string local_old_pwd = old_password;
+ old_password.clear();
+
+ // CKM does not allow to change user password if database does
+ // not exists. We must create database before change password.
+ auto ctrl = CKM::Control::create();
+ int ec = ctrl->unlockUserKey(uid, local_old_pwd.c_str());
+
+ if (CKM_API_SUCCESS != ec) {
+ // no DB reset here: somebody else might have changed password in mean time
+ // if desync happened, next login attempt will remove the DB
+ pam_syslog(pamh, LOG_ERR, "attempt to change key-manager password failed:"
+ "can not open/create the database, ec: %d\n", ec);
+ return PAM_SERVICE_ERR;
+ }
+
+ ec = ctrl->changeUserPassword(uid, local_old_pwd.c_str(), passwd.c_str());
+
+ if (CKM_API_SUCCESS != ec) {
+ pam_syslog(pamh, LOG_ERR, "attempt to change key-manager password ec: %d\n",
+ ec);
+ return PAM_SERVICE_ERR;
+ }
+
+ return PAM_SUCCESS;
+ }
+ }
+
+ pam_syslog(pamh, LOG_ERR,
+ "key-manager plugin called with no valid \"change_step\" option setting\n");
+ return PAM_SERVICE_ERR;
}