summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2016-05-26 13:20:59 +0200
committerSumit Bose <sbose@redhat.com>2016-05-26 13:20:59 +0200
commit6ced3a031b2c8d59fbd1572e3c8b068f24a6dae5 (patch)
tree102719ca7ac847eb4ef5d1bbdebf6f858f20750c
parent149174acae677d1e72a0da431bf0850d55f2ccb4 (diff)
downloadsssd-prompting.tar.gz
sssd-prompting.tar.xz
sssd-prompting.zip
WIP auth ind promptingprompting
-rw-r--r--src/providers/krb5/krb5_child.c58
-rw-r--r--src/sss_client/pam_message.h2
-rw-r--r--src/sss_client/pam_sss.c15
-rw-r--r--src/sss_client/sss_cli.h5
4 files changed, 75 insertions, 5 deletions
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index fff6a0a0c..123907237 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -54,6 +54,7 @@ struct krb5_req {
char* name;
krb5_creds *creds;
bool otp;
+ bool password_prompting;
char *otp_vendor;
char *otp_token_id;
char *otp_challenge;
@@ -586,11 +587,49 @@ static krb5_error_code sss_krb5_responder(krb5_context ctx,
krb5_responder_context rctx)
{
struct krb5_req *kr = talloc_get_type(data, struct krb5_req);
+ const char * const *question_list;
+ size_t c;
+ const char *pwd;
+ int ret;
+ krb5_error_code kerr;
if (kr == NULL) {
return EINVAL;
}
+ question_list = krb5_responder_list_questions(ctx, rctx);
+
+ if (question_list != NULL) {
+ for (c = 0; question_list[c] != NULL; c++) {
+ DEBUG(SSSDBG_TRACE_ALL, "Got question [%s].\n", question_list[c]);
+
+ if (strcmp(question_list[c],
+ KRB5_RESPONDER_QUESTION_PASSWORD) == 0) {
+ kr->password_prompting = true;
+ }
+
+ if (kr->pd->cmd == SSS_PAM_AUTHENTICATE
+ && sss_authtok_get_type(kr->pd->authtok)
+ == SSS_AUTHTOK_TYPE_PASSWORD) {
+ ret = sss_authtok_get_password(kr->pd->authtok, &pwd, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sss_authtok_get_password failed.\n");
+ return ret;
+ }
+
+ kerr = krb5_responder_set_answer(ctx, rctx,
+ KRB5_RESPONDER_QUESTION_PASSWORD,
+ pwd);
+ if (kerr != 0) {
+ DEBUG(SSSDBG_OP_FAILURE, "krb5_responder_set_answer failed.\n");
+ }
+
+ return kerr;
+ }
+ }
+ }
+
return answer_otp(ctx, kr, rctx);
}
#endif
@@ -602,6 +641,11 @@ static krb5_error_code sss_krb5_prompter(krb5_context context, void *data,
int ret;
struct krb5_req *kr = talloc_get_type(data, struct krb5_req);
+ DEBUG(SSSDBG_TRACE_ALL,
+ "sss_krb5_prompter name [%s] banner [%s] num_prompts [%d] EINVAL.\n",
+ name, banner, num_prompts);
+ return EINVAL;
+
if (num_prompts != 0) {
DEBUG(SSSDBG_CRIT_FAILURE, "Cannot handle password prompts.\n");
return KRB5_LIBOS_CANTREADPWD;
@@ -1217,7 +1261,7 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr,
DEBUG(SSSDBG_TRACE_FUNC,
"Attempting kinit for realm [%s]\n",realm_name);
kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
- discard_const(password),
+ NULL,
sss_krb5_prompter, kr, 0,
NULL, kr->options);
if (kr->pd->cmd == SSS_PAM_PREAUTH) {
@@ -1396,7 +1440,7 @@ static errno_t changepw_child(struct krb5_req *kr, bool prelim)
DEBUG(SSSDBG_TRACE_FUNC,
"Attempting kinit for realm [%s]\n",realm_name);
kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
- discard_const(password),
+ NULL,
prompter, kr, 0,
SSSD_KRB5_CHANGEPW_PRINCIPAL,
kr->options);
@@ -1564,6 +1608,14 @@ static errno_t tgt_req_child(struct krb5_req *kr)
if (kr->otp) {
kerr = k5c_attach_otp_info_msg(kr);
}
+
+ if (kr->password_prompting) {
+ ret = pam_add_response(kr->pd, SSS_PASSWORD_PROMPTING, 0, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
+ goto done;
+ }
+ }
} else {
if (kerr == 0) {
kerr = k5c_attach_ccname_msg(kr);
@@ -1589,7 +1641,7 @@ static errno_t tgt_req_child(struct krb5_req *kr)
set_changepw_options(kr->options);
kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
- discard_const(password),
+ NULL,
sss_krb5_prompter, kr, 0,
SSSD_KRB5_CHANGEPW_PRINCIPAL,
kr->options);
diff --git a/src/sss_client/pam_message.h b/src/sss_client/pam_message.h
index f0a7a076c..34889e074 100644
--- a/src/sss_client/pam_message.h
+++ b/src/sss_client/pam_message.h
@@ -25,6 +25,7 @@
#include <unistd.h>
#include <stdint.h>
+#include <stdbool.h>
#include "sss_client/sss_cli.h"
@@ -56,6 +57,7 @@ struct pam_items {
char *otp_token_id;
char *otp_challenge;
char *first_factor;
+ bool password_prompting;
char *cert_user;
char *token_name;
diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c
index 5b2307c1b..cb2273c08 100644
--- a/src/sss_client/pam_sss.c
+++ b/src/sss_client/pam_sss.c
@@ -992,6 +992,10 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf,
D(("cert user: [%s] token name: [%s]", pi->cert_user,
pi->token_name));
break;
+ case SSS_PASSWORD_PROMPTING:
+ D(("Password prompting available."));
+ pi->password_prompting = true;
+ break;
default:
D(("Unknown response type [%d]", type));
}
@@ -1071,6 +1075,7 @@ static int get_pam_items(pam_handle_t *pamh, struct pam_items *pi)
pi->otp_vendor = NULL;
pi->otp_token_id = NULL;
pi->otp_challenge = NULL;
+ pi->password_prompting = false;
pi->cert_user = NULL;
pi->token_name = NULL;
@@ -1538,8 +1543,14 @@ static int get_authtok_for_authentication(pam_handle_t *pamh,
if (flags & FLAGS_USE_2FA
|| (pi->otp_vendor != NULL && pi->otp_token_id != NULL
&& pi->otp_challenge != NULL)) {
- ret = prompt_2fa(pamh, pi, _("First Factor: "),
- _("Second Factor: "));
+ if (pi->password_prompting) {
+ ret = prompt_2fa(pamh, pi, _("First Factor or Password: "),
+ _("Second Factor, press return for "
+ "Password authentication: "));
+ } else {
+ ret = prompt_2fa(pamh, pi, _("First Factor: "),
+ _("Second Factor: "));
+ }
} else if (pi->cert_user != NULL) {
ret = prompt_sc_pin(pamh, pi);
} else {
diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h
index f39ceba5e..7fe23796e 100644
--- a/src/sss_client/sss_cli.h
+++ b/src/sss_client/sss_cli.h
@@ -421,6 +421,11 @@ enum response_type {
SSS_OTP, /**< Indicates that the autotok was a OTP, so don't
* cache it. There is no message.
* @param None. */
+ SSS_PASSWORD_PROMPTING, /**< Indicates that password prompting is possible.
+ * This might be used together with
+ * SSS_PAM_OTP_INFO to determine the type of
+ * prompting. There is no message.
+ * @param None. */
};
/**