LCOV - code coverage report
Current view: top level - providers/ipa - ipa_subdomains_server.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 29 512 5.7 %
Date: 2016-06-29 Functions: 3 28 10.7 %

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     IPA Subdomains Module - server mode
       5             : 
       6             :     Authors:
       7             :         Sumit Bose <sbose@redhat.com>
       8             : 
       9             :     Copyright (C) 2015 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 "providers/ldap/sdap_async.h"
      26             : #include "providers/ldap/sdap_idmap.h"
      27             : #include "providers/ipa/ipa_subdomains.h"
      28             : #include "providers/ipa/ipa_common.h"
      29             : #include "providers/ipa/ipa_id.h"
      30             : 
      31             : /* These constants are defined in MS-ADTS 6.1.6.7.1
      32             :  *  https://msdn.microsoft.com/en-us/library/cc223768.aspx
      33             :  */
      34             : #define LSA_TRUST_DIRECTION_INBOUND  0x00000001
      35             : #define LSA_TRUST_DIRECTION_OUTBOUND 0x00000002
      36             : 
      37           0 : static char *forest_keytab(TALLOC_CTX *mem_ctx, const char *forest)
      38             : {
      39           0 :     return talloc_asprintf(mem_ctx,
      40             :                            "%s/%s.keytab", IPA_TRUST_KEYTAB_DIR, forest);
      41             : }
      42             : 
      43           0 : static char *subdomain_trust_princ(TALLOC_CTX *mem_ctx,
      44             :                                    const char *forest_realm,
      45             :                                    struct sss_domain_info *sd)
      46             : {
      47           0 :     if (sd->parent->flat_name == NULL) {
      48           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
      49             :               "Unknown flat name for parent %s\n", sd->parent->name);
      50           0 :         return NULL;
      51             :     }
      52             : 
      53           0 :     return talloc_asprintf(mem_ctx, "%s$@%s",
      54           0 :                            sd->parent->flat_name, forest_realm);
      55             : }
      56             : 
      57           2 : static uint32_t default_direction(TALLOC_CTX *mem_ctx,
      58             :                                   struct ldb_context *ldb_ctx,
      59             :                                   struct sysdb_attrs *attrs)
      60             : {
      61           2 :     struct ldb_dn *dn = NULL;
      62             :     uint32_t direction;
      63             : 
      64           2 :     dn = ipa_subdom_ldb_dn(mem_ctx, ldb_ctx, attrs);
      65           2 :     if (dn == NULL) {
      66             :         /* Shouldn't happen, but let's try system keytab in this case */
      67           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
      68             :               "Cannot determine subdomain DN, falling back to two-way trust\n");
      69           0 :         return (LSA_TRUST_DIRECTION_INBOUND|LSA_TRUST_DIRECTION_OUTBOUND);
      70             :     }
      71             : 
      72           2 :     if (ipa_subdom_is_member_dom(dn) == true) {
      73             :         /* It's expected member domains do not have the direction */
      74           1 :         direction = 0;
      75             :     } else {
      76             :         /* Old server? Default to 2way trust */
      77           1 :         direction = (LSA_TRUST_DIRECTION_INBOUND|LSA_TRUST_DIRECTION_OUTBOUND);
      78             :     }
      79             : 
      80           2 :     talloc_free(dn);
      81           2 :     return direction;
      82             : }
      83             : 
      84           5 : errno_t ipa_server_get_trust_direction(struct sysdb_attrs *sd,
      85             :                                        struct ldb_context *ldb_ctx,
      86             :                                        uint32_t *_direction)
      87             : {
      88           5 :     uint32_t ipa_trust_direction = 0;
      89             :     uint32_t direction;
      90             :     int ret;
      91             : 
      92           5 :     ret = sysdb_attrs_get_uint32_t(sd, IPA_TRUST_DIRECTION,
      93             :                                    &ipa_trust_direction);
      94           5 :     DEBUG(SSSDBG_TRACE_INTERNAL,
      95             :           "Raw %s value: %d\n", IPA_TRUST_DIRECTION, ipa_trust_direction);
      96           5 :     if (ret == ENOENT) {
      97           2 :         direction = default_direction(sd, ldb_ctx, sd);
      98           3 :     } else if (ret == EOK) {
      99             :         /* Just store the AD value in SYSDB, we will check it while we're
     100             :          * trying to use the trust */
     101           3 :         direction = ipa_trust_direction;
     102             :     } else {
     103           0 :         return ret;
     104             :     }
     105             : 
     106           5 :     *_direction = direction;
     107           5 :     return EOK;
     108             : }
     109             : 
     110           4 : const char *ipa_trust_dir2str(uint32_t direction)
     111             : {
     112           4 :     if ((direction & LSA_TRUST_DIRECTION_OUTBOUND)
     113           1 :             && (direction & LSA_TRUST_DIRECTION_INBOUND)) {
     114           0 :         return "two-way trust";
     115           4 :     } else if (direction & LSA_TRUST_DIRECTION_OUTBOUND) {
     116           1 :         return "one-way outbound: local domain is trusted by remote domain";
     117           3 :     } else if (direction & LSA_TRUST_DIRECTION_INBOUND) {
     118           1 :         return "one-way inbound: local domain trusts the remote domain";
     119           2 :     } else if (direction == 0) {
     120           1 :         return "trust direction not set";
     121             :     }
     122             : 
     123           1 :     return "unknown";
     124             : }
     125             : 
     126             : #ifndef IPA_GETKEYTAB_TIMEOUT
     127             : #define IPA_GETKEYTAB_TIMEOUT 5
     128             : #endif /* IPA_GETKEYTAB_TIMEOUT */
     129             : 
     130             : static struct ad_options *
     131           0 : ipa_create_1way_trust_ctx(struct ipa_id_ctx *id_ctx,
     132             :                           const char *forest,
     133             :                           const char *forest_realm,
     134             :                           struct sss_domain_info *subdom)
     135             : {
     136             :     char *keytab;
     137             :     char *principal;
     138             :     struct ad_options *ad_options;
     139             :     const char *ad_domain;
     140             : 
     141           0 :     ad_domain = subdom->name;
     142           0 :     keytab = forest_keytab(id_ctx, forest);
     143           0 :     principal = subdomain_trust_princ(id_ctx, forest_realm, subdom);
     144           0 :     if (keytab == NULL || principal == NULL) {
     145           0 :         return NULL;
     146             :     }
     147             : 
     148           0 :     ad_options = ad_create_1way_trust_options(id_ctx,
     149             :                                               ad_domain,
     150           0 :                                               id_ctx->server_mode->hostname,
     151             :                                               keytab,
     152             :                                               principal);
     153           0 :     if (ad_options == NULL) {
     154           0 :         talloc_free(keytab);
     155           0 :         talloc_free(principal);
     156           0 :         return NULL;
     157             :     }
     158             : 
     159           0 :     return ad_options;
     160             : }
     161             : 
     162           0 : static struct ad_options *ipa_ad_options_new(struct ipa_id_ctx *id_ctx,
     163             :                                              struct sss_domain_info *subdom)
     164             : {
     165           0 :     struct ad_options *ad_options = NULL;
     166             :     uint32_t direction;
     167             :     const char *forest;
     168             :     const char *forest_realm;
     169             : 
     170             :     /* Trusts are only established with forest roots */
     171           0 :     direction = subdom->forest_root->trust_direction;
     172           0 :     forest_realm = subdom->forest_root->realm;
     173           0 :     forest = subdom->forest_root->forest;
     174             : 
     175           0 :     if (direction & LSA_TRUST_DIRECTION_OUTBOUND) {
     176           0 :         ad_options = ad_create_2way_trust_options(id_ctx,
     177           0 :                                                   id_ctx->server_mode->realm,
     178           0 :                                                   subdom->name,
     179           0 :                                                   id_ctx->server_mode->hostname,
     180             :                                                   NULL);
     181           0 :     } else if (direction & LSA_TRUST_DIRECTION_INBOUND) {
     182           0 :         ad_options = ipa_create_1way_trust_ctx(id_ctx, forest,
     183             :                                                forest_realm, subdom);
     184             :     } else {
     185           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported trust direction!\n");
     186           0 :         ad_options = NULL;
     187             :     }
     188             : 
     189           0 :     if (ad_options == NULL) {
     190           0 :         DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD options\n");
     191           0 :         return NULL;
     192             :     }
     193           0 :     return ad_options;
     194             : }
     195             : 
     196             : 
     197             : static errno_t
     198           0 : ipa_ad_ctx_new(struct be_ctx *be_ctx,
     199             :                struct ipa_id_ctx *id_ctx,
     200             :                struct sss_domain_info *subdom,
     201             :                struct ad_id_ctx **_ad_id_ctx)
     202             : {
     203             :     struct ad_options *ad_options;
     204             :     struct ad_id_ctx *ad_id_ctx;
     205             :     const char *gc_service_name;
     206             :     struct ad_srv_plugin_ctx *srv_ctx;
     207             :     const char *ad_domain;
     208             :     const char *ad_site_override;
     209             :     struct sdap_domain *sdom;
     210             :     errno_t ret;
     211             :     const char *extra_attrs;
     212             : 
     213           0 :     ad_domain = subdom->name;
     214           0 :     DEBUG(SSSDBG_TRACE_LIBS, "Setting up AD subdomain %s\n", subdom->name);
     215             : 
     216           0 :     ad_options = ipa_ad_options_new(id_ctx, subdom);
     217           0 :     if (ad_options == NULL) {
     218           0 :         DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD options\n");
     219           0 :         talloc_free(ad_options);
     220           0 :         return ENOMEM;
     221             :     }
     222             : 
     223           0 :     extra_attrs = dp_opt_get_string(id_ctx->sdap_id_ctx->opts->basic,
     224             :                             SDAP_USER_EXTRA_ATTRS);
     225           0 :     if (extra_attrs != NULL) {
     226           0 :         DEBUG(SSSDBG_TRACE_ALL,
     227             :               "Setting extra attrs for subdomain [%s] to [%s].\n", ad_domain,
     228             :                                                                    extra_attrs);
     229             : 
     230           0 :         ret = dp_opt_set_string(ad_options->id->basic, SDAP_USER_EXTRA_ATTRS,
     231             :                                 extra_attrs);
     232           0 :         if (ret != EOK) {
     233           0 :             DEBUG(SSSDBG_OP_FAILURE, "dp_opt_get_string failed.\n");
     234           0 :             talloc_free(ad_options);
     235           0 :             return ret;
     236             :         }
     237             : 
     238           0 :         ret = sdap_extend_map_with_list(ad_options->id, ad_options->id,
     239             :                                         SDAP_USER_EXTRA_ATTRS,
     240           0 :                                         ad_options->id->user_map,
     241             :                                         SDAP_OPTS_USER,
     242           0 :                                         &ad_options->id->user_map,
     243           0 :                                         &ad_options->id->user_map_cnt);
     244           0 :         if (ret != EOK) {
     245           0 :             DEBUG(SSSDBG_OP_FAILURE, "sdap_extend_map_with_list failed.\n");
     246           0 :             talloc_free(ad_options);
     247           0 :             return ret;
     248             :         }
     249             :     } else {
     250           0 :         DEBUG(SSSDBG_TRACE_ALL, "No extra attrs set.\n");
     251             :     }
     252             : 
     253           0 :     gc_service_name = talloc_asprintf(ad_options, "%s%s", "gc_", subdom->forest);
     254           0 :     if (gc_service_name == NULL) {
     255           0 :         talloc_free(ad_options);
     256           0 :         return ENOMEM;
     257             :     }
     258             : 
     259             :     /* Set KRB5 realm to same as the one of IPA when IPA
     260             :      * is able to attach PAC. For testing, use hardcoded. */
     261           0 :     ret = ad_failover_init(ad_options, be_ctx, NULL, NULL,
     262           0 :                            id_ctx->server_mode->realm,
     263           0 :                            subdom->name, gc_service_name,
     264           0 :                            subdom->name, &ad_options->service);
     265           0 :     if (ret != EOK) {
     266           0 :         DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD failover\n");
     267           0 :         talloc_free(ad_options);
     268           0 :         return ret;
     269             :     }
     270             : 
     271           0 :     ad_id_ctx = ad_id_ctx_init(ad_options, be_ctx);
     272           0 :     if (ad_id_ctx == NULL) {
     273           0 :         talloc_free(ad_options);
     274           0 :         return ENOMEM;
     275             :     }
     276           0 :     ad_id_ctx->sdap_id_ctx->opts = ad_options->id;
     277           0 :     ad_options->id_ctx = ad_id_ctx;
     278             : 
     279           0 :     ad_site_override = dp_opt_get_string(ad_options->basic, AD_SITE);
     280             : 
     281             :     /* use AD plugin */
     282           0 :     srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx->be_res,
     283             :                                      default_host_dbs,
     284           0 :                                      ad_id_ctx->ad_options->id,
     285           0 :                                      id_ctx->server_mode->hostname,
     286             :                                      ad_domain,
     287             :                                      ad_site_override);
     288           0 :     if (srv_ctx == NULL) {
     289           0 :         DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
     290           0 :         return ENOMEM;
     291             :     }
     292           0 :     be_fo_set_srv_lookup_plugin(be_ctx, ad_srv_plugin_send,
     293             :                                 ad_srv_plugin_recv, srv_ctx, "AD");
     294             : 
     295           0 :     ret = sdap_domain_subdom_add(ad_id_ctx->sdap_id_ctx,
     296           0 :                                  ad_id_ctx->sdap_id_ctx->opts->sdom,
     297             :                                  subdom->parent);
     298           0 :     if (ret != EOK) {
     299           0 :         DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize sdap domain\n");
     300           0 :         talloc_free(ad_options);
     301           0 :         return ret;
     302             :     }
     303             : 
     304           0 :     sdom = sdap_domain_get(ad_id_ctx->sdap_id_ctx->opts, subdom);
     305           0 :     if (sdom == NULL) {
     306           0 :         return EFAULT;
     307             :     }
     308             : 
     309           0 :     sdap_inherit_options(subdom->parent->sd_inherit,
     310           0 :                          id_ctx->sdap_id_ctx->opts,
     311           0 :                          ad_id_ctx->sdap_id_ctx->opts);
     312             : 
     313           0 :     ret = sdap_id_setup_tasks(be_ctx,
     314             :                               ad_id_ctx->sdap_id_ctx,
     315             :                               sdom,
     316             :                               ldap_enumeration_send,
     317             :                               ldap_enumeration_recv,
     318           0 :                               ad_id_ctx->sdap_id_ctx);
     319           0 :     if (ret != EOK) {
     320           0 :         talloc_free(ad_options);
     321           0 :         return ret;
     322             :     }
     323             : 
     324           0 :     sdom->pvt = ad_id_ctx;
     325             : 
     326             :     /* Set up the ID mapping object */
     327           0 :     ad_id_ctx->sdap_id_ctx->opts->idmap_ctx =
     328           0 :         id_ctx->sdap_id_ctx->opts->idmap_ctx;
     329             : 
     330           0 :     *_ad_id_ctx = ad_id_ctx;
     331           0 :     return EOK;
     332             : }
     333             : 
     334             : struct ipa_getkeytab_state {
     335             :     int child_status;
     336             :     struct sss_child_ctx_old *child_ctx;
     337             :     struct tevent_timer *timeout_handler;
     338             : };
     339             : 
     340             : static void ipa_getkeytab_exec(const char *ccache,
     341             :                                const char *server,
     342             :                                const char *principal,
     343             :                                const char *keytab_path);
     344             : static void ipa_getkeytab_done(int child_status,
     345             :                                struct tevent_signal *sige,
     346             :                                void *pvt);
     347             : static void ipa_getkeytab_timeout(struct tevent_context *ev,
     348             :                                   struct tevent_timer *te,
     349             :                                   struct timeval tv, void *pvt);
     350             : 
     351           0 : static struct tevent_req *ipa_getkeytab_send(TALLOC_CTX *mem_ctx,
     352             :                                              struct tevent_context *ev,
     353             :                                              const char *ccache,
     354             :                                              const char *server,
     355             :                                              const char *principal,
     356             :                                              const char *keytab)
     357             : 
     358             : 
     359             : {
     360             :     errno_t ret;
     361           0 :     struct tevent_req *req = NULL;
     362             :     struct ipa_getkeytab_state *state;
     363             :     pid_t child_pid;
     364             :     struct timeval tv;
     365             : 
     366           0 :     req = tevent_req_create(mem_ctx, &state, struct ipa_getkeytab_state);
     367           0 :     if (req == NULL) {
     368           0 :         return NULL;
     369             :     }
     370           0 :     state->child_status = EFAULT;
     371             : 
     372           0 :     if (server == NULL || principal == NULL || keytab == NULL) {
     373           0 :         ret = EINVAL;
     374           0 :         goto done;
     375             :     }
     376             : 
     377           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     378             :           "Retrieving keytab for %s from %s into %s using ccache %s\n",
     379             :           principal, server, keytab, ccache);
     380             : 
     381           0 :     child_pid = fork();
     382           0 :     if (child_pid == 0) { /* child */
     383           0 :         ipa_getkeytab_exec(ccache, server, principal, keytab);
     384           0 :     } else if (child_pid > 0) { /* parent */
     385             :         /* Set up SIGCHLD handler */
     386           0 :         ret = child_handler_setup(ev, child_pid, ipa_getkeytab_done, req,
     387           0 :                                   &state->child_ctx);
     388           0 :         if (ret != EOK) {
     389           0 :             DEBUG(SSSDBG_OP_FAILURE, "Could not set up child handlers [%d]: %s\n",
     390             :                 ret, sss_strerror(ret));
     391           0 :             ret = ERR_IPA_GETKEYTAB_FAILED;
     392           0 :             goto done;
     393             :         }
     394             : 
     395             :         /* Set up timeout handler */
     396           0 :         tv = tevent_timeval_current_ofs(IPA_GETKEYTAB_TIMEOUT, 0);
     397           0 :         state->timeout_handler = tevent_add_timer(ev, req, tv,
     398             :                                                   ipa_getkeytab_timeout, req);
     399           0 :         if(state->timeout_handler == NULL) {
     400           0 :             ret = ERR_IPA_GETKEYTAB_FAILED;
     401           0 :             goto done;
     402             :         }
     403             : 
     404             :         /* Now either wait for the timeout to fire or the child
     405             :          * to finish
     406             :          */
     407             :     } else { /* error */
     408           0 :         ret = errno;
     409           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     410             :               "fork failed [%d][%s].\n", ret, sss_strerror(ret));
     411           0 :         goto done;
     412             :     }
     413             : 
     414           0 :     ret = EOK;
     415             : done:
     416           0 :     if (ret != EOK) {
     417           0 :         tevent_req_error(req, ret);
     418           0 :         tevent_req_post(req, ev);
     419             :     }
     420           0 :     return req;
     421             : }
     422             : 
     423           0 : static void ipa_getkeytab_exec(const char *ccache,
     424             :                                const char *server,
     425             :                                const char *principal,
     426             :                                const char *keytab_path)
     427             : {
     428             :     errno_t ret;
     429             :     int debug_fd;
     430           0 :     const char *gkt_env[2] = { NULL, NULL };
     431             : 
     432           0 :     if (debug_level >= SSSDBG_TRACE_LIBS) {
     433           0 :         debug_fd = get_fd_from_debug_file();
     434           0 :         ret = dup2(debug_fd, STDERR_FILENO);
     435           0 :         if (ret == -1) {
     436           0 :             ret = errno;
     437           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
     438             :                 "dup2 failed [%d][%s].\n", ret, sss_strerror(ret));
     439             :             /* stderr is not fatal */
     440             :         }
     441             :     }
     442             : 
     443           0 :     gkt_env[0] = talloc_asprintf(NULL, "KRB5CCNAME=%s", ccache);
     444           0 :     if (gkt_env[0] == NULL) {
     445           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to format KRB5CCNAME\n");
     446           0 :         exit(1);
     447             :     }
     448             : 
     449             :     /* ipa-getkeytab cannot add keys to an empty file, let's unlink it and only
     450             :      * use the filename */
     451           0 :     ret = unlink(keytab_path);
     452           0 :     if (ret == -1) {
     453           0 :         ret = errno;
     454           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     455             :               "Failed to unlink the temporary ccname [%d][%s]\n",
     456             :               ret, sss_strerror(ret));
     457           0 :         exit(1);
     458             :     }
     459             : 
     460           0 :     errno = 0;
     461           0 :     ret = execle(IPA_GETKEYTAB_PATH, IPA_GETKEYTAB_PATH,
     462             :                  "-r", "-s", server, "-p", principal, "-k", keytab_path, NULL,
     463             :                  gkt_env);
     464             : 
     465           0 :     DEBUG(SSSDBG_CRIT_FAILURE,
     466             :           "execle returned %d, this shouldn't happen!\n", ret);
     467             : 
     468             :     /* The child should never end up here */
     469           0 :     ret = errno;
     470           0 :     DEBUG(SSSDBG_CRIT_FAILURE,
     471             :           "execle failed [%d][%s].\n", ret, sss_strerror(ret));
     472           0 :     exit(1);
     473             : }
     474             : 
     475           0 : static void ipa_getkeytab_done(int child_status,
     476             :                                struct tevent_signal *sige,
     477             :                                void *pvt)
     478             : {
     479           0 :     struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
     480           0 :     struct ipa_getkeytab_state *state =
     481           0 :             tevent_req_data(req, struct ipa_getkeytab_state);
     482             : 
     483           0 :     state->child_status = child_status;
     484             : 
     485           0 :     if (WIFEXITED(child_status) && WEXITSTATUS(child_status) != 0) {
     486           0 :         DEBUG(SSSDBG_OP_FAILURE,
     487             :               "ipa-getkeytab failed with status [%d]\n", child_status);
     488           0 :         tevent_req_error(req, ERR_IPA_GETKEYTAB_FAILED);
     489           0 :         return;
     490             :     }
     491             : 
     492           0 :     if (WIFSIGNALED(child_status)) {
     493           0 :         DEBUG(SSSDBG_OP_FAILURE,
     494             :               "ipa-getkeytab was terminated by signal [%d]\n",
     495             :                WTERMSIG(child_status));
     496           0 :         tevent_req_error(req, ERR_IPA_GETKEYTAB_FAILED);
     497           0 :         return;
     498             :     }
     499             : 
     500           0 :     tevent_req_done(req);
     501             : }
     502             : 
     503           0 : static void ipa_getkeytab_timeout(struct tevent_context *ev,
     504             :                                   struct tevent_timer *te,
     505             :                                   struct timeval tv, void *pvt)
     506             : {
     507           0 :     struct tevent_req *req =
     508             :             talloc_get_type(pvt, struct tevent_req);
     509           0 :     struct ipa_getkeytab_state *state =
     510           0 :             tevent_req_data(req, struct ipa_getkeytab_state);
     511             : 
     512           0 :     DEBUG(SSSDBG_CRIT_FAILURE, "Timeout reached for retrieving keytab from IPA server\n");
     513           0 :     child_handler_destroy(state->child_ctx);
     514           0 :     state->child_ctx = NULL;
     515           0 :     state->child_status = ETIMEDOUT;
     516           0 :     tevent_req_error(req, ERR_IPA_GETKEYTAB_FAILED);
     517           0 : }
     518             : 
     519           0 : static errno_t ipa_getkeytab_recv(struct tevent_req *req, int *child_status)
     520             : {
     521           0 :     struct ipa_getkeytab_state *state =
     522           0 :             tevent_req_data(req, struct ipa_getkeytab_state);
     523             : 
     524           0 :     DEBUG(SSSDBG_TRACE_INTERNAL,
     525             :           "ipa-getkeytab status %d\n", state->child_status);
     526           0 :     if (child_status) {
     527           0 :         *child_status = state->child_status;
     528             :     }
     529             : 
     530           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     531             : 
     532           0 :     return EOK;
     533             : }
     534             : 
     535           0 : static errno_t ipa_check_keytab(const char *keytab,
     536             :                                 uid_t kt_owner_uid,
     537             :                                 gid_t kt_owner_gid)
     538             : {
     539             :     errno_t ret;
     540             : 
     541           0 :     ret = check_file(keytab, getuid(), getgid(), S_IFREG|0600, 0, NULL, false);
     542           0 :     if (ret == ENOENT) {
     543           0 :         DEBUG(SSSDBG_TRACE_FUNC, "Keytab %s is not present\n", keytab);
     544           0 :         goto done;
     545           0 :     } else if (ret != EOK) {
     546           0 :         if (kt_owner_uid) {
     547           0 :             ret = check_file(keytab, kt_owner_uid, kt_owner_gid,
     548             :                              S_IFREG|0600, 0, NULL, false);
     549             :         }
     550             : 
     551           0 :         if (ret != EOK) {
     552           0 :             if (ret != ENOENT) {
     553           0 :                 DEBUG(SSSDBG_OP_FAILURE, "Failed to check for %s\n", keytab);
     554             :             } else {
     555           0 :                 DEBUG(SSSDBG_TRACE_FUNC, "Keytab %s is not present\n", keytab);
     556             :             }
     557             :         }
     558           0 :         goto done;
     559             :     }
     560             : 
     561           0 :     DEBUG(SSSDBG_TRACE_ALL, "keytab %s already exists\n", keytab);
     562           0 :     ret = EOK;
     563             : done:
     564           0 :     return ret;
     565             : }
     566             : 
     567             : struct ipa_server_trusted_dom_setup_state {
     568             :     struct tevent_context *ev;
     569             :     struct be_ctx *be_ctx;
     570             :     struct ipa_id_ctx *id_ctx;
     571             :     struct sss_domain_info *subdom;
     572             : 
     573             :     uint32_t direction;
     574             :     const char *forest;
     575             :     const char *keytab;
     576             :     char *new_keytab;
     577             :     const char *principal;
     578             :     const char *forest_realm;
     579             :     const char *ccache;
     580             : };
     581             : 
     582             : static errno_t ipa_server_trusted_dom_setup_1way(struct tevent_req *req);
     583             : static void ipa_server_trust_1way_kt_done(struct tevent_req *subreq);
     584             : 
     585             : struct tevent_req *
     586           0 : ipa_server_trusted_dom_setup_send(TALLOC_CTX *mem_ctx,
     587             :                                   struct tevent_context *ev,
     588             :                                   struct be_ctx *be_ctx,
     589             :                                   struct ipa_id_ctx *id_ctx,
     590             :                                   struct sss_domain_info *subdom)
     591             : {
     592           0 :     struct tevent_req *req = NULL;
     593           0 :     struct ipa_server_trusted_dom_setup_state *state = NULL;
     594             :     errno_t ret;
     595             : 
     596           0 :     req = tevent_req_create(mem_ctx, &state,
     597             :                             struct ipa_server_trusted_dom_setup_state);
     598           0 :     if (req == NULL) {
     599           0 :         return NULL;
     600             :     }
     601           0 :     state->ev = ev;
     602           0 :     state->be_ctx = be_ctx;
     603           0 :     state->id_ctx = id_ctx;
     604           0 :     state->subdom = subdom;
     605             : 
     606             :     /* Trusts are only established with forest roots */
     607           0 :     if (subdom->forest_root == NULL) {
     608           0 :         DEBUG(SSSDBG_OP_FAILURE,
     609             :               "Subdomain %s has no forest root?\n", subdom->name);
     610           0 :         ret = ERR_TRUST_FOREST_UNKNOWN;
     611           0 :         goto immediate;
     612             :     }
     613             : 
     614           0 :     state->direction = subdom->forest_root->trust_direction;
     615           0 :     state->forest = subdom->forest_root->forest;
     616           0 :     state->forest_realm = subdom->forest_root->realm;
     617           0 :     state->ccache = talloc_asprintf(state, "%s/ccache_%s",
     618           0 :                                     DB_PATH, subdom->parent->realm);
     619           0 :     if (state->ccache == NULL) {
     620           0 :         ret = ENOMEM;
     621           0 :         goto immediate;
     622             :     }
     623             : 
     624           0 :     DEBUG(SSSDBG_TRACE_LIBS,
     625             :           "Trust direction of subdom %s from forest %s is: %s\n",
     626             :           subdom->name, state->forest,
     627             :           ipa_trust_dir2str(state->direction));
     628             : 
     629           0 :     if (state->direction & LSA_TRUST_DIRECTION_OUTBOUND) {
     630             :         /* Use system keytab, nothing to do here */
     631           0 :         ret = EOK;
     632           0 :         goto immediate;
     633           0 :     } else if (state->direction & LSA_TRUST_DIRECTION_INBOUND) {
     634             :         /* Need special keytab */
     635           0 :         ret = ipa_server_trusted_dom_setup_1way(req);
     636           0 :         if (ret == EAGAIN) {
     637             :             /* In progress.. */
     638           0 :             return req;
     639           0 :         } else if (ret == EOK) {
     640             :             /* Keytab available, shortcut */
     641           0 :             ret = EOK;
     642           0 :             goto immediate;
     643             :         }
     644             :     } else {
     645             :         /* Even unset is an error at this point */
     646           0 :         DEBUG(SSSDBG_OP_FAILURE,
     647             :               "Subdomain %s has trust direction %d\n",
     648             :               subdom->name, subdom->trust_direction);
     649           0 :         ret = ERR_TRUST_NOT_SUPPORTED;
     650             :     }
     651             : 
     652             : immediate:
     653           0 :     if (ret != EOK) {
     654           0 :         DEBUG(SSSDBG_OP_FAILURE,
     655             :               "Could not add trusted subdomain %s from forest %s\n",
     656             :               subdom->name, state->forest);
     657           0 :         tevent_req_error(req, ret);
     658             :     } else {
     659           0 :         tevent_req_done(req);
     660             :     }
     661           0 :     tevent_req_post(req, ev);
     662           0 :     return req;
     663             : }
     664             : 
     665           0 : static errno_t ipa_server_trusted_dom_setup_1way(struct tevent_req *req)
     666             : {
     667             :     errno_t ret;
     668           0 :     struct tevent_req *subreq = NULL;
     669           0 :     struct ipa_server_trusted_dom_setup_state *state =
     670           0 :             tevent_req_data(req, struct ipa_server_trusted_dom_setup_state);
     671             :     const char *hostname;
     672             : 
     673           0 :     state->keytab = forest_keytab(state, state->forest);
     674           0 :     if (state->keytab == NULL) {
     675           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set up ipa_get_keytab\n");
     676           0 :         return EIO;
     677             :     }
     678             : 
     679           0 :     state->new_keytab = talloc_asprintf(state, "%sXXXXXX", state->keytab);
     680           0 :     if (state->new_keytab == NULL) {
     681           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set up ipa_get_keytab\n");
     682           0 :         return ENOMEM;
     683             :     }
     684             : 
     685           0 :     ret = sss_unique_filename(state, state->new_keytab);
     686           0 :     if (ret != EOK) {
     687           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create temporary keytab name\n");
     688           0 :         return ret;
     689             :     }
     690             : 
     691           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     692             :           "Will re-fetch keytab for %s\n", state->subdom->name);
     693             : 
     694           0 :     hostname = dp_opt_get_string(state->id_ctx->ipa_options->basic,
     695             :                                  IPA_HOSTNAME);
     696             : 
     697           0 :     state->principal = subdomain_trust_princ(state,
     698             :                                              state->forest_realm,
     699             :                                              state->subdom);
     700           0 :     if (state->principal == NULL) {
     701           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set up ipa_get_keytab\n");
     702           0 :         return EIO;
     703             :     }
     704             : 
     705           0 :     subreq = ipa_getkeytab_send(state->be_ctx, state->be_ctx->ev,
     706             :                                 state->ccache,
     707             :                                 hostname,
     708             :                                 state->principal,
     709           0 :                                 state->new_keytab);
     710           0 :     if (subreq == NULL) {
     711           0 :         return ENOMEM;
     712             :     }
     713           0 :     tevent_req_set_callback(subreq, ipa_server_trust_1way_kt_done, req);
     714           0 :     return EAGAIN;
     715             : }
     716             : 
     717           0 : static void ipa_server_trust_1way_kt_done(struct tevent_req *subreq)
     718             : {
     719             :     errno_t ret;
     720           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     721             :                                                       struct tevent_req);
     722           0 :     struct ipa_server_trusted_dom_setup_state *state =
     723           0 :             tevent_req_data(req, struct ipa_server_trusted_dom_setup_state);
     724             : 
     725           0 :     ret = ipa_getkeytab_recv(subreq, NULL);
     726           0 :     talloc_zfree(subreq);
     727           0 :     if (ret != EOK) {
     728             :         /* Do not fail here, but try to check and use the previous keytab,
     729             :          * if any */
     730           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "ipa_getkeytab_recv failed: %d\n", ret);
     731             :     } else {
     732           0 :         DEBUG(SSSDBG_TRACE_FUNC,
     733             :               "Keytab successfully retrieved to %s\n", state->new_keytab);
     734             :     }
     735             : 
     736           0 :     ret = ipa_check_keytab(state->new_keytab,
     737           0 :                            state->id_ctx->server_mode->kt_owner_uid,
     738           0 :                            state->id_ctx->server_mode->kt_owner_gid);
     739           0 :     if (ret == EOK) {
     740           0 :         ret = rename(state->new_keytab, state->keytab);
     741           0 :         if (ret == -1) {
     742           0 :             ret = errno;
     743           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     744             :                 "rename failed [%d][%s].\n", ret, strerror(ret));
     745           0 :             tevent_req_error(req, ret);
     746           0 :             return;
     747             :         }
     748           0 :         DEBUG(SSSDBG_TRACE_INTERNAL, "Keytab renamed to %s\n", state->keytab);
     749           0 :     } else if (ret != EOK) {
     750           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     751             :               "Trying to recover and use the previous keytab, if available\n");
     752           0 :         ret = ipa_check_keytab(state->keytab,
     753           0 :                                state->id_ctx->server_mode->kt_owner_uid,
     754           0 :                                state->id_ctx->server_mode->kt_owner_gid);
     755           0 :         if (ret == EOK) {
     756           0 :             DEBUG(SSSDBG_TRACE_FUNC,
     757             :                   "The previous keytab %s contains the expected principal\n",
     758             :                   state->keytab);
     759             :         } else {
     760           0 :             DEBUG(SSSDBG_OP_FAILURE,
     761             :                   "Cannot use the old keytab: %d\n", ret);
     762             :             /* Nothing we can do now */
     763           0 :             tevent_req_error(req, ret);
     764           0 :             return;
     765             :         }
     766             :     }
     767             : 
     768           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     769             :           "Keytab %s contains the expected principals\n", state->new_keytab);
     770             : 
     771           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     772             :           "Established trust context for %s\n", state->subdom->name);
     773           0 :     tevent_req_done(req);
     774             : }
     775             : 
     776           0 : errno_t ipa_server_trusted_dom_setup_recv(struct tevent_req *req)
     777             : {
     778           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     779           0 :     return EOK;
     780             : }
     781             : 
     782             : struct ipa_server_create_trusts_state {
     783             :     struct tevent_context *ev;
     784             :     struct be_ctx *be_ctx;
     785             :     struct ipa_id_ctx *id_ctx;
     786             :     struct sss_domain_info *domiter;
     787             : };
     788             : 
     789             : static errno_t ipa_server_create_trusts_step(struct tevent_req *req);
     790             : static errno_t ipa_server_create_trusts_ctx(struct tevent_req *req);
     791             : static void ipa_server_create_trusts_done(struct tevent_req *subreq);
     792             : 
     793             : struct tevent_req *
     794           0 : ipa_server_create_trusts_send(TALLOC_CTX *mem_ctx,
     795             :                               struct tevent_context *ev,
     796             :                               struct be_ctx *be_ctx,
     797             :                               struct ipa_id_ctx *id_ctx,
     798             :                               struct sss_domain_info *parent)
     799             : {
     800           0 :     struct tevent_req *req = NULL;
     801           0 :     struct ipa_server_create_trusts_state *state = NULL;
     802             :     errno_t ret;
     803             : 
     804           0 :     req = tevent_req_create(mem_ctx, &state,
     805             :                             struct ipa_server_create_trusts_state);
     806           0 :     if (req == NULL) {
     807           0 :         return NULL;
     808             :     }
     809             : 
     810           0 :     state->ev = ev;
     811           0 :     state->be_ctx = be_ctx;
     812           0 :     state->id_ctx = id_ctx;
     813           0 :     state->domiter = parent;
     814             : 
     815           0 :     ret = ipa_server_create_trusts_step(req);
     816           0 :     if (ret != EAGAIN) {
     817           0 :         goto immediate;
     818             :     }
     819             : 
     820           0 :     return req;
     821             : 
     822             : immediate:
     823           0 :     if (ret != EOK) {
     824           0 :         tevent_req_error(req, ret);
     825             :     } else {
     826           0 :         tevent_req_done(req);
     827             :     }
     828           0 :     tevent_req_post(req, ev);
     829           0 :     return req;
     830             : }
     831             : 
     832           0 : static errno_t ipa_server_create_trusts_step(struct tevent_req *req)
     833             : {
     834           0 :     struct tevent_req *subreq = NULL;
     835             :     struct ipa_ad_server_ctx *trust_iter;
     836           0 :     struct ipa_server_create_trusts_state *state = NULL;
     837             : 
     838           0 :     state = tevent_req_data(req, struct ipa_server_create_trusts_state);
     839             : 
     840           0 :     for (state->domiter = get_next_domain(state->domiter, SSS_GND_DESCEND);
     841           0 :          state->domiter && IS_SUBDOMAIN(state->domiter);
     842           0 :          state->domiter = get_next_domain(state->domiter, 0)) {
     843             : 
     844             :         /* Check if we already have an ID context for this subdomain */
     845           0 :         DLIST_FOR_EACH(trust_iter, state->id_ctx->server_mode->trusts) {
     846           0 :             if (trust_iter->dom == state->domiter) {
     847           0 :                 break;
     848             :             }
     849             :         }
     850             : 
     851             :         /* Newly detected trust */
     852           0 :         if (trust_iter == NULL) {
     853           0 :             subreq = ipa_server_trusted_dom_setup_send(state,
     854             :                                                        state->ev,
     855             :                                                        state->be_ctx,
     856             :                                                        state->id_ctx,
     857             :                                                        state->domiter);
     858           0 :             if (subreq == NULL) {
     859           0 :                 return ENOMEM;
     860             :             }
     861           0 :             tevent_req_set_callback(subreq, ipa_server_create_trusts_done, req);
     862           0 :             return EAGAIN;
     863             :         }
     864             :     }
     865             : 
     866           0 :     return EOK;
     867             : }
     868             : 
     869           0 : static void ipa_server_create_trusts_done(struct tevent_req *subreq)
     870             : {
     871             :     errno_t ret;
     872           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     873             :                                                       struct tevent_req);
     874             : 
     875           0 :     ret = ipa_server_trusted_dom_setup_recv(subreq);
     876           0 :     talloc_zfree(subreq);
     877           0 :     if (ret != EOK) {
     878           0 :         tevent_req_error(req, ret);
     879           0 :         return;
     880             :     }
     881             : 
     882           0 :     ret = ipa_server_create_trusts_ctx(req);
     883           0 :     if (ret != EOK) {
     884           0 :         tevent_req_error(req, ret);
     885           0 :         return;
     886             :     }
     887             : 
     888           0 :     ret = ipa_server_create_trusts_step(req);
     889           0 :     if (ret == EOK) {
     890           0 :         tevent_req_done(req);
     891           0 :         return;
     892           0 :     } else if (ret != EAGAIN) {
     893           0 :         tevent_req_error(req, ret);
     894           0 :         return;
     895             :     }
     896             : 
     897             :     /* Will cycle back */
     898             : }
     899             : 
     900           0 : static errno_t ipa_server_create_trusts_ctx(struct tevent_req *req)
     901             : {
     902             :     struct ipa_ad_server_ctx *trust_ctx;
     903             :     struct ad_id_ctx *ad_id_ctx;
     904             :     errno_t ret;
     905           0 :     struct ipa_server_create_trusts_state *state = NULL;
     906             : 
     907           0 :     state = tevent_req_data(req, struct ipa_server_create_trusts_state);
     908             : 
     909           0 :     ret = ipa_ad_ctx_new(state->be_ctx, state->id_ctx, state->domiter, &ad_id_ctx);
     910           0 :     if (ret != EOK) {
     911           0 :         DEBUG(SSSDBG_OP_FAILURE,
     912             :               "Cannot create ad_id_ctx for subdomain %s\n", state->domiter->name);
     913           0 :         return ret;
     914             :     }
     915             : 
     916           0 :     trust_ctx = talloc(state->id_ctx->server_mode, struct ipa_ad_server_ctx);
     917           0 :     if (trust_ctx == NULL) {
     918           0 :         return ENOMEM;
     919             :     }
     920           0 :     trust_ctx->dom = state->domiter;
     921           0 :     trust_ctx->ad_id_ctx = ad_id_ctx;
     922             : 
     923           0 :     DLIST_ADD(state->id_ctx->server_mode->trusts, trust_ctx);
     924           0 :     return EOK;
     925             : }
     926             : 
     927           0 : errno_t ipa_server_create_trusts_recv(struct tevent_req *req)
     928             : {
     929           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     930           0 :     return EOK;
     931             : }
     932             : 
     933           0 : void ipa_ad_subdom_remove(struct be_ctx *be_ctx,
     934             :                           struct ipa_id_ctx *id_ctx,
     935             :                           struct sss_domain_info *subdom)
     936             : {
     937             :     struct ipa_ad_server_ctx *iter;
     938             :     struct sdap_domain *sdom;
     939             : 
     940           0 :     if (dp_opt_get_bool(id_ctx->ipa_options->basic,
     941           0 :                         IPA_SERVER_MODE) == false) {
     942           0 :         return;
     943             :     }
     944             : 
     945           0 :     DLIST_FOR_EACH(iter, id_ctx->server_mode->trusts) {
     946           0 :         if (iter->dom == subdom) break;
     947             :     }
     948             : 
     949           0 :     if (iter == NULL) {
     950           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "No IPA-AD context for subdomain %s\n",
     951             :               subdom->name);
     952           0 :         return;
     953             :     }
     954             : 
     955           0 :     sdom = sdap_domain_get(iter->ad_id_ctx->sdap_id_ctx->opts, subdom);
     956           0 :     if (sdom == NULL) return;
     957           0 :     be_ptask_destroy(&sdom->enum_task);
     958           0 :     be_ptask_destroy(&sdom->cleanup_task);
     959             : 
     960           0 :     sdap_domain_remove(iter->ad_id_ctx->sdap_id_ctx->opts, subdom);
     961           0 :     DLIST_REMOVE(id_ctx->server_mode->trusts, iter);
     962             : 
     963             :     /* terminate all requests for this subdomain so we can free it */
     964           0 :     dp_terminate_domain_requests(be_ctx->provider, subdom->name);
     965           0 :     talloc_zfree(sdom);
     966             : }
     967             : 
     968             : struct ipa_ad_subdom_reinit_state {
     969             :     struct tevent_context *ev;
     970             :     struct be_ctx *be_ctx;
     971             :     struct ipa_id_ctx *id_ctx;
     972             :     struct sss_domain_info *parent;
     973             : };
     974             : 
     975           0 : static void create_trusts_at_startup_done(struct tevent_req *req)
     976             : {
     977             :     errno_t ret;
     978             : 
     979           0 :     ret = ipa_server_create_trusts_recv(req);
     980           0 :     talloc_free(req);
     981           0 :     if (ret != EOK) {
     982           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     983             :               "ipa_server_create_trusts_send request failed [%d]: %s\n",
     984             :               ret, sss_strerror(ret));
     985             :     }
     986           0 : }
     987             : 
     988           0 : static void create_trusts_at_startup(struct tevent_context *ev,
     989             :                                      struct tevent_immediate *imm,
     990             :                                      void *pvt)
     991             : {
     992             :     struct tevent_req *req;
     993             :     struct ipa_ad_subdom_reinit_state *state;
     994             : 
     995           0 :     state = talloc_get_type(pvt, struct ipa_ad_subdom_reinit_state);
     996             : 
     997           0 :     req = ipa_server_create_trusts_send(state, state->ev, state->be_ctx,
     998             :                                         state->id_ctx, state->parent);
     999           0 :     if (req == NULL) {
    1000           0 :         DEBUG(SSSDBG_OP_FAILURE, "ipa_server_create_trusts_send failed.\n");
    1001           0 :         talloc_free(state);
    1002           0 :         return;
    1003             :     }
    1004             : 
    1005           0 :     tevent_req_set_callback(req, create_trusts_at_startup_done, state);
    1006           0 :     return;
    1007             : }
    1008             : 
    1009           0 : static errno_t ipa_ad_subdom_reinit(TALLOC_CTX *mem_ctx,
    1010             :                                     struct tevent_context *ev,
    1011             :                                     struct be_ctx *be_ctx,
    1012             :                                     struct ipa_id_ctx *id_ctx,
    1013             :                                     struct sss_domain_info *parent)
    1014             : {
    1015             :     struct tevent_immediate *imm;
    1016             :     struct ipa_ad_subdom_reinit_state *state;
    1017             : 
    1018           0 :     state = talloc(mem_ctx, struct ipa_ad_subdom_reinit_state);
    1019           0 :     if (state == NULL) {
    1020           0 :         return ENOMEM;
    1021             :     }
    1022           0 :     state->ev = ev;
    1023           0 :     state->be_ctx = be_ctx;
    1024           0 :     state->id_ctx = id_ctx;
    1025           0 :     state->parent = parent;
    1026             : 
    1027           0 :     if (dp_opt_get_bool(id_ctx->ipa_options->basic,
    1028           0 :                         IPA_SERVER_MODE) == false) {
    1029           0 :         return EOK;
    1030             :     }
    1031             : 
    1032           0 :     imm = tevent_create_immediate(mem_ctx);
    1033           0 :     if (imm == NULL) {
    1034           0 :         DEBUG(SSSDBG_OP_FAILURE, "tevent_create_immediate failed.\n");
    1035           0 :         talloc_free(state);
    1036           0 :         return ENOMEM;
    1037             :     }
    1038             : 
    1039           0 :     tevent_schedule_immediate(imm, ev, create_trusts_at_startup, state);
    1040           0 :     return EOK;
    1041             : }
    1042             : 
    1043           0 : int ipa_ad_subdom_init(struct be_ctx *be_ctx,
    1044             :                        struct ipa_id_ctx *id_ctx)
    1045             : {
    1046             :     char *realm;
    1047             :     char *hostname;
    1048             :     errno_t ret;
    1049             : 
    1050           0 :     if (dp_opt_get_bool(id_ctx->ipa_options->basic,
    1051           0 :                         IPA_SERVER_MODE) == false) {
    1052           0 :         return EOK;
    1053             :     }
    1054             : 
    1055             :     /* The IPA code relies on the default FQDN format to unparse user
    1056             :      * names. Warn loudly if the full_name_format was customized on the
    1057             :      * IPA server
    1058             :      */
    1059           0 :     if ((strcmp(be_ctx->domain->names->fq_fmt,
    1060             :                CONFDB_DEFAULT_FULL_NAME_FORMAT) != 0)
    1061           0 :             && (strcmp(be_ctx->domain->names->fq_fmt,
    1062             :                        CONFDB_DEFAULT_FULL_NAME_FORMAT_INTERNAL) != 0)) {
    1063           0 :         DEBUG(SSSDBG_FATAL_FAILURE, "%s is set to a non-default value [%s] " \
    1064             :               "lookups of subdomain users will likely fail!\n",
    1065             :               CONFDB_FULL_NAME_FORMAT, be_ctx->domain->names->fq_fmt);
    1066           0 :         sss_log(SSS_LOG_ERR, "%s is set to a non-default value [%s] " \
    1067             :                 "lookups of subdomain users will likely fail!\n",
    1068           0 :                 CONFDB_FULL_NAME_FORMAT, be_ctx->domain->names->fq_fmt);
    1069             :         /* Attempt to continue */
    1070             :     }
    1071             : 
    1072           0 :     realm = dp_opt_get_string(id_ctx->ipa_options->basic, IPA_KRB5_REALM);
    1073           0 :     if (realm == NULL) {
    1074           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm for IPA?\n");
    1075           0 :         return EINVAL;
    1076             :     }
    1077             : 
    1078           0 :     hostname = dp_opt_get_string(id_ctx->ipa_options->basic, IPA_HOSTNAME);
    1079           0 :     if (hostname == NULL) {
    1080           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "No host name for IPA?\n");
    1081           0 :         return EINVAL;
    1082             :     }
    1083             : 
    1084           0 :     id_ctx->server_mode = talloc_zero(id_ctx, struct ipa_server_mode_ctx);
    1085           0 :     if (id_ctx->server_mode == NULL) {
    1086           0 :         return ENOMEM;
    1087             :     }
    1088           0 :     id_ctx->server_mode->realm = realm;
    1089           0 :     id_ctx->server_mode->hostname = hostname;
    1090           0 :     id_ctx->server_mode->trusts = NULL;
    1091           0 :     id_ctx->server_mode->ext_groups = NULL;
    1092           0 :     id_ctx->server_mode->kt_owner_uid = 0;
    1093           0 :     id_ctx->server_mode->kt_owner_gid = 0;
    1094             : 
    1095           0 :     if (getuid() == 0) {
    1096             :         /* We need to handle keytabs created by IPA oddjob script gracefully
    1097             :          * even if we're running as root and IPA creates them as the SSSD user
    1098             :          */
    1099           0 :         ret = sss_user_by_name_or_uid(SSSD_USER,
    1100           0 :                                       &id_ctx->server_mode->kt_owner_uid,
    1101           0 :                                       &id_ctx->server_mode->kt_owner_gid);
    1102           0 :         if (ret != EOK) {
    1103           0 :             DEBUG(SSSDBG_MINOR_FAILURE, "Failed to get ID of %s\n", SSSD_USER);
    1104             :         }
    1105             :     }
    1106             : 
    1107           0 :     ret = ipa_ad_subdom_reinit(be_ctx, be_ctx->ev,
    1108             :                                be_ctx, id_ctx, be_ctx->domain);
    1109           0 :     if (ret != EOK) {
    1110           0 :         DEBUG(SSSDBG_OP_FAILURE, "ipa_ad_subdom_refresh failed.\n");
    1111           0 :         return ret;
    1112             :     }
    1113             : 
    1114           0 :     return EOK;
    1115             : }

Generated by: LCOV version 1.10