summaryrefslogtreecommitdiff
path: root/server/providers/ipa
diff options
context:
space:
mode:
Diffstat (limited to 'server/providers/ipa')
-rw-r--r--server/providers/ipa/ipa_access.c1823
-rw-r--r--server/providers/ipa/ipa_access.h66
-rw-r--r--server/providers/ipa/ipa_auth.c313
-rw-r--r--server/providers/ipa/ipa_auth.h32
-rw-r--r--server/providers/ipa/ipa_common.c597
-rw-r--r--server/providers/ipa/ipa_common.h83
-rw-r--r--server/providers/ipa/ipa_init.c293
-rw-r--r--server/providers/ipa/ipa_timerules.c1186
-rw-r--r--server/providers/ipa/ipa_timerules.h56
9 files changed, 0 insertions, 4449 deletions
diff --git a/server/providers/ipa/ipa_access.c b/server/providers/ipa/ipa_access.c
deleted file mode 100644
index 7dfe1fd9..00000000
--- a/server/providers/ipa/ipa_access.c
+++ /dev/null
@@ -1,1823 +0,0 @@
-/*
- SSSD
-
- IPA Backend Module -- Access control
-
- Authors:
- Sumit Bose <sbose@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <sys/param.h>
-#include <security/pam_modules.h>
-
-#include "util/util.h"
-#include "providers/ldap/sdap_async.h"
-#include "providers/ipa/ipa_common.h"
-#include "providers/ipa/ipa_access.h"
-#include "providers/ipa/ipa_timerules.h"
-
-#define IPA_HOST_MEMBEROF "memberOf"
-#define IPA_HOST_SERVERHOSTNAME "serverHostName"
-#define IPA_HOST_FQDN "fqdn"
-#define IPA_ACCESS_RULE_TYPE "accessRuleType"
-#define IPA_MEMBER_USER "memberUser"
-#define IPA_USER_CATEGORY "userCategory"
-#define IPA_SERVICE_NAME "serviceName"
-#define IPA_SOURCE_HOST "sourceHost"
-#define IPA_SOURCE_HOST_CATEGORY "sourceHostCategory"
-#define IPA_EXTERNAL_HOST "externalHost"
-#define IPA_ACCESS_TIME "accessTime"
-#define IPA_UNIQUE_ID "ipauniqueid"
-#define IPA_ENABLED_FLAG "ipaenabledflag"
-#define IPA_MEMBER_HOST "memberHost"
-#define IPA_HOST_CATEGORY "hostCategory"
-#define IPA_CN "cn"
-
-#define IPA_HOST_BASE_TMPL "cn=computers,cn=accounts,dc=%s"
-#define IPA_HBAC_BASE_TMPL "cn=hbac,dc=%s"
-
-#define SYSDB_HBAC_BASE_TMPL "cn=hbac,"SYSDB_TMPL_CUSTOM_BASE
-
-#define HBAC_RULES_SUBDIR "hbac_rules"
-#define HBAC_HOSTS_SUBDIR "hbac_hosts"
-
-static errno_t msgs2attrs_array(TALLOC_CTX *mem_ctx, size_t count,
- struct ldb_message **msgs,
- struct sysdb_attrs ***attrs)
-{
- int i;
- struct sysdb_attrs **a;
-
- a = talloc_array(mem_ctx, struct sysdb_attrs *, count);
- if (a == NULL) {
- DEBUG(1, ("talloc_array failed.\n"));
- return ENOMEM;
- }
-
- for (i = 0; i < count; i++) {
- a[i] = talloc(a, struct sysdb_attrs);
- if (a[i] == NULL) {
- DEBUG(1, ("talloc_array failed.\n"));
- talloc_free(a);
- return ENOMEM;
- }
- a[i]->num = msgs[i]->num_elements;
- a[i]->a = talloc_steal(a[i], msgs[i]->elements);
- }
-
- *attrs = a;
-
- return EOK;
-}
-
-static void ipa_access_reply(struct be_req *be_req, int pam_status)
-{
- struct pam_data *pd;
- pd = talloc_get_type(be_req->req_data, struct pam_data);
- pd->pam_status = pam_status;
-
- if (pam_status == PAM_SUCCESS) {
- be_req->fn(be_req, DP_ERR_OK, pam_status, NULL);
- } else {
- be_req->fn(be_req, DP_ERR_FATAL, pam_status, NULL);
- }
-}
-
-struct hbac_get_user_info_state {
- struct tevent_context *ev;
- struct be_ctx *be_ctx;;
- struct sysdb_handle *handle;
-
- const char *user;
- const char *user_orig_dn;
- struct ldb_dn *user_dn;
- size_t groups_count;
- const char **groups;
-};
-
-static void search_user_done(struct tevent_req *subreq);
-static void search_groups_done(struct tevent_req *subreq);
-
-struct tevent_req *hbac_get_user_info_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct be_ctx *be_ctx,
- const char *user)
-{
- struct tevent_req *req = NULL;
- struct tevent_req *subreq = NULL;
- struct hbac_get_user_info_state *state;
- int ret;
- const char **attrs;
-
- req = tevent_req_create(memctx, &state, struct hbac_get_user_info_state);
- if (req == NULL) {
- DEBUG(1, ("tevent_req_create failed.\n"));
- return NULL;
- }
-
- state->ev = ev;
- state->be_ctx = be_ctx;
- state->handle = NULL;
- state->user = user;
- state->user_orig_dn = NULL;
- state->user_dn = NULL;
- state->groups_count = 0;
- state->groups = NULL;
-
- attrs = talloc_array(state, const char *, 2);
- if (attrs == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- attrs[0] = SYSDB_ORIG_DN;
- attrs[1] = NULL;
-
- subreq = sysdb_search_user_by_name_send(state, ev, be_ctx->sysdb, NULL,
- be_ctx->domain, user, attrs);
- if (subreq == NULL) {
- DEBUG(1, ("sysdb_search_user_by_name_send failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
-
- tevent_req_set_callback(subreq, search_user_done, req);
-
- return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void search_user_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct hbac_get_user_info_state *state = tevent_req_data(req,
- struct hbac_get_user_info_state);
- int ret;
- const char **attrs;
- const char *dummy;
- struct ldb_message *user_msg;
-
-
- ret = sysdb_search_user_recv(subreq, state, &user_msg);
- talloc_zfree(subreq);
- if (ret != EOK) {
- tevent_req_error(req, ret);
- return;
- }
-
- DEBUG(9, ("Found user info for user [%s].\n", state->user));
- state->user_dn = talloc_steal(state, user_msg->dn);
- dummy = ldb_msg_find_attr_as_string(user_msg, SYSDB_ORIG_DN, NULL);
- if (dummy == NULL) {
- DEBUG(1, ("Original DN of user [%s] not available.\n", state->user));
- ret = EINVAL;
- goto failed;
- }
- state->user_orig_dn = talloc_strdup(state, dummy);
- if (state->user_dn == NULL) {
- DEBUG(1, ("talloc_strdup failed.\n"));
- ret = ENOMEM;
- goto failed;
- }
- DEBUG(9, ("Found original DN [%s] for user [%s].\n", state->user_orig_dn,
- state->user));
-
- attrs = talloc_array(state, const char *, 2);
- if (attrs == NULL) {
- DEBUG(1, ("talloc_array failed.\n"));
- ret = ENOMEM;
- goto failed;
- }
- attrs[0] = SYSDB_ORIG_DN;
- attrs[1] = NULL;
-
- subreq = sysdb_asq_search_send(state, state->ev, state->be_ctx->sysdb, NULL,
- state->be_ctx->domain, state->user_dn, NULL,
- SYSDB_MEMBEROF, attrs);
- if (subreq == NULL) {
- DEBUG(1, ("sysdb_asq_search_send failed.\n"));
- ret = ENOMEM;
- goto failed;
- }
-
- tevent_req_set_callback(subreq, search_groups_done, req);
- return;
-
-failed:
- tevent_req_error(req, ret);
- return;
-}
-
-static void search_groups_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct hbac_get_user_info_state *state = tevent_req_data(req,
- struct hbac_get_user_info_state);
- int ret;
- int i;
- struct ldb_message **msg;
-
- ret = sysdb_asq_search_recv(subreq, state, &state->groups_count, &msg);
- talloc_zfree(subreq);
- if (ret != EOK) {
- tevent_req_error(req, ret);
- return;
- }
-
- if (state->groups_count == 0) {
- tevent_req_done(req);
- return;
- }
-
- state->groups = talloc_array(state, const char *, state->groups_count);
- if (state->groups == NULL) {
- DEBUG(1, ("talloc_groups failed.\n"));
- ret = ENOMEM;
- goto failed;
- }
-
- for(i = 0; i < state->groups_count; i++) {
- if (msg[i]->num_elements != 1) {
- DEBUG(1, ("Unexpected number of elements.\n"));
- ret = EINVAL;
- goto failed;
- }
-
- if (msg[i]->elements[0].num_values != 1) {
- DEBUG(1, ("Unexpected number of values.\n"));
- ret = EINVAL;
- goto failed;
- }
-
- state->groups[i] = talloc_strndup(state->groups,
- (const char *) msg[i]->elements[0].values[0].data,
- msg[i]->elements[0].values[0].length);
- if (state->groups[i] == NULL) {
- DEBUG(1, ("talloc_strndup failed.\n"));
- ret = ENOMEM;
- goto failed;
- }
-
- DEBUG(9, ("Found group [%s].\n", state->groups[i]));
- }
-
- tevent_req_done(req);
- return;
-
-failed:
- talloc_free(state->groups);
- tevent_req_error(req, ret);
- return;
-}
-
-static int hbac_get_user_info_recv(struct tevent_req *req, TALLOC_CTX *memctx,
- const char **user_dn, size_t *groups_count,
- const char ***groups)
-{
- struct hbac_get_user_info_state *state = tevent_req_data(req,
- struct hbac_get_user_info_state);
- int i;
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- *user_dn = talloc_steal(memctx, state->user_orig_dn);
- *groups_count = state->groups_count;
- for (i = 0; i < state->groups_count; i++) {
- talloc_steal(memctx, state->groups[i]);
- }
- *groups = talloc_steal(memctx, state->groups);
-
- return EOK;
-}
-
-
-struct hbac_get_host_info_state {
- struct tevent_context *ev;
- struct sdap_id_ctx *sdap_ctx;
- struct sysdb_ctx *sysdb;
- struct sysdb_handle *handle;
- bool offline;
-
- char *host_filter;
- char *host_search_base;
- const char **host_attrs;
-
- struct sysdb_attrs **host_reply_list;
- size_t host_reply_count;
- size_t current_item;
- struct hbac_host_info **hbac_host_info;
-};
-
-static void hbac_get_host_info_connect_done(struct tevent_req *subreq);
-static void hbac_get_host_memberof_done(struct tevent_req *subreq);
-static void hbac_get_host_info_sysdb_transaction_started(struct tevent_req *subreq);
-static void hbac_get_host_info_store_prepare(struct tevent_req *req);
-static void hbac_get_host_info_store_done(struct tevent_req *subreq);
-
-static struct tevent_req *hbac_get_host_info_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- bool offline,
- struct sdap_id_ctx *sdap_ctx,
- struct sysdb_ctx *sysdb,
- const char *ipa_domain,
- const char **hostnames)
-{
- struct tevent_req *req = NULL;
- struct tevent_req *subreq = NULL;
- struct hbac_get_host_info_state *state;
- int ret;
- int i;
-
- if (hostnames == NULL || ipa_domain == NULL) {
- DEBUG(1, ("Missing hostnames or domain.\n"));
- return NULL;
- }
-
- req = tevent_req_create(memctx, &state, struct hbac_get_host_info_state);
- if (req == NULL) {
- DEBUG(1, ("tevent_req_create failed.\n"));
- return NULL;
- }
-
- state->ev = ev;
- state->sdap_ctx = sdap_ctx;
- state->sysdb = sysdb;
- state->handle = NULL;
- state->offline = offline;
-
- state->host_reply_list = NULL;
- state->host_reply_count = 0;
- state->current_item = 0;
- state->hbac_host_info = NULL;
-
- state->host_filter = talloc_asprintf(state, "(|");
- if (state->host_filter == NULL) {
- DEBUG(1, ("Failed to create filter.\n"));
- ret = ENOMEM;
- goto fail;
- }
- for (i = 0; hostnames[i] != NULL; i++) {
- state->host_filter = talloc_asprintf_append(state->host_filter,
- "(&(objectclass=ipaHost)"
- "(|(fqdn=%s)(serverhostname=%s)))",
- hostnames[i], hostnames[i]);
- if (state->host_filter == NULL) {
- ret = ENOMEM;
- goto fail;
- }
- }
- state->host_filter = talloc_asprintf_append(state->host_filter, ")");
- if (state->host_filter == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- state->host_search_base = talloc_asprintf(state, IPA_HOST_BASE_TMPL,
- ipa_domain);
- if (state->host_search_base == NULL) {
- DEBUG(1, ("Failed to create host search base.\n"));
- ret = ENOMEM;
- goto fail;
- }
-
- state->host_attrs = talloc_array(state, const char *, 7);
- if (state->host_attrs == NULL) {
- DEBUG(1, ("Failed to allocate host attribute list.\n"));
- ret = ENOMEM;
- goto fail;
- }
- state->host_attrs[0] = IPA_HOST_MEMBEROF;
- state->host_attrs[1] = IPA_HOST_SERVERHOSTNAME;
- state->host_attrs[2] = IPA_HOST_FQDN;
- state->host_attrs[3] = "objectClass";
- state->host_attrs[4] = SYSDB_ORIG_DN;
- state->host_attrs[5] = SYSDB_ORIG_MEMBEROF;
- state->host_attrs[6] = NULL;
-
- if (offline) {
- subreq = sysdb_search_custom_send(state, state->ev, state->sysdb, NULL,
- state->sdap_ctx->be->domain,
- state->host_filter, HBAC_HOSTS_SUBDIR,
- state->host_attrs);
- if (subreq == NULL) {
- DEBUG(1, ("sysdb_search_custom_send.\n"));
- ret = ENOMEM;
- goto fail;
- }
-
- tevent_req_set_callback(subreq, hbac_get_host_memberof_done, req);
-
- return req;
- }
-
- if (sdap_ctx->gsh == NULL || ! sdap_ctx->gsh->connected) {
- if (sdap_ctx->gsh != NULL) {
- talloc_zfree(sdap_ctx->gsh);
- }
-
- subreq = sdap_cli_connect_send(state, ev, sdap_ctx->opts,
- sdap_ctx->be, sdap_ctx->service, NULL);
- if (!subreq) {
- DEBUG(1, ("sdap_cli_connect_send failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
-
- tevent_req_set_callback(subreq, hbac_get_host_info_connect_done, req);
-
- return req;
- }
-
- subreq = sdap_get_generic_send(state, state->ev,
- state->sdap_ctx->opts,
- state->sdap_ctx->gsh,
- state->host_search_base,
- LDAP_SCOPE_SUB,
- state->host_filter,
- state->host_attrs,
- NULL, 0);
-
- if (subreq == NULL) {
- DEBUG(1, ("sdap_get_generic_send failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
-
- tevent_req_set_callback(subreq, hbac_get_host_memberof_done, req);
-
- return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void hbac_get_host_info_connect_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct hbac_get_host_info_state *state = tevent_req_data(req,
- struct hbac_get_host_info_state);
- int ret;
-
- ret = sdap_cli_connect_recv(subreq, state->sdap_ctx, &state->sdap_ctx->gsh,
- NULL);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- subreq = sdap_get_generic_send(state, state->ev,
- state->sdap_ctx->opts,
- state->sdap_ctx->gsh,
- state->host_search_base,
- LDAP_SCOPE_SUB,
- state->host_filter,
- state->host_attrs,
- NULL, 0);
-
- if (subreq == NULL) {
- DEBUG(1, ("sdap_get_generic_send failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
-
- tevent_req_set_callback(subreq, hbac_get_host_memberof_done, req);
-
- return;
-
-fail:
- tevent_req_error(req, ret);
- return;
-}
-
-static void hbac_get_host_memberof_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct hbac_get_host_info_state *state = tevent_req_data(req,
- struct hbac_get_host_info_state);
- int ret;
- int i;
- int v;
- struct ldb_message_element *el;
- struct hbac_host_info **hhi;
- struct ldb_message **msgs;
-
- if (state->offline) {
- ret = sysdb_search_custom_recv(subreq, state, &state->host_reply_count,
- &msgs);
- } else {
- ret = sdap_get_generic_recv(subreq, state, &state->host_reply_count,
- &state->host_reply_list);
- }
- talloc_zfree(subreq);
- if (ret != EOK) {
- tevent_req_error(req, ret);
- return;
- }
-
- if (state->host_reply_count == 0) {
- DEBUG(1, ("No hosts not found in IPA server.\n"));
- ret = ENOENT;
- goto fail;
- }
-
- if (state->offline) {
- ret = msgs2attrs_array(state, state->host_reply_count, msgs,
- &state->host_reply_list);
- talloc_zfree(msgs);
- if (ret != EOK) {
- DEBUG(1, ("msgs2attrs_array failed.\n"));
- goto fail;
- }
- }
-
- hhi = talloc_array(state, struct hbac_host_info *, state->host_reply_count + 1);
- if (hhi == NULL) {
- DEBUG(1, ("talloc_array failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
- memset(hhi, 0,
- sizeof(struct hbac_host_info *) * (state->host_reply_count + 1));
-
- for (i = 0; i < state->host_reply_count; i++) {
- hhi[i] = talloc_zero(hhi, struct hbac_host_info);
- if (hhi[i] == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- ret = sysdb_attrs_get_el(state->host_reply_list[i], SYSDB_ORIG_DN, &el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- goto fail;
- }
- if (el->num_values == 0) {
- ret = EINVAL;
- goto fail;
- }
- DEBUG(9, ("OriginalDN: [%.*s].\n", el->values[0].length,
- (char *)el->values[0].data));
- hhi[i]->dn = talloc_strndup(hhi, (char *)el->values[0].data,
- el->values[0].length);
- if (hhi[i]->dn == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- ret = sysdb_attrs_get_el(state->host_reply_list[i],
- IPA_HOST_SERVERHOSTNAME, &el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- goto fail;
- }
- if (el->num_values == 0) {
- ret = EINVAL;
- goto fail;
- }
- DEBUG(9, ("ServerHostName: [%.*s].\n", el->values[0].length,
- (char *)el->values[0].data));
- hhi[i]->serverhostname = talloc_strndup(hhi, (char *)el->values[0].data,
- el->values[0].length);
- if (hhi[i]->serverhostname == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- ret = sysdb_attrs_get_el(state->host_reply_list[i],
- IPA_HOST_FQDN, &el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- goto fail;
- }
- if (el->num_values == 0) {
- ret = EINVAL;
- goto fail;
- }
- DEBUG(9, ("FQDN: [%.*s].\n", el->values[0].length,
- (char *)el->values[0].data));
- hhi[i]->fqdn = talloc_strndup(hhi, (char *)el->values[0].data,
- el->values[0].length);
- if (hhi[i]->fqdn == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- ret = sysdb_attrs_get_el(state->host_reply_list[i],
- state->offline ? SYSDB_ORIG_MEMBEROF :
- IPA_HOST_MEMBEROF,
- &el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- goto fail;
- }
-
- hhi[i]->memberof = talloc_array(hhi, const char *, el->num_values + 1);
- if (hhi[i]->memberof == NULL) {
- ret = ENOMEM;
- goto fail;
- }
- memset(hhi[i]->memberof, 0,
- sizeof(const char *) * (el->num_values + 1));
-
- for(v = 0; v < el->num_values; v++) {
- DEBUG(9, ("%s: [%.*s].\n", IPA_HOST_MEMBEROF, el->values[v].length,
- (const char *)el->values[v].data));
- hhi[i]->memberof[v] = talloc_strndup(hhi,
- (const char *)el->values[v].data,
- el->values[v].length);
- if (hhi[i]->memberof[v] == NULL) {
- ret = ENOMEM;
- goto fail;
- }
- }
- }
-
- state->hbac_host_info = hhi;
-
- if (state->offline) {
- tevent_req_done(req);
- return;
- }
-
- subreq = sysdb_transaction_send(state, state->ev, state->sysdb);
- if (subreq == NULL) {
- DEBUG(1, ("sysdb_transaction_send failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, hbac_get_host_info_sysdb_transaction_started, req);
- return;
-
-fail:
- tevent_req_error(req, ret);
- return;
-}
-
-static void hbac_get_host_info_sysdb_transaction_started(
- struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct hbac_get_host_info_state *state = tevent_req_data(req,
- struct hbac_get_host_info_state);
- int ret;
-
- ret = sysdb_transaction_recv(subreq, state, &state->handle);
- talloc_zfree(subreq);
- if (ret != EOK) {
- tevent_req_error(req, ret);
- return;
- }
-
- state->current_item = 0;
- hbac_get_host_info_store_prepare(req);
- return;
-}
-
-static void hbac_get_host_info_store_prepare(struct tevent_req *req)
-{
- struct hbac_get_host_info_state *state = tevent_req_data(req,
- struct hbac_get_host_info_state);
- int ret;
- char *object_name;
- struct ldb_message_element *el;
- struct tevent_req *subreq;
-
- if (state->current_item < state->host_reply_count) {
- ret = sysdb_attrs_get_el(state->host_reply_list[state->current_item],
- IPA_HOST_FQDN, &el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- goto fail;
- }
- if (el->num_values == 0) {
- ret = EINVAL;
- goto fail;
- }
- object_name = talloc_strndup(state, (const char *)el->values[0].data,
- el->values[0].length);
- if (object_name == NULL) {
- ret = ENOMEM;
- goto fail;
- }
- DEBUG(9, ("Fqdn [%s].\n", object_name));
-
-
- ret = sysdb_attrs_replace_name(
- state->host_reply_list[state->current_item],
- IPA_HOST_MEMBEROF, SYSDB_ORIG_MEMBEROF);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_replace_name failed.\n"));
- goto fail;
- }
-
- subreq = sysdb_store_custom_send(state, state->ev,
- state->handle,
- state->sdap_ctx->be->domain,
- object_name,
- HBAC_HOSTS_SUBDIR,
- state->host_reply_list[state->current_item]);
-
- if (subreq == NULL) {
- DEBUG(1, ("sysdb_store_custom_send failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
-
- tevent_req_set_callback(subreq, hbac_get_host_info_store_done, req);
- return;
- }
-
- subreq = sysdb_transaction_commit_send(state, state->ev, state->handle);
- if (subreq == NULL) {
- DEBUG(1, ("sysdb_transaction_commit_send failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, sysdb_transaction_complete, req);
-
- return;
-
-fail:
- tevent_req_error(req, ret);
- return;
-}
-
-static void hbac_get_host_info_store_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct hbac_get_host_info_state *state = tevent_req_data(req,
- struct hbac_get_host_info_state);
- int ret;
-
- ret = sysdb_store_custom_recv(subreq);
- talloc_zfree(subreq);
- if (ret != EOK) {
- tevent_req_error(req, ret);
- return;
- }
-
- state->current_item++;
- hbac_get_host_info_store_prepare(req);
-}
-
-static int hbac_get_host_info_recv(struct tevent_req *req, TALLOC_CTX *memctx,
- struct hbac_host_info ***hhi)
-{
- struct hbac_get_host_info_state *state = tevent_req_data(req,
- struct hbac_get_host_info_state);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- *hhi = talloc_steal(memctx, state->hbac_host_info);
- return EOK;
-}
-
-
-struct hbac_get_rules_state {
- struct tevent_context *ev;
- struct sdap_id_ctx *sdap_ctx;
- struct sysdb_ctx *sysdb;
- struct sysdb_handle *handle;
- bool offline;
-
- const char *host_dn;
- const char **memberof;
- char *hbac_filter;
- char *hbac_search_base;
- const char **hbac_attrs;
-
- struct ldb_message *old_rules;
- struct sysdb_attrs **hbac_reply_list;
- size_t hbac_reply_count;
- int current_item;
-};
-
-static void hbac_get_rules_connect_done(struct tevent_req *subreq);
-static void hbac_rule_get_done(struct tevent_req *subreq);
-static void hbac_rule_sysdb_transaction_started(struct tevent_req *subreq);
-static void hbac_rule_sysdb_delete_done(struct tevent_req *subreq);
-static void hbac_rule_store_prepare(struct tevent_req *req);
-static void hbac_rule_store_done(struct tevent_req *subreq);
-
-static struct tevent_req *hbac_get_rules_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- bool offline,
- struct sdap_id_ctx *sdap_ctx,
- struct sysdb_ctx *sysdb,
- const char *ipa_domain,
- const char *host_dn,
- const char **memberof)
-{
- struct tevent_req *req = NULL;
- struct tevent_req *subreq = NULL;
- struct hbac_get_rules_state *state;
- int ret;
- int i;
-
- if (host_dn == NULL || ipa_domain == NULL) {
- DEBUG(1, ("Missing host_dn or domain.\n"));
- return NULL;
- }
-
- req = tevent_req_create(memctx, &state, struct hbac_get_rules_state);
- if (req == NULL) {
- DEBUG(1, ("tevent_req_create failed.\n"));
- return NULL;
- }
-
- state->ev = ev;
- state->offline = offline;
- state->sdap_ctx = sdap_ctx;
- state->sysdb = sysdb;
- state->handle = NULL;
- state->host_dn = host_dn;
- state->memberof = memberof;
-
- state->old_rules = NULL;
- state->hbac_reply_list = NULL;
- state->hbac_reply_count = 0;
- state->current_item = 0;
-
- state->hbac_search_base = talloc_asprintf(state, IPA_HBAC_BASE_TMPL,
- ipa_domain);
- if (state->hbac_search_base == NULL) {
- DEBUG(1, ("Failed to create HBAC search base.\n"));
- ret = ENOMEM;
- goto fail;
- }
-
- state->hbac_attrs = talloc_array(state, const char *, 16);
- if (state->hbac_attrs == NULL) {
- DEBUG(1, ("Failed to allocate HBAC attribute list.\n"));
- ret = ENOMEM;
- goto fail;
- }
- state->hbac_attrs[0] = IPA_ACCESS_RULE_TYPE;
- state->hbac_attrs[1] = IPA_MEMBER_USER;
- state->hbac_attrs[2] = IPA_USER_CATEGORY;
- state->hbac_attrs[3] = IPA_SERVICE_NAME;
- state->hbac_attrs[4] = IPA_SOURCE_HOST;
- state->hbac_attrs[5] = IPA_SOURCE_HOST_CATEGORY;
- state->hbac_attrs[6] = IPA_EXTERNAL_HOST;
- state->hbac_attrs[7] = IPA_ACCESS_TIME;
- state->hbac_attrs[8] = IPA_UNIQUE_ID;
- state->hbac_attrs[9] = IPA_ENABLED_FLAG;
- state->hbac_attrs[10] = IPA_CN;
- state->hbac_attrs[11] = "objectclass";
- state->hbac_attrs[12] = IPA_MEMBER_HOST;
- state->hbac_attrs[13] = IPA_HOST_CATEGORY;
- state->hbac_attrs[14] = SYSDB_ORIG_DN;
- state->hbac_attrs[15] = NULL;
-
- state->hbac_filter = talloc_asprintf(state,
- "(&(objectclass=ipaHBACRule)"
- "(|(%s=%s)(%s=%s)",
- IPA_HOST_CATEGORY, "all",
- IPA_MEMBER_HOST, host_dn);
- if (state->hbac_filter == NULL) {
- ret = ENOMEM;
- goto fail;
- }
- for (i = 0; memberof[i] != NULL; i++) {
- state->hbac_filter = talloc_asprintf_append(state->hbac_filter,
- "(%s=%s)",
- IPA_MEMBER_HOST,
- memberof[i]);
- if (state->hbac_filter == NULL) {
- ret = ENOMEM;
- goto fail;
- }
- }
- state->hbac_filter = talloc_asprintf_append(state->hbac_filter, "))");
- if (state->hbac_filter == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- DEBUG(9, ("HBAC rule filter: [%s].\n", state->hbac_filter));
-
- if (offline) {
- subreq = sysdb_search_custom_send(state, state->ev, state->sysdb, NULL,
- state->sdap_ctx->be->domain,
- state->hbac_filter, HBAC_RULES_SUBDIR,
- state->hbac_attrs);
- if (subreq == NULL) {
- DEBUG(1, ("sysdb_search_custom_send failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
-
- tevent_req_set_callback(subreq, hbac_rule_get_done, req);
-
- return req;
- }
-
- if (sdap_ctx->gsh == NULL || ! sdap_ctx->gsh->connected) {
- if (sdap_ctx->gsh != NULL) {
- talloc_zfree(sdap_ctx->gsh);
- }
-
- subreq = sdap_cli_connect_send(state, ev, sdap_ctx->opts,
- sdap_ctx->be, sdap_ctx->service, NULL);
- if (!subreq) {
- DEBUG(1, ("sdap_cli_connect_send failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
-
- tevent_req_set_callback(subreq, hbac_get_rules_connect_done, req);
-
- return req;
- }
-
- subreq = sdap_get_generic_send(state, state->ev,
- state->sdap_ctx->opts,
- state->sdap_ctx->gsh,
- state->hbac_search_base,
- LDAP_SCOPE_SUB,
- state->hbac_filter,
- state->hbac_attrs,
- NULL, 0);
-
- if (subreq == NULL) {
- DEBUG(1, ("sdap_get_generic_send failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
-
- tevent_req_set_callback(subreq, hbac_rule_get_done, req);
-
- return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-static void hbac_get_rules_connect_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct hbac_get_rules_state *state = tevent_req_data(req,
- struct hbac_get_rules_state);
- int ret;
-
- ret = sdap_cli_connect_recv(subreq, state->sdap_ctx, &state->sdap_ctx->gsh,
- NULL);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- subreq = sdap_get_generic_send(state, state->ev,
- state->sdap_ctx->opts,
- state->sdap_ctx->gsh,
- state->hbac_search_base,
- LDAP_SCOPE_SUB,
- state->hbac_filter,
- state->hbac_attrs,
- NULL, 0);
-
- if (subreq == NULL) {
- DEBUG(1, ("sdap_get_generic_send failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
-
- tevent_req_set_callback(subreq, hbac_rule_get_done, req);
- return;
-
-fail:
- tevent_req_error(req, ret);
- return;
-}
-
-static void hbac_rule_get_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct hbac_get_rules_state *state = tevent_req_data(req,
- struct hbac_get_rules_state);
- int ret;
- int i;
- struct ldb_message_element *el;
- struct ldb_message **msgs;
-
- if (state->offline) {
- ret = sysdb_search_custom_recv(subreq, state, &state->hbac_reply_count,
- &msgs);
- } else {
- ret = sdap_get_generic_recv(subreq, state, &state->hbac_reply_count,
- &state->hbac_reply_list);
- }
- talloc_zfree(subreq);
- if (ret != EOK) {
- tevent_req_error(req, ret);
- return;
- }
-
- if (state->offline) {
- ret = msgs2attrs_array(state, state->hbac_reply_count, msgs,
- &state->hbac_reply_list);
- talloc_zfree(msgs);
- if (ret != EOK) {
- DEBUG(1, ("msgs2attrs_array failed.\n"));
- goto fail;
- }
- }
-
- for (i = 0; i < state->hbac_reply_count; i++) {
- ret = sysdb_attrs_get_el(state->hbac_reply_list[i], SYSDB_ORIG_DN, &el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- goto fail;
- }
- if (el->num_values == 0) {
- DEBUG(1, ("Missing original DN.\n"));
- ret = EINVAL;
- goto fail;
- }
- DEBUG(9, ("OriginalDN: [%s].\n", (const char *)el->values[0].data));
- }
-
- if (state->hbac_reply_count == 0 || state->offline) {
- tevent_req_done(req);
- return;
- }
-
- subreq = sysdb_transaction_send(state, state->ev, state->sysdb);
- if (subreq == NULL) {
- DEBUG(1, ("sysdb_transaction_send failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, hbac_rule_sysdb_transaction_started, req);
- return;
-
-fail:
- tevent_req_error(req, ret);
- return;
-}
-
-static void hbac_rule_sysdb_transaction_started(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct hbac_get_rules_state *state = tevent_req_data(req,
- struct hbac_get_rules_state);
- int ret;
- struct ldb_dn *hbac_base_dn;
-
- ret = sysdb_transaction_recv(subreq, state, &state->handle);
- talloc_zfree(subreq);
- if (ret != EOK) {
- tevent_req_error(req, ret);
- return;
- }
-
- hbac_base_dn = sysdb_custom_subtree_dn(state->sysdb, state,
- state->sdap_ctx->be->domain->name,
- HBAC_RULES_SUBDIR);
- if (hbac_base_dn == NULL) {
- ret = ENOMEM;
- goto fail;
- }
- subreq = sysdb_delete_recursive_send(state, state->ev, state->handle,
- hbac_base_dn, true);
- if (subreq == NULL) {
- DEBUG(1, ("sysdb_delete_recursive_send failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, hbac_rule_sysdb_delete_done, req);
- return;
-
-fail:
- tevent_req_error(req, ret);
- return;
-}
-
-static void hbac_rule_sysdb_delete_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct hbac_get_rules_state *state = tevent_req_data(req,
- struct hbac_get_rules_state);
- int ret;
-
- ret = sysdb_delete_recursive_recv(subreq);
- talloc_zfree(subreq);
- if (ret != EOK) {
- tevent_req_error(req, ret);
- return;
- }
-
- state->current_item = 0;
- hbac_rule_store_prepare(req);
-}
-
-static void hbac_rule_store_prepare(struct tevent_req *req)
-{
- struct hbac_get_rules_state *state = tevent_req_data(req,
- struct hbac_get_rules_state);
- int ret;
- struct ldb_message_element *el;
- struct tevent_req *subreq;
- char *object_name;
-
- if (state->current_item < state->hbac_reply_count) {
-
- ret = sysdb_attrs_get_el(state->hbac_reply_list[state->current_item],
- IPA_UNIQUE_ID, &el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- goto fail;
- }
- if (el->num_values == 0) {
- ret = EINVAL;
- goto fail;
- }
- object_name = talloc_strndup(state, (const char *)el->values[0].data,
- el->values[0].length);
- if (object_name == NULL) {
- ret = ENOMEM;
- goto fail;
- }
- DEBUG(9, ("IPAUniqueId: [%s].\n", object_name));
-
- subreq = sysdb_store_custom_send(state, state->ev,
- state->handle,
- state->sdap_ctx->be->domain,
- object_name,
- HBAC_RULES_SUBDIR,
- state->hbac_reply_list[state->current_item]);
-
- if (subreq == NULL) {
- DEBUG(1, ("sysdb_store_custom_send failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
-
- tevent_req_set_callback(subreq, hbac_rule_store_done, req);
- return;
- }
-
- subreq = sysdb_transaction_commit_send(state, state->ev, state->handle);
- if (subreq == NULL) {
- DEBUG(1, ("sysdb_transaction_commit_send failed.\n"));
- ret = ENOMEM;
- goto fail;
- }
- tevent_req_set_callback(subreq, sysdb_transaction_complete, req);
-
- return;
-
-fail:
- tevent_req_error(req, ret);
- return;
-}
-
-static void hbac_rule_store_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct hbac_get_rules_state *state = tevent_req_data(req,
- struct hbac_get_rules_state);
- int ret;
-
- ret = sysdb_store_custom_recv(subreq);
- talloc_zfree(subreq);
- if (ret != EOK) {
- tevent_req_error(req, ret);
- return;
- }
-
- state->current_item++;
- hbac_rule_store_prepare(req);
-}
-
-static int hbac_get_rules_recv(struct tevent_req *req, TALLOC_CTX *memctx,
- size_t *hbac_rule_count,
- struct sysdb_attrs ***hbac_rule_list)
-{
- struct hbac_get_rules_state *state = tevent_req_data(req,
- struct hbac_get_rules_state);
- int i;
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- *hbac_rule_count = state->hbac_reply_count;
- *hbac_rule_list = talloc_steal(memctx, state->hbac_reply_list);
- for (i = 0; i < state->hbac_reply_count; i++) {
- talloc_steal(memctx, state->hbac_reply_list[i]);
- }
- return EOK;
-}
-
-enum hbac_result {
- HBAC_ALLOW = 1,
- HBAC_DENY,
- HBAC_NOT_APPLICABLE
-};
-
-enum check_result {
- RULE_APPLICABLE = 0,
- RULE_NOT_APPLICABLE,
- RULE_ERROR
-};
-
-enum check_result check_service(struct pam_data *pd,
- struct sysdb_attrs *rule_attrs)
-{
- int ret;
- int i;
- struct ldb_message_element *el;
-
- if (pd->service == NULL) {
- DEBUG(1, ("No service in pam data, assuming error.\n"));
- return RULE_ERROR;
- }
-
- ret = sysdb_attrs_get_el(rule_attrs, IPA_SERVICE_NAME, &el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- return RULE_ERROR;
- }
- if (el->num_values == 0) {
- DEBUG(9, ("No services in rule specified, assuming rule applies.\n"));
- return RULE_APPLICABLE;
- } else {
- for (i = 0; i < el->num_values; i++) {
- if (strncasecmp(pd->service, (const char *) el->values[i].data,
- el->values[i].length) == 0) {
- DEBUG(9, ("Service [%s] found, rule applies.\n",
- pd->service));
- return RULE_APPLICABLE;
- }
- }
- DEBUG(9, ("No matching service found, rule does not apply.\n"));
- return RULE_NOT_APPLICABLE;
- }
-
- return RULE_ERROR;
-}
-
-enum check_result check_access_time(struct time_rules_ctx *tr_ctx,
- struct sysdb_attrs *rule_attrs)
-{
- int ret;
- int i;
- TALLOC_CTX *tmp_ctx = NULL;
- struct ldb_message_element *el;
- char *rule;
- time_t now;
- bool result;
-
- now = time(NULL);
- if (now == (time_t) -1) {
- DEBUG(1, ("time failed [%d][%s].\n", errno, strerror(errno)));
- return RULE_ERROR;
- }
-
- ret = sysdb_attrs_get_el(rule_attrs, IPA_ACCESS_TIME, &el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- return RULE_ERROR;
- }
- if (el->num_values == 0) {
- DEBUG(9, ("No access time specified, assuming rule applies.\n"));
- return RULE_APPLICABLE;
- } else {
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
- DEBUG(1, ("talloc_new failed.\n"));
- return RULE_ERROR;
- }
-
- for (i = 0; i < el->num_values; i++) {
- rule = talloc_strndup(tmp_ctx, (const char *) el->values[i].data,
- el->values[i].length);
- ret = check_time_rule(tmp_ctx, tr_ctx, rule, now, &result);
- if (ret != EOK) {
- DEBUG(1, ("check_time_rule failed.\n"));
- ret = RULE_ERROR;
- goto done;
- }
-
- if (result) {
- DEBUG(9, ("Current time [%d] matches rule [%s].\n", now, rule));
- ret = RULE_APPLICABLE;
- goto done;
- }
- }
- }
-
- ret = RULE_NOT_APPLICABLE;
-
-done:
- talloc_free(tmp_ctx);
- return ret;
-}
-
-enum check_result check_user(struct hbac_ctx *hbac_ctx,
- struct sysdb_attrs *rule_attrs)
-{
- int ret;
- int i;
- int g;
- struct ldb_message_element *el;
-
- if (hbac_ctx->user_dn == NULL) {
- DEBUG(1, ("No user DN available, this should never happen.\n"));
- return RULE_ERROR;
- }
-
- ret = sysdb_attrs_get_el(rule_attrs, IPA_USER_CATEGORY, &el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- return RULE_ERROR;
- }
- if (el->num_values == 0) {
- DEBUG(9, ("USer category is not set.\n"));
- } else {
- for (i = 0; i < el->num_values; i++) {
- if (strncasecmp("all", (const char *) el->values[i].data,
- el->values[i].length) == 0) {
- DEBUG(9, ("User category is set to 'all', rule applies.\n"));
- return RULE_APPLICABLE;
- }
- DEBUG(9, ("Unsupported user category [%.*s].\n",
- el->values[i].length,
- (char *) el->values[i].data));
- }
- }
-
- ret = sysdb_attrs_get_el(rule_attrs, IPA_MEMBER_USER, &el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- return RULE_ERROR;
- }
- if (el->num_values == 0) {
- DEBUG(9, ("No user specified, rule does not apply.\n"));
- return RULE_APPLICABLE;
- } else {
- for (i = 0; i < el->num_values; i++) {
- DEBUG(9, ("Searching matches for [%.*s].\n", el->values[i].length,
- (const char *) el->values[i].data));
- DEBUG(9, ("Checking user [%s].\n", hbac_ctx->user_dn));
- if (strncmp(hbac_ctx->user_dn, (const char *) el->values[i].data,
- el->values[i].length) == 0) {
- DEBUG(9, ("User [%s] found, rule applies.\n",
- hbac_ctx->user_dn));
- return RULE_APPLICABLE;
- }
-
- for (g = 0; g < hbac_ctx->groups_count; g++) {
- DEBUG(9, ("Checking group [%s].\n", hbac_ctx->groups[g]));
- if (strncmp(hbac_ctx->groups[g],
- (const char *) el->values[i].data,
- el->values[i].length) == 0) {
- DEBUG(9, ("Group [%s] found, rule applies.\n",
- hbac_ctx->groups[g]));
- return RULE_APPLICABLE;
- }
- }
- }
- DEBUG(9, ("No matching user found, rule does not apply.\n"));
- return RULE_NOT_APPLICABLE;
- }
-
- return RULE_ERROR;
-}
-
-enum check_result check_remote_hosts(const char *rhost,
- struct hbac_host_info *hhi,
- struct sysdb_attrs *rule_attrs)
-{
- int ret;
- int i;
- int m;
- struct ldb_message_element *cat_el;
- struct ldb_message_element *src_el;
- struct ldb_message_element *ext_el;
-
- if (hhi == NULL && (rhost == NULL || *rhost == '\0')) {
- DEBUG(1, ("No remote host information specified, assuming error.\n"));
- return RULE_ERROR;
- }
-
- ret = sysdb_attrs_get_el(rule_attrs, IPA_SOURCE_HOST_CATEGORY, &cat_el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- return RULE_ERROR;
- }
- if (cat_el->num_values == 0) {
- DEBUG(9, ("Source host category not set.\n"));
- } else {
- for(i = 0; i < cat_el->num_values; i++) {
- if (strncasecmp("all", (const char *) cat_el->values[i].data,
- cat_el->values[i].length) == 0) {
- DEBUG(9, ("Source host category is set to 'all', "
- "rule applies.\n"));
- return RULE_APPLICABLE;
- }
- DEBUG(9, ("Unsupported source hosts category [%.*s].\n",
- cat_el->values[i].length,
- (char *) cat_el->values[i].data));
- }
- }
-
- ret = sysdb_attrs_get_el(rule_attrs, IPA_SOURCE_HOST, &src_el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- return RULE_ERROR;
- }
- ret = sysdb_attrs_get_el(rule_attrs, IPA_EXTERNAL_HOST, &ext_el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- return RULE_ERROR;
- }
-
- if (src_el->num_values == 0 && ext_el->num_values == 0) {
- DEBUG(9, ("No remote host specified in rule, rule does not apply.\n"));
- return RULE_NOT_APPLICABLE;
- } else {
- if (hhi != NULL) {
- for (i = 0; i < src_el->num_values; i++) {
- if (strncasecmp(hhi->dn, (const char *) src_el->values[i].data,
- src_el->values[i].length) == 0) {
- DEBUG(9, ("Source host [%s] found, rule applies.\n",
- hhi->dn));
- return RULE_APPLICABLE;
- }
- for (m = 0; hhi->memberof[m] != NULL; m++) {
- if (strncasecmp(hhi->memberof[m],
- (const char *) src_el->values[i].data,
- src_el->values[i].length) == 0) {
- DEBUG(9, ("Source host group [%s] found, rule applies.\n",
- hhi->memberof[m]));
- return RULE_APPLICABLE;
- }
- }
- }
- }
-
- if (rhost != NULL && *rhost != '\0') {
- for (i = 0; i < ext_el->num_values; i++) {
- if (strncasecmp(rhost, (const char *) ext_el->values[i].data,
- ext_el->values[i].length) == 0) {
- DEBUG(9, ("External host [%s] found, rule applies.\n",
- rhost));
- return RULE_APPLICABLE;
- }
- }
- }
- DEBUG(9, ("No matching remote host found.\n"));
- return RULE_NOT_APPLICABLE;
- }
-
- return RULE_ERROR;
-}
-
-static errno_t check_if_rule_applies(enum hbac_result *result,
- struct hbac_ctx *hbac_ctx,
- struct sysdb_attrs *rule_attrs) {
- int ret;
- struct ldb_message_element *el;
- enum hbac_result rule_type;
- char *rule_name;
- struct pam_data *pd = hbac_ctx->pd;
-
- ret = sysdb_attrs_get_el(rule_attrs, IPA_CN, &el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- return ret;
- }
- if (el->num_values == 0) {
- DEBUG(4, ("rule has no name, assuming '(none)'.\n"));
- rule_name = talloc_strdup(rule_attrs, "(none)");
- } else {
- rule_name = talloc_strndup(rule_attrs, (const char*) el->values[0].data,
- el->values[0].length);
- }
- if (rule_name == NULL) {
- DEBUG(1, ("talloc_strdup failed.\n"));
- return ENOMEM;
- }
- DEBUG(9, ("Processsing rule [%s].\n", rule_name));
-
- /* rule type */
- ret = sysdb_attrs_get_el(rule_attrs, IPA_ACCESS_RULE_TYPE, &el);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_attrs_get_el failed.\n"));
- return ret;
- }
- if (el->num_values == 0) {
- DEBUG(4, ("rule has no type, assuming 'deny'.\n"));
- rule_type = HBAC_DENY;
- } else if (el->num_values == 1) {
- if (strncasecmp((const char *) el->values[0].data, "allow",
- el->values[0].length) == 0) {
- rule_type = HBAC_ALLOW;
- } else {
- rule_type = HBAC_DENY;
- }
- } else {
- DEBUG(1, ("rule has an unsupported number of values [%d].\n",
- el->num_values));
- return EINVAL;
- }
-
- ret = check_service(pd, rule_attrs);
- if (ret != RULE_APPLICABLE) {
- goto not_applicable;
- }
-
- ret = check_user(hbac_ctx, rule_attrs);
- if (ret != RULE_APPLICABLE) {
- goto not_applicable;
- }
-
- ret = check_access_time(hbac_ctx->tr_ctx, rule_attrs);
- if (ret != RULE_APPLICABLE) {
- goto not_applicable;
- }
-
- ret = check_remote_hosts(pd->rhost, hbac_ctx->remote_hhi, rule_attrs);
- if (ret != RULE_APPLICABLE) {
- goto not_applicable;
- }
-
- *result = rule_type;
-
- return EOK;
-
-not_applicable:
- if (ret == RULE_NOT_APPLICABLE) {
- *result = HBAC_NOT_APPLICABLE;
- } else {
- *result = HBAC_DENY;
- }
- return EOK;
-}
-
-static int evaluate_ipa_hbac_rules(struct hbac_ctx *hbac_ctx,
- bool *access_allowed)
-{
- bool allow_matched = false;
- enum hbac_result result;
- int ret;
- int i;
-
- *access_allowed = false;
-
- for (i = 0; i < hbac_ctx->hbac_rule_count ; i++) {
-
- ret = check_if_rule_applies(&result, hbac_ctx,
- hbac_ctx->hbac_rule_list[i]);
- if (ret != EOK) {
- DEBUG(1, ("check_if_rule_applies failed.\n"));
- return ret;
- }
-
- switch (result) {
- case HBAC_DENY:
- DEBUG(3, ("Access denied by single rule.\n"));
- return EOK;
- break;
- case HBAC_ALLOW:
- allow_matched = true;
- DEBUG(9, ("Current rule allows access.\n"));
- break;
- default:
- DEBUG(9, ("Current rule does not apply.\n"));
- }
-
- }
-
- *access_allowed = allow_matched;
-
- return EOK;
-}
-
-static void hbac_get_host_info_done(struct tevent_req *req);
-static void hbac_get_rules_done(struct tevent_req *req);
-static void hbac_get_user_info_done(struct tevent_req *req);
-
-void ipa_access_handler(struct be_req *be_req)
-{
- struct tevent_req *req;
- struct pam_data *pd;
- struct hbac_ctx *hbac_ctx;
- int pam_status = PAM_SYSTEM_ERR;
- struct ipa_access_ctx *ipa_access_ctx;
- const char *hostlist[3];
-
- pd = talloc_get_type(be_req->req_data, struct pam_data);
-
- hbac_ctx = talloc_zero(be_req, struct hbac_ctx);
- if (hbac_ctx == NULL) {
- DEBUG(1, ("talloc failed.\n"));
- goto fail;
- }
- hbac_ctx->be_req = be_req;
- hbac_ctx->pd = pd;
- ipa_access_ctx = talloc_get_type(
- be_req->be_ctx->bet_info[BET_ACCESS].pvt_bet_data,
- struct ipa_access_ctx);
- hbac_ctx->sdap_ctx = ipa_access_ctx->sdap_ctx;
- hbac_ctx->ipa_options = ipa_access_ctx->ipa_options;
- hbac_ctx->tr_ctx = ipa_access_ctx->tr_ctx;
- hbac_ctx->offline = be_is_offline(be_req->be_ctx);
-
- DEBUG(9, ("Connection status is [%s].\n", hbac_ctx->offline ? "offline" :
- "online"));
-
-
- hostlist[0] = dp_opt_get_cstring(hbac_ctx->ipa_options, IPA_HOSTNAME);
- if (hostlist[0] == NULL) {
- DEBUG(1, ("ipa_hostname not available.\n"));
- goto fail;
- }
- if (pd->rhost != NULL && *pd->rhost != '\0') {
- hostlist[1] = pd->rhost;
- } else {
- hostlist[1] = NULL;
- pd->rhost = dp_opt_get_string(hbac_ctx->ipa_options, IPA_HOSTNAME);
- if (pd->rhost == NULL) {
- DEBUG(1, ("ipa_hostname not available.\n"));
- goto fail;
- }
- }
- hostlist[2] = NULL;
-
- req = hbac_get_host_info_send(hbac_ctx, be_req->be_ctx->ev,
- hbac_ctx->offline,
- hbac_ctx->sdap_ctx, be_req->be_ctx->sysdb,
- dp_opt_get_string(hbac_ctx->ipa_options,
- IPA_DOMAIN),
- hostlist);
- if (req == NULL) {
- DEBUG(1, ("hbac_get_host_info_send failed.\n"));
- goto fail;
- }
-
- tevent_req_set_callback(req, hbac_get_host_info_done, hbac_ctx);
- return;
-
-fail:
- ipa_access_reply(be_req, pam_status);
-}
-
-static void hbac_get_host_info_done(struct tevent_req *req)
-{
- struct hbac_ctx *hbac_ctx = tevent_req_callback_data(req, struct hbac_ctx);
- struct be_req *be_req = hbac_ctx->be_req;
- int ret;
- int pam_status = PAM_SYSTEM_ERR;
- const char *ipa_hostname;
- struct hbac_host_info *local_hhi = NULL;
- int i;
-
- ret = hbac_get_host_info_recv(req, hbac_ctx, &hbac_ctx->hbac_host_info);
- talloc_zfree(req);
- if (ret != EOK) {
- goto fail;
- }
-
- ipa_hostname = dp_opt_get_cstring(hbac_ctx->ipa_options, IPA_HOSTNAME);
- if (ipa_hostname == NULL) {
- DEBUG(1, ("Missing ipa_hostname, this should never happen.\n"));
- ret = EINVAL;
- goto fail;
- }
-
- for (i = 0; hbac_ctx->hbac_host_info[i] != NULL; i++) {
- if (strcmp(hbac_ctx->hbac_host_info[i]->fqdn, ipa_hostname) == 0 ||
- strcmp(hbac_ctx->hbac_host_info[i]->serverhostname,
- ipa_hostname) == 0) {
- local_hhi = hbac_ctx->hbac_host_info[i];
- }
- if (hbac_ctx->pd->rhost != NULL && *hbac_ctx->pd->rhost != '\0') {
- if (strcmp(hbac_ctx->hbac_host_info[i]->fqdn,
- hbac_ctx->pd->rhost) == 0 ||
- strcmp(hbac_ctx->hbac_host_info[i]->serverhostname,
- hbac_ctx->pd->rhost) == 0) {
- hbac_ctx->remote_hhi = hbac_ctx->hbac_host_info[i];
- }
- }
- }
- if (local_hhi == NULL) {
- DEBUG(1, ("Missing host info for [%s].\n", ipa_hostname));
- ret = EINVAL;
- goto fail;
- }
- req = hbac_get_rules_send(hbac_ctx, be_req->be_ctx->ev, hbac_ctx->offline,
- hbac_ctx->sdap_ctx, be_req->be_ctx->sysdb,
- dp_opt_get_string(hbac_ctx->ipa_options,
- IPA_DOMAIN),
- local_hhi->dn, local_hhi->memberof);
- if (req == NULL) {
- DEBUG(1, ("hbac_get_rules_send failed.\n"));
- goto fail;
- }
-
- tevent_req_set_callback(req, hbac_get_rules_done, hbac_ctx);
- return;
-
-fail:
- ipa_access_reply(be_req, pam_status);
-}
-
-static void hbac_get_rules_done(struct tevent_req *req)
-{
- struct hbac_ctx *hbac_ctx = tevent_req_callback_data(req, struct hbac_ctx);
- struct pam_data *pd = hbac_ctx->pd;
- struct be_req *be_req = hbac_ctx->be_req;
- int ret;
- int pam_status = PAM_SYSTEM_ERR;
-
- ret = hbac_get_rules_recv(req, hbac_ctx, &hbac_ctx->hbac_rule_count,
- &hbac_ctx->hbac_rule_list);
- talloc_zfree(req);
- if (ret != EOK) {
- goto fail;
- }
-
- req = hbac_get_user_info_send(hbac_ctx, be_req->be_ctx->ev, be_req->be_ctx,
- pd->user);
- if (req == NULL) {
- DEBUG(1, ("hbac_get_user_info_send failed.\n"));
- goto fail;
- }
-
- tevent_req_set_callback(req, hbac_get_user_info_done, hbac_ctx);
- return;
-
-fail:
- ipa_access_reply(be_req, pam_status);
-}
-
-static void hbac_get_user_info_done(struct tevent_req *req)
-{
- struct hbac_ctx *hbac_ctx = tevent_req_callback_data(req, struct hbac_ctx);
- struct be_req *be_req = hbac_ctx->be_req;
- int ret;
- int pam_status = PAM_SYSTEM_ERR;
- bool access_allowed = false;
-
- ret = hbac_get_user_info_recv(req, hbac_ctx, &hbac_ctx->user_dn,
- &hbac_ctx->groups_count,
- &hbac_ctx->groups);
- talloc_zfree(req);
- if (ret != EOK) {
- goto failed;
- }
-
- ret = evaluate_ipa_hbac_rules(hbac_ctx, &access_allowed);
- if (ret != EOK) {
- DEBUG(1, ("evaluate_ipa_hbac_rules failed.\n"));
- goto failed;
- }
-
- if (access_allowed) {
- pam_status = PAM_SUCCESS;
- DEBUG(5, ("Access allowed.\n"));
- } else {
- pam_status = PAM_PERM_DENIED;
- DEBUG(3, ("Access denied.\n"));
- }
-
-failed:
- ipa_access_reply(be_req, pam_status);
-}
diff --git a/server/providers/ipa/ipa_access.h b/server/providers/ipa/ipa_access.h
deleted file mode 100644
index bd221c57..00000000
--- a/server/providers/ipa/ipa_access.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- SSSD
-
- IPA Backend Module -- Access control
-
- Authors:
- Sumit Bose <sbose@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _IPA_ACCESS_H_
-#define _IPA_ACCESS_H_
-
-#include "providers/ldap/ldap_common.h"
-
-enum ipa_access_mode {
- IPA_ACCESS_DENY = 0,
- IPA_ACCESS_ALLOW
-};
-
-struct hbac_host_info {
- const char *fqdn;
- const char *serverhostname;
- const char *dn;
- const char **memberof;
-};
-
-struct ipa_access_ctx {
- struct sdap_id_ctx *sdap_ctx;
- struct dp_option *ipa_options;
- struct time_rules_ctx *tr_ctx;
-};
-
-struct hbac_ctx {
- struct sdap_id_ctx *sdap_ctx;
- struct dp_option *ipa_options;
- struct time_rules_ctx *tr_ctx;
- struct be_req *be_req;
- struct pam_data *pd;
- struct hbac_host_info **hbac_host_info;
- struct hbac_host_info *remote_hhi;
- struct sysdb_attrs **hbac_rule_list;
- size_t hbac_rule_count;
- const char *user_dn;
- size_t groups_count;
- const char **groups;
- bool offline;
-};
-
-void ipa_access_handler(struct be_req *be_req);
-
-#endif /* _IPA_ACCESS_H_ */
diff --git a/server/providers/ipa/ipa_auth.c b/server/providers/ipa/ipa_auth.c
deleted file mode 100644
index 86b72e49..00000000
--- a/server/providers/ipa/ipa_auth.c
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
- SSSD
-
- IPA Backend Module -- Authentication
-
- Authors:
- Sumit Bose <sbose@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <sys/param.h>
-#include <security/pam_modules.h>
-
-#include "util/util.h"
-#include "providers/ldap/ldap_common.h"
-#include "providers/ldap/sdap_async.h"
-#include "providers/krb5/krb5_auth.h"
-#include "providers/ipa/ipa_common.h"
-
-struct ipa_auth_ctx {
- struct sdap_auth_ctx *sdap_auth_ctx;
- struct krb5_ctx *krb5_ctx;
- struct be_req *be_req;
- be_async_callback_t callback;
- void *pvt;
- bool password_migration;
-
- int dp_err_type;
- int errnum;
- char *errstr;
-};
-
-static void ipa_auth_reply(struct ipa_auth_ctx *ipa_auth_ctx)
-{
- struct pam_data *pd;
- struct be_req *be_req = ipa_auth_ctx->be_req;
- be_req->fn = ipa_auth_ctx->callback;
- be_req->pvt = ipa_auth_ctx->pvt;
- be_req->be_ctx->bet_info[BET_AUTH].pvt_bet_data = ipa_auth_ctx->krb5_ctx;
- pd = talloc_get_type(be_req->req_data, struct pam_data);
- int dp_err_type = ipa_auth_ctx->dp_err_type;
- char *errstr = ipa_auth_ctx->errstr;
-
- talloc_zfree(ipa_auth_ctx);
- DEBUG(9, ("sending [%d] [%d] [%s].\n", dp_err_type, pd->pam_status,
- errstr));
-
- be_req->fn(be_req, dp_err_type, pd->pam_status, errstr);
-}
-
-struct ipa_auth_handler_state {
- struct tevent_context *ev;
-
- int dp_err_type;
- int errnum;
- char *errstr;
-};
-
-static void ipa_auth_handler_callback(struct be_req *be_req,
- int dp_err_type,
- int errnum,
- const char *errstr);
-
-static struct tevent_req *ipa_auth_handler_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct be_req *be_req,
- be_req_fn_t auth_handler)
-{
- struct ipa_auth_handler_state *state;
- struct tevent_req *req;
-
- req = tevent_req_create(memctx, &state, struct ipa_auth_handler_state);
- if (req == NULL) {
- DEBUG(1, ("tevent_req_create failed.\n"));
- return NULL;
- }
-
- state->ev = ev;
-
- be_req->fn = ipa_auth_handler_callback;
- be_req->pvt = req;
-
- auth_handler(be_req);
-
- return req;
-}
-
-static void ipa_auth_handler_callback(struct be_req *be_req,
- int dp_err_type,
- int errnum,
- const char *errstr)
-{
- struct tevent_req *req = talloc_get_type(be_req->pvt, struct tevent_req);
- struct ipa_auth_handler_state *state = tevent_req_data(req,
- struct ipa_auth_handler_state);
-
- DEBUG(9, ("received from handler [%d] [%d] [%s].\n", dp_err_type, errnum,
- errstr));
- state->dp_err_type = dp_err_type;
- state->errnum = errnum;
- state->errstr = talloc_strdup(state, errstr);
-
- tevent_req_post(req, state->ev);
- tevent_req_done(req);
- return;
-}
-
-static int ipa_auth_handler_recv(struct tevent_req *req, TALLOC_CTX *memctx,
- int *dp_err_type, int *errnum,
- char **errstr)
-{
- struct ipa_auth_handler_state *state = tevent_req_data(req,
- struct ipa_auth_handler_state);
- enum tevent_req_state tstate;
- uint64_t err;
-
- if (tevent_req_is_error(req, &tstate, &err)) {
- if (err) return err;
- return EIO;
- }
-
- *dp_err_type = state->dp_err_type;
- *errnum = state->errnum;
- *errstr = talloc_steal(memctx, state->errstr);
-
- return EOK;
-}
-
-
-static void ipa_auth_handler_done(struct tevent_req *req);
-static void ipa_auth_ldap_done(struct tevent_req *req);
-static void ipa_auth_handler_retry_done(struct tevent_req *req);
-
-void ipa_auth(struct be_req *be_req)
-{
- struct tevent_req *req;
- struct ipa_auth_ctx *ipa_auth_ctx;
- struct sdap_id_ctx *sdap_id_ctx;
-
- ipa_auth_ctx = talloc_zero(be_req, struct ipa_auth_ctx);
- if (ipa_auth_ctx == NULL) {
- DEBUG(1, ("talloc failed.\n"));
- be_req->fn(be_req, DP_ERR_FATAL, PAM_SYSTEM_ERR, NULL);
- }
-
- ipa_auth_ctx->callback = be_req->fn;
- ipa_auth_ctx->pvt = be_req->pvt;
-
- ipa_auth_ctx->be_req = be_req;
-
- ipa_auth_ctx->sdap_auth_ctx = talloc_zero(ipa_auth_ctx,
- struct sdap_auth_ctx);
- if (ipa_auth_ctx->sdap_auth_ctx == NULL) {
- DEBUG(1, ("talloc failed.\n"));
- goto fail;
- }
-
- sdap_id_ctx = talloc_get_type(
- be_req->be_ctx->bet_info[BET_ID].pvt_bet_data,
- struct sdap_id_ctx);
- ipa_auth_ctx->sdap_auth_ctx->be = sdap_id_ctx->be;
- ipa_auth_ctx->sdap_auth_ctx->opts = sdap_id_ctx->opts;
-
- ipa_auth_ctx->krb5_ctx = talloc_get_type(
- be_req->be_ctx->bet_info[BET_AUTH].pvt_bet_data,
- struct krb5_ctx);
-
-/* TODO: test and activate when server side support is available */
- ipa_auth_ctx->password_migration = false;
-
- ipa_auth_ctx->dp_err_type = DP_ERR_FATAL;
- ipa_auth_ctx->errnum = EIO;
- ipa_auth_ctx->errstr = NULL;
-
- req = ipa_auth_handler_send(ipa_auth_ctx, be_req->be_ctx->ev, be_req,
- krb5_pam_handler);
- if (req == NULL) {
- DEBUG(1, ("ipa_auth_handler_send failed.\n"));
- goto fail;
- }
-
- tevent_req_set_callback(req, ipa_auth_handler_done, ipa_auth_ctx);
- return;
-
-fail:
- ipa_auth_reply(ipa_auth_ctx);
-}
-
-static void ipa_auth_handler_done(struct tevent_req *req)
-{
- struct ipa_auth_ctx *ipa_auth_ctx = tevent_req_callback_data(req,
- struct ipa_auth_ctx);
- struct pam_data *pd;
- struct be_req *be_req;
- int ret;
-
- be_req = ipa_auth_ctx->be_req;
- pd = talloc_get_type(be_req->req_data, struct pam_data);
-
- ret = ipa_auth_handler_recv(req, ipa_auth_ctx, &ipa_auth_ctx->dp_err_type,
- &ipa_auth_ctx->errnum, &ipa_auth_ctx->errstr);
- talloc_zfree(req);
- if (ret != EOK) {
- DEBUG(1, ("ipa_auth_handler request failed.\n"));
- pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
- if (ipa_auth_ctx->dp_err_type != DP_ERR_OK) {
- pd->pam_status = ipa_auth_ctx->errnum;
- goto done;
- }
-
- if (ipa_auth_ctx->password_migration && pd->pam_status == PAM_CRED_ERR) {
- DEBUG(1, ("Assuming Kerberos password is missing, "
- "starting password migration.\n"));
- be_req->be_ctx->bet_info[BET_AUTH].pvt_bet_data =
- ipa_auth_ctx->sdap_auth_ctx;
- req = ipa_auth_handler_send(ipa_auth_ctx, be_req->be_ctx->ev, be_req,
- sdap_pam_auth_handler);
- if (req == NULL) {
- DEBUG(1, ("ipa_auth_ldap_send failed.\n"));
- goto done;
- }
-
- tevent_req_set_callback(req, ipa_auth_ldap_done, ipa_auth_ctx);
- return;
- }
-
-done:
- ipa_auth_reply(ipa_auth_ctx);
-}
-
-static void ipa_auth_ldap_done(struct tevent_req *req)
-{
- struct ipa_auth_ctx *ipa_auth_ctx = tevent_req_callback_data(req,
- struct ipa_auth_ctx);
- struct pam_data *pd;
- struct be_req *be_req;
- int ret;
-
- be_req = ipa_auth_ctx->be_req;
- pd = talloc_get_type(be_req->req_data, struct pam_data);
-
- ret = ipa_auth_handler_recv(req, ipa_auth_ctx, &ipa_auth_ctx->dp_err_type,
- &ipa_auth_ctx->errnum, &ipa_auth_ctx->errstr);
- talloc_zfree(req);
- if (ret != EOK) {
- DEBUG(1, ("ipa_auth_handler request failed.\n"));
- pd->pam_status = PAM_SYSTEM_ERR;
- goto done;
- }
- if (ipa_auth_ctx->dp_err_type != DP_ERR_OK) {
- pd->pam_status = ipa_auth_ctx->errnum;
- goto done;
- }
-
- if (pd->pam_status == PAM_SUCCESS) {
- DEBUG(1, ("LDAP authentication succeded, "
- "trying Kerberos authentication again.\n"));
- be_req->be_ctx->bet_info[BET_AUTH].pvt_bet_data = ipa_auth_ctx->krb5_ctx;
- req = ipa_auth_handler_send(ipa_auth_ctx, be_req->be_ctx->ev, be_req,
- krb5_pam_handler);
- if (req == NULL) {
- DEBUG(1, ("ipa_auth_ldap_send failed.\n"));
- goto done;
- }
-
- tevent_req_set_callback(req, ipa_auth_handler_retry_done, ipa_auth_ctx);
- return;
- }
-
-done:
- ipa_auth_reply(ipa_auth_ctx);
-}
-
-static void ipa_auth_handler_retry_done(struct tevent_req *req)
-{
- struct ipa_auth_ctx *ipa_auth_ctx = tevent_req_callback_data(req,
- struct ipa_auth_ctx);
- struct pam_data *pd;
- struct be_req *be_req;
- int ret;
-
- be_req = ipa_auth_ctx->be_req;
- pd = talloc_get_type(be_req->req_data, struct pam_data);
-
- ret = ipa_auth_handler_recv(req, ipa_auth_ctx, &ipa_auth_ctx->dp_err_type,
- &ipa_auth_ctx->errnum, &ipa_auth_ctx->errstr);
- talloc_zfree(req);
- if (ret != EOK) {
- DEBUG(1, ("ipa_auth_handler request failed.\n"));
- pd->pam_status = PAM_SYSTEM_ERR;
- }
- if (ipa_auth_ctx->dp_err_type != DP_ERR_OK) {
- pd->pam_status = ipa_auth_ctx->errnum;
- }
-
- ipa_auth_reply(ipa_auth_ctx);
-}
diff --git a/server/providers/ipa/ipa_auth.h b/server/providers/ipa/ipa_auth.h
deleted file mode 100644
index 3079bbd1..00000000
--- a/server/providers/ipa/ipa_auth.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- SSSD
-
- IPA Backend Module -- Authentication
-
- Authors:
- Sumit Bose <sbose@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _IPA_AUTH_H_
-#define _IPA_AUTH_H_
-
-#include "providers/dp_backend.h"
-
-void ipa_auth(struct be_req *be_req);
-
-#endif /* _IPA_AUTH_H_ */
diff --git a/server/providers/ipa/ipa_common.c b/server/providers/ipa/ipa_common.c
deleted file mode 100644
index 7686227a..00000000
--- a/server/providers/ipa/ipa_common.c
+++ /dev/null
@@ -1,597 +0,0 @@
-/*
- SSSD
-
- IPA Provider Common Functions
-
- Authors:
- Simo Sorce <ssorce@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <netdb.h>
-#include <ctype.h>
-#include "providers/ipa/ipa_common.h"
-
-struct dp_option ipa_basic_opts[] = {
- { "ipa_domain", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ipa_server", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ipa_hostname", DP_OPT_STRING, NULL_STRING, NULL_STRING },
-};
-
-struct dp_option ipa_def_ldap_opts[] = {
- { "ldap_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_default_bind_dn", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_default_authtok_type", DP_OPT_STRING, NULL_STRING, NULL_STRING},
- { "ldap_default_authtok", DP_OPT_BLOB, NULL_BLOB, NULL_BLOB },
- { "ldap_search_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER },
- { "ldap_network_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER },
- { "ldap_opt_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER },
- { "ldap_tls_reqcert", DP_OPT_STRING, { "hard" }, NULL_STRING },
- { "ldap_user_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_user_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING },
- { "ldap_user_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_group_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_group_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING },
- { "ldap_group_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_schema", DP_OPT_STRING, { "ipa_v1" }, NULL_STRING },
- { "ldap_offline_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER },
- { "ldap_force_upper_case_realm", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE },
- { "ldap_enumeration_refresh_timeout", DP_OPT_NUMBER, { .number = 300 }, NULL_NUMBER },
- { "ldap_purge_cache_timeout", DP_OPT_NUMBER, { .number = 3600 }, NULL_NUMBER },
- { "entry_cache_timeout", DP_OPT_NUMBER, { .number = 1800 }, NULL_NUMBER },
- { "ldap_tls_cacert", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_tls_cacertdir", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_id_use_start_tls", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
- { "ldap_sasl_mech", DP_OPT_STRING, { "GSSAPI" } , NULL_STRING },
- { "ldap_sasl_authid", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_krb5_keytab", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_krb5_init_creds", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE },
- /* use the same parm name as the krb5 module so we set it only once */
- { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "ldap_pwd_policy", DP_OPT_STRING, { "none" } , NULL_STRING },
- { "ldap_referrals", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }
-};
-
-struct sdap_attr_map ipa_attr_map[] = {
- { "ldap_entry_usn", "entryUSN", SYSDB_USN, NULL },
- { "ldap_rootdse_last_usn", "lastUSN", SYSDB_HIGH_USN, NULL }
-};
-
-struct sdap_attr_map ipa_user_map[] = {
- { "ldap_user_object_class", "posixAccount", SYSDB_USER_CLASS, NULL },
- { "ldap_user_name", "uid", SYSDB_NAME, NULL },
- { "ldap_user_pwd", "userPassword", SYSDB_PWD, NULL },
- { "ldap_user_uid_number", "uidNumber", SYSDB_UIDNUM, NULL },
- { "ldap_user_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
- { "ldap_user_gecos", "gecos", SYSDB_GECOS, NULL },
- { "ldap_user_home_directory", "homeDirectory", SYSDB_HOMEDIR, NULL },
- { "ldap_user_shell", "loginShell", SYSDB_SHELL, NULL },
- { "ldap_user_principal", "krbPrincipalName", SYSDB_UPN, NULL },
- { "ldap_user_fullname", "cn", SYSDB_FULLNAME, NULL },
- { "ldap_user_member_of", "memberOf", SYSDB_MEMBEROF, NULL },
- { "ldap_user_uuid", "nsUniqueId", SYSDB_UUID, NULL },
- { "ldap_user_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
- { "ldap_user_shadow_last_change", "shadowLastChange", SYSDB_SHADOWPW_LASTCHANGE, NULL },
- { "ldap_user_shadow_min", "shadowMin", SYSDB_SHADOWPW_MIN, NULL },
- { "ldap_user_shadow_max", "shadowMax", SYSDB_SHADOWPW_MAX, NULL },
- { "ldap_user_shadow_warning", "shadowWarning", SYSDB_SHADOWPW_WARNING, NULL },
- { "ldap_user_shadow_inactive", "shadowInactive", SYSDB_SHADOWPW_INACTIVE, NULL },
- { "ldap_user_shadow_expire", "shadowExpire", SYSDB_SHADOWPW_EXPIRE, NULL },
- { "ldap_user_shadow_flag", "shadowFlag", SYSDB_SHADOWPW_FLAG, NULL },
- { "ldap_user_krb_last_pwd_change", "krbLastPwdChange", SYSDB_KRBPW_LASTCHANGE, NULL },
- { "ldap_user_krb_password_expiration", "krbPasswordExpiration", SYSDB_KRBPW_EXPIRATION, NULL },
- { "ldap_pwd_attribute", "pwdAttribute", SYSDB_PWD_ATTRIBUTE, NULL }
-};
-
-struct sdap_attr_map ipa_group_map[] = {
- { "ldap_group_object_class", "posixGroup", SYSDB_GROUP_CLASS, NULL },
- { "ldap_group_name", "cn", SYSDB_NAME, NULL },
- { "ldap_group_pwd", "userPassword", SYSDB_PWD, NULL },
- { "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
- { "ldap_group_member", "member", SYSDB_MEMBER, NULL },
- { "ldap_group_uuid", "nsUniqueId", SYSDB_UUID, NULL },
- { "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }
-};
-
-struct dp_option ipa_def_krb5_opts[] = {
- { "krb5_kdcip", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING },
- { "krb5_ccachedir", DP_OPT_STRING, { "/tmp" }, NULL_STRING },
- { "krb5_ccname_template", DP_OPT_STRING, { "FILE:%d/krb5cc_%U_XXXXXX" }, NULL_STRING},
- { "krb5_changepw_principal", DP_OPT_STRING, { "kadmin/changepw" }, NULL_STRING },
- { "krb5_auth_timeout", DP_OPT_NUMBER, { .number = 15 }, NULL_NUMBER },
- { "krb5_keytab", DP_OPT_STRING, { "/etc/krb5.keytab" }, NULL_STRING },
- { "krb5_validate", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }
-};
-
-int domain_to_basedn(TALLOC_CTX *memctx, const char *domain, char **basedn)
-{
- const char *s;
- char *dn;
- char *p;
- int l;
-
- s = domain;
- dn = talloc_strdup(memctx, "dc=");
-
- while ((p = strchr(s, '.'))) {
- l = p - s;
- dn = talloc_asprintf_append_buffer(dn, "%.*s,dc=", l, s);
- if (!dn) {
- return ENOMEM;
- }
- s = p + 1;
- }
- dn = talloc_strdup_append_buffer(dn, s);
- if (!dn) {
- return ENOMEM;
- }
-
- *basedn = dn;
- return EOK;
-}
-
-int ipa_get_options(TALLOC_CTX *memctx,
- struct confdb_ctx *cdb,
- const char *conf_path,
- struct sss_domain_info *dom,
- struct ipa_options **_opts)
-{
- struct ipa_options *opts;
- char *domain;
- char *server;
- char *ipa_hostname;
- int ret;
- char hostname[HOST_NAME_MAX + 1];
-
- opts = talloc_zero(memctx, struct ipa_options);
- if (!opts) return ENOMEM;
-
- ret = dp_get_options(opts, cdb, conf_path,
- ipa_basic_opts,
- IPA_OPTS_BASIC,
- &opts->basic);
- if (ret != EOK) {
- goto done;
- }
-
- domain = dp_opt_get_string(opts->basic, IPA_DOMAIN);
- if (!domain) {
- ret = dp_opt_set_string(opts->basic, IPA_DOMAIN, dom->name);
- if (ret != EOK) {
- goto done;
- }
- }
-
- /* FIXME: Make non-fatal once we have discovery */
- server = dp_opt_get_string(opts->basic, IPA_SERVER);
- if (!server) {
- DEBUG(0, ("Can't find ipa server, missing option!\n"));
- ret = EINVAL;
- goto done;
- }
-
- ipa_hostname = dp_opt_get_string(opts->basic, IPA_HOSTNAME);
- if (ipa_hostname == NULL) {
- ret = gethostname(hostname, HOST_NAME_MAX);
- if (ret != EOK) {
- DEBUG(1, ("gethostname failed [%d][%s].\n", errno,
- strerror(errno)));
- ret = errno;
- goto done;
- }
- hostname[HOST_NAME_MAX] = '\0';
- DEBUG(9, ("Setting ipa_hostname to [%s].\n", hostname));
- ret = dp_opt_set_string(opts->basic, IPA_HOSTNAME, hostname);
- if (ret != EOK) {
- goto done;
- }
- }
-
-
- ret = EOK;
- *_opts = opts;
-
-done:
- if (ret != EOK) {
- talloc_zfree(opts);
- }
- return ret;
-}
-
-int ipa_get_id_options(struct ipa_options *ipa_opts,
- struct confdb_ctx *cdb,
- const char *conf_path,
- struct sdap_options **_opts)
-{
- TALLOC_CTX *tmpctx;
- char *hostname;
- char *basedn;
- char *realm;
- char *value;
- int ret;
- int i;
-
- /* self check test, this should never fail, unless someone forgot
- * to properly update the code after new ldap options have been added */
- if (SDAP_OPTS_BASIC != IPA_OPTS_BASIC_TEST) {
- DEBUG(0, ("Option numbers do not match (%d != %d)\n",
- SDAP_OPTS_BASIC, IPA_OPTS_BASIC_TEST));
- abort();
- }
-
- tmpctx = talloc_new(ipa_opts);
- if (!tmpctx) {
- return ENOMEM;
- }
-
- ipa_opts->id = talloc_zero(ipa_opts, struct sdap_options);
- if (!ipa_opts->id) {
- ret = ENOMEM;
- goto done;
- }
-
- /* get sdap options */
- ret = dp_get_options(ipa_opts->id, cdb, conf_path,
- ipa_def_ldap_opts,
- SDAP_OPTS_BASIC,
- &ipa_opts->id->basic);
- if (ret != EOK) {
- goto done;
- }
-
- if (NULL == dp_opt_get_string(ipa_opts->id->basic, SDAP_SEARCH_BASE)) {
- ret = domain_to_basedn(tmpctx,
- dp_opt_get_string(ipa_opts->basic, IPA_DOMAIN),
- &basedn);
- if (ret != EOK) {
- goto done;
- }
-
- /* FIXME: get values by querying IPA */
- /* set search base */
- value = talloc_asprintf(tmpctx, "cn=accounts,%s", basedn);
- if (!value) {
- ret = ENOMEM;
- goto done;
- }
- ret = dp_opt_set_string(ipa_opts->id->basic,
- SDAP_SEARCH_BASE, value);
- if (ret != EOK) {
- goto done;
- }
- DEBUG(6, ("Option %s set to %s\n",
- ipa_opts->id->basic[SDAP_SEARCH_BASE].opt_name,
- dp_opt_get_string(ipa_opts->id->basic, SDAP_SEARCH_BASE)));
- }
-
- /* set the ldap_sasl_authid if the ipa_hostname override was specified */
- if (NULL == dp_opt_get_string(ipa_opts->id->basic, SDAP_SASL_AUTHID)) {
- hostname = dp_opt_get_string(ipa_opts->basic, IPA_HOSTNAME);
- if (hostname) {
- value = talloc_asprintf(tmpctx, "host/%s", hostname);
- if (!value) {
- ret = ENOMEM;
- goto done;
- }
- ret = dp_opt_set_string(ipa_opts->id->basic,
- SDAP_SASL_AUTHID, value);
- if (ret != EOK) {
- goto done;
- }
- }
- DEBUG(6, ("Option %s set to %s\n",
- ipa_opts->id->basic[SDAP_SASL_AUTHID].opt_name,
- dp_opt_get_string(ipa_opts->id->basic, SDAP_SASL_AUTHID)));
- }
-
- /* set krb realm */
- if (NULL == dp_opt_get_string(ipa_opts->id->basic, SDAP_KRB5_REALM)) {
- realm = dp_opt_get_string(ipa_opts->basic, IPA_DOMAIN);
- for (i = 0; realm[i]; i++) {
- realm[i] = toupper(realm[i]);
- }
- ret = dp_opt_set_string(ipa_opts->id->basic,
- SDAP_KRB5_REALM, realm);
- if (ret != EOK) {
- goto done;
- }
- DEBUG(6, ("Option %s set to %s\n",
- ipa_opts->id->basic[SDAP_KRB5_REALM].opt_name,
- dp_opt_get_string(ipa_opts->id->basic, SDAP_KRB5_REALM)));
- }
-
- /* fix schema to IPAv1 for now */
- ipa_opts->id->schema_type = SDAP_SCHEMA_IPA_V1;
-
- /* set user/group search bases if they are not specified */
- if (NULL == dp_opt_get_string(ipa_opts->id->basic,
- SDAP_USER_SEARCH_BASE)) {
- ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_USER_SEARCH_BASE,
- dp_opt_get_string(ipa_opts->id->basic,
- SDAP_SEARCH_BASE));
- if (ret != EOK) {
- goto done;
- }
- DEBUG(6, ("Option %s set to %s\n",
- ipa_opts->id->basic[SDAP_USER_SEARCH_BASE].opt_name,
- dp_opt_get_string(ipa_opts->id->basic,
- SDAP_USER_SEARCH_BASE)));
- }
-
- if (NULL == dp_opt_get_string(ipa_opts->id->basic,
- SDAP_GROUP_SEARCH_BASE)) {
- ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_GROUP_SEARCH_BASE,
- dp_opt_get_string(ipa_opts->id->basic,
- SDAP_SEARCH_BASE));
- if (ret != EOK) {
- goto done;
- }
- DEBUG(6, ("Option %s set to %s\n",
- ipa_opts->id->basic[SDAP_GROUP_SEARCH_BASE].opt_name,
- dp_opt_get_string(ipa_opts->id->basic,
- SDAP_GROUP_SEARCH_BASE)));
- }
-
- ret = sdap_get_map(ipa_opts->id, cdb, conf_path,
- ipa_attr_map,
- SDAP_AT_GENERAL,
- &ipa_opts->id->gen_map);
- if (ret != EOK) {
- goto done;
- }
-
- ret = sdap_get_map(ipa_opts->id,
- cdb, conf_path,
- ipa_user_map,
- SDAP_OPTS_USER,
- &ipa_opts->id->user_map);
- if (ret != EOK) {
- goto done;
- }
-
- ret = sdap_get_map(ipa_opts->id,
- cdb, conf_path,
- ipa_group_map,
- SDAP_OPTS_GROUP,
- &ipa_opts->id->group_map);
- if (ret != EOK) {
- goto done;
- }
-
- ret = EOK;
- *_opts = ipa_opts->id;
-
-done:
- talloc_zfree(tmpctx);
- if (ret != EOK) {
- talloc_zfree(ipa_opts->id);
- }
- return ret;
-}
-
-/* the following define is used to keep track of * the options in the krb5
- * module, so that if they change and ipa is not updated correspondingly
- * this will trigger a runtime abort error */
-#define IPA_KRB5_OPTS_TEST 8
-
-int ipa_get_auth_options(struct ipa_options *ipa_opts,
- struct confdb_ctx *cdb,
- const char *conf_path,
- struct dp_option **_opts)
-{
- char *value;
- int ret;
- int i;
-
- /* self check test, this should never fail, unless someone forgot
- * to properly update the code after new ldap options have been added */
- if (KRB5_OPTS != IPA_KRB5_OPTS_TEST) {
- DEBUG(0, ("Option numbers do not match (%d != %d)\n",
- KRB5_OPTS, IPA_KRB5_OPTS_TEST));
- abort();
- }
-
- ipa_opts->auth = talloc_zero(ipa_opts, struct dp_option);
- if (ipa_opts->auth == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
- /* get krb5 options */
- ret = dp_get_options(ipa_opts, cdb, conf_path,
- ipa_def_krb5_opts,
- KRB5_OPTS, &ipa_opts->auth);
- if (ret != EOK) {
- goto done;
- }
-
- /* set krb realm */
- if (NULL == dp_opt_get_string(ipa_opts->auth, KRB5_REALM)) {
- value = dp_opt_get_string(ipa_opts->basic, IPA_DOMAIN);
- if (!value) {
- ret = ENOMEM;
- goto done;
- }
- for (i = 0; value[i]; i++) {
- value[i] = toupper(value[i]);
- }
- ret = dp_opt_set_string(ipa_opts->auth, KRB5_REALM, value);
- if (ret != EOK) {
- goto done;
- }
- DEBUG(6, ("Option %s set to %s\n",
- ipa_opts->auth[KRB5_REALM].opt_name,
- dp_opt_get_string(ipa_opts->auth, KRB5_REALM)));
- }
-
- *_opts = ipa_opts->auth;
- ret = EOK;
-
-done:
- if (ret != EOK) {
- talloc_zfree(ipa_opts->auth);
- }
- return ret;
-}
-
-static void ipa_resolve_callback(void *private_data, struct fo_server *server)
-{
- struct ipa_service *service;
- struct hostent *srvaddr;
- char *address;
- char *new_uri;
- int ret;
-
- service = talloc_get_type(private_data, struct ipa_service);
- if (!service) {
- DEBUG(1, ("FATAL: Bad private_data\n"));
- return;
- }
-
- srvaddr = fo_get_server_hostent(server);
- if (!srvaddr) {
- DEBUG(1, ("FATAL: No hostent available for server (%s)\n",
- fo_get_server_name(server)));
- return;
- }
-
- address = talloc_asprintf(service, "%s", srvaddr->h_name);
- if (!address) {
- DEBUG(1, ("Failed to copy address ...\n"));
- return;
- }
-
- new_uri = talloc_asprintf(service, "ldap://%s", address);
- if (!new_uri) {
- DEBUG(2, ("Failed to copy URI ...\n"));
- talloc_free(address);
- return;
- }
-
- /* free old one and replace with new one */
- talloc_zfree(service->sdap->uri);
- service->sdap->uri = new_uri;
- talloc_zfree(service->krb5_service->address);
- service->krb5_service->address = address;
-
- ret = write_kdcinfo_file(service->krb5_service->realm, address);
- if (ret != EOK) {
- DEBUG(2, ("write_kdcinfo_file failed, authentication might fail.\n"));
- }
-
-}
-
-int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
- const char *servers, const char *domain,
- struct ipa_service **_service)
-{
- TALLOC_CTX *tmp_ctx;
- struct ipa_service *service;
- char **list = NULL;
- char *realm;
- int ret;
- int i;
-
- tmp_ctx = talloc_new(memctx);
- if (!tmp_ctx) {
- return ENOMEM;
- }
-
- service = talloc_zero(tmp_ctx, struct ipa_service);
- if (!service) {
- ret = ENOMEM;
- goto done;
- }
- service->sdap = talloc_zero(service, struct sdap_service);
- if (!service->sdap) {
- ret = ENOMEM;
- goto done;
- }
- service->krb5_service = talloc_zero(service, struct krb5_service);
- if (!service->krb5_service) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = be_fo_add_service(ctx, "IPA");
- if (ret != EOK) {
- DEBUG(1, ("Failed to create failover service!\n"));
- goto done;
- }
-
- service->sdap->name = talloc_strdup(service, "IPA");
- if (!service->sdap->name) {
- ret = ENOMEM;
- goto done;
- }
-
- service->krb5_service->name = talloc_strdup(service, "IPA");
- if (!service->krb5_service->name) {
- ret = ENOMEM;
- goto done;
- }
-
- realm = talloc_strdup(service, domain);
- if (!realm) {
- ret = ENOMEM;
- goto done;
- }
- for (i = 0; realm[i]; i++) {
- realm[i] = toupper(realm[i]);
- }
- service->krb5_service->realm = realm;
-
- /* split server parm into a list */
- ret = split_on_separator(tmp_ctx, servers, ',', true, &list, NULL);
- if (ret != EOK) {
- DEBUG(1, ("Failed to parse server list!\n"));
- goto done;
- }
-
- /* now for each one add a new server to the failover service */
- for (i = 0; list[i]; i++) {
-
- talloc_steal(service, list[i]);
-
- ret = be_fo_add_server(ctx, "IPA", list[i], 0, NULL);
- if (ret && ret != EEXIST) {
- DEBUG(0, ("Failed to add server\n"));
- goto done;
- }
-
- DEBUG(6, ("Added Server %s\n", list[i]));
- }
-
- ret = be_fo_service_add_callback(memctx, ctx, "IPA",
- ipa_resolve_callback, service);
- if (ret != EOK) {
- DEBUG(1, ("Failed to add failover callback!\n"));
- goto done;
- }
-
- ret = EOK;
-
-done:
- if (ret == EOK) {
- *_service = talloc_steal(memctx, service);
- }
- talloc_zfree(tmp_ctx);
- return ret;
-}
-
diff --git a/server/providers/ipa/ipa_common.h b/server/providers/ipa/ipa_common.h
deleted file mode 100644
index 60c7313f..00000000
--- a/server/providers/ipa/ipa_common.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- SSSD
-
- IPA Common utility code
-
- Copyright (C) Simo Sorce <ssorce@redhat.com> 2009
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _IPA_COMMON_H_
-#define _IPA_COMMON_H_
-
-#include "util/util.h"
-#include "confdb/confdb.h"
-#include "providers/ldap/ldap_common.h"
-#include "providers/krb5/krb5_common.h"
-
-struct ipa_service {
- struct sdap_service *sdap;
- struct krb5_service *krb5_service;
-};
-
-/* the following define is used to keep track of the options in the ldap
- * module, so that if they change and ipa is not updated correspondingly
- * this will trigger a runtime abort error */
-#define IPA_OPTS_BASIC_TEST 31
-
-enum ipa_basic_opt {
- IPA_DOMAIN = 0,
- IPA_SERVER,
- IPA_HOSTNAME,
-
- IPA_OPTS_BASIC /* opts counter */
-};
-
-struct ipa_options {
- struct dp_option *basic;
-
- struct ipa_service *service;
-
- /* id provider */
- struct sdap_options *id;
- struct sdap_id_ctx *id_ctx;
-
- /* auth and chpass provider */
- struct dp_option *auth;
- struct krb5_ctx *auth_ctx;
-};
-
-/* options parsers */
-int ipa_get_options(TALLOC_CTX *memctx,
- struct confdb_ctx *cdb,
- const char *conf_path,
- struct sss_domain_info *dom,
- struct ipa_options **_opts);
-
-int ipa_get_id_options(struct ipa_options *ipa_opts,
- struct confdb_ctx *cdb,
- const char *conf_path,
- struct sdap_options **_opts);
-
-int ipa_get_auth_options(struct ipa_options *ipa_opts,
- struct confdb_ctx *cdb,
- const char *conf_path,
- struct dp_option **_opts);
-
-int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
- const char *servers, const char *domain,
- struct ipa_service **_service);
-
-#endif /* _IPA_COMMON_H_ */
diff --git a/server/providers/ipa/ipa_init.c b/server/providers/ipa/ipa_init.c
deleted file mode 100644
index 10b9257a..00000000
--- a/server/providers/ipa/ipa_init.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- SSSD
-
- IPA Provider Initialization functions
-
- Authors:
- Simo Sorce <ssorce@redhat.com>
-
- Copyright (C) 2009 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include "providers/child_common.h"
-#include "providers/ipa/ipa_common.h"
-#include "providers/krb5/krb5_auth.h"
-#include "providers/ipa/ipa_auth.h"
-#include "providers/ipa/ipa_access.h"
-#include "providers/ipa/ipa_timerules.h"
-
-struct ipa_options *ipa_options = NULL;
-
-/* Id Handler */
-struct bet_ops ipa_id_ops = {
- .handler = sdap_account_info_handler,
- .finalize = NULL
-};
-
-struct bet_ops ipa_auth_ops = {
- .handler = ipa_auth,
- .finalize = NULL,
-};
-
-struct bet_ops ipa_chpass_ops = {
- .handler = krb5_pam_handler,
- .finalize = NULL,
-};
-
-struct bet_ops ipa_access_ops = {
- .handler = ipa_access_handler,
- .finalize = NULL
-};
-
-int common_ipa_init(struct be_ctx *bectx)
-{
- const char *ipa_servers;
- const char *ipa_domain;
- int ret;
-
- ret = ipa_get_options(bectx, bectx->cdb,
- bectx->conf_path,
- bectx->domain, &ipa_options);
- if (ret != EOK) {
- return ret;
- }
-
- ipa_servers = dp_opt_get_string(ipa_options->basic, IPA_SERVER);
- if (!ipa_servers) {
- DEBUG(0, ("Missing ipa_server option!\n"));
- return EINVAL;
- }
-
- ipa_domain = dp_opt_get_string(ipa_options->basic, IPA_DOMAIN);
- if (!ipa_domain) {
- DEBUG(0, ("Missing ipa_domain option!\n"));
- return EINVAL;
- }
-
- ret = ipa_service_init(ipa_options, bectx, ipa_servers, ipa_domain,
- &ipa_options->service);
- if (ret != EOK) {
- DEBUG(0, ("Failed to init IPA failover service!\n"));
- return ret;
- }
-
- return EOK;
-}
-
-int sssm_ipa_init(struct be_ctx *bectx,
- struct bet_ops **ops,
- void **pvt_data)
-{
- struct sdap_id_ctx *ctx;
- int ret;
-
- if (!ipa_options) {
- ret = common_ipa_init(bectx);
- if (ret != EOK) {
- return ret;
- }
- }
-
- if (ipa_options->id_ctx) {
- /* already initialized */
- *ops = &ipa_id_ops;
- *pvt_data = ipa_options->id_ctx;
- return EOK;
- }
-
- ctx = talloc_zero(ipa_options, struct sdap_id_ctx);
- if (!ctx) {
- return ENOMEM;
- }
- ctx->be = bectx;
- ctx->service = ipa_options->service->sdap;
- ipa_options->id_ctx = ctx;
-
- ret = ipa_get_id_options(ipa_options, bectx->cdb,
- bectx->conf_path,
- &ctx->opts);
- if (ret != EOK) {
- goto done;
- }
-
- ret = setup_tls_config(ctx->opts->basic);
- if (ret != EOK) {
- DEBUG(1, ("setup_tls_config failed [%d][%s].\n",
- ret, strerror(ret)));
- goto done;
- }
-
- ret = sdap_id_setup_tasks(ctx);
- if (ret != EOK) {
- goto done;
- }
-
- ret = setup_child(ctx);
- if (ret != EOK) {
- DEBUG(1, ("setup_child failed [%d][%s].\n",
- ret, strerror(ret)));
- goto done;
- }
-
- *ops = &ipa_id_ops;
- *pvt_data = ctx;
- ret = EOK;
-
-done:
- if (ret != EOK) {
- talloc_zfree(ipa_options->id_ctx);
- }
- return ret;
-}
-
-int sssm_ipa_auth_init(struct be_ctx *bectx,
- struct bet_ops **ops,
- void **pvt_data)
-{
- struct krb5_ctx *ctx;
- struct tevent_signal *sige;
- FILE *debug_filep;
- unsigned v;
- int ret;
-
- if (!ipa_options) {
- ret = common_ipa_init(bectx);
- if (ret != EOK) {
- return ret;
- }
- }
-
- if (ipa_options->auth_ctx) {
- /* already initialized */
- *ops = &ipa_auth_ops;
- *pvt_data = ipa_options->auth_ctx;
- return EOK;
- }
-
- ctx = talloc_zero(bectx, struct krb5_ctx);
- if (!ctx) {
- return ENOMEM;
- }
- ctx->service = ipa_options->service->krb5_service;
- ipa_options->auth_ctx = ctx;
-
- ret = ipa_get_auth_options(ipa_options, bectx->cdb,
- bectx->conf_path,
- &ctx->opts);
- if (ret != EOK) {
- goto done;
- }
-
- ret = check_and_export_options(ctx->opts, bectx->domain);
- if (ret != EOK) {
- DEBUG(1, ("check_and_export_opts failed.\n"));
- goto done;
- }
-
- sige = tevent_add_signal(bectx->ev, ctx, SIGCHLD, SA_SIGINFO,
- child_sig_handler, NULL);
- if (sige == NULL) {
- DEBUG(1, ("tevent_add_signal failed.\n"));
- ret = ENOMEM;
- goto done;
- }
-
- if (debug_to_file != 0) {
- ret = open_debug_file_ex("krb5_child", &debug_filep);
- if (ret != EOK) {
- DEBUG(0, ("Error setting up logging (%d) [%s]\n",
- ret, strerror(ret)));
- goto done;
- }
-
- ctx->child_debug_fd = fileno(debug_filep);
- if (ctx->child_debug_fd == -1) {
- DEBUG(0, ("fileno failed [%d][%s]\n", errno, strerror(errno)));
- ret = errno;
- goto done;
- }
-
- v = fcntl(ctx->child_debug_fd, F_GETFD, 0);
- fcntl(ctx->child_debug_fd, F_SETFD, v & ~FD_CLOEXEC);
- }
-
- *ops = &ipa_auth_ops;
- *pvt_data = ctx;
- ret = EOK;
-
-done:
- if (ret != EOK) {
- talloc_zfree(ipa_options->auth_ctx);
- }
- return ret;
-}
-
-int sssm_ipa_chpass_init(struct be_ctx *bectx,
- struct bet_ops **ops,
- void **pvt_data)
-{
- int ret;
- ret = sssm_ipa_auth_init(bectx, ops, pvt_data);
- *ops = &ipa_chpass_ops;
- return ret;
-}
-
-int sssm_ipa_access_init(struct be_ctx *bectx,
- struct bet_ops **ops,
- void **pvt_data)
-{
- int ret;
- struct ipa_access_ctx *ipa_access_ctx;
-
- ipa_access_ctx = talloc_zero(bectx, struct ipa_access_ctx);
- if (ipa_access_ctx == NULL) {
- DEBUG(1, ("talloc_zero failed.\n"));
- return ENOMEM;
- }
-
- ret = sssm_ipa_init(bectx, ops, (void **) &ipa_access_ctx->sdap_ctx);
- if (ret != EOK) {
- DEBUG(1, ("sssm_ipa_init failed.\n"));
- goto done;
- }
-
- ret = dp_copy_options(ipa_access_ctx, ipa_options->basic,
- IPA_OPTS_BASIC, &ipa_access_ctx->ipa_options);
- if (ret != EOK) {
- DEBUG(1, ("dp_copy_options failed.\n"));
- goto done;
- }
-
- ret = init_time_rules_parser(ipa_access_ctx, &ipa_access_ctx->tr_ctx);
- if (ret != EOK) {
- DEBUG(1, ("init_time_rules_parser failed.\n"));
- goto done;
- }
-
- *ops = &ipa_access_ops;
- *pvt_data = ipa_access_ctx;
-
-done:
- if (ret != EOK) {
- talloc_free(ipa_access_ctx);
- }
- return ret;
-}
diff --git a/server/providers/ipa/ipa_timerules.c b/server/providers/ipa/ipa_timerules.c
deleted file mode 100644
index 1a52eef1..00000000
--- a/server/providers/ipa/ipa_timerules.c
+++ /dev/null
@@ -1,1186 +0,0 @@
-/*
- SSSD
-
- IPA Provider Time Rules Parsing
-
- Authors:
- Jakub Hrozek <jhrozek@redhat.com>
-
- Copyright (C) Red Hat, Inc 2009
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define _XOPEN_SOURCE /* strptime() needs this */
-
-#include <pcre.h>
-#include <talloc.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <time.h>
-#include <stdbool.h>
-#include <limits.h>
-
-#include "providers/ipa/ipa_timerules.h"
-#include "util/util.h"
-
-#define JMP_NEOK(variable) do { \
- if (variable != EOK) goto done; \
-} while (0)
-
-#define JMP_NEOK_LABEL(variable, label) do { \
- if (variable != EOK) goto label; \
-} while (0)
-
-#define CHECK_PTR(ptr) do { \
- if (ptr == NULL) { \
- return ENOMEM; \
- } \
-} while (0)
-
-#define CHECK_PTR_JMP(ptr) do { \
- if (ptr == NULL) { \
- ret = ENOMEM; \
- goto done; \
- } \
-} while (0)
-
-#define BUFFER_OR_JUMP(ctx, ptr, count) do { \
- ptr = talloc_array(ctx, unsigned char, count); \
- if (ptr == NULL) { \
- return ENOMEM; \
- } \
- memset(ptr, 0, sizeof(unsigned char)*count); \
-} while (0)
-
-#define TEST_BIT_RANGE(bitfield, index, resptr) do { \
- if (bitfield) { \
- if (test_bit(&bitfield, index) == 0) { \
- *resptr = false; \
- return EOK; \
- } \
- } \
-} while (0)
-
-#define TEST_BIT_RANGE_PTR(bitfield, index, resptr) do { \
- if (bitfield) { \
- if (test_bit(bitfield, index) == 0) { \
- *resptr = false; \
- return EOK; \
- } \
- } \
-} while (0)
-
-/* number of match offsets when matching pcre regexes */
-#define OVEC_SIZE 30
-
-/* regular expressions describing syntax of our HBAC grammar */
-#define RGX_WEEKLY "day (?P<day_of_week>(0|1|2|3|4|5|6|7|Mon|Tue|Wed|Thu|Fri|Sat|Sun|,|-)+)"
-
-#define RGX_MDAY "(?P<mperspec_day>day) (?P<interval_day>[0-9,-]+) "
-#define RGX_MWEEK "(?P<mperspec_week>week) (?P<interval_week>[0-9,-]+) "RGX_WEEKLY
-#define RGX_MONTHLY RGX_MDAY"|"RGX_MWEEK
-
-#define RGX_YDAY "(?P<yperspec_day>day) (?P<day_of_year>[0-9,-]+) "
-#define RGX_YWEEK "(?P<yperspec_week>week) (?P<week_of_year>[0-9,-]+) "RGX_WEEKLY
-#define RGX_YMONTH "(?P<yperspec_month>month) (?P<month_number>[0-9,-]+) (?P<m_period>.*?)$"
-#define RGX_YEARLY RGX_YMONTH"|"RGX_YWEEK"|"RGX_YDAY
-
-#define RGX_TIMESPEC "(?P<timeFrom>[0-9]{4}) ~ (?P<timeTo>[0-9]{4})"
-
-#define RGX_GENERALIZED "(?P<year>[0-9]{4})(?P<month>[0-9]{2})(?P<day>[0-9]{2})(?P<hour>[0-9]{2})?(?P<minute>[0-9]{2})?(?P<second>[0-9]{2})?"
-
-#define RGX_PERIODIC "^periodic (?P<perspec>daily|weekly|monthly|yearly) (?P<period>.*?)"RGX_TIMESPEC"$"
-#define RGX_ABSOLUTE "^absolute (?P<from>\\S+) ~ (?P<to>\\S+)$"
-
-/* limits on various parameters */
-#define DAY_OF_WEEK_MAX 7
-#define DAY_OF_MONTH_MAX 31
-#define WEEK_OF_MONTH_MAX 5
-#define WEEK_OF_YEAR_MAX 54
-#define DAY_OF_YEAR_MAX 366
-#define MONTH_MAX 12
-#define HOUR_MAX 23
-#define MINUTE_MAX 59
-
-/* limits on sizes of buffers for bit arrays */
-#define DAY_OF_MONTH_BUFSIZE 8
-#define DAY_OF_YEAR_BUFSIZE 44
-#define WEEK_OF_YEAR_BUFSIZE 13
-#define MONTH_BUFSIZE 2
-#define HOUR_BUFSIZE 4
-#define MINUTE_BUFSIZE 8
-
-/* Lookup tables for translating names of days and months */
-static const char *names_day_of_week[] =
- { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", NULL };
-static const char *names_months[] =
- { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Nov", "Dec", NULL };
-
-/*
- * Timelib knows two types of ranges - periodic and absolute
- */
-enum rangetypes {
- TYPE_ABSOLUTE,
- TYPE_PERIODIC
-};
-
-struct absolute_range {
- time_t time_from;
- time_t time_to;
-};
-
-struct periodic_range {
- unsigned char day_of_week;
- unsigned char *day_of_month;
- unsigned char *day_of_year;
- unsigned char week_of_month;
- unsigned char *week_of_year;
- unsigned char *month;
- unsigned char *hour;
- unsigned char *minute;
-};
-
-/*
- * Context of one time rule being analyzed
- */
-struct range_ctx {
- /* main context with precompiled patterns */
- struct time_rules_ctx *trctx;
- /* enum rangetypes */
- enum rangetypes type;
-
- struct absolute_range *abs;
- struct periodic_range *per;
-};
-
-
-/*
- * The context of one regular expression
- */
-struct parse_ctx {
- /* the regular expression used for one parsing */
- pcre *re;
- /* number of matches */
- int matches;
- /* vector of matches */
- int *ovec;
-};
-
-/* indexes to the array of precompiled regexes */
-enum timelib_rgx {
- LP_RGX_GENERALIZED,
- LP_RGX_MDAY,
- LP_RGX_MWEEK,
- LP_RGX_YEARLY,
- LP_RGX_WEEKLY,
- LP_RGX_ABSOLUTE,
- LP_RGX_PERIODIC,
- LP_RGX_MAX,
-};
-
-/* matches the indexes */
-static const char *lookup_table[] = {
- RGX_GENERALIZED,
- RGX_MDAY,
- RGX_MWEEK,
- RGX_YEARLY,
- RGX_WEEKLY,
- RGX_ABSOLUTE,
- RGX_PERIODIC,
- NULL,
-};
-
-/*
- * Main struct passed outside
- * holds precompiled regular expressions
- */
-struct time_rules_ctx {
- pcre *re[LP_RGX_MAX];
-};
-
-/*******************************************************************
- * helper function - bit arrays *
- *******************************************************************/
-
-/* set a single bit in a bitmap */
-static void set_bit(unsigned char *bitmap, unsigned int bit)
-{
- bitmap[bit/CHAR_BIT] |= 1 << (bit%CHAR_BIT);
-}
-
-/*
- * This function is based on bit_nset macro written originally by Paul Vixie,
- * copyrighted by The Regents of the University of California, as found
- * in tarball of fcron, file bitstring.h
- */
-static void set_bit_range(unsigned char *bitmap, unsigned int start,
- unsigned int stop)
-{
- int startbyte = start/CHAR_BIT;
- int stopbyte = stop/CHAR_BIT;
-
- if (startbyte == stopbyte) {
- bitmap[startbyte] |= ((0xff << (start & 0x7)) &
- (0xff >> (CHAR_BIT- 1 - (stop & 0x7))));
- } else {
- bitmap[startbyte] |= 0xff << (start & 0x7);
- while (++startbyte < stopbyte) {
- bitmap[startbyte] |= 0xff;
- }
- bitmap[stopbyte] |= 0xff >> (CHAR_BIT- 1 - (stop & 0x7));
- }
-}
-
-static int test_bit(unsigned char *bitmap, unsigned int bit)
-{
- return (int)(bitmap[bit/CHAR_BIT] >> (bit%CHAR_BIT)) & 1;
-}
-
-/*******************************************************************
- * parsing intervals *
- *******************************************************************/
-
-/*
- * Some ranges allow symbolic names, like Mon..Sun for names of day.
- * This routine takes a list of symbolic names as NAME_ARRAY and the
- * one we're looking for as KEY and returns its index or -1 when not
- * found. The last member of NAME_ARRAY must be NULL.
- */
-static int name_index(const char **name_array, const char *key, int min)
-{
- int index = 0;
- const char *one;
-
- if (name_array == NULL) {
- return -1;
- }
-
- while ((one = name_array[index]) != NULL) {
- if (strcmp(key,one) == 0) {
- return index+min;
- }
- index++;
- }
-
- return -1;
-}
-
-/*
- * Sets appropriate bits given by an interval in STR (in form of 1,5-7,10) to
- * a bitfield given in OUT. Does no boundary checking. STR can also contain
- * symbolic names, these would be given in TRANSLATE.
- */
-static int interval2bitfield(TALLOC_CTX *mem_ctx,
- unsigned char *out,
- const char *str,
- int min, int max,
- const char **translate)
-{
- char *copy;
- char *next, *token;
- int tokval, tokmax;
- char *end_ptr;
- int ret;
- char *dash;
-
- DEBUG(9, ("Converting '%s' to interval\n", str));
-
- copy = talloc_strdup(mem_ctx, str);
- CHECK_PTR(copy);
-
- next = copy;
- while (next) {
- token = next;
- next = strchr(next, ',');
- if (next) {
- *next = '\0';
- next++;
- }
-
- errno = 0;
- tokval = strtol(token, &end_ptr, 10);
- if (*end_ptr == '\0' && errno == 0) {
- if (tokval <= max && tokval >= 0) {
- set_bit(out, tokval);
- continue;
- } else {
- ret = ERANGE;
- goto done;
- }
- } else if ((dash = strchr(token, '-')) != NULL){
- *dash = '\0';
- ++dash;
-
- errno = 0;
- tokval = strtol(token, &end_ptr, 10);
- if (*end_ptr != '\0' || errno != 0) {
- tokval = name_index(translate, token, min);
- if (tokval == -1) {
- ret = ERANGE;
- goto done;
- }
- }
- errno = 0;
- tokmax = strtol(dash, &end_ptr, 10);
- if (*end_ptr != '\0' || errno != 0) {
- tokmax = name_index(translate, dash, min);
- if (tokmax == -1) {
- ret = ERANGE;
- goto done;
- }
- }
-
- if (tokval <= max && tokmax <= max &&
- tokval >= min && tokmax >= min) {
- if (tokmax > tokval) {
- DEBUG(7, ("Setting interval %d-%d\n", tokval, tokmax));
- DEBUG(9, ("interval: %p\n", out));
- set_bit_range(out, tokval, tokmax);
- } else {
- /* Interval wraps around - i.e. from 18.00 to 06.00 */
- DEBUG(7, ("Setting inverted interval %d-%d\n", tokval, tokmax));
- DEBUG(9, ("interval: %p\n", out));
- set_bit_range(out, min, tokmax);
- set_bit_range(out, tokval, max);
- }
- continue;
- } else {
- /* tokval or tokmax are not between <min, max> */
- ret = ERANGE;
- goto done;
- }
- } else if ((tokval = name_index(translate, token, min)) != -1) {
- /* Try to translate one token by name */
- if (tokval <= max) {
- set_bit(out, tokval);
- continue;
- } else {
- ret = ERANGE;
- goto done;
- }
- } else {
- ret = EINVAL;
- goto done;
- }
- }
-
- ret = EOK;
-done:
- talloc_free(copy);
- return ret;
-}
-
-/*******************************************************************
- * wrappers around regexp handling *
- *******************************************************************/
-
-/*
- * Copies a named substring SUBSTR_NAME from string STR using the parsing
- * information from PCTX. The context PCTX is also used as a talloc context.
- *
- * The resulting string is stored in OUT.
- * Return value is EOK on no error or ENOENT on error capturing the substring
- */
-static int copy_substring(struct parse_ctx *pctx,
- const char *str,
- const char *substr_name,
- char **out)
-{
- const char *result = NULL;
- int ret;
- char *o = NULL;
-
- result = NULL;
-
- ret = pcre_get_named_substring(pctx->re, str, pctx->ovec,
- pctx->matches, substr_name, &result);
- if (ret < 0 || result == NULL) {
- DEBUG(5, ("named substring '%s' does not exist in '%s'\n",
- substr_name, str));
- return ENOENT;
- }
-
- o = talloc_strdup(pctx, result);
- pcre_free_substring(result);
- if (o == NULL) {
- return ENOMEM;
- }
-
- DEBUG(9, ("Copied substring named '%s' value '%s'\n", substr_name, o));
-
- *out = o;
- return EOK;
-}
-
-/*
- * Copies a named substring SUBSTR_NAME from string STR using the parsing
- * information from PCTX and converts it to an integer.
- * The context PCTX is also used as a talloc context.
- *
- * The resulting string is stored in OUT.
- * Return value is EOK on no error or ENOENT on error capturing the substring
- */
-static int substring_strtol(struct parse_ctx *pctx,
- const char *str,
- const char *substr_name,
- int *out)
-{
- char *substr = NULL;
- int ret;
- int val;
- char *err_ptr;
-
- ret = copy_substring(pctx, str, substr_name, &substr);
- if (ret != EOK) {
- DEBUG(5, ("substring '%s' does not exist\n", substr_name));
- return ret;
- }
-
- errno = 0;
- val = strtol(substr, &err_ptr, 10);
- if (substr == '\0' || *err_ptr != '\0' || errno != 0) {
- DEBUG(5, ("substring '%s' does not contain an integerexist\n",
- substr));
- talloc_free(substr);
- return EINVAL;
- }
-
- *out = val;
- talloc_free(substr);
- return EOK;
-}
-
-/*
- * Compiles a regular expression REGEXP and tries to match it against the
- * string STR. Fills in structure _PCTX with info about matching.
- *
- * Returns EOK on no error, EFAULT on bad regexp, EINVAL when it cannot
- * match the regexp.
- */
-static int matches_regexp(TALLOC_CTX *ctx,
- struct time_rules_ctx *trctx,
- const char *str,
- enum timelib_rgx regex,
- struct parse_ctx **_pctx)
-{
- int ret;
- struct parse_ctx *pctx = NULL;
-
- pctx = talloc_zero(ctx, struct parse_ctx);
- CHECK_PTR(pctx);
- pctx->ovec = talloc_array(pctx, int, OVEC_SIZE);
- CHECK_PTR_JMP(pctx->ovec);
- pctx->re = trctx->re[regex];
-
- ret = pcre_exec(pctx->re, NULL, str, strlen(str), 0, PCRE_NOTEMPTY, pctx->ovec, OVEC_SIZE);
- if (ret <= 0) {
- DEBUG(8, ("string '%s' did *NOT* match regexp '%s'\n", str, lookup_table[regex]));
- ret = EINVAL;
- goto done;
- }
- DEBUG(8, ("string '%s' matched regexp '%s'\n", str, lookup_table[regex]));
-
- pctx->matches = ret;
- *_pctx = pctx;
- return EOK;
-
-done:
- talloc_free(pctx);
- return ret;
-}
-
-/*******************************************************************
- * date/time helper functions *
- *******************************************************************/
-
-/*
- * Returns week number as an integer
- * This may seem ugly, but I think it's actually less error prone
- * than writing my own routine
- */
-static int weeknum(const struct tm *t)
-{
- char buf[3];
-
- if (!strftime(buf, 3, "%U", t)) {
- return -1;
- }
-
- /* %U returns 0-53, we want 1-54 */
- return atoi(buf)+1;
-}
-
-/*
- * Return the week of the month
- * Range is 1 to 5
- */
-static int get_week_of_month(const struct tm *t)
-{
- int fs; /* first sunday */
-
- fs = (t->tm_mday % 7) - t->tm_wday;
- if (fs <= 0) {
- fs += 7;
- }
-
- return (t->tm_mday <= fs) ? 1 : (2 + (t->tm_mday - fs - 1) / 7);
-}
-
-/*
- * Normalize differencies between our HBAC definition and semantics of
- * struct tm
- */
-static void abs2tm(struct tm *t)
-{
- /* tm defines tm_year as num of yrs since 1900, we have absolute number */
- t->tm_year %= 1900;
- /* struct tm defines tm_mon as number of month since January */
- t->tm_mon--;
-}
-
-/*
- * Normalize differencies between our HBAC definition and semantics of
- * struct tm
- */
-static void tm2abs(struct tm *t)
-{
- /* tm defines tm_year as num of yrs since 1900, we have absolute number */
- t->tm_year += 1900;
- /* struct tm defines tm_mon as number of month since January */
- t->tm_mon++;
-}
-
-/*******************************************************************
- * parsing of HBAC rules themselves *
- *******************************************************************/
-
-/*
- * Parses generalized time string given in STR and fills the
- * information into OUT.
- */
-static int parse_generalized_time(struct parse_ctx *pctx,
- struct time_rules_ctx *trctx,
- const char *str,
- time_t *out)
-{
- int ret;
- struct parse_ctx *gctx = NULL;
- struct tm tm;
-
- memset(&tm, 0, sizeof(tm));
- tm.tm_isdst = -1;
-
- ret = matches_regexp(pctx, trctx, str, LP_RGX_GENERALIZED, &gctx);
- JMP_NEOK(ret);
-
- /* compulsory */
- ret = substring_strtol(gctx, str, "year", &tm.tm_year);
- JMP_NEOK(ret);
- ret = substring_strtol(gctx, str, "month", &tm.tm_mon);
- JMP_NEOK(ret);
- ret = substring_strtol(gctx, str, "day", &tm.tm_mday);
- JMP_NEOK(ret);
- /* optional */
- ret = substring_strtol(gctx, str, "hour", &tm.tm_hour);
- JMP_NEOK_LABEL(ret, enoent);
- ret = substring_strtol(gctx, str, "minute", &tm.tm_min);
- JMP_NEOK_LABEL(ret, enoent);
- ret = substring_strtol(gctx, str, "second", &tm.tm_sec);
- JMP_NEOK_LABEL(ret, enoent);
-
-enoent:
- if (ret == ENOENT) {
- ret = EOK;
- }
-
- abs2tm(&tm);
-
- *out = mktime(&tm);
- DEBUG(3, ("converted to time: '%s'\n", ctime(out)));
- if (*out == -1) {
- ret = EINVAL;
- }
-done:
- talloc_free(gctx);
- return ret;
-}
-
-/*
- * Parses absolute timerange string given in STR and fills the
- * information into ABS.
- */
-static int parse_absolute(struct absolute_range *absr,
- struct time_rules_ctx *trctx,
- struct parse_ctx *pctx,
- const char *str)
-{
- char *from = NULL, *to = NULL;
- int ret;
-
- ret = copy_substring(pctx, str, "from", &from);
- if (ret != EOK) {
- DEBUG(1, ("Missing required part 'from' in absolute timespec\n"));
- ret = EINVAL;
- goto done;
- }
- ret = copy_substring(pctx, str, "to", &to);
- if (ret != EOK) {
- DEBUG(1, ("Missing required part 'to' in absolute timespec\n"));
- ret = EINVAL;
- goto done;
- }
-
- ret = parse_generalized_time(pctx, trctx, from, &absr->time_from);
- if (ret != EOK) {
- DEBUG(1, ("Cannot parse generalized time - first part\n"));
- goto done;
- }
-
- ret = parse_generalized_time(pctx, trctx, to, &absr->time_to);
- if (ret != EOK) {
- DEBUG(1, ("Cannot parse generalized time - second part\n"));
- goto done;
- }
-
- if (difftime(absr->time_to, absr->time_from) < 0) {
- DEBUG(1, ("Not a valid interval\n"));
- ret = EINVAL;
- }
-
- ret = EOK;
-done:
- talloc_free(from);
- talloc_free(to);
- return ret;
-}
-
-static int parse_hhmm(const char *str, int *hour, int *min)
-{
- struct tm t;
- char *err;
-
- err = strptime(str, "%H%M", &t);
- if (*err != '\0') {
- return EINVAL;
- }
-
- *hour = t.tm_hour;
- *min = t.tm_min;
-
- return EOK;
-}
-
-/*
- * Parses monthly periodic timerange given in STR.
- * Fills the information into PER.
- */
-static int parse_periodic_monthly(TALLOC_CTX *ctx,
- struct time_rules_ctx *trctx,
- struct periodic_range *per,
- const char *str)
-{
- int ret;
- struct parse_ctx *mpctx = NULL;
- char *match = NULL;
- char *mperspec = NULL;
-
- /* This code would be much less ugly if RHEL5 PCRE knew about PCRE_DUPNAMES */
- ret = matches_regexp(ctx, trctx, str, LP_RGX_MDAY, &mpctx);
- if (ret == EOK) {
- ret = copy_substring(mpctx, str, "mperspec_day", &mperspec);
- JMP_NEOK(ret);
- ret = copy_substring(mpctx, str, "interval_day", &match);
- JMP_NEOK(ret);
- BUFFER_OR_JUMP(ctx, per->day_of_month, DAY_OF_MONTH_BUFSIZE);
- ret = interval2bitfield(mpctx, per->day_of_month, match,
- 1, DAY_OF_MONTH_MAX, NULL);
- JMP_NEOK(ret);
- } else {
- ret = matches_regexp(ctx, trctx, str, LP_RGX_MWEEK, &mpctx);
- JMP_NEOK(ret);
- ret = copy_substring(mpctx, str, "mperspec_week", &mperspec);
- JMP_NEOK(ret);
-
- ret = copy_substring(mpctx, str, "interval_week", &match);
- JMP_NEOK(ret);
- ret = interval2bitfield(mpctx, &per->week_of_month, match,
- 1, WEEK_OF_MONTH_MAX, NULL);
- JMP_NEOK(ret);
-
- ret = copy_substring(mpctx, str, "day_of_week", &match);
- JMP_NEOK(ret);
- ret = interval2bitfield(mpctx, &per->day_of_week, match,
- 1, DAY_OF_WEEK_MAX, names_day_of_week);
- JMP_NEOK(ret);
- }
-
-done:
- talloc_free(mpctx);
- return ret;
-}
-
-/*
- * Parses yearly periodic timerange given in STR.
- * Fills the information into PER.
- */
-static int parse_periodic_yearly(TALLOC_CTX *ctx,
- struct time_rules_ctx *trctx,
- struct periodic_range *per,
- const char *str)
-{
- int ret;
- struct parse_ctx *ypctx = NULL;
- char *match = NULL;
- char *yperspec = NULL;
-
- ret = matches_regexp(ctx, trctx, str, LP_RGX_YEARLY, &ypctx);
- JMP_NEOK(ret);
- ret = copy_substring(ypctx, str, "yperspec_day", &yperspec);
- if (ret == EOK) {
- ret = copy_substring(ypctx, str, "day_of_year", &match);
- JMP_NEOK(ret);
- BUFFER_OR_JUMP(ypctx, per->day_of_year, DAY_OF_YEAR_BUFSIZE);
- ret = interval2bitfield(ypctx, per->day_of_year, match,
- 1, DAY_OF_YEAR_MAX, NULL);
- JMP_NEOK(ret);
- }
-
- if (ret != ENOENT) goto done;
-
- ret = copy_substring(ypctx, str, "yperspec_week", &yperspec);
- if (ret == EOK) {
- ret = copy_substring(ypctx, str, "week_of_year", &match);
- JMP_NEOK(ret);
- BUFFER_OR_JUMP(ypctx, per->week_of_year, WEEK_OF_YEAR_BUFSIZE);
- ret = interval2bitfield(ypctx, per->week_of_year, match,
- 1, WEEK_OF_YEAR_MAX, NULL);
- JMP_NEOK(ret);
-
- talloc_free(match);
- ret = copy_substring(ypctx, str, "day_of_week", &match);
- JMP_NEOK(ret);
- ret = interval2bitfield(ypctx, &per->day_of_week, match,
- 1, DAY_OF_WEEK_MAX, names_day_of_week);
- JMP_NEOK(ret);
- }
-
- if (ret != ENOENT) goto done;
-
- ret = copy_substring(ypctx, str, "yperspec_month", &yperspec);
- JMP_NEOK(ret);
-
- talloc_free(match);
- ret = copy_substring(ypctx, str, "month_number", &match);
- JMP_NEOK(ret);
- BUFFER_OR_JUMP(ypctx, per->month, MONTH_BUFSIZE);
- ret = interval2bitfield(ypctx, per->month, match,
- 1, MONTH_MAX, names_months);
- JMP_NEOK(ret);
-
- talloc_free(match);
- ret = copy_substring(ypctx, str, "m_period", &match);
- JMP_NEOK(ret);
- DEBUG(7, ("Monthly year period - calling parse_periodic_monthly()\n"));
- ret = parse_periodic_monthly(ypctx, trctx, per, match);
- JMP_NEOK(ret);
-
-done:
- talloc_free(ypctx);
- return ret;
-}
-
-/*
- * Parses weekly periodic timerange given in STR.
- * Fills the information into PER.
- */
-static int parse_periodic_weekly(TALLOC_CTX *ctx,
- struct time_rules_ctx *trctx,
- struct periodic_range *per,
- const char *str)
-{
- int ret;
- struct parse_ctx *wpctx = NULL;
- char *dow = NULL;
-
- ret = matches_regexp(ctx, trctx, str, LP_RGX_WEEKLY, &wpctx);
- JMP_NEOK(ret);
-
- ret = copy_substring(wpctx, str, "day_of_week", &dow);
- JMP_NEOK(ret);
- DEBUG(8, ("day_of_week = '%s'\n", dow));
-
- ret = interval2bitfield(wpctx, &per->day_of_week, dow,
- 1, DAY_OF_WEEK_MAX, names_day_of_week);
-
-done:
- talloc_free(wpctx);
- return ret;
-}
-
-static int parse_periodic_time(struct periodic_range *per,
- struct parse_ctx *pctx,
- const char *str)
-{
- char *substr = NULL;
- int ret;
-
- int hour_from;
- int hour_to;
- int min_from;
- int min_to;
-
- /* parse out the time */
- ret = copy_substring(pctx, str, "timeFrom", &substr);
- JMP_NEOK(ret);
- parse_hhmm(substr, &hour_from, &min_from);
- DEBUG(7, ("Parsed timeFrom: %d:%d\n", hour_from, min_from));
- JMP_NEOK(ret);
-
- talloc_free(substr);
- ret = copy_substring(pctx, str, "timeTo", &substr);
- JMP_NEOK(ret);
- parse_hhmm(substr, &hour_to, &min_to);
- DEBUG(7, ("Parsed timeTo: %d:%d\n", hour_to, min_to));
- JMP_NEOK(ret);
-
- /* set the interval */
- if (hour_from > hour_to ) {
- set_bit_range(per->hour, 0, hour_to);
- set_bit_range(per->hour, hour_from, HOUR_MAX);
- } else {
- set_bit_range(per->hour, hour_from, hour_to);
- }
-
- if (min_from > min_to) {
- set_bit_range(per->minute, 0, min_to);
- set_bit_range(per->minute, min_from, MINUTE_MAX);
- } else {
- set_bit_range(per->minute, min_from, min_to);
- }
-
-
- ret = EOK;
-done:
- talloc_free(substr);
- return ret;
-}
-
-/*
- * Parses periodic timerange given in STR.
- * Fills the information into PER.
- */
-static int parse_periodic(struct periodic_range *per,
- struct time_rules_ctx *trctx,
- struct parse_ctx *pctx,
- const char *str)
-{
- char *substr = NULL;
- char *period = NULL;
- int ret;
-
- /* These are mandatory */
- BUFFER_OR_JUMP(per, per->hour, HOUR_BUFSIZE);
- BUFFER_OR_JUMP(per, per->minute, MINUTE_BUFSIZE);
-
- ret = copy_substring(pctx, str, "perspec", &substr);
- JMP_NEOK(ret);
- ret = copy_substring(pctx, str, "period", &period);
- JMP_NEOK(ret);
-
- if (strcmp(substr, "yearly") == 0) {
- DEBUG(5, ("periodic yearly\n"));
- ret = parse_periodic_yearly(pctx, trctx, per, period);
- JMP_NEOK(ret);
- } else if (strcmp(substr, "monthly") == 0) {
- DEBUG(5, ("periodic monthly\n"));
- ret = parse_periodic_monthly(pctx, trctx, per, period);
- JMP_NEOK(ret);
- } else if (strcmp(substr, "weekly") == 0) {
- DEBUG(5, ("periodic weekly\n"));
- ret = parse_periodic_weekly(pctx, trctx, per, period);
- JMP_NEOK(ret);
- } else if (strcmp(substr, "daily") == 0) {
- DEBUG(5, ("periodic daily\n"));
- } else {
- DEBUG(1, ("Cannot determine periodic rule type"
- "(perspec = '%s', period = '%s')\n", substr, period));
- ret = EINVAL;
- goto done;
- }
-
- talloc_free(period);
-
- ret = parse_periodic_time(per, pctx, str);
- JMP_NEOK(ret);
-
- ret = EOK;
-done:
- talloc_free(substr);
- return ret;
-}
-
-/*
- * Parses time specification given in string RULE into range_ctx
- * context CTX.
- */
-static int parse_timespec(struct range_ctx *ctx, const char *rule)
-{
- int ret;
- struct parse_ctx *pctx = NULL;
-
- if (matches_regexp(ctx, ctx->trctx, rule, LP_RGX_ABSOLUTE, &pctx) == EOK) {
- DEBUG(5, ("Matched absolute range\n"));
- ctx->type = TYPE_ABSOLUTE;
- ctx->abs = talloc_zero(ctx, struct absolute_range);
- CHECK_PTR_JMP(ctx->abs);
-
- ret = parse_absolute(ctx->abs, ctx->trctx, pctx, rule);
- JMP_NEOK(ret);
- } else if (matches_regexp(ctx, ctx->trctx, rule, LP_RGX_PERIODIC, &pctx) == EOK) {
- DEBUG(5, ("Matched periodic range\n"));
- ctx->type = TYPE_PERIODIC;
- ctx->per = talloc_zero(ctx, struct periodic_range);
- CHECK_PTR_JMP(ctx->per);
-
- ret = parse_periodic(ctx->per, ctx->trctx, pctx, rule);
- JMP_NEOK(ret);
- } else {
- DEBUG(1, ("Cannot determine rule type\n"));
- ret = EINVAL;
- goto done;
- }
-
- ret = EOK;
-done:
- talloc_free(pctx);
- return ret;
-}
-
-/*******************************************************************
- * validation of rules against time_t *
- *******************************************************************/
-
-static int absolute_timerange_valid(struct absolute_range *absr,
- const time_t now,
- bool *result)
-{
- if (difftime(absr->time_from, now) > 0) {
- DEBUG(3, ("Absolute timerange invalid (before interval)\n"));
- *result = false;
- return EOK;
- }
-
- if (difftime(absr->time_to, now) < 0) {
- DEBUG(3, ("Absolute timerange invalid (after interval)\n"));
- *result = false;
- return EOK;
- }
-
- DEBUG(3, ("Absolute timerange valid\n"));
- *result = true;
- return EOK;
-}
-
-static int periodic_timerange_valid(struct periodic_range *per,
- const time_t now,
- bool *result)
-{
- struct tm tm_now;
- int wnum;
- int wom;
-
- memset(&tm_now, 0, sizeof(struct tm));
- if (localtime_r(&now, &tm_now) == NULL) {
- DEBUG(0, ("Cannot convert time_t to struct tm\n"));
- return EFAULT;
- }
- DEBUG(9, ("Got struct tm value %s", asctime(&tm_now)));
- tm2abs(&tm_now);
-
- wnum = weeknum(&tm_now);
- if (wnum == -1) {
- DEBUG(7, ("Cannot get week number"));
- return EINVAL;
- }
- DEBUG(9, ("Week number is %d\n", wnum));
-
- wom = get_week_of_month(&tm_now);
- if (wnum == -1) {
- DEBUG(7, ("Cannot get week of number"));
- return EINVAL;
- }
- DEBUG(9, ("Week of month number is %d\n", wom));
-
- /* The validation itself */
- TEST_BIT_RANGE(per->day_of_week, tm_now.tm_wday, result);
- DEBUG(9, ("day of week OK\n"));
- TEST_BIT_RANGE_PTR(per->day_of_month, tm_now.tm_mday, result);
- DEBUG(9, ("day of month OK\n"));
- TEST_BIT_RANGE(per->week_of_month, wom, result);
- DEBUG(9, ("week of month OK\n"));
- TEST_BIT_RANGE_PTR(per->week_of_year, wnum, result);
- DEBUG(9, ("week of year OK\n"));
- TEST_BIT_RANGE_PTR(per->month, tm_now.tm_mon, result);
- DEBUG(9, ("month OK\n"));
- TEST_BIT_RANGE_PTR(per->day_of_year, tm_now.tm_yday, result);
- DEBUG(9, ("day of year OK\n"));
- TEST_BIT_RANGE_PTR(per->hour, tm_now.tm_hour, result);
- DEBUG(9, ("hour OK\n"));
- TEST_BIT_RANGE_PTR(per->minute, tm_now.tm_min, result);
- DEBUG(9, ("minute OK\n"));
-
- DEBUG(3, ("Periodic timerange valid\n"));
- *result = true;
- return EOK;
-}
-
-/*
- * Returns EOK if the timerange in range_ctx context is valid compared against a
- * given time_t value in NOW, returns ERANGE if the time value is outside the
- * specified range.
- */
-static int timerange_valid(struct range_ctx *ctx,
- const time_t now,
- bool *result)
-{
- int ret;
-
- switch(ctx->type) {
- case TYPE_ABSOLUTE:
- DEBUG(7, ("Checking absolute range\n"));
- ret = absolute_timerange_valid(ctx->abs, now, result);
- break;
-
- case TYPE_PERIODIC:
- DEBUG(7, ("Checking periodic range\n"));
- ret = periodic_timerange_valid(ctx->per, now, result);
- break;
-
- default:
- DEBUG(1, ("Unknown range type (%d)\n", ctx->type));
- ret = EINVAL;
- break;
- }
-
- return ret;
-}
-
-/*******************************************************************
- * public interface *
- *******************************************************************/
-
-/*
- * This is actually the meat of the library. The function takes a string
- * representation of a time rule in STR and time to check against (usually that
- * would be current time) in NOW.
- *
- * It returns EOK if the rule is valid in the current time, ERANGE if not and
- * EINVAL if the rule cannot be parsed
- */
-int check_time_rule(TALLOC_CTX *mem_ctx,
- struct time_rules_ctx *trctx,
- const char *str,
- const time_t now,
- bool *result)
-{
- int ret;
- struct range_ctx *ctx;
-
- ctx = talloc_zero(mem_ctx, struct range_ctx);
- CHECK_PTR_JMP(ctx);
- ctx->trctx = trctx;
-
- DEBUG(9, ("Got time_t value %s", ctime(&now)));
-
- ret = parse_timespec(ctx, str);
- if (ret != EOK) {
- DEBUG(1, ("Cannot parse the time specification (%d)\n", ret));
- goto done;
- }
-
- ret = timerange_valid(ctx, now, result);
- if (ret != EOK) {
- DEBUG(1, ("Cannot check the time range (%d)\n", ret));
- goto done;
- }
-
- ret = EOK;
-done:
- talloc_free(ctx);
- return EOK;
-}
-
-/*
- * Frees the resources taken by the precompiled rules
- */
-static int time_rules_parser_destructor(struct time_rules_ctx *ctx)
-{
- int i;
-
- for (i = 0; i< LP_RGX_MAX; ++i) {
- pcre_free(ctx->re[i]);
- ctx->re[i] = NULL;
- }
-
- return 0;
-}
-
-/*
- * Initializes the parser by precompiling the regular expressions
- * for later use
- */
-int init_time_rules_parser(TALLOC_CTX *mem_ctx,
- struct time_rules_ctx **_out)
-{
- const char *errstr;
- int errval;
- int errpos;
- int ret;
- int i;
- struct time_rules_ctx *ctx = NULL;
-
- ctx = talloc_zero(mem_ctx, struct time_rules_ctx);
- CHECK_PTR(ctx);
- talloc_set_destructor(ctx, time_rules_parser_destructor);
-
- /* Precompile regular expressions */
- for (i = LP_RGX_GENERALIZED; i< LP_RGX_MAX; ++i) {
- ctx->re[i] = pcre_compile2(lookup_table[i],
- 0,
- &errval,
- &errstr,
- &errpos,
- NULL);
-
- if (ctx->re[i] == NULL) {
- DEBUG(0, ("Invalid Regular Expression pattern '%s' at position %d"
- " (Error: %d [%s])\n", lookup_table[i],
- errpos, errval, errstr));
- ret = EFAULT;
- goto done;
- }
-
- }
-
- *_out = ctx;
- return EOK;
-done:
- talloc_free(ctx);
- return ret;
-}
-
diff --git a/server/providers/ipa/ipa_timerules.h b/server/providers/ipa/ipa_timerules.h
deleted file mode 100644
index e1beaa22..00000000
--- a/server/providers/ipa/ipa_timerules.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- SSSD
-
- IPA Provider Time Rules Parsing
-
- Authors:
- Jakub Hrozek <jhrozek@redhat.com>
-
- Copyright (C) Red Hat, Inc 2009
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __IPA_TIMERULES_H_
-#define __IPA_TIMERULES_H_
-
-#include <stdbool.h>
-#include <talloc.h>
-
-/* Opaque structure given after init */
-struct time_rules_ctx;
-
-/*
- * Init the parser. Destroy the allocated resources by simply
- * talloc_free()-ing the time_rules_ctx
- */
-int init_time_rules_parser(TALLOC_CTX *mem_ctx,
- struct time_rules_ctx **_out);
-
-/*
- * This is actually the meat of the library. The function takes a string
- * representation of a time rule in STR and time to check against (usually that
- * would be current time) in NOW.
- *
- * It returns EOK if the rule can be parsed, error code if not. If the time
- * given in the NOW parameter would be accepted by the rule, it stores true in
- * RESULT, false otherwise.
- */
-int check_time_rule(TALLOC_CTX *mem_ctx,
- struct time_rules_ctx *trctx,
- const char *str,
- const time_t now,
- bool *result);
-
-#endif /* __IPA_TIMERULES_H_ */