ipa_auth.c revision a3c8390d19593b1e5277d95bfb4ab206d4785150
7cb128dc4cae2a03a742f63ba7afee23c78e3af0Phil Carmody/*
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen SSSD
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen
acc039dfc0b0f4588cf2feec04727b61e1c672a1Timo Sirainen IPA Backend Module -- Authentication
fab850a6aee4aaef4f4795bd7946807a3ba45041Timo Sirainen
28b8434ca4cba2e310d13ffc55e895d658725f43Timo Sirainen Authors:
28b8434ca4cba2e310d13ffc55e895d658725f43Timo Sirainen Sumit Bose <sbose@redhat.com>
06af65f82453bb976cf8aa6fe2507e3a6253a04fTimo Sirainen
4909421ac41e143fe07a235c0d11e9f0452d716bTimo Sirainen Copyright (C) 2009 Red Hat
e5d7056b6ef069e228f8ad3c9467662955cab3c6Timo Sirainen
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen This program is free software; you can redistribute it and/or modify
134582c78f038b4d9b9fde127399aefa50935a53Timo Sirainen it under the terms of the GNU General Public License as published by
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen the Free Software Foundation; either version 3 of the License, or
4909421ac41e143fe07a235c0d11e9f0452d716bTimo Sirainen (at your option) any later version.
54f559f2e69ea1498e3ccfa7b65d16d9a622c391Timo Sirainen
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen This program is distributed in the hope that it will be useful,
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen but WITHOUT ANY WARRANTY; without even the implied warranty of
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen GNU General Public License for more details.
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen
8aa6fe58b1832da498b49de4383f9f1ef458945dTimo Sirainen You should have received a copy of the GNU General Public License
8aa6fe58b1832da498b49de4383f9f1ef458945dTimo Sirainen along with this program. If not, see <http://www.gnu.org/licenses/>.
8aa6fe58b1832da498b49de4383f9f1ef458945dTimo Sirainen*/
8aa6fe58b1832da498b49de4383f9f1ef458945dTimo Sirainen
8aa6fe58b1832da498b49de4383f9f1ef458945dTimo Sirainen#include <sys/param.h>
8aa6fe58b1832da498b49de4383f9f1ef458945dTimo Sirainen#include <security/pam_modules.h>
8aa6fe58b1832da498b49de4383f9f1ef458945dTimo Sirainen
8aa6fe58b1832da498b49de4383f9f1ef458945dTimo Sirainen#include "util/util.h"
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen#include "providers/ldap/ldap_common.h"
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen#include "providers/ldap/sdap_async.h"
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen#include "providers/krb5/krb5_auth.h"
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen#include "providers/ipa/ipa_auth.h"
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen#include "providers/ipa/ipa_common.h"
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen#include "providers/ipa/ipa_config.h"
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainenstruct get_password_migration_flag_state {
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen struct tevent_context *ev;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen struct sdap_id_op *sdap_op;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen struct sdap_id_ctx *sdap_id_ctx;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen struct fo_server *srv;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen char *ipa_realm;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen bool password_migration;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen};
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainenstatic void get_password_migration_flag_auth_done(struct tevent_req *subreq);
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainenstatic void get_password_migration_flag_done(struct tevent_req *subreq);
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainenstatic struct tevent_req *get_password_migration_flag_send(TALLOC_CTX *memctx,
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen struct tevent_context *ev,
bb1a7da5a76625640a5a207b19ed3abdb70c9617Timo Sirainen struct sdap_id_ctx *sdap_id_ctx,
bb1a7da5a76625640a5a207b19ed3abdb70c9617Timo Sirainen char *ipa_realm)
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen{
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen int ret;
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen struct tevent_req *req, *subreq;
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen struct get_password_migration_flag_state *state;
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen if (sdap_id_ctx == NULL || ipa_realm == NULL) {
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "Missing parameter.\n");
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen return NULL;
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen }
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen req = tevent_req_create(memctx, &state,
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen struct get_password_migration_flag_state);
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen if (req == NULL) {
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n");
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen return NULL;
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen }
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen state->ev = ev;
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen state->sdap_id_ctx = sdap_id_ctx;
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen state->srv = NULL;
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen state->password_migration = false;
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen state->ipa_realm = ipa_realm;
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen state->sdap_op = sdap_id_op_create(state,
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen state->sdap_id_ctx->conn->conn_cache);
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen if (state->sdap_op == NULL) {
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed.\n");
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen goto fail;
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen }
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret);
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen if (!subreq) {
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: %d(%s).\n",
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen ret, strerror(ret));
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen goto fail;
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen }
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen tevent_req_set_callback(subreq, get_password_migration_flag_auth_done, req);
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen return req;
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainenfail:
bb1a7da5a76625640a5a207b19ed3abdb70c9617Timo Sirainen talloc_zfree(req);
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen return NULL;
bb1a7da5a76625640a5a207b19ed3abdb70c9617Timo Sirainen}
bb1a7da5a76625640a5a207b19ed3abdb70c9617Timo Sirainen
bb1a7da5a76625640a5a207b19ed3abdb70c9617Timo Sirainenstatic void get_password_migration_flag_auth_done(struct tevent_req *subreq)
bb1a7da5a76625640a5a207b19ed3abdb70c9617Timo Sirainen{
bb1a7da5a76625640a5a207b19ed3abdb70c9617Timo Sirainen struct tevent_req *req = tevent_req_callback_data(subreq,
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen struct tevent_req);
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen struct get_password_migration_flag_state *state = tevent_req_data(req,
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen struct get_password_migration_flag_state);
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen int ret, dp_error;
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen ret = sdap_id_op_connect_recv(subreq, &dp_error);
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen talloc_zfree(subreq);
767431e5084a037c4dbefdf30ebfa03c84b1f449Timo Sirainen if (ret) {
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen if (dp_error == DP_ERR_OFFLINE) {
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen DEBUG(SSSDBG_MINOR_FAILURE,
acc039dfc0b0f4588cf2feec04727b61e1c672a1Timo Sirainen "No IPA server is available, cannot get the "
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen "migration flag while offline\n");
acc039dfc0b0f4588cf2feec04727b61e1c672a1Timo Sirainen } else {
10635b60b6f7776cd4c1f364ae8dc94c3b9254ecPascal Volk DEBUG(SSSDBG_OP_FAILURE,
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen "Failed to connect to IPA server: [%d](%s)\n",
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen ret, strerror(ret));
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen }
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen tevent_req_error(req, ret);
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen return;
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen }
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen subreq = ipa_get_config_send(state, state->ev,
acc039dfc0b0f4588cf2feec04727b61e1c672a1Timo Sirainen sdap_id_op_handle(state->sdap_op),
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen state->sdap_id_ctx->opts, state->ipa_realm, NULL);
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen tevent_req_set_callback(subreq, get_password_migration_flag_done, req);
767431e5084a037c4dbefdf30ebfa03c84b1f449Timo Sirainen}
767431e5084a037c4dbefdf30ebfa03c84b1f449Timo Sirainen
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainenstatic void get_password_migration_flag_done(struct tevent_req *subreq)
767431e5084a037c4dbefdf30ebfa03c84b1f449Timo Sirainen{
767431e5084a037c4dbefdf30ebfa03c84b1f449Timo Sirainen struct tevent_req *req = tevent_req_callback_data(subreq,
9ce62fcb795a4bb57f1c003fc8cbd63bff6e5463Timo Sirainen struct tevent_req);
9ce62fcb795a4bb57f1c003fc8cbd63bff6e5463Timo Sirainen struct get_password_migration_flag_state *state = tevent_req_data(req,
acc039dfc0b0f4588cf2feec04727b61e1c672a1Timo Sirainen struct get_password_migration_flag_state);
9f3bb0e10835efb0c9b1eb9e09e16b614ec41b97Timo Sirainen int ret;
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen struct sysdb_attrs *reply = NULL;
acc039dfc0b0f4588cf2feec04727b61e1c672a1Timo Sirainen const char *value = NULL;
acc039dfc0b0f4588cf2feec04727b61e1c672a1Timo Sirainen
9f3bb0e10835efb0c9b1eb9e09e16b614ec41b97Timo Sirainen ret = ipa_get_config_recv(subreq, state, &reply);
9f3bb0e10835efb0c9b1eb9e09e16b614ec41b97Timo Sirainen talloc_zfree(subreq);
9f3bb0e10835efb0c9b1eb9e09e16b614ec41b97Timo Sirainen if (ret) {
9f3bb0e10835efb0c9b1eb9e09e16b614ec41b97Timo Sirainen goto done;
9f3bb0e10835efb0c9b1eb9e09e16b614ec41b97Timo Sirainen }
28b8434ca4cba2e310d13ffc55e895d658725f43Timo Sirainen
acc039dfc0b0f4588cf2feec04727b61e1c672a1Timo Sirainen ret = sysdb_attrs_get_string(reply, IPA_CONFIG_MIGRATION_ENABLED, &value);
28b8434ca4cba2e310d13ffc55e895d658725f43Timo Sirainen if (ret == EOK && strcasecmp(value, "true") == 0) {
acc039dfc0b0f4588cf2feec04727b61e1c672a1Timo Sirainen state->password_migration = true;
acc039dfc0b0f4588cf2feec04727b61e1c672a1Timo Sirainen }
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen
fab850a6aee4aaef4f4795bd7946807a3ba45041Timo Sirainendone:
28b8434ca4cba2e310d13ffc55e895d658725f43Timo Sirainen if (ret != EOK) {
28b8434ca4cba2e310d13ffc55e895d658725f43Timo Sirainen tevent_req_error(req, ret);
28b8434ca4cba2e310d13ffc55e895d658725f43Timo Sirainen } else {
28b8434ca4cba2e310d13ffc55e895d658725f43Timo Sirainen tevent_req_done(req);
28b8434ca4cba2e310d13ffc55e895d658725f43Timo Sirainen }
acc039dfc0b0f4588cf2feec04727b61e1c672a1Timo Sirainen}
0f9a8663b0ff6fe30389d02284a2b002c40914ebTimo Sirainen
acc039dfc0b0f4588cf2feec04727b61e1c672a1Timo Sirainenstatic int get_password_migration_flag_recv(struct tevent_req *req,
bde78a7bf5f9000f1ae4dc7ce6cabd012e1f8b79Pascal Volk bool *password_migration)
acc039dfc0b0f4588cf2feec04727b61e1c672a1Timo Sirainen{
acc039dfc0b0f4588cf2feec04727b61e1c672a1Timo Sirainen struct get_password_migration_flag_state *state = tevent_req_data(req,
a3a55999bcfe2e57941cb64343f4ea80beabdab7Timo Sirainen struct get_password_migration_flag_state);
a3a55999bcfe2e57941cb64343f4ea80beabdab7Timo Sirainen
06af65f82453bb976cf8aa6fe2507e3a6253a04fTimo Sirainen TEVENT_REQ_RETURN_ON_ERROR(req);
06af65f82453bb976cf8aa6fe2507e3a6253a04fTimo Sirainen
a3a55999bcfe2e57941cb64343f4ea80beabdab7Timo Sirainen *password_migration = state->password_migration;
a3a55999bcfe2e57941cb64343f4ea80beabdab7Timo Sirainen return EOK;
a3a55999bcfe2e57941cb64343f4ea80beabdab7Timo Sirainen}
a3a55999bcfe2e57941cb64343f4ea80beabdab7Timo Sirainen
a3a55999bcfe2e57941cb64343f4ea80beabdab7Timo Sirainen
a3a55999bcfe2e57941cb64343f4ea80beabdab7Timo Sirainenstruct ipa_auth_state {
bde78a7bf5f9000f1ae4dc7ce6cabd012e1f8b79Pascal Volk struct be_req *be_req;
a3a55999bcfe2e57941cb64343f4ea80beabdab7Timo Sirainen struct tevent_context *ev;
a3a55999bcfe2e57941cb64343f4ea80beabdab7Timo Sirainen struct ipa_auth_ctx *ipa_auth_ctx;
cc52f19439f17c03e37fd65c6299a77d5c5e638aTimo Sirainen struct pam_data *pd;
cc52f19439f17c03e37fd65c6299a77d5c5e638aTimo Sirainen bool password_migration;
cc52f19439f17c03e37fd65c6299a77d5c5e638aTimo Sirainen struct sdap_handle *sh;
cc52f19439f17c03e37fd65c6299a77d5c5e638aTimo Sirainen};
cc52f19439f17c03e37fd65c6299a77d5c5e638aTimo Sirainen
f2a1955d993f67982bc40ad7bbae9a036dabfd64Timo Sirainenstatic void ipa_auth_handler_done(struct tevent_req *req);
f2a1955d993f67982bc40ad7bbae9a036dabfd64Timo Sirainenstatic void ipa_get_migration_flag_done(struct tevent_req *req);
f2a1955d993f67982bc40ad7bbae9a036dabfd64Timo Sirainenstatic void ipa_migration_flag_connect_done(struct tevent_req *req);
f2a1955d993f67982bc40ad7bbae9a036dabfd64Timo Sirainenstatic void ipa_auth_ldap_done(struct tevent_req *req);
cc52f19439f17c03e37fd65c6299a77d5c5e638aTimo Sirainenstatic void ipa_auth_handler_retry_done(struct tevent_req *req);
cc52f19439f17c03e37fd65c6299a77d5c5e638aTimo Sirainen
cc52f19439f17c03e37fd65c6299a77d5c5e638aTimo Sirainenvoid ipa_auth(struct be_req *be_req)
f2a1955d993f67982bc40ad7bbae9a036dabfd64Timo Sirainen{
f2a1955d993f67982bc40ad7bbae9a036dabfd64Timo Sirainen struct tevent_req *req;
f2a1955d993f67982bc40ad7bbae9a036dabfd64Timo Sirainen struct ipa_auth_state *state;
f2a1955d993f67982bc40ad7bbae9a036dabfd64Timo Sirainen struct pam_data *pd =
f2a1955d993f67982bc40ad7bbae9a036dabfd64Timo Sirainen talloc_get_type(be_req_get_data(be_req), struct pam_data);
f2a1955d993f67982bc40ad7bbae9a036dabfd64Timo Sirainen struct be_ctx *be_ctx = be_req_get_be_ctx(be_req);
f2a1955d993f67982bc40ad7bbae9a036dabfd64Timo Sirainen
e16cdc182bf122c37e252b49809db688e874b2a3Timo Sirainen state = talloc_zero(be_req, struct ipa_auth_state);
e16cdc182bf122c37e252b49809db688e874b2a3Timo Sirainen if (state == NULL) {
e16cdc182bf122c37e252b49809db688e874b2a3Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n");
e16cdc182bf122c37e252b49809db688e874b2a3Timo Sirainen goto fail;
e16cdc182bf122c37e252b49809db688e874b2a3Timo Sirainen }
e16cdc182bf122c37e252b49809db688e874b2a3Timo Sirainen
e16cdc182bf122c37e252b49809db688e874b2a3Timo Sirainen state->password_migration = false;
e16cdc182bf122c37e252b49809db688e874b2a3Timo Sirainen state->sh = NULL;
e16cdc182bf122c37e252b49809db688e874b2a3Timo Sirainen
acc039dfc0b0f4588cf2feec04727b61e1c672a1Timo Sirainen state->be_req = be_req;
acc039dfc0b0f4588cf2feec04727b61e1c672a1Timo Sirainen state->ev = be_ctx->ev;
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen
4909421ac41e143fe07a235c0d11e9f0452d716bTimo Sirainen state->pd = pd;
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen switch (state->pd->cmd) {
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen case SSS_PAM_AUTHENTICATE:
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen state->ipa_auth_ctx = talloc_get_type(
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen be_ctx->bet_info[BET_AUTH].pvt_bet_data,
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen struct ipa_auth_ctx);
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen break;
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen case SSS_PAM_CHAUTHTOK:
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen case SSS_PAM_CHAUTHTOK_PRELIM:
4909421ac41e143fe07a235c0d11e9f0452d716bTimo Sirainen state->ipa_auth_ctx = talloc_get_type(
4909421ac41e143fe07a235c0d11e9f0452d716bTimo Sirainen be_ctx->bet_info[BET_CHPASS].pvt_bet_data,
d5ef38077adbff5b3e4d0b3c94a2057581dc78b6Timo Sirainen struct ipa_auth_ctx);
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen break;
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen default:
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "Unsupported PAM task.\n");
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen goto fail;
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen }
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen req = krb5_auth_send(state, state->ev, be_ctx, state->pd,
d5ef38077adbff5b3e4d0b3c94a2057581dc78b6Timo Sirainen state->ipa_auth_ctx->krb5_auth_ctx);
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen if (req == NULL) {
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "krb5_auth_send failed.\n");
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen goto fail;
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen }
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen
d5eb47a791ec56149fd711cd8e44efc8babeaae5Timo Sirainen tevent_req_set_callback(req, ipa_auth_handler_done, state);
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen return;
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainenfail:
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen talloc_free(state);
e5d7056b6ef069e228f8ad3c9467662955cab3c6Timo Sirainen pd->pam_status = PAM_SYSTEM_ERR;
2e533fb1283b5f06a4063b519e47f1861c910386Timo Sirainen be_req_terminate(be_req, DP_ERR_FATAL, pd->pam_status, NULL);
2e533fb1283b5f06a4063b519e47f1861c910386Timo Sirainen}
2e533fb1283b5f06a4063b519e47f1861c910386Timo Sirainen
2e533fb1283b5f06a4063b519e47f1861c910386Timo Sirainenstatic void ipa_auth_handler_done(struct tevent_req *req)
d5ef38077adbff5b3e4d0b3c94a2057581dc78b6Timo Sirainen{
d5ef38077adbff5b3e4d0b3c94a2057581dc78b6Timo Sirainen struct ipa_auth_state *state = tevent_req_callback_data(req,
e5d7056b6ef069e228f8ad3c9467662955cab3c6Timo Sirainen struct ipa_auth_state);
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen int ret;
ff3337516aad9843599905aeeb29812ea67c09d1Timo Sirainen int pam_status = PAM_SYSTEM_ERR;
55accf49e32ff93bfdd92961cb54ccc8c329147cTimo Sirainen int dp_err;
ff3337516aad9843599905aeeb29812ea67c09d1Timo Sirainen
a3a55999bcfe2e57941cb64343f4ea80beabdab7Timo Sirainen ret = krb5_auth_recv(req, &pam_status, &dp_err);
f2a1955d993f67982bc40ad7bbae9a036dabfd64Timo Sirainen talloc_zfree(req);
ff3337516aad9843599905aeeb29812ea67c09d1Timo Sirainen state->pd->pam_status = pam_status;
ff3337516aad9843599905aeeb29812ea67c09d1Timo Sirainen if (ret != EOK && pam_status != PAM_CRED_ERR) {
4605cab1123700c52c515a433a2802fcbc827c62Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "krb5_auth_recv request failed.\n");
4605cab1123700c52c515a433a2802fcbc827c62Timo Sirainen dp_err = DP_ERR_OK;
ff3337516aad9843599905aeeb29812ea67c09d1Timo Sirainen goto done;
ff3337516aad9843599905aeeb29812ea67c09d1Timo Sirainen }
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen if (dp_err != DP_ERR_OK) {
a672f99363d5f37060c1331d00d2ee3c4626310fTimo Sirainen goto done;
a672f99363d5f37060c1331d00d2ee3c4626310fTimo Sirainen }
a672f99363d5f37060c1331d00d2ee3c4626310fTimo Sirainen
d5ef38077adbff5b3e4d0b3c94a2057581dc78b6Timo Sirainen if (state->pd->cmd == SSS_PAM_AUTHENTICATE &&
ff3337516aad9843599905aeeb29812ea67c09d1Timo Sirainen state->pd->pam_status == PAM_CRED_ERR) {
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen
5296198635718c9bf5b2f972c9d5be52092d3d58Timo Sirainen req = get_password_migration_flag_send(state, state->ev,
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen state->ipa_auth_ctx->sdap_id_ctx,
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen dp_opt_get_string(
885a3c2287ae3e5827aa580ea06b231de38abb47Timo Sirainen state->ipa_auth_ctx->ipa_options,
885a3c2287ae3e5827aa580ea06b231de38abb47Timo Sirainen IPA_KRB5_REALM));
5296198635718c9bf5b2f972c9d5be52092d3d58Timo Sirainen if (req == NULL) {
5296198635718c9bf5b2f972c9d5be52092d3d58Timo Sirainen DEBUG(SSSDBG_OP_FAILURE,
a672f99363d5f37060c1331d00d2ee3c4626310fTimo Sirainen "get_password_migration_flag failed.\n");
d5ef38077adbff5b3e4d0b3c94a2057581dc78b6Timo Sirainen goto done;
5296198635718c9bf5b2f972c9d5be52092d3d58Timo Sirainen }
5296198635718c9bf5b2f972c9d5be52092d3d58Timo Sirainen
5296198635718c9bf5b2f972c9d5be52092d3d58Timo Sirainen tevent_req_set_callback(req, ipa_get_migration_flag_done, state);
5296198635718c9bf5b2f972c9d5be52092d3d58Timo Sirainen return;
5296198635718c9bf5b2f972c9d5be52092d3d58Timo Sirainen }
5296198635718c9bf5b2f972c9d5be52092d3d58Timo Sirainen
72c47a26f4ded49d4827dc64818b34bbc9606fc4Timo Sirainendone:
7ed711d973b319320da100d3e905ef7b99ed69d6Timo Sirainen be_req_terminate(state->be_req, dp_err, state->pd->pam_status, NULL);
7ed711d973b319320da100d3e905ef7b99ed69d6Timo Sirainen}
5296198635718c9bf5b2f972c9d5be52092d3d58Timo Sirainen
5296198635718c9bf5b2f972c9d5be52092d3d58Timo Sirainenstatic void ipa_get_migration_flag_done(struct tevent_req *req)
5296198635718c9bf5b2f972c9d5be52092d3d58Timo Sirainen{
5296198635718c9bf5b2f972c9d5be52092d3d58Timo Sirainen struct ipa_auth_state *state = tevent_req_callback_data(req,
5296198635718c9bf5b2f972c9d5be52092d3d58Timo Sirainen struct ipa_auth_state);
5296198635718c9bf5b2f972c9d5be52092d3d58Timo Sirainen int ret;
5296198635718c9bf5b2f972c9d5be52092d3d58Timo Sirainen int dp_err = DP_ERR_FATAL;
a2857829c642e2671779576b00c37b7d04693731Timo Sirainen
4909421ac41e143fe07a235c0d11e9f0452d716bTimo Sirainen ret = get_password_migration_flag_recv(req, &state->password_migration);
4a26584a87ee0e986d23a224b3b3e85c44254d7fTimo Sirainen talloc_zfree(req);
4a26584a87ee0e986d23a224b3b3e85c44254d7fTimo Sirainen if (ret != EOK) {
4a26584a87ee0e986d23a224b3b3e85c44254d7fTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, "get_password_migration_flag "
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen "request failed.\n");
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen state->pd->pam_status = PAM_SYSTEM_ERR;
d5ef38077adbff5b3e4d0b3c94a2057581dc78b6Timo Sirainen dp_err = DP_ERR_OK;
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen goto done;
851404049fe55a02fb69d7c2b4d851d2d0fd4b8dTimo Sirainen }
4909421ac41e143fe07a235c0d11e9f0452d716bTimo Sirainen
55accf49e32ff93bfdd92961cb54ccc8c329147cTimo Sirainen if (state->password_migration) {
55accf49e32ff93bfdd92961cb54ccc8c329147cTimo Sirainen req = sdap_cli_connect_send(state, state->ev,
55accf49e32ff93bfdd92961cb54ccc8c329147cTimo Sirainen state->ipa_auth_ctx->sdap_auth_ctx->opts,
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen state->ipa_auth_ctx->sdap_auth_ctx->be,
2f896df28bbb7751c6d77219cb6675fa091d3c7aTimo Sirainen state->ipa_auth_ctx->sdap_auth_ctx->service,
968b2f633b7405bc2cf0596d04762994ceb279d0Timo Sirainen true, CON_TLS_ON, true);
a2857829c642e2671779576b00c37b7d04693731Timo Sirainen if (req == NULL) {
a2857829c642e2671779576b00c37b7d04693731Timo Sirainen DEBUG(SSSDBG_OP_FAILURE, "sdap_cli_connect_send failed.\n");
a2857829c642e2671779576b00c37b7d04693731Timo Sirainen goto done;
a2857829c642e2671779576b00c37b7d04693731Timo Sirainen }
a2857829c642e2671779576b00c37b7d04693731Timo Sirainen
a2857829c642e2671779576b00c37b7d04693731Timo Sirainen tevent_req_set_callback(req, ipa_migration_flag_connect_done, state);
a2857829c642e2671779576b00c37b7d04693731Timo Sirainen return;
134582c78f038b4d9b9fde127399aefa50935a53Timo Sirainen }
a2857829c642e2671779576b00c37b7d04693731Timo Sirainen
a2857829c642e2671779576b00c37b7d04693731Timo Sirainen DEBUG(SSSDBG_CONF_SETTINGS, "Password migration is not enabled.\n");
a2857829c642e2671779576b00c37b7d04693731Timo Sirainen dp_err = DP_ERR_OK;
a2857829c642e2671779576b00c37b7d04693731Timo Sirainendone:
a2857829c642e2671779576b00c37b7d04693731Timo Sirainen be_req_terminate(state->be_req, dp_err, state->pd->pam_status, NULL);
a2857829c642e2671779576b00c37b7d04693731Timo Sirainen}
a2857829c642e2671779576b00c37b7d04693731Timo Sirainen
a2857829c642e2671779576b00c37b7d04693731Timo Sirainenstatic void ipa_migration_flag_connect_done(struct tevent_req *req)
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen{
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen struct ipa_auth_state *state = tevent_req_callback_data(req,
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen struct ipa_auth_state);
1d5dbb87f3485544db62896e2d56c663cb728c17Timo Sirainen struct be_ctx *be_ctx = be_req_get_be_ctx(state->be_req);
1d5dbb87f3485544db62896e2d56c663cb728c17Timo Sirainen const char **attrs;
1d5dbb87f3485544db62896e2d56c663cb728c17Timo Sirainen struct ldb_message *user_msg;
1d5dbb87f3485544db62896e2d56c663cb728c17Timo Sirainen const char *dn;
dbcc7e1e5eaaad8a8cac6ee74076772c42a2649aTimo Sirainen int dp_err = DP_ERR_FATAL;
1d5dbb87f3485544db62896e2d56c663cb728c17Timo Sirainen int ret;
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen ret = sdap_cli_connect_recv(req, state, NULL, &state->sh, NULL);
aee3e2f7ab2b27572a90b9e7fd8fe60f13c6637eTimo Sirainen talloc_zfree(req);
aee3e2f7ab2b27572a90b9e7fd8fe60f13c6637eTimo Sirainen if (ret != EOK) {
aee3e2f7ab2b27572a90b9e7fd8fe60f13c6637eTimo Sirainen DEBUG(SSSDBG_OP_FAILURE,
aee3e2f7ab2b27572a90b9e7fd8fe60f13c6637eTimo Sirainen "Cannot connect to LDAP server to perform migration\n");
aee3e2f7ab2b27572a90b9e7fd8fe60f13c6637eTimo Sirainen goto done;
acc039dfc0b0f4588cf2feec04727b61e1c672a1Timo Sirainen }
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen
10515cb90514b169ab6c3693c72c4bf1017476dbTimo Sirainen state->pd->pam_status = PAM_SYSTEM_ERR;
10515cb90514b169ab6c3693c72c4bf1017476dbTimo Sirainen DEBUG(SSSDBG_TRACE_FUNC, "Assuming Kerberos password is missing, "
10515cb90514b169ab6c3693c72c4bf1017476dbTimo Sirainen "starting password migration.\n");
10515cb90514b169ab6c3693c72c4bf1017476dbTimo Sirainen
10515cb90514b169ab6c3693c72c4bf1017476dbTimo Sirainen attrs = talloc_array(state, const char *, 2);
10515cb90514b169ab6c3693c72c4bf1017476dbTimo Sirainen if (attrs == NULL) {
10515cb90514b169ab6c3693c72c4bf1017476dbTimo Sirainen DEBUG(1, "talloc_array failed.\n");
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen state->pd->pam_status = PAM_SYSTEM_ERR;
bd417d416988d11a6b555b9aa57779e7ed976951Timo Sirainen dp_err = DP_ERR_OK;
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen goto done;
a2857829c642e2671779576b00c37b7d04693731Timo Sirainen }
a2857829c642e2671779576b00c37b7d04693731Timo Sirainen attrs[0] = SYSDB_ORIG_DN;
134582c78f038b4d9b9fde127399aefa50935a53Timo Sirainen attrs[1] = NULL;
1c633f71ec2060e5bfa500a97f34cd881a958ecdTimo Sirainen
7ed711d973b319320da100d3e905ef7b99ed69d6Timo Sirainen ret = sysdb_search_user_by_name(state, be_ctx->domain, state->pd->user,
a2857829c642e2671779576b00c37b7d04693731Timo Sirainen attrs, &user_msg);
55accf49e32ff93bfdd92961cb54ccc8c329147cTimo Sirainen if (ret != EOK) {
4909421ac41e143fe07a235c0d11e9f0452d716bTimo Sirainen DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_name failed.\n");
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen goto done;
a6ab8f00351265e35b79f3a22b1f5a4978ae5c35Timo Sirainen }
dn = ldb_msg_find_attr_as_string(user_msg, SYSDB_ORIG_DN, NULL);
if (dn == NULL) {
DEBUG(SSSDBG_MINOR_FAILURE, "Missing original DN for user [%s].\n",
state->pd->user);
state->pd->pam_status = PAM_SYSTEM_ERR;
dp_err = DP_ERR_OK;
goto done;
}
req = sdap_auth_send(state, state->ev, state->sh, NULL, NULL, dn,
state->pd->authtok);
if (req == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "sdap_auth_send failed.\n");
goto done;
}
tevent_req_set_callback(req, ipa_auth_ldap_done, state);
return;
done:
be_req_terminate(state->be_req, dp_err, state->pd->pam_status, NULL);
}
static void ipa_auth_ldap_done(struct tevent_req *req)
{
struct ipa_auth_state *state = tevent_req_callback_data(req,
struct ipa_auth_state);
struct be_ctx *be_ctx = be_req_get_be_ctx(state->be_req);
int ret;
int dp_err = DP_ERR_FATAL;
ret = sdap_auth_recv(req, state, NULL);
talloc_zfree(req);
switch (ret) {
case EOK:
break;
case ERR_AUTH_DENIED:
case ERR_AUTH_FAILED:
case ERR_PASSWORD_EXPIRED:
/* TODO: do we need to handle expired passwords? */
DEBUG(SSSDBG_MINOR_FAILURE, "LDAP authentication failed, "
"Password migration not possible.\n");
state->pd->pam_status = PAM_CRED_INSUFFICIENT;
dp_err = DP_ERR_OK;
goto done;
default:
DEBUG(SSSDBG_OP_FAILURE, "auth_send request failed.\n");
state->pd->pam_status = PAM_SYSTEM_ERR;
dp_err = DP_ERR_OK;
goto done;
}
DEBUG(SSSDBG_TRACE_FUNC, "LDAP authentication succeded, "
"trying Kerberos authentication again.\n");
req = krb5_auth_send(state, state->ev, be_ctx, state->pd,
state->ipa_auth_ctx->krb5_auth_ctx);
if (req == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "krb5_auth_send failed.\n");
goto done;
}
tevent_req_set_callback(req, ipa_auth_handler_retry_done, state);
return;
done:
be_req_terminate(state->be_req, dp_err, state->pd->pam_status, NULL);
}
static void ipa_auth_handler_retry_done(struct tevent_req *req)
{
struct ipa_auth_state *state = tevent_req_callback_data(req,
struct ipa_auth_state);
int ret;
int pam_status;
int dp_err;
ret = krb5_auth_recv(req, &pam_status, &dp_err);
talloc_zfree(req);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "krb5_auth_recv request failed.\n");
state->pd->pam_status = PAM_SYSTEM_ERR;
dp_err = DP_ERR_OK;
goto done;
}
state->pd->pam_status = pam_status;
done:
be_req_terminate(state->be_req, dp_err, state->pd->pam_status, NULL);
}