Line data Source code
1 : /*
2 : SSSD
3 :
4 : IPA Provider Initialization functions
5 :
6 : Authors:
7 : Simo Sorce <ssorce@redhat.com>
8 :
9 : Copyright (C) 2009 Red Hat
10 :
11 : This program is free software; you can redistribute it and/or modify
12 : it under the terms of the GNU General Public License as published by
13 : the Free Software Foundation; either version 3 of the License, or
14 : (at your option) any later version.
15 :
16 : This program is distributed in the hope that it will be useful,
17 : but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : GNU General Public License for more details.
20 :
21 : You should have received a copy of the GNU General Public License
22 : along with this program. If not, see <http://www.gnu.org/licenses/>.
23 : */
24 :
25 : #include <sys/types.h>
26 : #include <unistd.h>
27 : #include <sys/stat.h>
28 : #include <fcntl.h>
29 :
30 : #include "util/child_common.h"
31 : #include "providers/ipa/ipa_common.h"
32 : #include "providers/krb5/krb5_auth.h"
33 : #include "providers/krb5/krb5_init_shared.h"
34 : #include "providers/ipa/ipa_id.h"
35 : #include "providers/ipa/ipa_auth.h"
36 : #include "providers/ipa/ipa_access.h"
37 : #include "providers/ipa/ipa_hostid.h"
38 : #include "providers/ipa/ipa_dyndns.h"
39 : #include "providers/ipa/ipa_selinux.h"
40 : #include "providers/ldap/sdap_access.h"
41 : #include "providers/ldap/sdap_idmap.h"
42 : #include "providers/ipa/ipa_subdomains.h"
43 : #include "providers/ipa/ipa_srv.h"
44 : #include "providers/be_dyndns.h"
45 :
46 : #define DNS_SRV_MISCONFIGURATION "SRV discovery is enabled on the IPA " \
47 : "server while using custom dns_discovery_domain. DNS discovery of " \
48 : "trusted AD domain will likely fail. It is recommended not to use " \
49 : "SRV discovery or the dns_discovery_domain option for the IPA " \
50 : "domain while running on the server itself\n"
51 :
52 : #define PREAUTH_INDICATOR_ERROR "Failed to create preauth indicator file, " \
53 : "special password prompting might not be available.\n"
54 :
55 : struct ipa_init_ctx {
56 : struct ipa_options *options;
57 : struct ipa_id_ctx *id_ctx;
58 : struct ipa_auth_ctx *auth_ctx;
59 : };
60 :
61 0 : static bool srv_in_server_list(const char *servers)
62 : {
63 : TALLOC_CTX *tmp_ctx;
64 0 : char **list = NULL;
65 0 : int ret = 0;
66 0 : bool has_srv = false;
67 :
68 0 : if (servers == NULL) return true;
69 :
70 0 : tmp_ctx = talloc_new(NULL);
71 0 : if (!tmp_ctx) {
72 0 : return false;
73 : }
74 :
75 : /* split server parm into a list */
76 0 : ret = split_on_separator(tmp_ctx, servers, ',', true, true, &list, NULL);
77 0 : if (ret != EOK) {
78 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse server list!\n");
79 0 : goto done;
80 : }
81 :
82 0 : for (int i = 0; list[i]; i++) {
83 0 : has_srv = be_fo_is_srv_identifier(list[i]);
84 0 : if (has_srv == true) {
85 0 : break;
86 : }
87 : }
88 :
89 : done:
90 0 : talloc_free(tmp_ctx);
91 0 : return has_srv;
92 : }
93 :
94 0 : static errno_t ipa_init_options(TALLOC_CTX *mem_ctx,
95 : struct be_ctx *be_ctx,
96 : struct ipa_options **_ipa_options)
97 : {
98 : struct ipa_options *ipa_options;
99 : const char *ipa_servers;
100 : const char *ipa_backup_servers;
101 : errno_t ret;
102 :
103 0 : ret = ipa_get_options(mem_ctx, be_ctx->cdb, be_ctx->conf_path,
104 : be_ctx->domain, &ipa_options);
105 0 : if (ret != EOK) {
106 0 : return ret;
107 : }
108 :
109 0 : ipa_servers = dp_opt_get_string(ipa_options->basic, IPA_SERVER);
110 0 : ipa_backup_servers = dp_opt_get_string(ipa_options->basic, IPA_BACKUP_SERVER);
111 :
112 0 : ret = ipa_service_init(ipa_options, be_ctx, ipa_servers,
113 : ipa_backup_servers, ipa_options,
114 0 : &ipa_options->service);
115 0 : if (ret != EOK) {
116 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Failed to init IPA service [%d]: %s\n",
117 : ret, sss_strerror(ret));
118 0 : talloc_free(ipa_options);
119 0 : return ret;
120 : }
121 :
122 0 : *_ipa_options = ipa_options;
123 0 : return EOK;
124 : }
125 :
126 0 : static errno_t ipa_init_id_ctx(TALLOC_CTX *mem_ctx,
127 : struct be_ctx *be_ctx,
128 : struct ipa_options *ipa_options,
129 : struct ipa_id_ctx **_ipa_id_ctx)
130 : {
131 0 : struct ipa_id_ctx *ipa_id_ctx = NULL;
132 0 : struct sdap_id_ctx *sdap_id_ctx = NULL;
133 : errno_t ret;
134 :
135 0 : ipa_id_ctx = talloc_zero(mem_ctx, struct ipa_id_ctx);
136 0 : if (ipa_id_ctx == NULL) {
137 0 : ret = ENOMEM;
138 0 : goto done;
139 : }
140 :
141 0 : sdap_id_ctx = sdap_id_ctx_new(mem_ctx, be_ctx, ipa_options->service->sdap);
142 0 : if (sdap_id_ctx == NULL) {
143 0 : ret = ENOMEM;
144 0 : goto done;
145 : }
146 :
147 0 : ipa_id_ctx->ipa_options = ipa_options;
148 0 : ipa_id_ctx->sdap_id_ctx = sdap_id_ctx;
149 0 : ipa_options->id_ctx = ipa_id_ctx;
150 :
151 0 : ret = ipa_get_id_options(ipa_options, be_ctx->cdb, be_ctx->conf_path,
152 : &sdap_id_ctx->opts);
153 0 : if (ret != EOK) {
154 0 : goto done;
155 : }
156 :
157 0 : *_ipa_id_ctx = ipa_id_ctx;
158 :
159 0 : ret = EOK;
160 :
161 : done:
162 0 : if (ret != EOK) {
163 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to init id context [%d]: %s\n",
164 : ret, sss_strerror(ret));
165 :
166 0 : talloc_free(ipa_id_ctx);
167 0 : talloc_free(sdap_id_ctx);
168 : }
169 :
170 0 : return ret;
171 : }
172 :
173 :
174 0 : static errno_t ipa_init_dyndns(struct be_ctx *be_ctx,
175 : struct ipa_options *ipa_options)
176 : {
177 : bool enabled;
178 : errno_t ret;
179 :
180 0 : ret = ipa_get_dyndns_options(be_ctx, ipa_options);
181 0 : if (ret != EOK) {
182 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get dyndns options [%d]: %s\n",
183 : ret, sss_strerror(ret));
184 0 : return ret;
185 : }
186 :
187 0 : enabled = dp_opt_get_bool(ipa_options->dyndns_ctx->opts,
188 : DP_OPT_DYNDNS_UPDATE);
189 0 : if (!enabled) {
190 0 : DEBUG(SSSDBG_CONF_SETTINGS, "Dynamic DNS updates are of.\n");
191 0 : return EOK;
192 : }
193 :
194 : /* Perform automatic DNS updates when the IP address changes.
195 : * Register a callback for successful LDAP reconnections.
196 : * This is the easiest way to identify that we have gone online.
197 : */
198 :
199 0 : DEBUG(SSSDBG_CONF_SETTINGS,
200 : "Dynamic DNS updates are on. Checking for nsupdate...\n");
201 :
202 0 : ret = be_nsupdate_check();
203 0 : if (ret != EOK) {
204 0 : DEBUG(SSSDBG_CONF_SETTINGS, "nsupdate is not availabe, "
205 : "dynamic DNS updates will not work\n");
206 0 : return EOK;
207 : }
208 :
209 0 : DEBUG(SSSDBG_CONF_SETTINGS, "nsupdate is available\n");
210 :
211 0 : ret = ipa_dyndns_init(be_ctx, ipa_options);
212 0 : if (ret != EOK) {
213 0 : DEBUG(SSSDBG_MINOR_FAILURE,
214 : "Failure setting up automatic DNS update\n");
215 : /* We will continue without DNS updating */
216 : }
217 :
218 0 : return EOK;
219 : }
220 :
221 0 : static errno_t ipa_init_server_mode(struct be_ctx *be_ctx,
222 : struct ipa_options *ipa_options,
223 : struct ipa_id_ctx *ipa_id_ctx)
224 : {
225 : const char *ipa_servers;
226 : const char *dnsdomain;
227 : const char *hostname;
228 : bool sites_enabled;
229 : errno_t ret;
230 :
231 0 : ipa_id_ctx->view_name = talloc_strdup(ipa_id_ctx, SYSDB_DEFAULT_VIEW_NAME);
232 0 : if (ipa_id_ctx->view_name == NULL) {
233 0 : DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup() failed.\n");
234 0 : return ENOMEM;
235 : }
236 :
237 0 : ret = sysdb_update_view_name(be_ctx->domain->sysdb, ipa_id_ctx->view_name);
238 0 : if (ret != EOK) {
239 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Cannot add/update view name to sysdb.\n");
240 0 : return ret;
241 : }
242 :
243 0 : hostname = dp_opt_get_string(ipa_options->basic, IPA_HOSTNAME);
244 0 : ipa_servers = dp_opt_get_string(ipa_options->basic, IPA_SERVER);
245 0 : sites_enabled = dp_opt_get_bool(ipa_options->basic, IPA_ENABLE_DNS_SITES);
246 0 : dnsdomain = dp_opt_get_string(be_ctx->be_res->opts, DP_RES_OPT_DNS_DOMAIN);
247 :
248 0 : if (srv_in_server_list(ipa_servers) || sites_enabled) {
249 0 : DEBUG(SSSDBG_MINOR_FAILURE, "SRV resolution or IPA sites enabled "
250 : "on the IPA server. Site discovery of trusted AD servers "
251 : "might not work.\n");
252 :
253 : /* If SRV discovery is enabled on the server and
254 : * dns_discovery_domain is set explicitly, then
255 : * the current failover code would use the dns_discovery
256 : * domain to try to find AD servers and fail.
257 : */
258 0 : if (dnsdomain != NULL) {
259 0 : sss_log(SSS_LOG_ERR, DNS_SRV_MISCONFIGURATION);
260 0 : DEBUG(SSSDBG_CRIT_FAILURE, DNS_SRV_MISCONFIGURATION);
261 : }
262 :
263 0 : ret = be_fo_set_dns_srv_lookup_plugin(be_ctx, hostname);
264 0 : if (ret != EOK) {
265 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set SRV lookup plugin "
266 : "[%d]: %s\n", ret, sss_strerror(ret));
267 0 : return ret;
268 : }
269 :
270 0 : return EOK;
271 : } else {
272 : /* In server mode we need to ignore the dns_discovery_domain if set
273 : * and only discover servers based on AD domains. */
274 0 : ret = dp_opt_set_string(be_ctx->be_res->opts, DP_RES_OPT_DNS_DOMAIN,
275 : NULL);
276 0 : if (ret != EOK) {
277 0 : DEBUG(SSSDBG_MINOR_FAILURE, "Could not reset the "
278 : "dns_discovery_domain, trusted AD domains discovery "
279 : "might fail. Please remove dns_discovery_domain "
280 : "from the config file and restart the SSSD\n");
281 : } else {
282 0 : DEBUG(SSSDBG_CONF_SETTINGS, "The value of dns_discovery_domain "
283 : "will be ignored in ipa_server_mode\n");
284 : }
285 : }
286 :
287 0 : return EOK;
288 : }
289 :
290 0 : static errno_t ipa_init_client_mode(struct be_ctx *be_ctx,
291 : struct ipa_options *ipa_options,
292 : struct ipa_id_ctx *ipa_id_ctx)
293 : {
294 : struct ipa_srv_plugin_ctx *srv_ctx;
295 : const char *ipa_domain;
296 : const char *hostname;
297 : bool sites_enabled;
298 : errno_t ret;
299 :
300 0 : ret = sysdb_get_view_name(ipa_id_ctx, be_ctx->domain->sysdb,
301 : &ipa_id_ctx->view_name);
302 0 : if (ret == ENOENT) {
303 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find view name in the cache. "
304 : "Will do online lookup later.\n");
305 0 : } else if (ret != EOK) {
306 0 : DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_view_name() failed [%d]: %s\n",
307 : ret, sss_strerror(ret));
308 0 : return ret;
309 : }
310 :
311 0 : hostname = dp_opt_get_string(ipa_options->basic, IPA_HOSTNAME);
312 0 : sites_enabled = dp_opt_get_bool(ipa_options->basic, IPA_ENABLE_DNS_SITES);
313 :
314 0 : if (sites_enabled) {
315 : /* use IPA plugin */
316 0 : ipa_domain = dp_opt_get_string(ipa_options->basic, IPA_DOMAIN);
317 0 : srv_ctx = ipa_srv_plugin_ctx_init(be_ctx, be_ctx->be_res->resolv,
318 : hostname, ipa_domain);
319 0 : if (srv_ctx == NULL) {
320 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
321 0 : return ENOMEM;
322 : }
323 :
324 0 : be_fo_set_srv_lookup_plugin(be_ctx, ipa_srv_plugin_send,
325 : ipa_srv_plugin_recv, srv_ctx, "IPA");
326 : } else {
327 : /* fall back to standard plugin on clients. */
328 0 : ret = be_fo_set_dns_srv_lookup_plugin(be_ctx, hostname);
329 0 : if (ret != EOK) {
330 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set SRV lookup plugin "
331 : "[%d]: %s\n", ret, strerror(ret));
332 0 : return ret;
333 : }
334 : }
335 :
336 0 : return EOK;
337 : }
338 :
339 0 : static errno_t ipa_init_ipa_auth_ctx(TALLOC_CTX *mem_ctx,
340 : struct ipa_options *ipa_options,
341 : struct ipa_id_ctx *ipa_id_ctx,
342 : struct ipa_auth_ctx **_ipa_auth_ctx)
343 : {
344 : struct ipa_auth_ctx *ipa_auth_ctx;
345 : errno_t ret;
346 :
347 0 : ipa_auth_ctx = talloc_zero(mem_ctx, struct ipa_auth_ctx);
348 0 : if (ipa_auth_ctx == NULL) {
349 0 : return ENOMEM;
350 : }
351 :
352 0 : ipa_auth_ctx->sdap_id_ctx = ipa_id_ctx->sdap_id_ctx;
353 :
354 0 : ret = dp_copy_options(ipa_auth_ctx, ipa_options->basic,
355 : IPA_OPTS_BASIC, &ipa_auth_ctx->ipa_options);
356 0 : if (ret != EOK) {
357 0 : DEBUG(SSSDBG_CRIT_FAILURE, "dp_copy_options failed.\n");
358 0 : talloc_free(ipa_auth_ctx);
359 0 : return ret;
360 : }
361 :
362 0 : *_ipa_auth_ctx = ipa_auth_ctx;
363 :
364 0 : return EOK;
365 : }
366 :
367 0 : static errno_t ipa_init_krb5_auth_ctx(TALLOC_CTX *mem_ctx,
368 : struct be_ctx *be_ctx,
369 : struct ipa_options *ipa_options,
370 : struct krb5_ctx **_krb5_auth_ctx)
371 : {
372 : struct krb5_ctx *krb5_auth_ctx;
373 : bool server_mode;
374 : errno_t ret;
375 :
376 0 : krb5_auth_ctx = talloc_zero(mem_ctx, struct krb5_ctx);
377 0 : if (krb5_auth_ctx == NULL) {
378 0 : return ENOMEM;
379 : }
380 :
381 0 : krb5_auth_ctx->service = ipa_options->service->krb5_service;
382 :
383 0 : server_mode = dp_opt_get_bool(ipa_options->basic, IPA_SERVER_MODE);
384 0 : krb5_auth_ctx->config_type = server_mode ? K5C_IPA_SERVER : K5C_IPA_CLIENT;
385 :
386 0 : ret = ipa_get_auth_options(ipa_options, be_ctx->cdb, be_ctx->conf_path,
387 : &krb5_auth_ctx->opts);
388 0 : if (ret != EOK) {
389 0 : talloc_free(krb5_auth_ctx);
390 0 : return ret;
391 : }
392 :
393 0 : *_krb5_auth_ctx = krb5_auth_ctx;
394 0 : return EOK;
395 : }
396 :
397 0 : static errno_t ipa_init_sdap_auth_ctx(TALLOC_CTX *mem_ctx,
398 : struct be_ctx *be_ctx,
399 : struct ipa_options *ipa_options,
400 : struct sdap_auth_ctx **_sdap_auth_ctx)
401 : {
402 : struct sdap_auth_ctx *sdap_auth_ctx;
403 :
404 0 : sdap_auth_ctx = talloc_zero(mem_ctx, struct sdap_auth_ctx);
405 0 : if (sdap_auth_ctx == NULL) {
406 0 : return ENOMEM;
407 : }
408 :
409 0 : sdap_auth_ctx->be = be_ctx;
410 0 : sdap_auth_ctx->service = ipa_options->service->sdap;
411 :
412 0 : if (ipa_options->id == NULL) {
413 0 : talloc_free(sdap_auth_ctx);
414 0 : return EINVAL;
415 : }
416 :
417 0 : sdap_auth_ctx->opts = ipa_options->id;
418 :
419 0 : *_sdap_auth_ctx = sdap_auth_ctx;
420 :
421 0 : return EOK;
422 : }
423 :
424 0 : static void cleanup_ipa_preauth_indicator(void)
425 : {
426 : int ret;
427 :
428 0 : ret = unlink(PAM_PREAUTH_INDICATOR);
429 0 : if (ret != EOK) {
430 0 : DEBUG(SSSDBG_OP_FAILURE,
431 : "Failed to remove preauth indicator file [%s].\n",
432 : PAM_PREAUTH_INDICATOR);
433 : }
434 0 : }
435 :
436 0 : static errno_t create_ipa_preauth_indicator(void)
437 : {
438 : TALLOC_CTX *tmp_ctx;
439 : errno_t ret;
440 : int fd;
441 :
442 0 : tmp_ctx = talloc_new(NULL);
443 0 : if (tmp_ctx == NULL) {
444 0 : DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
445 0 : return ENOMEM;
446 : }
447 :
448 0 : fd = open(PAM_PREAUTH_INDICATOR, O_CREAT | O_EXCL | O_WRONLY | O_NOFOLLOW,
449 : 0644);
450 0 : if (fd < 0) {
451 0 : if (errno != EEXIST) {
452 0 : DEBUG(SSSDBG_OP_FAILURE,
453 : "Failed to create preauth indicator file [%s].\n",
454 : PAM_PREAUTH_INDICATOR);
455 0 : ret = EOK;
456 0 : goto done;
457 : }
458 :
459 0 : DEBUG(SSSDBG_CRIT_FAILURE,
460 : "Preauth indicator file [%s] already exists. "
461 : "Maybe it is left after an unplanned exit. Continuing.\n",
462 : PAM_PREAUTH_INDICATOR);
463 : } else {
464 0 : close(fd);
465 : }
466 :
467 0 : ret = atexit(cleanup_ipa_preauth_indicator);
468 0 : if (ret != EOK) {
469 0 : DEBUG(SSSDBG_OP_FAILURE, "atexit failed. Continuing.\n");
470 : }
471 :
472 0 : ret = EOK;
473 :
474 : done:
475 0 : talloc_free(tmp_ctx);
476 :
477 0 : return ret;
478 : }
479 :
480 : static struct sdap_ext_member_ctx *
481 0 : ipa_create_ext_members_ctx(TALLOC_CTX *mem_ctx,
482 : struct ipa_id_ctx *id_ctx)
483 : {
484 0 : struct sdap_ext_member_ctx *ext_ctx = NULL;
485 :
486 0 : ext_ctx = talloc_zero(mem_ctx, struct sdap_ext_member_ctx);
487 0 : if (ext_ctx == NULL) {
488 0 : return NULL;
489 : }
490 :
491 0 : ext_ctx->pvt = id_ctx;
492 0 : ext_ctx->ext_member_resolve_send = ipa_ext_group_member_send;
493 0 : ext_ctx->ext_member_resolve_recv = ipa_ext_group_member_recv;
494 :
495 0 : return ext_ctx;
496 : }
497 :
498 0 : static errno_t ipa_init_auth_ctx(TALLOC_CTX *mem_ctx,
499 : struct be_ctx *be_ctx,
500 : struct ipa_options *ipa_options,
501 : struct ipa_id_ctx *id_ctx,
502 : struct ipa_auth_ctx **_auth_ctx)
503 : {
504 : struct sdap_auth_ctx *sdap_auth_ctx;
505 : struct ipa_auth_ctx *ipa_auth_ctx;
506 : struct krb5_ctx *krb5_auth_ctx;
507 : errno_t ret;
508 :
509 0 : ret = ipa_init_ipa_auth_ctx(mem_ctx, ipa_options, id_ctx, &ipa_auth_ctx);
510 0 : if (ret != EOK) {
511 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to init IPA auth context\n");
512 0 : return ret;
513 : }
514 :
515 0 : ipa_options->auth_ctx = ipa_auth_ctx;
516 :
517 0 : ret = ipa_init_krb5_auth_ctx(ipa_auth_ctx, be_ctx, ipa_options,
518 : &krb5_auth_ctx);
519 0 : if (ret != EOK) {
520 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to init KRB5 auth context\n");
521 0 : goto done;
522 : }
523 0 : ipa_options->auth_ctx->krb5_auth_ctx = krb5_auth_ctx;
524 :
525 0 : ret = ipa_init_sdap_auth_ctx(ipa_auth_ctx, be_ctx, ipa_options,
526 : &sdap_auth_ctx);
527 0 : if (ret != EOK) {
528 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to init SDAP auth context\n");
529 0 : goto done;
530 : }
531 0 : ipa_options->auth_ctx->sdap_auth_ctx = sdap_auth_ctx;
532 :
533 0 : ret = setup_tls_config(sdap_auth_ctx->opts->basic);
534 0 : if (ret != EOK) {
535 0 : DEBUG(SSSDBG_CRIT_FAILURE, "setup_tls_config failed [%d]: %s\n",
536 : ret, sss_strerror(ret));
537 0 : goto done;
538 : }
539 :
540 : /* Initialize features needed by the krb5_child */
541 0 : ret = krb5_child_init(krb5_auth_ctx, be_ctx);
542 0 : if (ret != EOK) {
543 0 : DEBUG(SSSDBG_FATAL_FAILURE, "Could not initialize krb5_child "
544 : "settings [%d]: %s\n", ret, sss_strerror(ret));
545 0 : goto done;
546 : }
547 :
548 0 : ret = create_ipa_preauth_indicator();
549 0 : if (ret != EOK) {
550 0 : DEBUG(SSSDBG_CRIT_FAILURE, PREAUTH_INDICATOR_ERROR);
551 0 : sss_log(SSSDBG_CRIT_FAILURE, PREAUTH_INDICATOR_ERROR);
552 : }
553 :
554 0 : *_auth_ctx = ipa_auth_ctx;
555 0 : ret = EOK;
556 :
557 : done:
558 0 : if (ret != EOK) {
559 0 : talloc_free(ipa_auth_ctx);
560 : }
561 :
562 0 : return ret;
563 : }
564 :
565 0 : static errno_t ipa_init_misc(struct be_ctx *be_ctx,
566 : struct ipa_options *ipa_options,
567 : struct ipa_id_ctx *ipa_id_ctx,
568 : struct sdap_id_ctx *sdap_id_ctx)
569 : {
570 : errno_t ret;
571 :
572 0 : ret = ipa_init_dyndns(be_ctx, ipa_options);
573 0 : if (ret != EOK) {
574 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to init dyndns [%d]: %s\n",
575 : ret, sss_strerror(ret));
576 0 : return ret;
577 : }
578 :
579 0 : ret = setup_tls_config(sdap_id_ctx->opts->basic);
580 0 : if (ret != EOK) {
581 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get TLS options [%d]: %s\n",
582 : ret, sss_strerror(ret));
583 0 : return ret;
584 : }
585 :
586 0 : ret = ipa_idmap_init(sdap_id_ctx, sdap_id_ctx,
587 0 : &sdap_id_ctx->opts->idmap_ctx);
588 0 : if (ret != EOK) {
589 0 : DEBUG(SSSDBG_FATAL_FAILURE,
590 : "Could not initialize ID mapping. In case ID mapping properties "
591 : "changed on the server, please remove the SSSD database\n");
592 0 : return ret;
593 : }
594 :
595 0 : ret = ldap_id_setup_tasks(sdap_id_ctx);
596 0 : if (ret != EOK) {
597 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup background tasks "
598 : "[%d]: %s\n", ret, sss_strerror(ret));
599 0 : return ret;
600 : }
601 :
602 0 : ret = sdap_setup_child();
603 0 : if (ret != EOK) {
604 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup sdap child [%d]: %s\n",
605 : ret, sss_strerror(ret));
606 0 : return ret;
607 : }
608 :
609 0 : if (dp_opt_get_bool(ipa_options->basic, IPA_SERVER_MODE)) {
610 0 : ret = ipa_init_server_mode(be_ctx, ipa_options, ipa_id_ctx);
611 0 : if (ret != EOK) {
612 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to init server mode "
613 : "[%d]: %s\n", ret, sss_strerror(ret));
614 0 : return ret;
615 : }
616 : } else {
617 0 : ret = ipa_init_client_mode(be_ctx, ipa_options, ipa_id_ctx);
618 0 : if (ret != EOK) {
619 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to init client mode "
620 : "[%d]: %s\n", ret, sss_strerror(ret));
621 0 : return ret;
622 : }
623 : }
624 :
625 0 : ret = sdap_refresh_init(be_ctx->refresh_ctx, sdap_id_ctx);
626 0 : if (ret != EOK && ret != EEXIST) {
627 0 : DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh "
628 : "will not work [%d]: %s\n", ret, sss_strerror(ret));
629 : }
630 :
631 0 : ipa_id_ctx->sdap_id_ctx->opts->ext_ctx = ipa_create_ext_members_ctx(
632 0 : ipa_id_ctx->sdap_id_ctx->opts, ipa_id_ctx);
633 0 : if (ipa_id_ctx->sdap_id_ctx->opts->ext_ctx == NULL) {
634 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set the extrernal group ctx\n");
635 0 : return ENOMEM;
636 : }
637 :
638 0 : return EOK;
639 : }
640 :
641 0 : errno_t sssm_ipa_init(TALLOC_CTX *mem_ctx,
642 : struct be_ctx *be_ctx,
643 : struct data_provider *provider,
644 : const char *module_name,
645 : void **_module_data)
646 : {
647 : struct ipa_init_ctx *init_ctx;
648 : errno_t ret;
649 :
650 0 : init_ctx = talloc_zero(mem_ctx, struct ipa_init_ctx);
651 0 : if (init_ctx == NULL) {
652 0 : return ENOMEM;
653 : }
654 :
655 : /* Always initialize options since it is needed everywhere. */
656 0 : ret = ipa_init_options(init_ctx, be_ctx, &init_ctx->options);
657 0 : if (ret != EOK) {
658 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to init IPA options "
659 : "[%d]: %s\n", ret, sss_strerror(ret));
660 0 : goto done;
661 : }
662 :
663 : /* Always initialize id_ctx since it is needed everywhere. */
664 0 : ret = ipa_init_id_ctx(init_ctx, be_ctx, init_ctx->options,
665 : &init_ctx->id_ctx);
666 0 : if (ret != EOK) {
667 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to init IPA ID context "
668 : "[%d]: %s\n", ret, sss_strerror(ret));
669 0 : goto done;
670 : }
671 :
672 : /* Setup miscellaneous things. */
673 0 : ret = ipa_init_misc(be_ctx, init_ctx->options, init_ctx->id_ctx,
674 0 : init_ctx->id_ctx->sdap_id_ctx);
675 0 : if (ret != EOK) {
676 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to init IPA module "
677 : "[%d]: %s\n", ret, sss_strerror(ret));
678 0 : goto done;
679 : }
680 :
681 : /* Initialize auth_ctx only if one of the target is enabled. */
682 0 : if (dp_target_enabled(provider, module_name, DPT_AUTH, DPT_CHPASS)) {
683 0 : ret = ipa_init_auth_ctx(init_ctx, be_ctx, init_ctx->options,
684 : init_ctx->id_ctx, &init_ctx->auth_ctx);
685 0 : if (ret != EOK) {
686 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to init IPA auth context "
687 : "[%d]: %s\n", ret, sss_strerror(ret));
688 0 : goto done;
689 : }
690 : }
691 :
692 0 : *_module_data = init_ctx;
693 :
694 0 : ret = EOK;
695 :
696 : done:
697 0 : if (ret != EOK) {
698 0 : talloc_free(init_ctx);
699 : }
700 :
701 0 : return ret;
702 : }
703 :
704 0 : errno_t sssm_ipa_id_init(TALLOC_CTX *mem_ctx,
705 : struct be_ctx *be_ctx,
706 : void *module_data,
707 : struct dp_method *dp_methods)
708 : {
709 : struct ipa_init_ctx *init_ctx;
710 : struct ipa_id_ctx *id_ctx;
711 :
712 0 : init_ctx = talloc_get_type(module_data, struct ipa_init_ctx);
713 0 : id_ctx = init_ctx->id_ctx;
714 :
715 0 : dp_set_method(dp_methods, DPM_ACCOUNT_HANDLER,
716 : ipa_account_info_handler_send, ipa_account_info_handler_recv, id_ctx,
717 : struct ipa_id_ctx, struct be_acct_req, struct dp_reply_std);
718 :
719 0 : dp_set_method(dp_methods, DPM_CHECK_ONLINE,
720 : sdap_online_check_handler_send, sdap_online_check_handler_recv, id_ctx->sdap_id_ctx,
721 : struct sdap_id_ctx, void, struct dp_reply_std);
722 :
723 0 : return EOK;
724 : }
725 :
726 0 : errno_t sssm_ipa_auth_init(TALLOC_CTX *mem_ctx,
727 : struct be_ctx *be_ctx,
728 : void *module_data,
729 : struct dp_method *dp_methods)
730 : {
731 : struct ipa_init_ctx *init_ctx;
732 : struct ipa_auth_ctx *auth_ctx;
733 :
734 0 : init_ctx = talloc_get_type(module_data, struct ipa_init_ctx);
735 0 : auth_ctx = init_ctx->auth_ctx;
736 :
737 0 : dp_set_method(dp_methods, DPM_AUTH_HANDLER,
738 : ipa_pam_auth_handler_send, ipa_pam_auth_handler_recv, auth_ctx,
739 : struct ipa_auth_ctx, struct pam_data, struct pam_data *);
740 :
741 0 : return EOK;
742 : }
743 :
744 0 : errno_t sssm_ipa_chpass_init(TALLOC_CTX *mem_ctx,
745 : struct be_ctx *be_ctx,
746 : void *module_data,
747 : struct dp_method *dp_methods)
748 : {
749 0 : return sssm_ipa_auth_init(mem_ctx, be_ctx, module_data, dp_methods);
750 : }
751 :
752 0 : errno_t sssm_ipa_access_init(TALLOC_CTX *mem_ctx,
753 : struct be_ctx *be_ctx,
754 : void *module_data,
755 : struct dp_method *dp_methods)
756 : {
757 : struct ipa_access_ctx *access_ctx;
758 : struct ipa_init_ctx *init_ctx;
759 : struct ipa_id_ctx *id_ctx;
760 : errno_t ret;
761 :
762 0 : init_ctx = talloc_get_type(module_data, struct ipa_init_ctx);
763 0 : id_ctx = init_ctx->id_ctx;
764 :
765 0 : access_ctx = talloc_zero(mem_ctx, struct ipa_access_ctx);
766 0 : if (access_ctx == NULL) {
767 0 : DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero() failed.\n");
768 0 : return ENOMEM;
769 : }
770 :
771 0 : access_ctx->sdap_ctx = id_ctx->sdap_id_ctx;
772 0 : access_ctx->host_map = id_ctx->ipa_options->host_map;
773 0 : access_ctx->hostgroup_map = id_ctx->ipa_options->hostgroup_map;
774 0 : access_ctx->host_search_bases = id_ctx->ipa_options->host_search_bases;
775 0 : access_ctx->hbac_search_bases = id_ctx->ipa_options->hbac_search_bases;
776 :
777 0 : ret = dp_copy_options(access_ctx, id_ctx->ipa_options->basic,
778 : IPA_OPTS_BASIC, &access_ctx->ipa_options);
779 0 : if (ret != EOK) {
780 0 : DEBUG(SSSDBG_CRIT_FAILURE, "dp_copy_options() failed.\n");
781 0 : goto done;
782 : }
783 :
784 : /* Set up an sdap_access_ctx for checking expired/locked accounts. */
785 0 : access_ctx->sdap_access_ctx = talloc_zero(access_ctx, struct sdap_access_ctx);
786 0 : if (access_ctx->sdap_access_ctx == NULL) {
787 0 : DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero() failed\n");
788 0 : ret = ENOMEM;
789 0 : goto done;
790 : }
791 :
792 0 : access_ctx->sdap_access_ctx->id_ctx = access_ctx->sdap_ctx;
793 0 : access_ctx->sdap_access_ctx->access_rule[0] = LDAP_ACCESS_EXPIRE;
794 0 : access_ctx->sdap_access_ctx->access_rule[1] = LDAP_ACCESS_EMPTY;
795 :
796 0 : dp_set_method(dp_methods, DPM_ACCESS_HANDLER,
797 : ipa_pam_access_handler_send, ipa_pam_access_handler_recv, access_ctx,
798 : struct ipa_access_ctx, struct pam_data, struct pam_data *);
799 :
800 0 : ret = EOK;
801 :
802 : done:
803 0 : if (ret != EOK) {
804 0 : talloc_free(access_ctx);
805 : }
806 :
807 0 : return ret;
808 : }
809 :
810 0 : errno_t sssm_ipa_selinux_init(TALLOC_CTX *mem_ctx,
811 : struct be_ctx *be_ctx,
812 : void *module_data,
813 : struct dp_method *dp_methods)
814 : {
815 : #if defined HAVE_SELINUX && defined HAVE_SELINUX_LOGIN_DIR
816 : struct ipa_selinux_ctx *selinux_ctx;
817 : struct ipa_init_ctx *init_ctx;
818 : struct ipa_options *opts;
819 :
820 0 : init_ctx = talloc_get_type(module_data, struct ipa_init_ctx);
821 0 : opts = init_ctx->options;
822 :
823 0 : selinux_ctx = talloc_zero(mem_ctx, struct ipa_selinux_ctx);
824 0 : if (selinux_ctx == NULL) {
825 0 : DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero() failed.\n");
826 0 : return ENOMEM;
827 : }
828 :
829 0 : selinux_ctx->id_ctx = init_ctx->id_ctx;
830 0 : selinux_ctx->hbac_search_bases = opts->hbac_search_bases;
831 0 : selinux_ctx->host_search_bases = opts->host_search_bases;
832 0 : selinux_ctx->selinux_search_bases = opts->selinux_search_bases;
833 :
834 0 : dp_set_method(dp_methods, DPM_SELINUX_HANDLER,
835 : ipa_selinux_handler_send, ipa_selinux_handler_recv, selinux_ctx,
836 : struct ipa_selinux_ctx, struct pam_data, struct pam_data *);
837 :
838 0 : return EOK;
839 : #else
840 : DEBUG(SSSDBG_MINOR_FAILURE, "SELinux init handler called but SSSD is "
841 : "built without SSH support, ignoring\n");
842 : return EOK;
843 : #endif
844 : }
845 :
846 0 : errno_t sssm_ipa_hostid_init(TALLOC_CTX *mem_ctx,
847 : struct be_ctx *be_ctx,
848 : void *module_data,
849 : struct dp_method *dp_methods)
850 : {
851 : #ifdef BUILD_SSH
852 : struct ipa_hostid_ctx *hostid_ctx;
853 : struct ipa_init_ctx *init_ctx;
854 :
855 0 : init_ctx = talloc_get_type(module_data, struct ipa_init_ctx);
856 :
857 0 : hostid_ctx = talloc_zero(mem_ctx, struct ipa_hostid_ctx);
858 0 : if (hostid_ctx == NULL) {
859 0 : DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n");
860 0 : return ENOMEM;
861 : }
862 :
863 0 : hostid_ctx->sdap_id_ctx = init_ctx->id_ctx->sdap_id_ctx;
864 0 : hostid_ctx->host_search_bases = init_ctx->options->host_search_bases;
865 0 : hostid_ctx->ipa_opts = init_ctx->options;
866 :
867 0 : dp_set_method(dp_methods, DPM_HOSTID_HANDLER,
868 : ipa_hostid_handler_send, ipa_hostid_handler_recv, hostid_ctx,
869 : struct ipa_hostid_ctx, struct dp_hostid_data, struct dp_reply_std);
870 :
871 0 : return EOK;
872 : #else
873 : DEBUG(SSSDBG_MINOR_FAILURE, "HostID init handler called but SSSD is "
874 : "built without SSH support, ignoring\n");
875 : return EOK;
876 : #endif
877 : }
878 :
879 0 : errno_t sssm_ipa_autofs_init(TALLOC_CTX *mem_ctx,
880 : struct be_ctx *be_ctx,
881 : void *module_data,
882 : struct dp_method *dp_methods)
883 : {
884 : #ifdef BUILD_AUTOFS
885 : struct ipa_init_ctx *init_ctx;
886 :
887 0 : DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing IPA autofs handler\n");
888 0 : init_ctx = talloc_get_type(module_data, struct ipa_init_ctx);
889 :
890 0 : return ipa_autofs_init(mem_ctx, be_ctx, init_ctx->id_ctx, dp_methods);
891 : #else
892 : DEBUG(SSSDBG_MINOR_FAILURE, "Autofs init handler called but SSSD is "
893 : "built without autofs support, ignoring\n");
894 : return EOK;
895 : #endif
896 : }
897 :
898 0 : errno_t sssm_ipa_subdomains_init(TALLOC_CTX *mem_ctx,
899 : struct be_ctx *be_ctx,
900 : void *module_data,
901 : struct dp_method *dp_methods)
902 : {
903 : struct ipa_init_ctx *init_ctx;
904 :
905 0 : DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing IPA subdomains handler\n");
906 0 : init_ctx = talloc_get_type(module_data, struct ipa_init_ctx);
907 :
908 0 : return ipa_subdomains_init(mem_ctx, be_ctx, init_ctx->id_ctx, dp_methods);
909 : }
910 :
911 0 : errno_t sssm_ipa_sudo_init(TALLOC_CTX *mem_ctx,
912 : struct be_ctx *be_ctx,
913 : void *module_data,
914 : struct dp_method *dp_methods)
915 : {
916 : #ifdef BUILD_SUDO
917 : struct ipa_init_ctx *init_ctx;
918 :
919 0 : DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing IPA sudo handler\n");
920 0 : init_ctx = talloc_get_type(module_data, struct ipa_init_ctx);
921 :
922 0 : return ipa_sudo_init(mem_ctx, be_ctx, init_ctx->id_ctx, dp_methods);
923 : #else
924 : DEBUG(SSSDBG_MINOR_FAILURE, "Sudo init handler called but SSSD is "
925 : "built without sudo support, ignoring\n");
926 : return EOK;
927 : #endif
928 : }
|