35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher/*
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher SSSD
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher sdap_access.c
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher Authors:
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher Stephen Gallagher <sgallagh@redhat.com>
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher Copyright (C) 2010 Red Hat
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher This program is free software; you can redistribute it and/or modify
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher it under the terms of the GNU General Public License as published by
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher the Free Software Foundation; either version 3 of the License, or
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher (at your option) any later version.
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher This program is distributed in the hope that it will be useful,
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher but WITHOUT ANY WARRANTY; without even the implied warranty of
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher GNU General Public License for more details.
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher You should have received a copy of the GNU General Public License
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher along with this program. If not, see <http://www.gnu.org/licenses/>.
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher*/
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
5389b3714be747f1a11ac51beb0c5988cfb6c240Lukas Slebodnik#include "config.h"
5389b3714be747f1a11ac51beb0c5988cfb6c240Lukas Slebodnik
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose#include <time.h>
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher#include <security/pam_modules.h>
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher#include <talloc.h>
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher#include <tevent.h>
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher#include <errno.h>
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher#include "util/util.h"
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl#include "util/strtonum.h"
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher#include "db/sysdb.h"
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher#include "providers/ldap/ldap_common.h"
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher#include "providers/ldap/sdap.h"
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher#include "providers/ldap/sdap_access.h"
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher#include "providers/ldap/sdap_async.h"
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher#include "providers/data_provider.h"
cc2d77d5218c188119fa954c856e858cbde76947Pavel Březina#include "providers/backend.h"
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl#include "providers/ldap/ldap_auth.h"
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl#define PERMANENTLY_LOCKED_ACCOUNT "000001010000Z"
46ebf4415306454e1d062b61a2495b7cdb821c0fPavel Reichl#define MALFORMED_FILTER "Malformed access control filter [%s]\n"
46ebf4415306454e1d062b61a2495b7cdb821c0fPavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlenum sdap_pwpolicy_mode {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl PWP_LOCKOUT_ONLY,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl PWP_LOCKOUT_EXPIRE,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl PWP_SENTINEL,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl};
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichlstatic errno_t perform_pwexpire_policy(TALLOC_CTX *mem_ctx,
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl struct sss_domain_info *domain,
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl struct pam_data *pd,
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl struct sdap_options *opts);
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichlstatic errno_t sdap_save_user_cache_bool(struct sss_domain_info *domain,
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl const char *username,
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl const char *attr_name,
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl bool value);
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichlstatic errno_t sdap_get_basedn_user_entry(struct ldb_message *user_entry,
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl const char *username,
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl const char **_basedn);
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichlstatic struct tevent_req *
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlsdap_access_ppolicy_send(TALLOC_CTX *mem_ctx,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct tevent_context *ev,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct be_ctx *be_ctx,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct sss_domain_info *domain,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct sdap_access_ctx *access_ctx,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct sdap_id_conn_ctx *conn,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl const char *username,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct ldb_message *user_entry,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl enum sdap_pwpolicy_mode pwpol_mod);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bosestatic struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx,
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose struct tevent_context *ev,
249a28dbf31e11794c7f35d709c5561c1555898dSimo Sorce struct be_ctx *be_ctx,
249a28dbf31e11794c7f35d709c5561c1555898dSimo Sorce struct sss_domain_info *domain,
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose struct sdap_access_ctx *access_ctx,
443eb8217741df57d9f58f2098487b91e3404e71Jakub Hrozek struct sdap_id_conn_ctx *conn,
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose const char *username,
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose struct ldb_message *user_entry);
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorcestatic errno_t sdap_access_filter_recv(struct tevent_req *req);
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlstatic errno_t sdap_access_ppolicy_recv(struct tevent_req *req);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorcestatic errno_t sdap_account_expired(struct sdap_access_ctx *access_ctx,
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce struct pam_data *pd,
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce struct ldb_message *user_entry);
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorcestatic errno_t sdap_access_service(struct pam_data *pd,
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce struct ldb_message *user_entry);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorcestatic errno_t sdap_access_host(struct ldb_message *user_entry);
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiyerrno_t sdap_access_rhost(struct ldb_message *user_entry, char *rhost);
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichlenum sdap_access_control_type {
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl SDAP_ACCESS_CONTROL_FILTER,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl SDAP_ACCESS_CONTROL_PPOLICY_LOCK,
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl};
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagherstruct sdap_access_req_ctx {
6ff6ccd3eec35217708870b0fe7a6362e97de95fStephen Gallagher struct pam_data *pd;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher struct tevent_context *ev;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher struct sdap_access_ctx *access_ctx;
443eb8217741df57d9f58f2098487b91e3404e71Jakub Hrozek struct sdap_id_conn_ctx *conn;
249a28dbf31e11794c7f35d709c5561c1555898dSimo Sorce struct be_ctx *be_ctx;
249a28dbf31e11794c7f35d709c5561c1555898dSimo Sorce struct sss_domain_info *domain;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose struct ldb_message *user_entry;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose size_t current_rule;
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl enum sdap_access_control_type ac_type;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher};
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichlstatic errno_t sdap_access_check_next_rule(struct sdap_access_req_ctx *state,
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl struct tevent_req *req);
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichlstatic void sdap_access_done(struct tevent_req *subreq);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce
8372129f446e1558f1923a112f328a266144c3ceStephen Gallagherstruct tevent_req *
8372129f446e1558f1923a112f328a266144c3ceStephen Gallaghersdap_access_send(TALLOC_CTX *mem_ctx,
8372129f446e1558f1923a112f328a266144c3ceStephen Gallagher struct tevent_context *ev,
249a28dbf31e11794c7f35d709c5561c1555898dSimo Sorce struct be_ctx *be_ctx,
249a28dbf31e11794c7f35d709c5561c1555898dSimo Sorce struct sss_domain_info *domain,
8372129f446e1558f1923a112f328a266144c3ceStephen Gallagher struct sdap_access_ctx *access_ctx,
443eb8217741df57d9f58f2098487b91e3404e71Jakub Hrozek struct sdap_id_conn_ctx *conn,
8372129f446e1558f1923a112f328a266144c3ceStephen Gallagher struct pam_data *pd)
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher{
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher errno_t ret;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher struct sdap_access_req_ctx *state;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher struct tevent_req *req;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher struct ldb_result *res;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose const char *attrs[] = { "*", NULL };
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher req = tevent_req_create(mem_ctx, &state, struct sdap_access_req_ctx);
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher if (req == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create failed.\n");
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher return NULL;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
249a28dbf31e11794c7f35d709c5561c1555898dSimo Sorce state->be_ctx = be_ctx;
249a28dbf31e11794c7f35d709c5561c1555898dSimo Sorce state->domain = domain;
6ff6ccd3eec35217708870b0fe7a6362e97de95fStephen Gallagher state->pd = pd;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher state->ev = ev;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher state->access_ctx = access_ctx;
443eb8217741df57d9f58f2098487b91e3404e71Jakub Hrozek state->conn = conn;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose state->current_rule = 0;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Performing access check for user [%s]\n", pd->user);
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose if (access_ctx->access_rule[0] == LDAP_ACCESS_EMPTY) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "No access rules defined, access denied.\n");
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = ERR_ACCESS_DENIED;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose goto done;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose }
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
443eb8217741df57d9f58f2098487b91e3404e71Jakub Hrozek /* Get original user DN, domain already points to the right (sub)domain */
b3292840ebaa747a9fd596ff47cc5d18198361d0Michal Zidek ret = sysdb_get_user_attr(state, domain, pd->user, attrs, &res);
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher if (ret != EOK) {
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher if (ret == ENOENT) {
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce /* If we can't find the user, return access denied */
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = ERR_ACCESS_DENIED;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose goto done;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose goto done;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher else {
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher if (res->count == 0) {
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce /* If we can't find the user, return access denied */
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = ERR_ACCESS_DENIED;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose goto done;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher if (res->count != 1) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Invalid response from sysdb_get_user_attr\n");
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose ret = EINVAL;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose goto done;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose }
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose }
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose state->user_entry = res->msgs[0];
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl ret = sdap_access_check_next_rule(state, req);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce if (ret == EAGAIN) {
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return req;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose }
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bosedone:
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose if (ret == EOK) {
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose tevent_req_done(req);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose } else {
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose tevent_req_error(req, ret);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose }
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose tevent_req_post(req, ev);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose return req;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose}
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichlstatic errno_t sdap_access_check_next_rule(struct sdap_access_req_ctx *state,
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl struct tevent_req *req)
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose{
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose struct tevent_req *subreq;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce int ret = EOK;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce while (ret == EOK) {
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce switch (state->access_ctx->access_rule[state->current_rule]) {
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose case LDAP_ACCESS_EMPTY:
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce /* we are done with no errors */
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return EOK;
6ff6ccd3eec35217708870b0fe7a6362e97de95fStephen Gallagher
108a49f0e816d95cf75a1e964f63b397e53c8b56Pavel Reichl /* This option is deprecated by LDAP_ACCESS_PPOLICY */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl case LDAP_ACCESS_LOCKOUT:
108a49f0e816d95cf75a1e964f63b397e53c8b56Pavel Reichl DEBUG(SSSDBG_MINOR_FAILURE,
108a49f0e816d95cf75a1e964f63b397e53c8b56Pavel Reichl "WARNING: %s option is deprecated and might be removed in "
108a49f0e816d95cf75a1e964f63b397e53c8b56Pavel Reichl "a future release. Please migrate to %s option instead.\n",
108a49f0e816d95cf75a1e964f63b397e53c8b56Pavel Reichl LDAP_ACCESS_LOCK_NAME, LDAP_ACCESS_PPOLICY_NAME);
108a49f0e816d95cf75a1e964f63b397e53c8b56Pavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl subreq = sdap_access_ppolicy_send(state, state->ev, state->be_ctx,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state->domain,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state->access_ctx,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state->conn,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state->pd->user,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state->user_entry,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl PWP_LOCKOUT_ONLY);
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl if (subreq == NULL) {
108a49f0e816d95cf75a1e964f63b397e53c8b56Pavel Reichl DEBUG(SSSDBG_CRIT_FAILURE,
108a49f0e816d95cf75a1e964f63b397e53c8b56Pavel Reichl "sdap_access_ppolicy_send failed.\n");
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl return ENOMEM;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl }
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state->ac_type = SDAP_ACCESS_CONTROL_PPOLICY_LOCK;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl tevent_req_set_callback(subreq, sdap_access_done, req);
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl return EAGAIN;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl case LDAP_ACCESS_PPOLICY:
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl subreq = sdap_access_ppolicy_send(state, state->ev, state->be_ctx,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state->domain,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state->access_ctx,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state->conn,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state->pd->user,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state->user_entry,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl PWP_LOCKOUT_EXPIRE);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (subreq == NULL) {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl DEBUG(SSSDBG_CRIT_FAILURE,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl "sdap_access_ppolicy_send failed.\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl return ENOMEM;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->ac_type = SDAP_ACCESS_CONTROL_PPOLICY_LOCK;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl tevent_req_set_callback(subreq, sdap_access_done, req);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl return EAGAIN;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose case LDAP_ACCESS_FILTER:
249a28dbf31e11794c7f35d709c5561c1555898dSimo Sorce subreq = sdap_access_filter_send(state, state->ev, state->be_ctx,
249a28dbf31e11794c7f35d709c5561c1555898dSimo Sorce state->domain,
6ff6ccd3eec35217708870b0fe7a6362e97de95fStephen Gallagher state->access_ctx,
443eb8217741df57d9f58f2098487b91e3404e71Jakub Hrozek state->conn,
6ff6ccd3eec35217708870b0fe7a6362e97de95fStephen Gallagher state->pd->user,
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose state->user_entry);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose if (subreq == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "sdap_access_filter_send failed.\n");
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose return ENOMEM;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose }
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl state->ac_type = SDAP_ACCESS_CONTROL_FILTER;
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl tevent_req_set_callback(subreq, sdap_access_done, req);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return EAGAIN;
6ff6ccd3eec35217708870b0fe7a6362e97de95fStephen Gallagher
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose case LDAP_ACCESS_EXPIRE:
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = sdap_account_expired(state->access_ctx,
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce state->pd, state->user_entry);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce break;
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl case LDAP_ACCESS_EXPIRE_POLICY_REJECT:
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl ret = perform_pwexpire_policy(state, state->domain, state->pd,
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl state->access_ctx->id_ctx->opts);
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl if (ret == ERR_PASSWORD_EXPIRED) {
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl ret = ERR_PASSWORD_EXPIRED_REJECT;
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl }
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl break;
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl case LDAP_ACCESS_EXPIRE_POLICY_WARN:
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl ret = perform_pwexpire_policy(state, state->domain, state->pd,
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl state->access_ctx->id_ctx->opts);
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl if (ret == ERR_PASSWORD_EXPIRED) {
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl ret = ERR_PASSWORD_EXPIRED_WARN;
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl }
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl break;
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl case LDAP_ACCESS_EXPIRE_POLICY_RENEW:
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl ret = perform_pwexpire_policy(state, state->domain, state->pd,
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl state->access_ctx->id_ctx->opts);
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl if (ret == ERR_PASSWORD_EXPIRED) {
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl ret = ERR_PASSWORD_EXPIRED_RENEW;
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl }
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl break;
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher case LDAP_ACCESS_SERVICE:
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = sdap_access_service( state->pd, state->user_entry);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce break;
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman case LDAP_ACCESS_HOST:
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = sdap_access_host(state->user_entry);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce break;
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy case LDAP_ACCESS_RHOST:
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy ret = sdap_access_rhost(state->user_entry, state->pd->rhost);
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy break;
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose default:
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Unexpected access rule type. Access denied.\n");
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = ERR_ACCESS_DENIED;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce }
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce state->current_rule++;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose }
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ret;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose}
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichlstatic void sdap_access_done(struct tevent_req *subreq)
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose{
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce errno_t ret;
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl struct tevent_req *req;
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl struct sdap_access_req_ctx *state;
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl req = tevent_req_callback_data(subreq, struct tevent_req);
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl state = tevent_req_data(req, struct sdap_access_req_ctx);
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl /* process subrequest */
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl switch(state->ac_type) {
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl case SDAP_ACCESS_CONTROL_FILTER:
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl ret = sdap_access_filter_recv(subreq);
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl break;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl case SDAP_ACCESS_CONTROL_PPOLICY_LOCK:
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl ret = sdap_access_ppolicy_recv(subreq);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl break;
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl default:
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl ret = EINVAL;
b07a3b729892d2bc2ffa73d93de95e19003cc6c8Pavel Reichl DEBUG(SSSDBG_MINOR_FAILURE, "Unknown access control type: %d.\n",
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl state->ac_type);
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl break;
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl }
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce talloc_zfree(subreq);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce if (ret != EOK) {
9956e720e7f055afdb6ada141b4ab892bfa0930bPavel Reichl if (ret == ERR_ACCESS_DENIED) {
9956e720e7f055afdb6ada141b4ab892bfa0930bPavel Reichl DEBUG(SSSDBG_TRACE_FUNC, "Access was denied.\n");
9956e720e7f055afdb6ada141b4ab892bfa0930bPavel Reichl } else {
9956e720e7f055afdb6ada141b4ab892bfa0930bPavel Reichl DEBUG(SSSDBG_CRIT_FAILURE,
9956e720e7f055afdb6ada141b4ab892bfa0930bPavel Reichl "Error retrieving access check result.\n");
9956e720e7f055afdb6ada141b4ab892bfa0930bPavel Reichl }
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce tevent_req_error(req, ret);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose return;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose }
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose state->current_rule++;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl ret = sdap_access_check_next_rule(state, req);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce switch (ret) {
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce case EAGAIN:
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce case EOK:
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce tevent_req_done(req);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce default:
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce tevent_req_error(req, ret);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose }
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce}
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorceerrno_t sdap_access_recv(struct tevent_req *req)
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce{
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce TEVENT_REQ_RETURN_ON_ERROR(req);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return EOK;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose}
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
6742203fd84e97822cdddc4065402c15f3c5703fSumit Bose#define SHADOW_EXPIRE_MSG "Account expired according to shadow attributes"
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
6742203fd84e97822cdddc4065402c15f3c5703fSumit Bosestatic errno_t sdap_account_expired_shadow(struct pam_data *pd,
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce struct ldb_message *user_entry)
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose{
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose int ret;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose const char *val;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose long sp_expire;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose long today;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Performing access shadow check for user [%s]\n", pd->user);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose val = ldb_msg_find_attr_as_string(user_entry, SYSDB_SHADOWPW_EXPIRE, NULL);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose if (val == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_MINOR_FAILURE, "Shadow expire attribute not found. "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Access will be granted.\n");
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose return EOK;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose }
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose ret = string_to_shadowpw_days(val, &sp_expire);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Failed to retrieve shadow expire date.\n");
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose return ret;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose }
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose today = (long) (time(NULL) / (60 * 60 * 24));
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose if (sp_expire > 0 && today > sp_expire) {
6742203fd84e97822cdddc4065402c15f3c5703fSumit Bose
6742203fd84e97822cdddc4065402c15f3c5703fSumit Bose ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
6742203fd84e97822cdddc4065402c15f3c5703fSumit Bose sizeof(SHADOW_EXPIRE_MSG),
6742203fd84e97822cdddc4065402c15f3c5703fSumit Bose (const uint8_t *) SHADOW_EXPIRE_MSG);
6742203fd84e97822cdddc4065402c15f3c5703fSumit Bose if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
6742203fd84e97822cdddc4065402c15f3c5703fSumit Bose }
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ERR_ACCOUNT_EXPIRED;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose }
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose return EOK;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose}
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose#define UAC_ACCOUNTDISABLE 0x00000002
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose#define AD_NEVER_EXP 0x7fffffffffffffffLL
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose#define AD_TO_UNIX_TIME_CONST 11644473600LL
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose#define AD_DISABLE_MESSAGE "The user account is disabled on the AD server"
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose#define AD_EXPIRED_MESSAGE "The user account is expired on the AD server"
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bosestatic bool ad_account_expired(uint64_t expiration_time)
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose{
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose time_t now;
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose int err;
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose uint64_t nt_now;
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose if (expiration_time == 0 || expiration_time == AD_NEVER_EXP) {
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose return false;
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose }
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose now = time(NULL);
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose if (now == ((time_t) -1)) {
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose err = errno;
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "time failed [%d][%s].\n", err, strerror(err));
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose return true;
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose }
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose /* NT timestamps start at 1601-01-01 and use a 100ns base */
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose nt_now = (now + AD_TO_UNIX_TIME_CONST) * 1000 * 1000 * 10;
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose if (nt_now > expiration_time) {
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose return true;
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose }
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose return false;
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose}
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bosestatic errno_t sdap_account_expired_ad(struct pam_data *pd,
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce struct ldb_message *user_entry)
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose{
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose uint32_t uac;
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose uint64_t expiration_time;
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose int ret;
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Performing AD access check for user [%s]\n", pd->user);
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose uac = ldb_msg_find_attr_as_uint(user_entry, SYSDB_AD_USER_ACCOUNT_CONTROL,
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose 0);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "User account control for user [%s] is [%X].\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov pd->user, uac);
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose expiration_time = ldb_msg_find_attr_as_uint64(user_entry,
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose SYSDB_AD_ACCOUNT_EXPIRES, 0);
69c83119c0504fd1590299b8a4ecdabf86a8f18dLukas Slebodnik DEBUG(SSSDBG_TRACE_ALL,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Expiration time for user [%s] is [%"PRIu64"].\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov pd->user, expiration_time);
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose if (uac & UAC_ACCOUNTDISABLE) {
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose sizeof(AD_DISABLE_MESSAGE),
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose (const uint8_t *) AD_DISABLE_MESSAGE);
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose }
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ERR_ACCESS_DENIED;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose } else if (ad_account_expired(expiration_time)) {
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose sizeof(AD_EXPIRED_MESSAGE),
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose (const uint8_t *) AD_EXPIRED_MESSAGE);
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose }
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ERR_ACCOUNT_EXPIRED;
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose }
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose return EOK;
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose}
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose#define RHDS_LOCK_MSG "The user account is locked on the server"
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose
d73fcc5183a676aed4fd040714b87274248b784cSumit Bosestatic errno_t sdap_account_expired_rhds(struct pam_data *pd,
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce struct ldb_message *user_entry)
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose{
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose bool locked;
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose int ret;
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Performing RHDS access check for user [%s]\n", pd->user);
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose locked = ldb_msg_find_attr_as_bool(user_entry, SYSDB_NS_ACCOUNT_LOCK, false);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "Account for user [%s] is%s locked.\n", pd->user,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov locked ? "" : " not" );
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose if (locked) {
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose sizeof(RHDS_LOCK_MSG),
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose (const uint8_t *) RHDS_LOCK_MSG);
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose }
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ERR_ACCESS_DENIED;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce }
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose return EOK;
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose}
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose#define NDS_DISABLE_MSG "The user account is disabled on the server"
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose#define NDS_EXPIRED_MSG "The user account is expired"
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose#define NDS_TIME_MAP_MSG "The user account is not allowed at this time"
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
50b8a36b0932a510e825ed1ad8103f81ead2b7d8Pavel Reichlbool nds_check_expired(const char *exp_time_str)
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose{
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose time_t expire_time;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose time_t now;
08f83281cf4b0f35e8569851fae7364e140371f9Pavel Reichl errno_t ret;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose if (exp_time_str == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "ndsLoginExpirationTime is not set, access granted.\n");
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose return false;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose }
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
08f83281cf4b0f35e8569851fae7364e140371f9Pavel Reichl ret = sss_utc_to_time_t(exp_time_str, "%Y%m%d%H%M%SZ",
08f83281cf4b0f35e8569851fae7364e140371f9Pavel Reichl &expire_time);
08f83281cf4b0f35e8569851fae7364e140371f9Pavel Reichl if (ret != EOK) {
08f83281cf4b0f35e8569851fae7364e140371f9Pavel Reichl DEBUG(SSSDBG_MINOR_FAILURE, "sss_utc_to_time_t failed with %d:%s.\n",
08f83281cf4b0f35e8569851fae7364e140371f9Pavel Reichl ret, sss_strerror(ret));
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose return true;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose }
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose now = time(NULL);
57cd3443dcb7c073c5a00a9f2c3c3a3030ae2d3eLukas Slebodnik DEBUG(SSSDBG_TRACE_ALL,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Time info: tzname[0] [%s] tzname[1] [%s] timezone [%ld] "
937928d1161a4f7bd894cb365ada97569ab0f78fLukas Slebodnik "daylight [%d] now [%ld] expire_time [%ld].\n", tzname[0],
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov tzname[1], timezone, daylight, now, expire_time);
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose if (difftime(now, expire_time) > 0.0) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS, "NDS account expired.\n");
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose return true;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose }
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose return false;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose}
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose/* There is no real documentation of the byte string value of
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose * loginAllowedTimeMap, but some good example code in
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose * http://http://developer.novell.com/documentation/samplecode/extjndi_sample/CheckBind.java.html
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose */
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bosestatic bool nds_check_time_map(const struct ldb_val *time_map)
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose{
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose time_t now;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose struct tm *tm_now;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose size_t map_index;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose div_t q;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose uint8_t mask = 0;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose if (time_map == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "loginAllowedTimeMap is missing, access granted.\n");
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose return false;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose }
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose if (time_map->length != 42) {
0e65abe5cf2abf5d4b431cf6bd161b419f07901dLukas Slebodnik DEBUG(SSSDBG_FUNC_DATA,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Allowed time map has the wrong size, "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "got [%zu], expected 42.\n", time_map->length);
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose return true;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose }
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose now = time(NULL);
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose tm_now = gmtime(&now);
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose map_index = tm_now->tm_wday * 48 + tm_now->tm_hour * 2 +
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose (tm_now->tm_min < 30 ? 0 : 1);
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose if (map_index > 335) {
b8e6d0e6d6b9b56ef508578a2ae0078b5b7d22d0Lukas Slebodnik DEBUG(SSSDBG_CRIT_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Unexpected index value [%zu] for time map.\n", map_index);
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose return true;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose }
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose q = div(map_index, 8);
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose if (q.quot > 41 || q.quot < 0 || q.rem > 7 || q.rem < 0) {
b8e6d0e6d6b9b56ef508578a2ae0078b5b7d22d0Lukas Slebodnik DEBUG(SSSDBG_CRIT_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Unexpected result of div(), [%zu][%d][%d].\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov map_index, q.quot, q.rem);
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose return true;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose }
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose if (q.rem > 0) {
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose mask = 1 << q.rem;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose }
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose if (time_map->data[q.quot] & mask) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS, "Access allowed by time map.\n");
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose return false;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose }
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose return true;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose}
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bosestatic errno_t sdap_account_expired_nds(struct pam_data *pd,
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce struct ldb_message *user_entry)
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose{
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose bool locked = true;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose int ret;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose const char *exp_time_str;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose const struct ldb_val *time_map;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Performing NDS access check for user [%s]\n", pd->user);
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose locked = ldb_msg_find_attr_as_bool(user_entry, SYSDB_NDS_LOGIN_DISABLED,
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose false);
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL, "Account for user [%s] is%s disabled.\n", pd->user,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov locked ? "" : " not");
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose if (locked) {
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose sizeof(NDS_DISABLE_MSG),
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose (const uint8_t *) NDS_DISABLE_MSG);
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose }
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ERR_ACCESS_DENIED;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose } else {
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose exp_time_str = ldb_msg_find_attr_as_string(user_entry,
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose SYSDB_NDS_LOGIN_EXPIRATION_TIME,
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose NULL);
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose locked = nds_check_expired(exp_time_str);
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Account for user [%s] is%s expired.\n", pd->user,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov locked ? "" : " not");
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose if (locked) {
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose sizeof(NDS_EXPIRED_MSG),
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose (const uint8_t *) NDS_EXPIRED_MSG);
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose }
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ERR_ACCESS_DENIED;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose } else {
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose time_map = ldb_msg_find_ldb_val(user_entry,
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP);
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose locked = nds_check_time_map(time_map);
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_ALL,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Account for user [%s] is%s locked at this time.\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov pd->user, locked ? "" : " not");
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose if (locked) {
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose sizeof(NDS_TIME_MAP_MSG),
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose (const uint8_t *) NDS_TIME_MAP_MSG);
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose }
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ERR_ACCESS_DENIED;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose }
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose }
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose }
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose return EOK;
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose}
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorcestatic errno_t sdap_account_expired(struct sdap_access_ctx *access_ctx,
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce struct pam_data *pd,
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce struct ldb_message *user_entry)
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose{
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose const char *expire;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce int ret;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose expire = dp_opt_get_cstring(access_ctx->id_ctx->opts->basic,
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose SDAP_ACCOUNT_EXPIRE_POLICY);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose if (expire == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Missing account expire policy. Access denied\n");
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ERR_ACCESS_DENIED;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose } else {
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose if (strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_SHADOW) == 0) {
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = sdap_account_expired_shadow(pd, user_entry);
c820e6db26426c9f74a0e8f8ff9d9cf79d57406aPavel Reichl if (ret == ERR_ACCOUNT_EXPIRED) {
c820e6db26426c9f74a0e8f8ff9d9cf79d57406aPavel Reichl DEBUG(SSSDBG_TRACE_FUNC,
c820e6db26426c9f74a0e8f8ff9d9cf79d57406aPavel Reichl "sdap_account_expired_shadow: %s.\n", sss_strerror(ret));
c820e6db26426c9f74a0e8f8ff9d9cf79d57406aPavel Reichl } else if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "sdap_account_expired_shadow failed.\n");
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose }
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose } else if (strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_AD) == 0) {
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = sdap_account_expired_ad(pd, user_entry);
c820e6db26426c9f74a0e8f8ff9d9cf79d57406aPavel Reichl if (ret == ERR_ACCOUNT_EXPIRED || ret == ERR_ACCESS_DENIED) {
c820e6db26426c9f74a0e8f8ff9d9cf79d57406aPavel Reichl DEBUG(SSSDBG_TRACE_FUNC,
c820e6db26426c9f74a0e8f8ff9d9cf79d57406aPavel Reichl "sdap_account_expired_ad: %s.\n", sss_strerror(ret));
c820e6db26426c9f74a0e8f8ff9d9cf79d57406aPavel Reichl } else if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "sdap_account_expired_ad failed.\n");
22f4c1b86dcf5589e63f2ae043dc65a8f72f6f18Sumit Bose }
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose } else if (strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_RHDS) == 0 ||
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_IPA) == 0 ||
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_389DS) == 0) {
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = sdap_account_expired_rhds(pd, user_entry);
c820e6db26426c9f74a0e8f8ff9d9cf79d57406aPavel Reichl if (ret == ERR_ACCESS_DENIED) {
c820e6db26426c9f74a0e8f8ff9d9cf79d57406aPavel Reichl DEBUG(SSSDBG_TRACE_FUNC,
c820e6db26426c9f74a0e8f8ff9d9cf79d57406aPavel Reichl "sdap_account_expired_rhds: %s.\n", sss_strerror(ret));
c820e6db26426c9f74a0e8f8ff9d9cf79d57406aPavel Reichl } else if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "sdap_account_expired_rhds failed.\n");
d73fcc5183a676aed4fd040714b87274248b784cSumit Bose }
eedfc2cced329731c90317a5be3cd82a3749eb8aJakub Hrozek
eedfc2cced329731c90317a5be3cd82a3749eb8aJakub Hrozek if (ret == EOK &&
eedfc2cced329731c90317a5be3cd82a3749eb8aJakub Hrozek strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_IPA) == 0) {
eedfc2cced329731c90317a5be3cd82a3749eb8aJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC,
eedfc2cced329731c90317a5be3cd82a3749eb8aJakub Hrozek "IPA access control succeeded, checking AD "
eedfc2cced329731c90317a5be3cd82a3749eb8aJakub Hrozek "access control\n");
eedfc2cced329731c90317a5be3cd82a3749eb8aJakub Hrozek ret = sdap_account_expired_ad(pd, user_entry);
eedfc2cced329731c90317a5be3cd82a3749eb8aJakub Hrozek if (ret == ERR_ACCOUNT_EXPIRED || ret == ERR_ACCESS_DENIED) {
eedfc2cced329731c90317a5be3cd82a3749eb8aJakub Hrozek DEBUG(SSSDBG_TRACE_FUNC,
eedfc2cced329731c90317a5be3cd82a3749eb8aJakub Hrozek "sdap_account_expired_ad: %s.\n", sss_strerror(ret));
eedfc2cced329731c90317a5be3cd82a3749eb8aJakub Hrozek } else if (ret != EOK) {
eedfc2cced329731c90317a5be3cd82a3749eb8aJakub Hrozek DEBUG(SSSDBG_CRIT_FAILURE,
eedfc2cced329731c90317a5be3cd82a3749eb8aJakub Hrozek "sdap_account_expired_ad failed.\n");
eedfc2cced329731c90317a5be3cd82a3749eb8aJakub Hrozek }
eedfc2cced329731c90317a5be3cd82a3749eb8aJakub Hrozek }
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose } else if (strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_NDS) == 0) {
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = sdap_account_expired_nds(pd, user_entry);
c820e6db26426c9f74a0e8f8ff9d9cf79d57406aPavel Reichl if (ret == ERR_ACCESS_DENIED) {
c820e6db26426c9f74a0e8f8ff9d9cf79d57406aPavel Reichl DEBUG(SSSDBG_TRACE_FUNC,
c820e6db26426c9f74a0e8f8ff9d9cf79d57406aPavel Reichl "sdap_account_expired_nds: %s.\n", sss_strerror(ret));
c820e6db26426c9f74a0e8f8ff9d9cf79d57406aPavel Reichl } else if (ret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "sdap_account_expired_nds failed.\n");
37e7e93f1996cf50677cf59fd8af6938dd5d85b2Sumit Bose }
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose } else {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Unsupported LDAP account expire policy [%s]. "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Access denied.\n", expire);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = ERR_ACCESS_DENIED;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ret;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose}
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichlstatic errno_t perform_pwexpire_policy(TALLOC_CTX *mem_ctx,
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl struct sss_domain_info *domain,
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl struct pam_data *pd,
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl struct sdap_options *opts)
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl{
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl enum pwexpire pw_expire_type;
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl void *pw_expire_data;
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl errno_t ret;
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl char *dn;
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl ret = get_user_dn(mem_ctx, domain, opts, pd->user, &dn, &pw_expire_type,
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl &pw_expire_data);
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl if (ret != EOK) {
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl DEBUG(SSSDBG_MINOR_FAILURE, "get_user_dn returned %d:[%s].\n",
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl ret, sss_strerror(ret));
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl goto done;
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl }
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl ret = check_pwexpire_policy(pw_expire_type, pw_expire_data, pd,
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl domain->pwd_expiration_warning);
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl if (ret != EOK) {
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl DEBUG(SSSDBG_MINOR_FAILURE,
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl "check_pwexpire_policy returned %d:[%s].\n",
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl ret, sss_strerror(ret));
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl goto done;
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl }
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichldone:
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl return ret;
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl}
c9b0071bfcb8eb8c71e40248de46d23aceecc0f3Pavel Reichl
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bosestruct sdap_access_filter_req_ctx {
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose const char *username;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose const char *filter;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose struct tevent_context *ev;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose struct sdap_access_ctx *access_ctx;
443eb8217741df57d9f58f2098487b91e3404e71Jakub Hrozek struct sdap_options *opts;
443eb8217741df57d9f58f2098487b91e3404e71Jakub Hrozek struct sdap_id_conn_ctx *conn;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose struct sdap_id_op *sdap_op;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose struct sysdb_handle *handle;
249a28dbf31e11794c7f35d709c5561c1555898dSimo Sorce struct sss_domain_info *domain;
1a357c873baa79c0b82ab1d084f942cfcc8ba1c0Pavel Reichl /* cached result of access control checks */
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose bool cached_access;
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl const char *basedn;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose};
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
1a357c873baa79c0b82ab1d084f942cfcc8ba1c0Pavel Reichlstatic errno_t sdap_access_decide_offline(bool cached_ac);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bosestatic int sdap_access_filter_retry(struct tevent_req *req);
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlstatic void sdap_access_ppolicy_connect_done(struct tevent_req *subreq);
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlstatic errno_t sdap_access_ppolicy_get_lockout_step(struct tevent_req *req);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bosestatic void sdap_access_filter_connect_done(struct tevent_req *subreq);
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichlstatic void sdap_access_filter_done(struct tevent_req *req);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bosestatic struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx,
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose struct tevent_context *ev,
249a28dbf31e11794c7f35d709c5561c1555898dSimo Sorce struct be_ctx *be_ctx,
249a28dbf31e11794c7f35d709c5561c1555898dSimo Sorce struct sss_domain_info *domain,
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose struct sdap_access_ctx *access_ctx,
443eb8217741df57d9f58f2098487b91e3404e71Jakub Hrozek struct sdap_id_conn_ctx *conn,
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose const char *username,
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose struct ldb_message *user_entry)
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose{
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose struct sdap_access_filter_req_ctx *state;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose struct tevent_req *req;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose char *clean_username;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce errno_t ret = ERR_INTERNAL;
dd2f33603228005a44675f1484c294ea647dbce3Jakub Hrozek char *name;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose req = tevent_req_create(mem_ctx, &state, struct sdap_access_filter_req_ctx);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose if (req == NULL) {
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose return NULL;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose }
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose if (access_ctx->filter == NULL || *access_ctx->filter == '\0') {
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose /* If no filter is set, default to restrictive */
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "No filter set. Access is denied.\n");
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = ERR_ACCESS_DENIED;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce goto done;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose }
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose state->filter = NULL;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose state->username = username;
443eb8217741df57d9f58f2098487b91e3404e71Jakub Hrozek state->opts = access_ctx->id_ctx->opts;
443eb8217741df57d9f58f2098487b91e3404e71Jakub Hrozek state->conn = conn;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose state->ev = ev;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose state->access_ctx = access_ctx;
249a28dbf31e11794c7f35d709c5561c1555898dSimo Sorce state->domain = domain;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Performing access filter check for user [%s]\n", username);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose state->cached_access = ldb_msg_find_attr_as_bool(user_entry,
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose SYSDB_LDAP_ACCESS_FILTER,
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher false);
1a357c873baa79c0b82ab1d084f942cfcc8ba1c0Pavel Reichl
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher /* Ok, we have one result, check if we are online or offline */
249a28dbf31e11794c7f35d709c5561c1555898dSimo Sorce if (be_is_offline(be_ctx)) {
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher /* Ok, we're offline. Return from the cache */
1a357c873baa79c0b82ab1d084f942cfcc8ba1c0Pavel Reichl ret = sdap_access_decide_offline(state->cached_access);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce goto done;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl ret = sdap_get_basedn_user_entry(user_entry, state->username,
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl &state->basedn);
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl if (ret != EOK) {
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce goto done;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher /* Construct the filter */
7a9f3fc59a2041e868fa9524d8351ec48ec8c158Jakub Hrozek ret = sss_parse_internal_fqname(state, username, &name, NULL);
dd2f33603228005a44675f1484c294ea647dbce3Jakub Hrozek if (ret != EOK) {
dd2f33603228005a44675f1484c294ea647dbce3Jakub Hrozek DEBUG(SSSDBG_OP_FAILURE,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Could not parse [%s] into name and "
7a9f3fc59a2041e868fa9524d8351ec48ec8c158Jakub Hrozek "domain components, access might fail\n", username);
dd2f33603228005a44675f1484c294ea647dbce3Jakub Hrozek name = discard_const(username);
dd2f33603228005a44675f1484c294ea647dbce3Jakub Hrozek }
85e8cbdd79359ae1f330c8b84f7b58d4fc6fda6eStephen Gallagher
dd2f33603228005a44675f1484c294ea647dbce3Jakub Hrozek ret = sss_filter_sanitize(state, name, &clean_username);
85e8cbdd79359ae1f330c8b84f7b58d4fc6fda6eStephen Gallagher if (ret != EOK) {
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce goto done;
85e8cbdd79359ae1f330c8b84f7b58d4fc6fda6eStephen Gallagher }
85e8cbdd79359ae1f330c8b84f7b58d4fc6fda6eStephen Gallagher
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher state->filter = talloc_asprintf(
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher state,
a6dbe52dc824f8338d209ef5c56f9e345aeeb2feStephen Gallagher "(&(%s=%s)(objectclass=%s)%s)",
443eb8217741df57d9f58f2098487b91e3404e71Jakub Hrozek state->opts->user_map[SDAP_AT_USER_NAME].name,
85e8cbdd79359ae1f330c8b84f7b58d4fc6fda6eStephen Gallagher clean_username,
443eb8217741df57d9f58f2098487b91e3404e71Jakub Hrozek state->opts->user_map[SDAP_OC_USER].name,
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher state->access_ctx->filter);
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher if (state->filter == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_FATAL_FAILURE, "Could not construct access filter\n");
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = ENOMEM;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce goto done;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
85e8cbdd79359ae1f330c8b84f7b58d4fc6fda6eStephen Gallagher talloc_zfree(clean_username);
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "Checking filter against LDAP\n");
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
dcb44c39dda9699cdd6488fd116a51ced0687de3Jakub Hrozek state->sdap_op = sdap_id_op_create(state,
443eb8217741df57d9f58f2098487b91e3404e71Jakub Hrozek state->conn->conn_cache);
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom if (!state->sdap_op) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n");
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = ENOMEM;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce goto done;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose ret = sdap_access_filter_retry(req);
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom if (ret != EOK) {
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce goto done;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher return req;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorcedone:
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce if (ret == EOK) {
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce tevent_req_done(req);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce } else {
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce tevent_req_error(req, ret);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher tevent_req_post(req, ev);
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher return req;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher}
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
1a357c873baa79c0b82ab1d084f942cfcc8ba1c0Pavel Reichl/* Helper function,
1a357c873baa79c0b82ab1d084f942cfcc8ba1c0Pavel Reichl * cached_ac => access granted
1a357c873baa79c0b82ab1d084f942cfcc8ba1c0Pavel Reichl * !cached_ac => access denied
1a357c873baa79c0b82ab1d084f942cfcc8ba1c0Pavel Reichl */
1a357c873baa79c0b82ab1d084f942cfcc8ba1c0Pavel Reichlstatic errno_t sdap_access_decide_offline(bool cached_ac)
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom{
1a357c873baa79c0b82ab1d084f942cfcc8ba1c0Pavel Reichl if (cached_ac) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "Access granted by cached credentials\n");
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return EOK;
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom } else {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "Access denied by cached credentials\n");
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ERR_ACCESS_DENIED;
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom }
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom}
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bosestatic int sdap_access_filter_retry(struct tevent_req *req)
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom{
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose struct sdap_access_filter_req_ctx *state =
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose tevent_req_data(req, struct sdap_access_filter_req_ctx);
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom struct tevent_req *subreq;
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom int ret;
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret);
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom if (!subreq) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_OP_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "sdap_id_op_connect_send failed: %d (%s)\n", ret, strerror(ret));
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom return ret;
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom }
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose tevent_req_set_callback(subreq, sdap_access_filter_connect_done, req);
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom return EOK;
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom}
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bosestatic void sdap_access_filter_connect_done(struct tevent_req *subreq)
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher{
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher struct tevent_req *req = tevent_req_callback_data(subreq,
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher struct tevent_req);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose struct sdap_access_filter_req_ctx *state =
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose tevent_req_data(req, struct sdap_access_filter_req_ctx);
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom int ret, dp_error;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom ret = sdap_id_op_connect_recv(subreq, &dp_error);
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher talloc_zfree(subreq);
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher if (ret != EOK) {
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom if (dp_error == DP_ERR_OFFLINE) {
1a357c873baa79c0b82ab1d084f942cfcc8ba1c0Pavel Reichl ret = sdap_access_decide_offline(state->cached_access);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce if (ret == EOK) {
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce tevent_req_done(req);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom tevent_req_error(req, ret);
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom return;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher /* Connection to LDAP succeeded
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher * Send filter request
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher */
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher subreq = sdap_get_generic_send(state,
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher state->ev,
443eb8217741df57d9f58f2098487b91e3404e71Jakub Hrozek state->opts,
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom sdap_id_op_handle(state->sdap_op),
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher state->basedn,
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher LDAP_SCOPE_BASE,
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher state->filter, NULL,
a530a96721d8106a6839b6b643b0abc5d7a7b9e0Sumit Bose NULL, 0,
443eb8217741df57d9f58f2098487b91e3404e71Jakub Hrozek dp_opt_get_int(state->opts->basic,
2f3ee3f49019f5b60adbe073070f31e6e2d7c7abStephen Gallagher SDAP_SEARCH_TIMEOUT),
2f3ee3f49019f5b60adbe073070f31e6e2d7c7abStephen Gallagher false);
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher if (subreq == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Could not start LDAP communication\n");
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher tevent_req_error(req, EIO);
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher return;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichl tevent_req_set_callback(subreq, sdap_access_filter_done, req);
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher}
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
ed2136eebe3fbffccb8a5c548afdb815a46d5d39Pavel Reichlstatic void sdap_access_filter_done(struct tevent_req *subreq)
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher{
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce int ret, tret, dp_error;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher size_t num_results;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher bool found = false;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher struct sysdb_attrs **results;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher struct tevent_req *req =
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher tevent_req_callback_data(subreq, struct tevent_req);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose struct sdap_access_filter_req_ctx *state =
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose tevent_req_data(req, struct sdap_access_filter_req_ctx);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher ret = sdap_get_generic_recv(subreq, state,
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher &num_results, &results);
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher talloc_zfree(subreq);
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom ret = sdap_id_op_done(state->sdap_op, ret, &dp_error);
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher if (ret != EOK) {
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom if (dp_error == DP_ERR_OK) {
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom /* retry */
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce tret = sdap_access_filter_retry(req);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce if (tret == EOK) {
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom return;
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom }
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom } else if (dp_error == DP_ERR_OFFLINE) {
1a357c873baa79c0b82ab1d084f942cfcc8ba1c0Pavel Reichl ret = sdap_access_decide_offline(state->cached_access);
2a96981a0ac781d01e5bba473409ed2bdf4cd4e0Jakub Hrozek } else if (ret == ERR_INVALID_FILTER) {
46ebf4415306454e1d062b61a2495b7cdb821c0fPavel Reichl sss_log(SSS_LOG_ERR, MALFORMED_FILTER, state->filter);
46ebf4415306454e1d062b61a2495b7cdb821c0fPavel Reichl DEBUG(SSSDBG_CRIT_FAILURE, MALFORMED_FILTER, state->filter);
2a96981a0ac781d01e5bba473409ed2bdf4cd4e0Jakub Hrozek ret = ERR_ACCESS_DENIED;
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom } else {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "sdap_get_generic_send() returned error [%d][%s]\n",
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov ret, sss_strerror(ret));
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom }
ee3b4d1d0a6a438626e2dbbae3bf96d2d6faaf18eindenbom
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher goto done;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher /* Check the number of responses we got
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher * If it's exactly 1, we passed the check
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher * If it's < 1, we failed the check
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher * Anything else is an error
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher */
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher if (num_results < 1) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "User [%s] was not found with the specified filter. "
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Denying access.\n", state->username);
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher found = false;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher else if (results == NULL) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "num_results > 0, but results is NULL\n");
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = ERR_INTERNAL;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher goto done;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher else if (num_results > 1) {
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher /* It should not be possible to get more than one reply
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher * here, since we're doing a base-scoped search
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher */
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Received multiple replies\n");
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = ERR_INTERNAL;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher goto done;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher else { /* Ok, we got a single reply */
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher found = true;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher if (found) {
46ebf4415306454e1d062b61a2495b7cdb821c0fPavel Reichl /* Save "allow" to the cache for future offline access checks. */
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "Access granted by online lookup\n");
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = EOK;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher else {
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher /* Save "disallow" to the cache for future offline
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher * access checks.
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher */
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "Access denied by online lookup\n");
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = ERR_ACCESS_DENIED;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl tret = sdap_save_user_cache_bool(state->domain, state->username,
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl SYSDB_LDAP_ACCESS_FILTER, found);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce if (tret != EOK) {
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher /* Failing to save to the cache is non-fatal.
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher * Just return the result.
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher */
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set user access attribute\n");
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher goto done;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagherdone:
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher if (ret == EOK) {
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher tevent_req_done(req);
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher else {
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher tevent_req_error(req, ret);
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher }
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher}
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorcestatic errno_t sdap_access_filter_recv(struct tevent_req *req)
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose{
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose TEVENT_REQ_RETURN_ON_ERROR(req);
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose return EOK;
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose}
32266b2c1c6b8bf95f3ba8fd7f3ff2ef63d8fb9aSumit Bose
e1522a568dac91499f5f2039ef978a0a4ceeb3b3Sumit Bose#define AUTHR_SRV_MISSING_MSG "Authorized service attribute missing, " \
e1522a568dac91499f5f2039ef978a0a4ceeb3b3Sumit Bose "access denied"
e1522a568dac91499f5f2039ef978a0a4ceeb3b3Sumit Bose#define AUTHR_SRV_DENY_MSG "Access denied by authorized service attribute"
e1522a568dac91499f5f2039ef978a0a4ceeb3b3Sumit Bose#define AUTHR_SRV_NO_MATCH_MSG "Authorized service attribute has " \
e1522a568dac91499f5f2039ef978a0a4ceeb3b3Sumit Bose "no matching rule, access denied"
e1522a568dac91499f5f2039ef978a0a4ceeb3b3Sumit Bose
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorcestatic errno_t sdap_access_service(struct pam_data *pd,
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce struct ldb_message *user_entry)
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher{
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce errno_t ret, tret;
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher struct ldb_message_element *el;
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher unsigned int i;
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher char *service;
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher el = ldb_msg_find_element(user_entry, SYSDB_AUTHORIZED_SERVICE);
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher if (!el || el->num_values == 0) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Missing authorized services. Access denied\n");
e1522a568dac91499f5f2039ef978a0a4ceeb3b3Sumit Bose
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce tret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
e1522a568dac91499f5f2039ef978a0a4ceeb3b3Sumit Bose sizeof(AUTHR_SRV_MISSING_MSG),
e1522a568dac91499f5f2039ef978a0a4ceeb3b3Sumit Bose (const uint8_t *) AUTHR_SRV_MISSING_MSG);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce if (tret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
e1522a568dac91499f5f2039ef978a0a4ceeb3b3Sumit Bose }
e1522a568dac91499f5f2039ef978a0a4ceeb3b3Sumit Bose
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ERR_ACCESS_DENIED;
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher }
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = ENOENT;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher for (i = 0; i < el->num_values; i++) {
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher service = (char *)el->values[i].data;
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher if (service[0] == '!' &&
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher strcasecmp(pd->service, service+1) == 0) {
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher /* This service is explicitly denied */
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS, "Access denied by [%s]\n", service);
e1522a568dac91499f5f2039ef978a0a4ceeb3b3Sumit Bose
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce tret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
e1522a568dac91499f5f2039ef978a0a4ceeb3b3Sumit Bose sizeof(AUTHR_SRV_DENY_MSG),
e1522a568dac91499f5f2039ef978a0a4ceeb3b3Sumit Bose (const uint8_t *) AUTHR_SRV_DENY_MSG);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce if (tret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
e1522a568dac91499f5f2039ef978a0a4ceeb3b3Sumit Bose }
e1522a568dac91499f5f2039ef978a0a4ceeb3b3Sumit Bose
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher /* A denial trumps all. Break here */
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ERR_ACCESS_DENIED;
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher } else if (strcasecmp(pd->service, service) == 0) {
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher /* This service is explicitly allowed */
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS, "Access granted for [%s]\n", service);
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher /* We still need to loop through to make sure
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher * that it's not also explicitly denied
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher */
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = EOK;
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher } else if (strcmp("*", service) == 0) {
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher /* This user has access to all services */
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS, "Access granted to all services\n");
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher /* We still need to loop through to make sure
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher * that it's not also explicitly denied
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher */
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = EOK;
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher }
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher }
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce if (ret == ENOENT) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS, "No matching service rule found\n");
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce tret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO,
586793c2f95b574695c5520cf6f3ef019fb58519Stephen Gallagher sizeof(AUTHR_SRV_NO_MATCH_MSG),
586793c2f95b574695c5520cf6f3ef019fb58519Stephen Gallagher (const uint8_t *) AUTHR_SRV_NO_MATCH_MSG);
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce if (tret != EOK) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n");
586793c2f95b574695c5520cf6f3ef019fb58519Stephen Gallagher }
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = ERR_ACCESS_DENIED;
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher }
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ret;
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher}
2a2f642aae37e3f41cbbda162a74c2b946a4521fStephen Gallagher
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichlstatic errno_t sdap_save_user_cache_bool(struct sss_domain_info *domain,
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl const char *username,
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl const char *attr_name,
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl bool value)
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl{
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl errno_t ret;
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl struct sysdb_attrs *attrs;
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl attrs = sysdb_new_attrs(NULL);
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl if (attrs == NULL) {
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl ret = ENOMEM;
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up attrs\n");
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl goto done;
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl }
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl ret = sysdb_attrs_add_bool(attrs, attr_name, value);
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl if (ret != EOK) {
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up attrs\n");
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl goto done;
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl }
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl ret = sysdb_set_user_attr(domain, username, attrs, SYSDB_MOD_REP);
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl if (ret != EOK) {
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set user access attribute\n");
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl goto done;
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl }
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichldone:
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl talloc_free(attrs);
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl return ret;
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl}
4c38ed71727a9668cec4d3bd1bf8f7e77ac5e6c0Pavel Reichl
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorcestatic errno_t sdap_access_host(struct ldb_message *user_entry)
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman{
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman errno_t ret;
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman struct ldb_message_element *el;
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman unsigned int i;
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman char *host;
bf6f1b3d49e17b1adf0448c0b06e94b1e52ddffdLukas Slebodnik char hostname[HOST_NAME_MAX + 1];
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman el = ldb_msg_find_element(user_entry, SYSDB_AUTHORIZED_HOST);
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman if (!el || el->num_values == 0) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE, "Missing hosts. Access denied\n");
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ERR_ACCESS_DENIED;
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman }
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman
bf6f1b3d49e17b1adf0448c0b06e94b1e52ddffdLukas Slebodnik if (gethostname(hostname, HOST_NAME_MAX) == -1) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CRIT_FAILURE,
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov "Unable to get system hostname. Access denied\n");
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ERR_ACCESS_DENIED;
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman }
bf6f1b3d49e17b1adf0448c0b06e94b1e52ddffdLukas Slebodnik hostname[HOST_NAME_MAX] = '\0';
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman /* FIXME: PADL's pam_ldap also calls gethostbyname() on the hostname
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman * in some attempt to get aliases and/or FQDN for the machine.
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman * Not sure this is a good idea, but we might want to add it in
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman * order to be compatible...
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman */
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = ENOENT;
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman for (i = 0; i < el->num_values; i++) {
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman host = (char *)el->values[i].data;
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman if (host[0] == '!' &&
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman strcasecmp(hostname, host+1) == 0) {
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman /* This host is explicitly denied */
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS, "Access denied by [%s]\n", host);
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman /* A denial trumps all. Break here */
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ERR_ACCESS_DENIED;
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman } else if (strcasecmp(hostname, host) == 0) {
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman /* This host is explicitly allowed */
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS, "Access granted for [%s]\n", host);
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman /* We still need to loop through to make sure
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman * that it's not also explicitly denied
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman */
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = EOK;
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman } else if (strcmp("*", host) == 0) {
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman /* This user has access to all hosts */
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS, "Access granted to all hosts\n");
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman /* We still need to loop through to make sure
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman * that it's not also explicitly denied
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman */
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = EOK;
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman }
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman }
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce if (ret == ENOENT) {
83bf46f4066e3d5e838a32357c201de9bd6ecdfdNikolai Kondrashov DEBUG(SSSDBG_CONF_SETTINGS, "No matching host rule found\n");
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce ret = ERR_ACCESS_DENIED;
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman }
3612c73e7957721bcbf31d0118e2ac210eb46b88Pierre Ossman
dfd71fc92db940b2892cc996911cec03d7b6c52bSimo Sorce return ret;
35480afaefafb77b28d35b29039989ab888aafe9Stephen Gallagher}
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiyerrno_t sdap_access_rhost(struct ldb_message *user_entry, char *pam_rhost)
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy{
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy errno_t ret;
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy struct ldb_message_element *el;
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy char *be_rhost_rule;
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy unsigned int i;
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy /* If user_entry is NULL do not perform any checks */
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy if (user_entry == NULL) {
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy DEBUG(SSSDBG_CRIT_FAILURE,
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy "user_entry is NULL, that is not possible, "
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy "so we just reject access\n");
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy return ERR_ACCESS_DENIED;
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy }
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy /* If pam_rhost is NULL do not perform any checks */
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy if (pam_rhost == NULL) {
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy DEBUG(SSSDBG_CRIT_FAILURE,
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy "pam_rhost is NULL, no rhost check is possible\n");
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy return EOK;
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy }
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy /* When the access is local we get empty string as pam_rhost
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy in which case we should not evaluate rhost access rules */
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy /* FIXME: I think ideally should have LDAP to define what to do in
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy * this case */
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy if (pam_rhost[0] == '\0') {
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy DEBUG(SSSDBG_CRIT_FAILURE,
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy "pam_rhost is empty, possible local access, "
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy "no rhost check possible\n");
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy return EOK;
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy }
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy /* If rhost validation is enabled and entry has no relevant attribute -
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy * deny access */
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy el = ldb_msg_find_element(user_entry, SYSDB_AUTHORIZED_RHOST);
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy if (!el || el->num_values == 0) {
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy DEBUG(SSSDBG_CONF_SETTINGS, "Missing rhost entries. Access denied\n");
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy return ERR_ACCESS_DENIED;
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy }
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy ret = ENOENT;
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy for (i = 0; i < el->num_values; i++) {
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy be_rhost_rule = (char *)el->values[i].data;
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy if (be_rhost_rule[0] == '!'
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy && strcasecmp(pam_rhost, be_rhost_rule+1) == 0) {
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy /* This rhost is explicitly denied */
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy DEBUG(SSSDBG_CONF_SETTINGS,
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy "Access from [%s] denied by [%s]\n",
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy pam_rhost, be_rhost_rule);
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy /* A denial trumps all. Break here */
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy return ERR_ACCESS_DENIED;
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy } else if (strcasecmp(pam_rhost, be_rhost_rule) == 0) {
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy /* This rhost is explicitly allowed */
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy DEBUG(SSSDBG_CONF_SETTINGS,
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy "Access from [%s] granted by [%s]\n",
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy pam_rhost, be_rhost_rule);
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy /* We still need to loop through to make sure
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy * that it's not also explicitly denied
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy */
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy ret = EOK;
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy } else if (strcmp("*", be_rhost_rule) == 0) {
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy /* This user has access from anywhere */
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy DEBUG(SSSDBG_CONF_SETTINGS,
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy "Access from [%s] granted by [*]\n", pam_rhost);
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy /* We still need to loop through to make sure
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy * that it's not also explicitly denied
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy */
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy ret = EOK;
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy }
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy }
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy if (ret == ENOENT) {
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy DEBUG(SSSDBG_CONF_SETTINGS,
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy "No matching rhost rules found\n");
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy ret = ERR_ACCESS_DENIED;
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy }
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy return ret;
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy}
f34a8330c1615511795847b0a1454249d782db2aAlexey Kamenskiy
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlstatic void sdap_access_ppolicy_get_lockout_done(struct tevent_req *subreq);
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlstatic int sdap_access_ppolicy_retry(struct tevent_req *req);
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlstatic errno_t sdap_access_ppolicy_step(struct tevent_req *req);
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlstatic void sdap_access_ppolicy_step_done(struct tevent_req *subreq);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlstruct sdap_access_ppolicy_req_ctx {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl const char *username;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl const char *filter;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl struct tevent_context *ev;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl struct sdap_access_ctx *access_ctx;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl struct sdap_options *opts;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl struct sdap_id_conn_ctx *conn;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl struct sdap_id_op *sdap_op;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl struct sysdb_handle *handle;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl struct sss_domain_info *domain;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* cached results of access control checks */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl bool cached_access;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl const char *basedn;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* default DNs to ppolicy */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl const char **ppolicy_dns;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl unsigned int ppolicy_dns_index;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl enum sdap_pwpolicy_mode pwpol_mode;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl};
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichlstatic struct tevent_req *
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlsdap_access_ppolicy_send(TALLOC_CTX *mem_ctx,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct tevent_context *ev,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct be_ctx *be_ctx,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct sss_domain_info *domain,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct sdap_access_ctx *access_ctx,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct sdap_id_conn_ctx *conn,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl const char *username,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct ldb_message *user_entry,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl enum sdap_pwpolicy_mode pwpol_mode)
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl{
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct sdap_access_ppolicy_req_ctx *state;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl struct tevent_req *req;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl errno_t ret;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl req = tevent_req_create(mem_ctx,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl &state, struct sdap_access_ppolicy_req_ctx);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (req == NULL) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl return NULL;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->filter = NULL;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->username = username;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->opts = access_ctx->id_ctx->opts;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->conn = conn;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->ev = ev;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->access_ctx = access_ctx;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->domain = domain;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->ppolicy_dns_index = 0;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state->pwpol_mode = pwpol_mode;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_TRACE_FUNC,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl "Performing access ppolicy check for user [%s]\n", username);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->cached_access = ldb_msg_find_attr_as_bool(
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl user_entry, SYSDB_LDAP_ACCESS_CACHED_LOCKOUT, false);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* Ok, we have one result, check if we are online or offline */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (be_is_offline(be_ctx)) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* Ok, we're offline. Return from the cache */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = sdap_access_decide_offline(state->cached_access);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = sdap_get_basedn_user_entry(user_entry, state->username,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl &state->basedn);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (ret != EOK) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl DEBUG(SSSDBG_TRACE_FUNC, "Checking ppolicy against LDAP\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->sdap_op = sdap_id_op_create(state,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->conn->conn_cache);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (!state->sdap_op) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = ENOMEM;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl ret = sdap_access_ppolicy_retry(req);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (ret != EOK) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl return req;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichldone:
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (ret == EOK) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl tevent_req_done(req);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl } else {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl tevent_req_error(req, ret);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl tevent_req_post(req, ev);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl return req;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl}
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlstatic int sdap_access_ppolicy_retry(struct tevent_req *req)
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl{
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct sdap_access_ppolicy_req_ctx *state;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl struct tevent_req *subreq;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl int ret;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (!subreq) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_OP_FAILURE,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl "sdap_id_op_connect_send failed: %d (%s)\n",
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl ret, sss_strerror(ret));
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl return ret;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl tevent_req_set_callback(subreq, sdap_access_ppolicy_connect_done, req);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl return EOK;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl}
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichlstatic const char**
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichlget_default_ppolicy_dns(TALLOC_CTX *mem_ctx, struct sdap_domain *sdom)
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl{
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl const char **ppolicy_dns;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl int count = 0;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl int i;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl while(sdom->search_bases[count] != NULL) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl count++;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* +1 to have space for final NULL */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ppolicy_dns = talloc_array(mem_ctx, const char*, count + 1);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl for(i = 0; i < count; i++) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ppolicy_dns[i] = talloc_asprintf(mem_ctx, "cn=ppolicy,ou=policies,%s",
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl sdom->search_bases[i]->basedn);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ppolicy_dns[count] = NULL;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl return ppolicy_dns;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl}
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlstatic void sdap_access_ppolicy_connect_done(struct tevent_req *subreq)
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl{
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl struct tevent_req *req;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct sdap_access_ppolicy_req_ctx *state;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl int ret, dp_error;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl const char *ppolicy_dn;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl req = tevent_req_callback_data(subreq, struct tevent_req);
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = sdap_id_op_connect_recv(subreq, &dp_error);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl talloc_zfree(subreq);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (ret != EOK) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (dp_error == DP_ERR_OFFLINE) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = sdap_access_decide_offline(state->cached_access);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (ret == EOK) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl tevent_req_done(req);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl return;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl tevent_req_error(req, ret);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl return;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ppolicy_dn = dp_opt_get_string(state->opts->basic,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl SDAP_PWDLOCKOUT_DN);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* option was configured */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (ppolicy_dn != NULL) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->ppolicy_dns = talloc_array(state, const char*, 2);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (state->ppolicy_dns == NULL) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate ppolicy_dns.\n");
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl tevent_req_error(req, ERR_INTERNAL);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl return;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->ppolicy_dns[0] = ppolicy_dn;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->ppolicy_dns[1] = NULL;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl } else {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* try to determine default value */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_CONF_SETTINGS,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl "ldap_pwdlockout_dn was not defined in configuration file.\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->ppolicy_dns = get_default_ppolicy_dns(state, state->opts->sdom);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (state->ppolicy_dns == NULL) {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl tevent_req_error(req, ERR_INTERNAL);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl return;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* Connection to LDAP succeeded
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl * Send 'pwdLockout' request
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl */
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl ret = sdap_access_ppolicy_get_lockout_step(req);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (ret != EOK && ret != EAGAIN) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_CRIT_FAILURE,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl "sdap_access_ppolicy_get_lockout_step failed: [%d][%s]\n",
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl ret, sss_strerror(ret));
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl tevent_req_error(req, ERR_INTERNAL);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl return;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl if (ret == EOK) {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl tevent_req_done(req);
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl}
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichlstatic errno_t
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlsdap_access_ppolicy_get_lockout_step(struct tevent_req *req)
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl{
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl const char *attrs[] = { SYSDB_LDAP_ACCESS_LOCKOUT, NULL };
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct sdap_access_ppolicy_req_ctx *state;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl struct tevent_req *subreq;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl errno_t ret;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* no more DNs to try */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (state->ppolicy_dns[state->ppolicy_dns_index] == NULL) {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl DEBUG(SSSDBG_TRACE_FUNC, "No more DNs to try.\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = EOK;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_CONF_SETTINGS,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl "Trying to find out if ppolicy is enabled using the DN: %s\n",
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->ppolicy_dns[state->ppolicy_dns_index]);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl subreq = sdap_get_generic_send(state,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->ev,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->opts,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl sdap_id_op_handle(state->sdap_op),
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->ppolicy_dns[state->ppolicy_dns_index],
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl LDAP_SCOPE_BASE,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl NULL, attrs,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl NULL, 0,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl dp_opt_get_int(state->opts->basic,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl SDAP_SEARCH_TIMEOUT),
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl false);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (subreq == NULL) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_CRIT_FAILURE, "Could not start LDAP communication\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = EIO;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* try next basedn */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->ppolicy_dns_index++;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl tevent_req_set_callback(subreq, sdap_access_ppolicy_get_lockout_done, req);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = EAGAIN;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichldone:
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl return ret;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl}
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlstatic void sdap_access_ppolicy_get_lockout_done(struct tevent_req *subreq)
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl{
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl int ret, tret, dp_error;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl size_t num_results;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl bool pwdLockout = false;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl struct sysdb_attrs **results;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl struct tevent_req *req;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct sdap_access_ppolicy_req_ctx *state;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl req = tevent_req_callback_data(subreq, struct tevent_req);
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = sdap_get_generic_recv(subreq, state, &num_results, &results);
4113389146cde7034bec7980a7fdf0d50f4c7bf7Jakub Hrozek talloc_zfree(subreq);
d80412010e18d1f48aa402bf7e31a909008edb24Jakub Hrozek if (ret != EOK) {
d80412010e18d1f48aa402bf7e31a909008edb24Jakub Hrozek DEBUG(SSSDBG_OP_FAILURE, "Cannot retrieve ppolicy\n");
d80412010e18d1f48aa402bf7e31a909008edb24Jakub Hrozek ret = ERR_NETWORK_IO;
d80412010e18d1f48aa402bf7e31a909008edb24Jakub Hrozek goto done;
d80412010e18d1f48aa402bf7e31a909008edb24Jakub Hrozek }
d80412010e18d1f48aa402bf7e31a909008edb24Jakub Hrozek
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* Check the number of responses we got
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl * If it's exactly 1, we passed the check
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl * If it's < 1, we failed the check
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl * Anything else is an error
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* Didn't find ppolicy attribute */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (num_results < 1) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* Try using next $search_base */
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl ret = sdap_access_ppolicy_get_lockout_step(req);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (ret == EOK) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* No more search bases to try */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_CONF_SETTINGS,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl "[%s] was not found. Granting access.\n",
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl SYSDB_LDAP_ACCESS_LOCKOUT);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl } else {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (ret != EAGAIN) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_CRIT_FAILURE,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl "sdap_access_ppolicy_get_lockout_step failed: "
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl "[%d][%s]\n",
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl ret, sss_strerror(ret));
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl } else if (results == NULL) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_CRIT_FAILURE, "num_results > 0, but results is NULL\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = ERR_INTERNAL;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl } else if (num_results > 1) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* It should not be possible to get more than one reply
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl * here, since we're doing a base-scoped search
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_CRIT_FAILURE, "Received multiple replies\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = ERR_INTERNAL;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl } else { /* Ok, we got a single reply */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = sysdb_attrs_get_bool(results[0], SYSDB_LDAP_ACCESS_LOCKOUT,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl &pwdLockout);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (ret != EOK) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_MINOR_FAILURE,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl "Error reading %s: [%s]\n", SYSDB_LDAP_ACCESS_LOCKOUT,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl sss_strerror(ret));
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = ERR_INTERNAL;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (pwdLockout) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_TRACE_FUNC,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl "Password policy is enabled on LDAP server.\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* ppolicy is enabled => find out if account is locked */
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl ret = sdap_access_ppolicy_step(req);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (ret != EOK && ret != EAGAIN) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_CRIT_FAILURE,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl "sdap_access_ppolicy_step failed: [%d][%s].\n",
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl ret, sss_strerror(ret));
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl } else {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_TRACE_FUNC,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl "Password policy is disabled on LDAP server "
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl "- storing 'access granted' in sysdb.\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl tret = sdap_save_user_cache_bool(state->domain, state->username,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl SYSDB_LDAP_ACCESS_CACHED_LOCKOUT,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl true);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (tret != EOK) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* Failing to save to the cache is non-fatal.
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl * Just return the result.
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_CRIT_FAILURE,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl "Failed to set user locked attribute\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = EOK;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichldone:
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (ret != EAGAIN) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* release connection */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl tret = sdap_id_op_done(state->sdap_op, ret, &dp_error);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (tret != EOK) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_CRIT_FAILURE,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl "sdap_get_generic_send() returned error [%d][%s]\n",
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret, sss_strerror(ret));
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (ret == EOK) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl tevent_req_done(req);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl } else {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl tevent_req_error(req, ret);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl}
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlerrno_t sdap_access_ppolicy_step(struct tevent_req *req)
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl{
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl errno_t ret;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl struct tevent_req *subreq;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct sdap_access_ppolicy_req_ctx *state;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl const char *attrs[] = { SYSDB_LDAP_ACCESS_LOCKED_TIME,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl SYSDB_LDAP_ACESS_LOCKOUT_DURATION,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl NULL };
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl subreq = sdap_get_generic_send(state,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->ev,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->opts,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl sdap_id_op_handle(state->sdap_op),
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl state->basedn,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl LDAP_SCOPE_BASE,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl NULL, attrs,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl NULL, 0,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl dp_opt_get_int(state->opts->basic,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl SDAP_SEARCH_TIMEOUT),
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl false);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (subreq == NULL) {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl DEBUG(SSSDBG_CRIT_FAILURE, "sdap_access_ppolicy_send failed.\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = ENOMEM;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl tevent_req_set_callback(subreq, sdap_access_ppolicy_step_done, req);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = EAGAIN;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichldone:
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl return ret;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl}
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlstatic errno_t
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlis_account_locked(const char *pwdAccountLockedTime,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl const char *pwdAccountLockedDurationTime,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl enum sdap_pwpolicy_mode pwpol_mode,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl const char *username,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl bool *_locked)
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl{
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl errno_t ret;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl time_t lock_time;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl time_t duration;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl time_t now;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl bool locked;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl /* Default action is to consider account to be locked. */
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl locked = true;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl /* account is permanently locked */
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl if (strcasecmp(pwdAccountLockedTime,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl PERMANENTLY_LOCKED_ACCOUNT) == 0) {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl ret = EOK;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl goto done;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl }
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl switch(pwpol_mode) {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl case PWP_LOCKOUT_ONLY:
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl /* We do *not* care about exact value of account locked time, we
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl * only *do* care if the value is equal to
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl * PERMANENTLY_LOCKED_ACCOUNT, which means that account is locked
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl * permanently.
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl */
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl DEBUG(SSSDBG_TRACE_FUNC,
871f340834f25ca92a481718939164e708a70e29Pavel Reichl "Account of: %s is being blocked by password policy, "
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl "but value: [%s] value is ignored by SSSD.\n",
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl username, pwdAccountLockedTime);
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl locked = false;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl break;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl case PWP_LOCKOUT_EXPIRE:
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl /* Account may be locked out from natural reasons (too many attempts,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl * expired password). In this case, pwdAccountLockedTime is also set,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl * to the time of lock out.
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl */
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl ret = sss_utc_to_time_t(pwdAccountLockedTime, "%Y%m%d%H%M%SZ",
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl &lock_time);
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl if (ret != EOK) {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl DEBUG(SSSDBG_TRACE_FUNC, "sss_utc_to_time_t failed with %d:%s.\n",
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl ret, sss_strerror(ret));
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl goto done;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl }
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl now = time(NULL);
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl /* Account was NOT locked in past. */
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl if (difftime(lock_time, now) > 0.0) {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl locked = false;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl } else if (pwdAccountLockedDurationTime != NULL) {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl errno = 0;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl duration = strtouint32(pwdAccountLockedDurationTime, NULL, 0);
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl if (errno) {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl ret = errno;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl goto done;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl }
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl /* Lockout has expired */
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl if (duration != 0 && difftime(now, lock_time) > duration) {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl locked = false;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl }
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl }
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl break;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl case PWP_SENTINEL:
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl default:
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl DEBUG(SSSDBG_MINOR_FAILURE,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl "Unexpected value of password policy mode: %d.\n", pwpol_mode);
79ee5fbacd6ee4153fa59edf5b1ae55b4f020211Pavel Reichl ret = EINVAL;
79ee5fbacd6ee4153fa59edf5b1ae55b4f020211Pavel Reichl goto done;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl }
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl ret = EOK;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichldone:
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl if (ret == EOK) {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl *_locked = locked;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl }
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl return ret;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl}
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlstatic void sdap_access_ppolicy_step_done(struct tevent_req *subreq)
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl{
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl int ret, tret, dp_error;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl size_t num_results;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl bool locked = false;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl const char *pwdAccountLockedTime;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl const char *pwdAccountLockedDurationTime;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl struct sysdb_attrs **results;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl struct tevent_req *req;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl struct sdap_access_ppolicy_req_ctx *state;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl req = tevent_req_callback_data(subreq, struct tevent_req);
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = sdap_get_generic_recv(subreq, state, &num_results, &results);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl talloc_zfree(subreq);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = sdap_id_op_done(state->sdap_op, ret, &dp_error);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (ret != EOK) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (dp_error == DP_ERR_OK) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* retry */
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl tret = sdap_access_ppolicy_retry(req);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (tret == EOK) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl return;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl } else if (dp_error == DP_ERR_OFFLINE) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = sdap_access_decide_offline(state->cached_access);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl } else {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_CRIT_FAILURE,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl "sdap_get_generic_send() returned error [%d][%s]\n",
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret, sss_strerror(ret));
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* Check the number of responses we got
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl * If it's exactly 1, we passed the check
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl * If it's < 1, we failed the check
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl * Anything else is an error
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (num_results < 1) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_CONF_SETTINGS,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl "User [%s] was not found with the specified filter. "
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl "Denying access.\n", state->username);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl } else if (results == NULL) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_CRIT_FAILURE, "num_results > 0, but results is NULL\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = ERR_INTERNAL;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl } else if (num_results > 1) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* It should not be possible to get more than one reply
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl * here, since we're doing a base-scoped search
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_CRIT_FAILURE, "Received multiple replies\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = ERR_INTERNAL;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl } else { /* Ok, we got a single reply */
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl ret = sysdb_attrs_get_string(results[0], SYSDB_LDAP_ACESS_LOCKOUT_DURATION,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl &pwdAccountLockedDurationTime);
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl if (ret != EOK) {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl /* This attribute might not be set even if account is locked */
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl pwdAccountLockedDurationTime = NULL;
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl }
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = sysdb_attrs_get_string(results[0], SYSDB_LDAP_ACCESS_LOCKED_TIME,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl &pwdAccountLockedTime);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (ret == EOK) {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl ret = is_account_locked(pwdAccountLockedTime,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl pwdAccountLockedDurationTime,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state->pwpol_mode,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl state->username,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl &locked);
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl if (ret != EOK) {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl if (ret == ERR_TIMESPEC_NOT_SUPPORTED) {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl DEBUG(SSSDBG_MINOR_FAILURE,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl "timezone specifier in ppolicy is not supported\n");
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl } else {
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl DEBUG(SSSDBG_MINOR_FAILURE,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl "is_account_locked failed: %d:[%s].\n",
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl ret, sss_strerror(ret));
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl }
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl DEBUG(SSSDBG_MINOR_FAILURE,
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichl "Account will be considered to be locked.\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl locked = true;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl } else {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* Attribute SYSDB_LDAP_ACCESS_LOCKED_TIME in not be present unless
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl * user's account is blocked by password policy.
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_TRACE_INTERNAL,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl "Attribute %s failed to be obtained - [%d][%s].\n",
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl SYSDB_LDAP_ACCESS_LOCKED_TIME, ret, strerror(ret));
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (locked) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_TRACE_FUNC,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl "Access denied by online lookup - account is locked.\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = ERR_ACCESS_DENIED;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl } else {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_TRACE_FUNC,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl "Access granted by online lookup - account is not locked.\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl ret = EOK;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* Save '!locked' to the cache for future offline access checks.
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl * Locked == true => access denied,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl * Locked == false => access granted
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl tret = sdap_save_user_cache_bool(state->domain, state->username,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl SYSDB_LDAP_ACCESS_CACHED_LOCKOUT,
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl !locked);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (tret != EOK) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl /* Failing to save to the cache is non-fatal.
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl * Just return the result.
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl */
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set user locked attribute\n");
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl goto done;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichldone:
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl if (ret == EOK) {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl tevent_req_done(req);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl } else {
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl tevent_req_error(req, ret);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl }
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl}
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
13ec767e6ca3e435e119f1f07bda10eb213383f6Pavel Reichlstatic errno_t sdap_access_ppolicy_recv(struct tevent_req *req)
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl{
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl TEVENT_REQ_RETURN_ON_ERROR(req);
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl return EOK;
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl}
2a91d3dd0ce4387332db27bd1a0c0005c74f870ePavel Reichl
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichlstatic errno_t sdap_get_basedn_user_entry(struct ldb_message *user_entry,
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl const char *username,
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl const char **_basedn)
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl{
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl const char *basedn;
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl errno_t ret;
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl basedn = ldb_msg_find_attr_as_string(user_entry, SYSDB_ORIG_DN, NULL);
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl if (basedn == NULL) {
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl DEBUG(SSSDBG_CRIT_FAILURE,"Could not find originalDN for user [%s]\n",
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl username);
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl ret = EINVAL;
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl goto done;
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl }
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl *_basedn = basedn;
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl ret = EOK;
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichldone:
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl return ret;
719985a9e2aeaf2cba960f1525325ff125b7e19bPavel Reichl}