summaryrefslogtreecommitdiffstats
path: root/server/providers/ipa
diff options
context:
space:
mode:
Diffstat (limited to 'server/providers/ipa')
-rw-r--r--server/providers/ipa/ipa_access.c6
-rw-r--r--server/providers/ipa/ipa_common.c165
-rw-r--r--server/providers/ipa/ipa_common.h10
-rw-r--r--server/providers/ipa/ipa_init.c50
4 files changed, 183 insertions, 48 deletions
diff --git a/server/providers/ipa/ipa_access.c b/server/providers/ipa/ipa_access.c
index 230cabc1d..675e7c202 100644
--- a/server/providers/ipa/ipa_access.c
+++ b/server/providers/ipa/ipa_access.c
@@ -386,7 +386,8 @@ static struct tevent_req *hbac_get_host_info_send(TALLOC_CTX *memctx,
talloc_zfree(sdap_ctx->gsh);
}
- subreq = sdap_cli_connect_send(state, ev, sdap_ctx->opts, NULL);
+ 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;
@@ -850,7 +851,8 @@ static struct tevent_req *hbac_get_rules_send(TALLOC_CTX *memctx,
talloc_zfree(sdap_ctx->gsh);
}
- subreq = sdap_cli_connect_send(state, ev, sdap_ctx->opts, NULL);
+ 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;
diff --git a/server/providers/ipa/ipa_common.c b/server/providers/ipa/ipa_common.c
index 38e4d53de..2bd9c76d1 100644
--- a/server/providers/ipa/ipa_common.c
+++ b/server/providers/ipa/ipa_common.c
@@ -22,6 +22,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <netdb.h>
#include <ctype.h>
#include "providers/ipa/ipa_common.h"
@@ -251,24 +252,6 @@ int ipa_get_id_options(struct ipa_options *ipa_opts,
goto done;
}
- /* set ldap_uri */
- if (NULL == dp_opt_get_string(ipa_opts->id->basic, SDAP_URI)) {
- value = talloc_asprintf(tmpctx, "ldap://%s",
- dp_opt_get_string(ipa_opts->basic,
- IPA_SERVER));
- if (!value) {
- ret = ENOMEM;
- goto done;
- }
- ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_URI, value);
- if (ret != EOK) {
- goto done;
- }
- DEBUG(6, ("Option %s set to %s\n",
- ipa_opts->id->basic[SDAP_URI].opt_name,
- dp_opt_get_string(ipa_opts->id->basic, SDAP_URI)));
- }
-
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),
@@ -429,22 +412,6 @@ int ipa_get_auth_options(struct ipa_options *ipa_opts,
goto done;
}
- /* set KDC */
- if (NULL == dp_opt_get_string(ipa_opts->auth, KRB5_KDC)) {
- value = dp_opt_get_string(ipa_opts->basic, IPA_SERVER);
- if (!value) {
- ret = ENOMEM;
- goto done;
- }
- ret = dp_opt_set_string(ipa_opts->auth, KRB5_KDC, value);
- if (ret != EOK) {
- goto done;
- }
- DEBUG(6, ("Option %s set to %s\n",
- ipa_opts->auth[KRB5_KDC].opt_name,
- dp_opt_get_string(ipa_opts->auth, KRB5_KDC)));
- }
-
/* set krb realm */
if (NULL == dp_opt_get_string(ipa_opts->auth, KRB5_REALM)) {
value = dp_opt_get_string(ipa_opts->basic, IPA_DOMAIN);
@@ -473,3 +440,133 @@ done:
}
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, 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->krb_server->address);
+ service->krb_server->address = address;
+
+ /* set also env variable */
+ ret = setenv(SSSD_KRB5_KDC, address, 1);
+ if (ret != EOK) {
+ DEBUG(2, ("setenv %s failed, authentication might fail.\n",
+ SSSD_KRB5_KDC));
+ }
+}
+
+int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
+ const char *servers, struct ipa_service **_service)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct ipa_service *service;
+ char **list = NULL;
+ int count = 0;
+ 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->krb_server = talloc_zero(service, struct krb_server);
+ if (!service->krb_server) {
+ 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;
+ }
+
+ /* split server parm into a list */
+ ret = sss_split_list(tmp_ctx, servers, ", ", &list, &count);
+ 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; i < count; 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
index 21e6e1a39..8d0840c58 100644
--- a/server/providers/ipa/ipa_common.h
+++ b/server/providers/ipa/ipa_common.h
@@ -27,6 +27,11 @@
#include "providers/ldap/ldap_common.h"
#include "providers/krb5/krb5_common.h"
+struct ipa_service {
+ struct sdap_service *sdap;
+ struct krb_server *krb_server;
+};
+
enum ipa_basic_opt {
IPA_DOMAIN = 0,
IPA_SERVER,
@@ -38,6 +43,8 @@ enum ipa_basic_opt {
struct ipa_options {
struct dp_option *basic;
+ struct ipa_service *service;
+
/* id provider */
struct sdap_options *id;
struct sdap_id_ctx *id_ctx;
@@ -64,4 +71,7 @@ int ipa_get_auth_options(struct ipa_options *ipa_opts,
const char *conf_path,
struct dp_option **_opts);
+int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
+ const char *servers, struct ipa_service **_service);
+
#endif /* _IPA_COMMON_H_ */
diff --git a/server/providers/ipa/ipa_init.c b/server/providers/ipa/ipa_init.c
index 701452879..ea279978d 100644
--- a/server/providers/ipa/ipa_init.c
+++ b/server/providers/ipa/ipa_init.c
@@ -56,6 +56,34 @@ struct bet_ops ipa_access_ops = {
.finalize = NULL
};
+int common_ipa_init(struct be_ctx *bectx)
+{
+ const char *ipa_servers;
+ 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;
+ }
+
+ ret = ipa_service_init(ipa_options, bectx,
+ ipa_servers, &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)
@@ -64,12 +92,10 @@ int sssm_ipa_init(struct be_ctx *bectx,
int ret;
if (!ipa_options) {
- ipa_get_options(bectx, bectx->cdb,
- bectx->conf_path,
- bectx->domain, &ipa_options);
- }
- if (!ipa_options) {
- return ENOMEM;
+ ret = common_ipa_init(bectx);
+ if (ret != EOK) {
+ return ret;
+ }
}
if (ipa_options->id_ctx) {
@@ -84,6 +110,7 @@ int sssm_ipa_init(struct be_ctx *bectx,
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,
@@ -127,12 +154,10 @@ int sssm_ipa_auth_init(struct be_ctx *bectx,
int ret;
if (!ipa_options) {
- ipa_get_options(bectx, bectx->cdb,
- bectx->conf_path,
- bectx->domain, &ipa_options);
- }
- if (!ipa_options) {
- return ENOMEM;
+ ret = common_ipa_init(bectx);
+ if (ret != EOK) {
+ return ret;
+ }
}
if (ipa_options->auth_ctx) {
@@ -146,6 +171,7 @@ int sssm_ipa_auth_init(struct be_ctx *bectx,
if (!ctx) {
return ENOMEM;
}
+ ctx->server = ipa_options->service->krb_server;
ipa_options->auth_ctx = ctx;
ret = ipa_get_auth_options(ipa_options, bectx->cdb,