ipa_subdomains.c revision 3b533d57a737e2de1b3e85b073b14d3bfb49dafc
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht/*
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht SSSD
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht IPA Subdomains Module
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht
da4b55f4795a4b585f513eaceb67cda10485febfChristian Maeder Authors:
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht Sumit Bose <sbose@redhat.com>
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht Copyright (C) 2011 Red Hat
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht This program is free software; you can redistribute it and/or modify
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht it under the terms of the GNU General Public License as published by
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht the Free Software Foundation; either version 3 of the License, or
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht (at your option) any later version.
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht This program is distributed in the hope that it will be useful,
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht but WITHOUT ANY WARRANTY; without even the implied warranty of
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht GNU General Public License for more details.
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht You should have received a copy of the GNU General Public License
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht along with this program. If not, see <http://www.gnu.org/licenses/>.
846ef0914b29a4806ca0444c116fd3cf267c4fb7Christian Maeder*/
846ef0914b29a4806ca0444c116fd3cf267c4fb7Christian Maeder
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht#include "providers/ldap/sdap_async.h"
8600e22385bce13c5d1048f7b955f9394a5d94d6Simon Ulbricht#include "providers/ipa/ipa_subdomains.h"
4d1df661384f74cd15d2ceba8a9a3c4760e9ddfbSimon Ulbricht#include "providers/ipa/ipa_common.h"
8600e22385bce13c5d1048f7b955f9394a5d94d6Simon Ulbricht#include <ctype.h>
79eb29c05606f195fe9c6fdca02bcaa458dde17dSimon Ulbricht
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht#define SUBDOMAINS_FILTER "objectclass=ipaNTTrustedDomain"
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht#define MASTER_DOMAIN_FILTER "objectclass=ipaNTDomainAttrs"
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht#define RANGE_FILTER "objectclass=ipaIDRange"
804459c3af78eeee3fd3c940c74594febd030dacSimon Ulbricht
da4b55f4795a4b585f513eaceb67cda10485febfChristian Maeder#define IPA_CN "cn"
4d1df661384f74cd15d2ceba8a9a3c4760e9ddfbSimon Ulbricht#define IPA_FLATNAME "ipaNTFlatName"
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht#define IPA_SID "ipaNTSecurityIdentifier"
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht#define IPA_TRUSTED_DOMAIN_SID "ipaNTTrustedDomainSID"
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht#define IPA_BASE_ID "ipaBaseID"
846ef0914b29a4806ca0444c116fd3cf267c4fb7Christian Maeder#define IPA_ID_RANGE_SIZE "ipaIDRangeSize"
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht#define IPA_BASE_RID "ipaBaseRID"
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht#define IPA_SECONDARY_BASE_RID "ipaSecondaryBaseRID"
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht#define OBJECTCLASS "objectClass"
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht/* do not refresh more often than every 5 seconds for now */
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht#define IPA_SUBDOMAIN_REFRESH_LIMIT 5
024d83266148fc53f9d6f82bedd0b8cb4a6213a9Simon Ulbricht
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht/* refresh automatically every 4 hours */
024d83266148fc53f9d6f82bedd0b8cb4a6213a9Simon Ulbricht#define IPA_SUBDOMAIN_REFRESH_PERIOD (3600 * 4)
024d83266148fc53f9d6f82bedd0b8cb4a6213a9Simon Ulbricht
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbrichtenum ipa_subdomains_req_type {
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht IPA_SUBDOMAINS_MASTER,
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht IPA_SUBDOMAINS_SLAVE,
5212c904eb65bed7c08f5c6e54df9618125d2939Simon Ulbricht IPA_SUBDOMAINS_RANGES,
21f01439b3d87ccc385d3bce73afb2d187d14d05Simon Ulbricht
21f01439b3d87ccc385d3bce73afb2d187d14d05Simon Ulbricht IPA_SUBDOMAINS_MAX /* Counter */
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht};
21f01439b3d87ccc385d3bce73afb2d187d14d05Simon Ulbricht
3ff10b5930bbec5d888826a65828397795877213Simon Ulbrichtstruct ipa_subdomains_req_params {
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht const char *filter;
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht tevent_req_fn cb;
765f0ff34c8f2354a4e8a4fbb4467ec5e788c55fSimon Ulbricht const char *attrs[8];
765f0ff34c8f2354a4e8a4fbb4467ec5e788c55fSimon Ulbricht};
846ef0914b29a4806ca0444c116fd3cf267c4fb7Christian Maeder
3ff10b5930bbec5d888826a65828397795877213Simon Ulbrichtstruct ipa_subdomains_ctx {
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht struct be_ctx *be_ctx;
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht struct sdap_id_ctx *sdap_id_ctx;
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht struct sdap_search_base **search_bases;
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht struct sdap_search_base **master_search_bases;
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht struct sdap_search_base **ranges_search_bases;
846ef0914b29a4806ca0444c116fd3cf267c4fb7Christian Maeder
846ef0914b29a4806ca0444c116fd3cf267c4fb7Christian Maeder time_t last_refreshed;
e90b8ee3fac5c932d83af2061579c6b57d528885Christian Maeder struct tevent_timer *timer_event;
846ef0914b29a4806ca0444c116fd3cf267c4fb7Christian Maeder
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht /* subdomain map cache */
846ef0914b29a4806ca0444c116fd3cf267c4fb7Christian Maeder int num_subdoms;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht struct sysdb_subdom *subdoms;
c25b3ec03906317eabc06bb4dd48bc9cf3841332Simon Ulbricht};
846ef0914b29a4806ca0444c116fd3cf267c4fb7Christian Maeder
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbrichtstatic void ipa_subdomains_reply(struct be_req *be_req, int dp_err, int result)
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht{
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht if (be_req) {
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht be_req->fn(be_req, dp_err, result, NULL);
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht }
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht}
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbrichtstatic errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx,
8600e22385bce13c5d1048f7b955f9394a5d94d6Simon Ulbricht size_t count,
846ef0914b29a4806ca0444c116fd3cf267c4fb7Christian Maeder struct sysdb_attrs **reply,
846ef0914b29a4806ca0444c116fd3cf267c4fb7Christian Maeder struct range_info ***_range_list)
846ef0914b29a4806ca0444c116fd3cf267c4fb7Christian Maeder{
846ef0914b29a4806ca0444c116fd3cf267c4fb7Christian Maeder struct range_info **range_list = NULL;
846ef0914b29a4806ca0444c116fd3cf267c4fb7Christian Maeder const char *value;
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht size_t c;
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht int ret;
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht range_list = talloc_array(mem_ctx, struct range_info *, count + 1);
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht if (range_list == NULL) {
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("talloc_array failed.\n"));
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht return ENOMEM;
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht }
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht for (c = 0; c < count; c++) {
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht range_list[c] = talloc_zero(range_list, struct range_info);
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht if (range_list[c] == NULL) {
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("talloc_zero failed.\n"));
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht ret = ENOMEM;
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht goto done;
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht }
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht ret = sysdb_attrs_get_string(reply[c], IPA_CN, &value);
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht if (ret != EOK) {
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht goto done;
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht }
8600e22385bce13c5d1048f7b955f9394a5d94d6Simon Ulbricht range_list[c]->name = talloc_strdup(range_list[c], value);
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht if (range_list[c]->name == NULL) {
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht ret = ENOMEM;
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht goto done;
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht }
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht ret = sysdb_attrs_get_string(reply[c], IPA_TRUSTED_DOMAIN_SID, &value);
1c258a97f602cf389ed2aed3924108889dbef512Simon Ulbricht if (ret == EOK) {
403c7e517cea70c01c7dd15695867fe4f8820ab4Simon Ulbricht range_list[c]->trusted_dom_sid = talloc_strdup(range_list[c],
403c7e517cea70c01c7dd15695867fe4f8820ab4Simon Ulbricht value);
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht if (range_list[c]->trusted_dom_sid == NULL) {
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht ret = ENOMEM;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht goto done;
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht }
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht } else if (ret != ENOENT) {
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht goto done;
5ea7ec7c1a5dead365687d6b0270837522c0e6feSimon Ulbricht }
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht ret = sysdb_attrs_get_uint32_t(reply[c], IPA_BASE_ID,
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht &range_list[c]->base_id);
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht if (ret != EOK && ret != ENOENT) {
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht goto done;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht }
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht ret = sysdb_attrs_get_uint32_t(reply[c], IPA_ID_RANGE_SIZE,
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht &range_list[c]->id_range_size);
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht if (ret != EOK && ret != ENOENT) {
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht goto done;
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht }
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht ret = sysdb_attrs_get_uint32_t(reply[c], IPA_BASE_RID,
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht &range_list[c]->base_rid);
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht if (ret != EOK && ret != ENOENT) {
403c7e517cea70c01c7dd15695867fe4f8820ab4Simon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
04641e4ea004e422b32d3e6359f68a3326b4aa8bSimon Ulbricht goto done;
04641e4ea004e422b32d3e6359f68a3326b4aa8bSimon Ulbricht }
403c7e517cea70c01c7dd15695867fe4f8820ab4Simon Ulbricht
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht ret = sysdb_attrs_get_uint32_t(reply[c], IPA_SECONDARY_BASE_RID,
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht &range_list[c]->secondary_base_rid);
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht if (ret != EOK && ret != ENOENT) {
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht goto done;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht }
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht }
c51cb4bddcd39a87711e238c0c562d67451476dbSimon Ulbricht range_list[c] = NULL;
94968509d2764786208bd34b59a93c7cbe3aa6dbSimon Ulbricht
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht *_range_list = range_list;
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht ret = EOK;
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbrichtdone:
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht if (ret != EOK) {
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht talloc_free(range_list);
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht }
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht return ret;
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht}
804459c3af78eeee3fd3c940c74594febd030dacSimon Ulbricht
804459c3af78eeee3fd3c940c74594febd030dacSimon Ulbrichtstatic char *name_to_realm(TALLOC_CTX *memctx, const char *name)
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht{
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht char *realm;
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht char *p;
403c7e517cea70c01c7dd15695867fe4f8820ab4Simon Ulbricht
04641e4ea004e422b32d3e6359f68a3326b4aa8bSimon Ulbricht realm = talloc_strdup(memctx, name);
04641e4ea004e422b32d3e6359f68a3326b4aa8bSimon Ulbricht if (!realm) {
04641e4ea004e422b32d3e6359f68a3326b4aa8bSimon Ulbricht return NULL;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht }
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht for (p = realm; *p; p++) {
4d1df661384f74cd15d2ceba8a9a3c4760e9ddfbSimon Ulbricht *p = toupper(*p);
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht }
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht return realm;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht}
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbrichtstatic errno_t ipa_subdom_parse(TALLOC_CTX *memctx,
4d1df661384f74cd15d2ceba8a9a3c4760e9ddfbSimon Ulbricht struct sysdb_attrs *attrs,
4d1df661384f74cd15d2ceba8a9a3c4760e9ddfbSimon Ulbricht struct sysdb_subdom *subdom)
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht{
4d1df661384f74cd15d2ceba8a9a3c4760e9ddfbSimon Ulbricht const char *value;
5917663ca76c8f8b60b767f7fb959f1d1609576bSimon Ulbricht int ret;
5917663ca76c8f8b60b767f7fb959f1d1609576bSimon Ulbricht
4d1df661384f74cd15d2ceba8a9a3c4760e9ddfbSimon Ulbricht ret = sysdb_attrs_get_string(attrs, IPA_CN, &value);
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht if (ret != EOK) {
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht return ret;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht }
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht if (subdom->name == NULL) {
96a17035df49356b70d7ac14bd9f4d52a5f0308dSimon Ulbricht subdom->name = talloc_strdup(memctx, value);
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht if (subdom->name == NULL) {
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht return ENOMEM;
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht }
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht } else if (strcmp(subdom->name, value) != 0) {
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("subdomain name mismatch!\n"));
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht return EINVAL;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht }
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht if (subdom->realm == NULL) {
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht /* Add Realm as upper(domain name), this is generally always correct
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht * with AD domains */
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht subdom->realm = name_to_realm(memctx, subdom->name);
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht if (!subdom->realm) {
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht return ENOMEM;
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht }
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht }
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht ret = sysdb_attrs_get_string(attrs, IPA_FLATNAME, &value);
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht if (ret) {
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht return ret;
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht }
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht /* in theory this may change, it should never happen, so we will log a
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht * warning if it does, but we will allow it for now */
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht if (subdom->flat_name != NULL) {
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht if (strcmp(subdom->flat_name, value) != 0) {
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht DEBUG(SSSDBG_TRACE_INTERNAL,
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht ("Flat name for subdomain changed!\n"));
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht talloc_free(discard_const(subdom->flat_name));
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht subdom->flat_name = (const char *)NULL;
55be4caff6a01e4c32ec47ee27fe00b67dfd3db5Simon Ulbricht }
9458e270eb4d18c8e76fdaa569023931ca7ca8dfSimon Ulbricht }
5917663ca76c8f8b60b767f7fb959f1d1609576bSimon Ulbricht if (subdom->flat_name == NULL) {
4d1df661384f74cd15d2ceba8a9a3c4760e9ddfbSimon Ulbricht subdom->flat_name = talloc_strdup(memctx, value);
4d1df661384f74cd15d2ceba8a9a3c4760e9ddfbSimon Ulbricht if (subdom->flat_name == NULL) {
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht return ENOMEM;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht }
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht }
4d1df661384f74cd15d2ceba8a9a3c4760e9ddfbSimon Ulbricht
4d1df661384f74cd15d2ceba8a9a3c4760e9ddfbSimon Ulbricht ret = sysdb_attrs_get_string(attrs, IPA_TRUSTED_DOMAIN_SID, &value);
4d1df661384f74cd15d2ceba8a9a3c4760e9ddfbSimon Ulbricht if (ret) {
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht return ret;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht }
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht /* in theory this may change, it should never happen, so we will log a
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht * warning if it does, but we will allow it for now */
4d1df661384f74cd15d2ceba8a9a3c4760e9ddfbSimon Ulbricht if (subdom->id != NULL) {
4d1df661384f74cd15d2ceba8a9a3c4760e9ddfbSimon Ulbricht if (strcmp(subdom->id, value) != 0) {
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht DEBUG(SSSDBG_TRACE_INTERNAL,
5917663ca76c8f8b60b767f7fb959f1d1609576bSimon Ulbricht ("ID for subdomain changed!\n"));
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht talloc_free(discard_const(subdom->id));
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht subdom->flat_name = (const char *)NULL;
96a17035df49356b70d7ac14bd9f4d52a5f0308dSimon Ulbricht }
96a17035df49356b70d7ac14bd9f4d52a5f0308dSimon Ulbricht }
30b3567d60173c99ef8db1f0a1d8bda73a4225fdSimon Ulbricht if (subdom->id == NULL) {
30b3567d60173c99ef8db1f0a1d8bda73a4225fdSimon Ulbricht subdom->id = talloc_strdup(memctx, value);
4d1df661384f74cd15d2ceba8a9a3c4760e9ddfbSimon Ulbricht if (subdom->id == NULL) {
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht return ENOMEM;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht }
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht }
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht return EOK;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht}
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbrichtstatic errno_t ipa_subdomains_refresh(struct ipa_subdomains_ctx *ctx,
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht int count, struct sysdb_attrs **reply,
da4b55f4795a4b585f513eaceb67cda10485febfChristian Maeder bool *changes)
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht{
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht bool handled[count];
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht const char *value;
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht int c, h;
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht int ret;
4d1df661384f74cd15d2ceba8a9a3c4760e9ddfbSimon Ulbricht int i, j;
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht memset(handled, 0, sizeof(bool) * count);
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht /* check existing subdoms in cache */
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht for (i = 0, h = 0; i < ctx->num_subdoms; i++) {
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht for (c = 0; c < count; c++) {
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht if (handled[c]) {
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht continue;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht }
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht ret = sysdb_attrs_get_string(reply[c], IPA_CN, &value);
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht if (ret != EOK) {
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_string failed.\n"));
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht goto done;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht }
192498961d079b4a31585f9f63148233804cc1c9Simon Ulbricht if (strcmp(value, ctx->subdoms[i].name) == 0) {
3c606bbc21a488c9eaebbfcd833b0b31af25341aSimon Ulbricht break;
67c57fe89afed0947d5ff8fc8b04c4ace0b9595eSimon Ulbricht }
3c606bbc21a488c9eaebbfcd833b0b31af25341aSimon Ulbricht }
3c606bbc21a488c9eaebbfcd833b0b31af25341aSimon Ulbricht
67c57fe89afed0947d5ff8fc8b04c4ace0b9595eSimon Ulbricht if (c >= count) {
3c606bbc21a488c9eaebbfcd833b0b31af25341aSimon Ulbricht /* ok this subdomain does not exist anymore, let's clean up */
5917663ca76c8f8b60b767f7fb959f1d1609576bSimon Ulbricht for (j = i; j < ctx->num_subdoms - 1; j++) {
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht ctx->subdoms[j] = ctx->subdoms[j + 1];
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht }
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht ctx->num_subdoms--;
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht i--;
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht } else {
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht /* ok let's try to update it */
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht ret = ipa_subdom_parse(ctx->subdoms, reply[c], &ctx->subdoms[i]);
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht if (ret) {
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("Failed to parse subdom data\n"));
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht goto done;
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht }
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht handled[c] = true;
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht h++;
972f1416b11d73d3e98597538cd6d96c13caf992Simon Ulbricht }
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht }
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht
e3d7fd1b63d824960b1c17b6c7009d52d7528c1eChristian Maeder if (count == h) {
e3d7fd1b63d824960b1c17b6c7009d52d7528c1eChristian Maeder /* all domains were already accounted for and have been updated */
149252aa10a12adce1929d98f5fcfe9c2e88167dSimon Ulbricht ret = EOK;
5b93337fb97e848522fcc277e384f694595bc42cSimon Ulbricht goto done;
149252aa10a12adce1929d98f5fcfe9c2e88167dSimon Ulbricht }
149252aa10a12adce1929d98f5fcfe9c2e88167dSimon Ulbricht
da4b55f4795a4b585f513eaceb67cda10485febfChristian Maeder /* if we get here it means we have changes to the subdomains list */
da4b55f4795a4b585f513eaceb67cda10485febfChristian Maeder *changes = true;
da4b55f4795a4b585f513eaceb67cda10485febfChristian Maeder
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht /* add space for unhandled domains */
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht c = count - h;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht ctx->subdoms = talloc_realloc(ctx, ctx->subdoms,
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht struct sysdb_subdom,
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht ctx->num_subdoms + c);
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht if (ctx->subdoms == NULL) {
4bf72807172000becf65e11bd225efc1dfd99713Simon Ulbricht ret = ENOMEM;
67c57fe89afed0947d5ff8fc8b04c4ace0b9595eSimon Ulbricht goto done;
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht }
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht for (c = 0; c < count; c++) {
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht if (handled[c]) {
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht continue;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht }
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht i = ctx->num_subdoms;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht memset(&ctx->subdoms[i], 0, sizeof(struct sysdb_subdom));
765f0ff34c8f2354a4e8a4fbb4467ec5e788c55fSimon Ulbricht ret = ipa_subdom_parse(ctx->subdoms, reply[c], &ctx->subdoms[i]);
765f0ff34c8f2354a4e8a4fbb4467ec5e788c55fSimon Ulbricht if (ret) {
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht DEBUG(SSSDBG_OP_FAILURE, ("Failed to parse subdom data\n"));
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht goto done;
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht }
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht ctx->num_subdoms++;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht }
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht ret = EOK;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbrichtdone:
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht if (ret != EOK) {
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht ctx->last_refreshed = 0;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht ctx->num_subdoms = 0;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht talloc_zfree(ctx->subdoms);
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht } else {
fe6a19b07759bc4190e88dda76a211d86bf32062Simon Ulbricht ctx->last_refreshed = time(NULL);
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht }
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht return ret;
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht}
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbrichtstruct ipa_subdomains_req_ctx {
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbricht struct be_req *be_req;
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbricht struct ipa_subdomains_ctx *sd_ctx;
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbricht struct sdap_id_op *sdap_op;
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbricht
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbricht char *current_filter;
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbricht
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbricht struct sdap_search_base **search_bases;
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbricht int search_base_iter;
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbricht
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbricht size_t reply_count;
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbricht struct sysdb_attrs **reply;
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbricht};
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbricht
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbrichtstatic void ipa_subdomains_get_conn_done(struct tevent_req *req);
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbrichtstatic errno_t
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbrichtipa_subdomains_handler_get(struct ipa_subdomains_req_ctx *ctx,
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbricht enum ipa_subdomains_req_type type);
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbrichtstatic void ipa_subdomains_handler_done(struct tevent_req *req);
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbrichtstatic void ipa_subdomains_handler_master_done(struct tevent_req *req);
da4b55f4795a4b585f513eaceb67cda10485febfChristian Maederstatic void ipa_subdomains_handler_ranges_done(struct tevent_req *req);
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbricht
7577ca4229962db6f297853d160c2e0214bd2034Simon Ulbrichtstatic struct ipa_subdomains_req_params subdomain_requests[] = {
67c57fe89afed0947d5ff8fc8b04c4ace0b9595eSimon Ulbricht { MASTER_DOMAIN_FILTER,
765f0ff34c8f2354a4e8a4fbb4467ec5e788c55fSimon Ulbricht ipa_subdomains_handler_master_done,
e4d1479434761dc3eb8d17b6c75de4eb24866f0bSimon Ulbricht { IPA_CN, IPA_FLATNAME, IPA_SID, NULL }
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht },
c3b1c9fa0aa53167405eb9a004137fb5e327fd4fSimon Ulbricht { SUBDOMAINS_FILTER,
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht ipa_subdomains_handler_done,
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht { IPA_CN, IPA_FLATNAME, IPA_TRUSTED_DOMAIN_SID, NULL }
8fa27254f463e2c958a10dc513450b992f80137bSimon Ulbricht },
c3b1c9fa0aa53167405eb9a004137fb5e327fd4fSimon Ulbricht { RANGE_FILTER,
c3b1c9fa0aa53167405eb9a004137fb5e327fd4fSimon Ulbricht ipa_subdomains_handler_ranges_done,
21f01439b3d87ccc385d3bce73afb2d187d14d05Simon Ulbricht { OBJECTCLASS, IPA_CN,
9458e270eb4d18c8e76fdaa569023931ca7ca8dfSimon Ulbricht IPA_BASE_ID, IPA_BASE_RID, IPA_SECONDARY_BASE_RID,
689c36560d1509e6f040c096b719a31b31d2d84cSimon Ulbricht IPA_ID_RANGE_SIZE, IPA_TRUSTED_DOMAIN_SID, NULL
9458e270eb4d18c8e76fdaa569023931ca7ca8dfSimon Ulbricht }
846ef0914b29a4806ca0444c116fd3cf267c4fb7Christian Maeder }
9458e270eb4d18c8e76fdaa569023931ca7ca8dfSimon Ulbricht};
/* NOTE: be_req can be NULL, this is used by the online callback to refresh
* subdomains without any request coming from a frontend */
static void ipa_subdomains_retrieve(struct ipa_subdomains_ctx *ctx, struct be_req *be_req)
{
struct ipa_subdomains_req_ctx *req_ctx = NULL;
struct tevent_req *req;
int dp_error = DP_ERR_FATAL;
int ret;
req_ctx = talloc(be_req, struct ipa_subdomains_req_ctx);
if (req_ctx == NULL) {
ret = ENOMEM;
goto done;
}
req_ctx->be_req = be_req;
req_ctx->sd_ctx = ctx;
req_ctx->search_base_iter = 0;
req_ctx->search_bases = ctx->search_bases;
req_ctx->current_filter = NULL;
req_ctx->reply_count = 0;
req_ctx->reply = NULL;
req_ctx->sdap_op = sdap_id_op_create(req_ctx,
ctx->sdap_id_ctx->conn_cache);
if (req_ctx->sdap_op == NULL) {
DEBUG(SSSDBG_OP_FAILURE, ("sdap_id_op_create failed.\n"));
ret = ENOMEM;
goto done;
}
req = sdap_id_op_connect_send(req_ctx->sdap_op, req_ctx, &ret);
if (req == NULL) {
DEBUG(SSSDBG_OP_FAILURE, ("sdap_id_op_connect_send failed: %d(%s).\n",
ret, strerror(ret)));
goto done;
}
tevent_req_set_callback(req, ipa_subdomains_get_conn_done, req_ctx);
return;
done:
talloc_free(req_ctx);
if (ret == EOK) {
dp_error = DP_ERR_OK;
}
ipa_subdomains_reply(be_req, dp_error, ret);
}
static void ipa_subdomains_get_conn_done(struct tevent_req *req)
{
int ret;
int dp_error = DP_ERR_FATAL;
struct be_req *be_req;
struct ipa_subdomains_req_ctx *ctx;
ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx);
ret = sdap_id_op_connect_recv(req, &dp_error);
talloc_zfree(req);
if (ret) {
if (dp_error == DP_ERR_OFFLINE) {
DEBUG(SSSDBG_MINOR_FAILURE,
("No IPA server is available, cannot get the "
"subdomain list while offline\n"));
/* FIXME: return saved results ?? */
} else {
DEBUG(SSSDBG_OP_FAILURE,
("Failed to connect to IPA server: [%d](%s)\n",
ret, strerror(ret)));
}
goto fail;
}
ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_SLAVE);
if (ret != EOK && ret != EAGAIN) {
goto fail;
}
return;
fail:
be_req = ctx->be_req;
talloc_free(ctx);
ipa_subdomains_reply(be_req, dp_error, ret);
}
static errno_t
ipa_subdomains_handler_get(struct ipa_subdomains_req_ctx *ctx,
enum ipa_subdomains_req_type type)
{
struct tevent_req *req;
struct sdap_search_base *base;
struct ipa_subdomains_req_params *params;
if (type >= IPA_SUBDOMAINS_MAX) {
return EINVAL;
}
params = &subdomain_requests[type];
base = ctx->search_bases[ctx->search_base_iter];
if (base == NULL) {
return EOK;
}
talloc_free(ctx->current_filter);
ctx->current_filter = sdap_get_id_specific_filter(ctx, params->filter,
base->filter);
if (ctx->current_filter == NULL) {
return ENOMEM;
}
req = sdap_get_generic_send(ctx, ctx->sd_ctx->be_ctx->ev,
ctx->sd_ctx->sdap_id_ctx->opts,
sdap_id_op_handle(ctx->sdap_op),
base->basedn, base->scope,
ctx->current_filter, params->attrs, NULL, 0,
dp_opt_get_int(ctx->sd_ctx->sdap_id_ctx->opts->basic,
SDAP_SEARCH_TIMEOUT), false);
if (req == NULL) {
DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send failed.\n"));
return ENOMEM;
}
tevent_req_set_callback(req, params->cb, ctx);
return EAGAIN;
}
static void ipa_subdomains_handler_done(struct tevent_req *req)
{
int ret;
size_t reply_count;
struct sysdb_attrs **reply = NULL;
struct ipa_subdomains_req_ctx *ctx;
struct be_req *be_req;
struct sysdb_ctx *sysdb;
bool refresh_has_changes = false;
ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx);
be_req = ctx->be_req;
if (be_req && be_req->sysdb) {
sysdb = be_req->sysdb;
} else {
sysdb = ctx->sd_ctx->be_ctx->sysdb;
}
ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply);
talloc_zfree(req);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send request failed.\n"));
goto done;
}
if (reply_count) {
ctx->reply = talloc_realloc(ctx, ctx->reply, struct sysdb_attrs *,
ctx->reply_count + reply_count);
if (ctx->reply == NULL) {
ret = ENOMEM;
goto done;
}
memcpy(ctx->reply+ctx->reply_count, reply,
reply_count * sizeof(struct sysdb_attrs *));
ctx->reply_count += reply_count;
}
ctx->search_base_iter++;
ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_SLAVE);
if (ret == EAGAIN) {
return;
} else if (ret != EOK) {
goto done;
}
ret = ipa_subdomains_refresh(ctx->sd_ctx, ctx->reply_count, ctx->reply,
&refresh_has_changes);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Failed to refresh subdomains.\n"));
goto done;
}
if (refresh_has_changes) {
ret = sysdb_update_subdomains(sysdb, ctx->sd_ctx->num_subdoms,
ctx->sd_ctx->subdoms);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("sysdb_update_subdomains failed.\n"));
goto done;
}
}
ctx->search_base_iter = 0;
ctx->search_bases = ctx->sd_ctx->ranges_search_bases;
ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_RANGES);
if (ret == EAGAIN) {
return;
} else if (ret != EOK) {
goto done;
}
DEBUG(SSSDBG_OP_FAILURE, ("No search base for ranges available.\n"));
ret = EINVAL;
done:
talloc_free(ctx);
ipa_subdomains_reply(be_req, DP_ERR_FATAL, ret);
}
static void ipa_subdomains_handler_ranges_done(struct tevent_req *req)
{
errno_t ret;
int dp_error = DP_ERR_FATAL;
size_t reply_count;
struct sysdb_attrs **reply = NULL;
struct ipa_subdomains_req_ctx *ctx;
struct be_req *be_req;
struct sysdb_subdom *domain_info;
struct range_info **range_list = NULL;
struct sysdb_ctx *sysdb;
ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx);
be_req = ctx->be_req;
if (be_req && be_req->sysdb) {
sysdb = be_req->sysdb;
} else {
sysdb = ctx->sd_ctx->be_ctx->sysdb;
}
ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply);
talloc_zfree(req);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send request failed.\n"));
goto done;
}
ret = ipa_ranges_parse_results(ctx, reply_count, reply, &range_list);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
("ipa_ranges_parse_results request failed.\n"));
goto done;
}
ret = sysdb_update_ranges(sysdb, range_list);
talloc_free(range_list);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("sysdb_update_ranges failed.\n"));
goto done;
}
ret = sysdb_master_domain_get_info(ctx, sysdb, &domain_info);
if (ret != EOK) {
goto done;
}
if (domain_info->flat_name == NULL ||
domain_info->id == NULL ||
domain_info->name == NULL) {
ctx->search_base_iter = 0;
ctx->search_bases = ctx->sd_ctx->master_search_bases;
ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_MASTER);
if (ret == EAGAIN) {
return;
} else if (ret != EOK) {
goto done;
}
} else {
ret = EOK;
}
done:
talloc_free(ctx);
if (ret == EOK) {
dp_error = DP_ERR_OK;
}
ipa_subdomains_reply(be_req, dp_error, ret);
}
static void ipa_subdomains_handler_master_done(struct tevent_req *req)
{
errno_t ret;
int dp_error = DP_ERR_FATAL;
size_t reply_count;
struct sysdb_attrs **reply = NULL;
struct ipa_subdomains_req_ctx *ctx;
struct be_req *be_req;
struct sysdb_subdom *domain_info;
const char *tmp_str;
ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx);
be_req = ctx->be_req;
ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply);
talloc_zfree(req);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send request failed.\n"));
goto done;
}
if (reply_count) {
domain_info = talloc_zero(ctx, struct sysdb_subdom);
if (domain_info == NULL) {
ret = ENOMEM;
goto done;
}
ret = sysdb_attrs_get_string(reply[0], IPA_FLATNAME, &tmp_str);
if (ret != EOK) {
goto done;
}
domain_info->flat_name = talloc_strdup(domain_info, tmp_str);
if (domain_info->flat_name == NULL) {
ret = ENOMEM;
goto done;
}
ret = sysdb_attrs_get_string(reply[0], IPA_SID, &tmp_str);
if (ret != EOK) {
goto done;
}
domain_info->id = talloc_strdup(domain_info, tmp_str);
if (domain_info->id == NULL) {
ret = ENOMEM;
goto done;
}
ret = sysdb_master_domain_add_info(ctx->sd_ctx->be_ctx->sysdb, domain_info);
goto done;
} else {
ctx->search_base_iter++;
ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_MASTER);
if (ret == EAGAIN) {
return;
} else if (ret != EOK) {
goto done;
}
/* Right now we know there has been an error
* and we don't have the master domain record
*/
DEBUG(SSSDBG_CRIT_FAILURE, ("Master domain record not found!\n"));
ret = EIO;
goto done;
}
done:
talloc_free(ctx);
if (ret == EOK) {
dp_error = DP_ERR_OK;
}
ipa_subdomains_reply(be_req, dp_error, ret);
}
static void ipa_subdom_online_cb(void *pvt);
static void ipa_subdom_timer_refresh(struct tevent_context *ev,
struct tevent_timer *te,
struct timeval current_time,
void *pvt)
{
ipa_subdom_online_cb(pvt);
}
static void ipa_subdom_online_cb(void *pvt)
{
struct ipa_subdomains_ctx *ctx;
struct timeval tv;
ctx = talloc_get_type(pvt, struct ipa_subdomains_ctx);
if (!ctx) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Bad private pointer\n"));
return;
}
ipa_subdomains_retrieve(ctx, NULL);
tv = tevent_timeval_current_ofs(IPA_SUBDOMAIN_REFRESH_PERIOD, 0);
ctx->timer_event = tevent_add_timer(ctx->be_ctx->ev, ctx, tv,
ipa_subdom_timer_refresh, ctx);
if (!ctx->timer_event) {
DEBUG(SSSDBG_MINOR_FAILURE, ("Failed to add subdom timer event\n"));
}
}
static void ipa_subdom_offline_cb(void *pvt)
{
struct ipa_subdomains_ctx *ctx;
ctx = talloc_get_type(pvt, struct ipa_subdomains_ctx);
if (ctx) {
talloc_zfree(ctx->timer_event);
}
}
void ipa_subdomains_handler(struct be_req *be_req)
{
struct ipa_subdomains_ctx *ctx;
ctx = talloc_get_type(be_req->be_ctx->bet_info[BET_SUBDOMAINS].pvt_bet_data,
struct ipa_subdomains_ctx);
if (!ctx) {
ipa_subdomains_reply(be_req, DP_ERR_FATAL, EINVAL);
return;
}
if (ctx->last_refreshed > time(NULL) - IPA_SUBDOMAIN_REFRESH_LIMIT) {
ipa_subdomains_reply(be_req, DP_ERR_OK, EOK);
return;
}
ipa_subdomains_retrieve(ctx, be_req);
}
struct bet_ops ipa_subdomains_ops = {
.handler = ipa_subdomains_handler,
.finalize = NULL
};
int ipa_subdom_init(struct be_ctx *be_ctx,
struct ipa_id_ctx *id_ctx,
struct bet_ops **ops,
void **pvt_data)
{
struct ipa_subdomains_ctx *ctx;
int ret;
ctx = talloc_zero(id_ctx, struct ipa_subdomains_ctx);
if (ctx == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_zero failed.\n"));
return ENOMEM;
}
ctx->be_ctx = be_ctx;
ctx->sdap_id_ctx = id_ctx->sdap_id_ctx;
ctx->search_bases = id_ctx->ipa_options->subdomains_search_bases;
ctx->master_search_bases = id_ctx->ipa_options->master_domain_search_bases;
ctx->ranges_search_bases = id_ctx->ipa_options->ranges_search_bases;
*ops = &ipa_subdomains_ops;
*pvt_data = ctx;
ret = be_add_online_cb(ctx, be_ctx, ipa_subdom_online_cb, ctx, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE, ("Failed to add subdom online callback"));
}
ret = be_add_offline_cb(ctx, be_ctx, ipa_subdom_offline_cb, ctx, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE, ("Failed to add subdom offline callback"));
}
return EOK;
}