LCOV - code coverage report
Current view: top level - providers/ipa - ipa_subdomains_server.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 352 512 68.8 %
Date: 2015-10-19 Functions: 27 28 96.4 %

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

Generated by: LCOV version 1.10