LCOV - code coverage report
Current view: top level - providers/ad - ad_common.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 186 569 32.7 %
Date: 2015-10-19 Functions: 14 24 58.3 %

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     Authors:
       5             :         Stephen Gallagher <sgallagh@redhat.com>
       6             : 
       7             :     Copyright (C) 2012 Red Hat
       8             : 
       9             :     This program is free software; you can redistribute it and/or modify
      10             :     it under the terms of the GNU General Public License as published by
      11             :     the Free Software Foundation; either version 3 of the License, or
      12             :     (at your option) any later version.
      13             : 
      14             :     This program is distributed in the hope that it will be useful,
      15             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :     GNU General Public License for more details.
      18             : 
      19             :     You should have received a copy of the GNU General Public License
      20             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : #include <ctype.h>
      23             : 
      24             : #include "providers/ad/ad_common.h"
      25             : #include "providers/ad/ad_opts.h"
      26             : #include "providers/dp_dyndns.h"
      27             : 
      28             : struct ad_server_data {
      29             :     bool gc;
      30             : };
      31             : 
      32             : errno_t ad_set_search_bases(struct sdap_options *id_opts);
      33             : static errno_t ad_set_sdap_options(struct ad_options *ad_opts,
      34             :                                    struct sdap_options *id_opts);
      35             : 
      36             : static struct sdap_options *
      37          19 : ad_create_default_sdap_options(TALLOC_CTX *mem_ctx)
      38             : {
      39             :     struct sdap_options *id_opts;
      40             :     errno_t ret;
      41             : 
      42          19 :     id_opts = talloc_zero(mem_ctx, struct sdap_options);
      43          19 :     if (!id_opts) {
      44           0 :         return NULL;
      45             :     }
      46             : 
      47          19 :     ret = dp_copy_defaults(id_opts,
      48             :                            ad_def_ldap_opts,
      49             :                            SDAP_OPTS_BASIC,
      50             :                            &id_opts->basic);
      51          19 :     if (ret != EOK) {
      52           0 :         goto fail;
      53             :     }
      54             : 
      55             :     /* Get sdap option maps */
      56             : 
      57             :     /* General Attribute Map */
      58          19 :     ret = sdap_copy_map(id_opts,
      59             :                        ad_2008r2_attr_map,
      60             :                        SDAP_AT_GENERAL,
      61             :                        &id_opts->gen_map);
      62          19 :     if (ret != EOK) {
      63           0 :         goto fail;
      64             :     }
      65             : 
      66             :     /* User map */
      67          19 :     ret = sdap_copy_map(id_opts,
      68             :                        ad_2008r2_user_map,
      69             :                        SDAP_OPTS_USER,
      70             :                        &id_opts->user_map);
      71          19 :     if (ret != EOK) {
      72           0 :         goto fail;
      73             :     }
      74          19 :     id_opts->user_map_cnt = SDAP_OPTS_USER;
      75             : 
      76             :     /* Group map */
      77          19 :     ret = sdap_copy_map(id_opts,
      78             :                        ad_2008r2_group_map,
      79             :                        SDAP_OPTS_GROUP,
      80             :                        &id_opts->group_map);
      81          19 :     if (ret != EOK) {
      82           0 :         goto fail;
      83             :     }
      84             : 
      85             :     /* Netgroup map */
      86          19 :     ret = sdap_copy_map(id_opts,
      87             :                        ad_netgroup_map,
      88             :                        SDAP_OPTS_NETGROUP,
      89             :                        &id_opts->netgroup_map);
      90          19 :     if (ret != EOK) {
      91           0 :         goto fail;
      92             :     }
      93             : 
      94             :     /* Services map */
      95          19 :     ret = sdap_copy_map(id_opts,
      96             :                        ad_service_map,
      97             :                        SDAP_OPTS_SERVICES,
      98             :                        &id_opts->service_map);
      99          19 :     if (ret != EOK) {
     100           0 :         goto fail;
     101             :     }
     102             : 
     103          19 :     return id_opts;
     104             : 
     105             : fail:
     106           0 :     talloc_free(id_opts);
     107           0 :     return NULL;
     108             : }
     109             : 
     110             : struct ad_options *
     111          19 : ad_create_default_options(TALLOC_CTX *mem_ctx)
     112             : {
     113             :     struct ad_options *ad_options;
     114             :     errno_t ret;
     115             : 
     116          19 :     ad_options = talloc_zero(mem_ctx, struct ad_options);
     117          19 :     if (ad_options == NULL) return NULL;
     118             : 
     119          19 :     ret = dp_copy_defaults(ad_options,
     120             :                            ad_basic_opts,
     121             :                            AD_OPTS_BASIC,
     122             :                            &ad_options->basic);
     123          19 :     if (ret != EOK) {
     124           0 :         talloc_free(ad_options);
     125           0 :         return NULL;
     126             :     }
     127             : 
     128          19 :     ad_options->id = ad_create_default_sdap_options(ad_options);
     129          19 :     if (ad_options->id == NULL) {
     130           0 :         DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD LDAP options\n");
     131           0 :         talloc_free(ad_options);
     132           0 :         return NULL;
     133             :     }
     134             : 
     135          19 :     return ad_options;
     136             : }
     137             : 
     138             : static errno_t
     139          18 : set_common_ad_trust_opts(struct ad_options *ad_options,
     140             :                          const char *realm,
     141             :                          const char *ad_domain,
     142             :                          const char *hostname)
     143             : {
     144             :     errno_t ret;
     145             : 
     146          18 :     ret = dp_opt_set_string(ad_options->basic, AD_KRB5_REALM, realm);
     147          18 :     if (ret != EOK) {
     148           0 :         DEBUG(SSSDBG_OP_FAILURE, "Cannot set AD krb5 realm\n");
     149           0 :         return ret;
     150             :     }
     151             : 
     152          18 :     ret = dp_opt_set_string(ad_options->basic, AD_DOMAIN, ad_domain);
     153          18 :     if (ret != EOK) {
     154           0 :         DEBUG(SSSDBG_OP_FAILURE, "Cannot set AD domain\n");
     155           0 :         return ret;
     156             :     }
     157             : 
     158          18 :     ret = dp_opt_set_string(ad_options->basic, AD_HOSTNAME, hostname);
     159          18 :     if (ret != EOK) {
     160           0 :         DEBUG(SSSDBG_OP_FAILURE, "Cannot set AD hostname\n");
     161           0 :         return ret;
     162             :     }
     163             : 
     164          18 :     return EOK;
     165             : }
     166             : 
     167             : struct ad_options *
     168           9 : ad_create_2way_trust_options(TALLOC_CTX *mem_ctx,
     169             :                              const char *realm,
     170             :                              const char *ad_domain,
     171             :                              const char *hostname)
     172             : {
     173             :     struct ad_options *ad_options;
     174             :     errno_t ret;
     175             : 
     176           9 :     ad_options = ad_create_default_options(mem_ctx);
     177           9 :     if (ad_options == NULL) return NULL;
     178             : 
     179           9 :     ret = set_common_ad_trust_opts(ad_options, realm, ad_domain, hostname);
     180           9 :     if (ret != EOK) {
     181           0 :         talloc_free(ad_options);
     182           0 :         return NULL;
     183             :     }
     184             : 
     185           9 :     ret = ad_set_sdap_options(ad_options, ad_options->id);
     186           9 :     if (ret != EOK) {
     187           0 :         talloc_free(ad_options);
     188           0 :         return NULL;
     189             :     }
     190             : 
     191           9 :     return ad_options;
     192             : }
     193             : 
     194             : struct ad_options *
     195           9 : ad_create_1way_trust_options(TALLOC_CTX *mem_ctx,
     196             :                              const char *ad_domain,
     197             :                              const char *hostname,
     198             :                              const char *keytab,
     199             :                              const char *sasl_authid)
     200             : {
     201             :     struct ad_options *ad_options;
     202             :     const char *realm;
     203             :     errno_t ret;
     204             : 
     205           9 :     ad_options = ad_create_default_options(mem_ctx);
     206           9 :     if (ad_options == NULL) return NULL;
     207             : 
     208           9 :     realm = get_uppercase_realm(ad_options, ad_domain);
     209           9 :     if (!realm) {
     210           0 :         talloc_free(ad_options);
     211           0 :         return NULL;
     212             :     }
     213             : 
     214           9 :     ret = set_common_ad_trust_opts(ad_options, realm,
     215             :                                    ad_domain, hostname);
     216           9 :     if (ret != EOK) {
     217           0 :         talloc_free(ad_options);
     218           0 :         return NULL;
     219             :     }
     220             : 
     221             :     /* Set AD_KEYTAB to the special 1way keytab */
     222           9 :     ret = dp_opt_set_string(ad_options->basic, AD_KEYTAB, keytab);
     223           9 :     if (ret != EOK) {
     224           0 :         DEBUG(SSSDBG_OP_FAILURE, "Cannot set trust keytab\n");
     225           0 :         talloc_free(ad_options);
     226           0 :         return NULL;
     227             :     }
     228             : 
     229             :     /* Set SDAP_SASL_AUTHID to the trust principal */
     230           9 :     ret = dp_opt_set_string(ad_options->id->basic,
     231             :                             SDAP_SASL_AUTHID, sasl_authid);
     232           9 :     if (ret != EOK) {
     233           0 :         DEBUG(SSSDBG_OP_FAILURE, "Cannot set SASL authid\n");
     234           0 :         talloc_free(ad_options);
     235           0 :         return NULL;
     236             :     }
     237             : 
     238           9 :     ret = ad_set_sdap_options(ad_options, ad_options->id);
     239           9 :     if (ret != EOK) {
     240           0 :         talloc_free(ad_options);
     241           0 :         return NULL;
     242             :     }
     243             : 
     244           9 :     return ad_options;
     245             : }
     246             : 
     247             : static errno_t
     248           0 : ad_create_sdap_options(TALLOC_CTX *mem_ctx,
     249             :                        struct confdb_ctx *cdb,
     250             :                        const char *conf_path,
     251             :                        struct sdap_options **_id_opts)
     252             : {
     253             :     struct sdap_options *id_opts;
     254             :     errno_t ret;
     255             : 
     256           0 :     id_opts = talloc_zero(mem_ctx, struct sdap_options);
     257           0 :     if (!id_opts) {
     258           0 :         ret = ENOMEM;
     259           0 :         goto done;
     260             :     }
     261             : 
     262           0 :     ret = dp_get_options(id_opts, cdb, conf_path,
     263             :                          ad_def_ldap_opts,
     264             :                          SDAP_OPTS_BASIC,
     265             :                          &id_opts->basic);
     266           0 :     if (ret != EOK) {
     267           0 :         goto done;
     268             :     }
     269             : 
     270             :     /* Get sdap option maps */
     271             : 
     272             :     /* General Attribute Map */
     273           0 :     ret = sdap_get_map(id_opts,
     274             :                        cdb, conf_path,
     275             :                        ad_2008r2_attr_map,
     276             :                        SDAP_AT_GENERAL,
     277             :                        &id_opts->gen_map);
     278           0 :     if (ret != EOK) {
     279           0 :         goto done;
     280             :     }
     281             : 
     282             :     /* User map */
     283           0 :     ret = sdap_get_map(id_opts,
     284             :                        cdb, conf_path,
     285             :                        ad_2008r2_user_map,
     286             :                        SDAP_OPTS_USER,
     287             :                        &id_opts->user_map);
     288           0 :     if (ret != EOK) {
     289           0 :         goto done;
     290             :     }
     291             : 
     292           0 :     ret = sdap_extend_map_with_list(id_opts, id_opts,
     293             :                                     SDAP_USER_EXTRA_ATTRS,
     294             :                                     id_opts->user_map,
     295             :                                     SDAP_OPTS_USER,
     296             :                                     &id_opts->user_map,
     297             :                                     &id_opts->user_map_cnt);
     298           0 :     if (ret != EOK) {
     299           0 :         goto done;
     300             :     }
     301             : 
     302             :     /* Group map */
     303           0 :     ret = sdap_get_map(id_opts,
     304             :                        cdb, conf_path,
     305             :                        ad_2008r2_group_map,
     306             :                        SDAP_OPTS_GROUP,
     307             :                        &id_opts->group_map);
     308           0 :     if (ret != EOK) {
     309           0 :         goto done;
     310             :     }
     311             : 
     312             :     /* Netgroup map */
     313           0 :     ret = sdap_get_map(id_opts,
     314             :                        cdb, conf_path,
     315             :                        ad_netgroup_map,
     316             :                        SDAP_OPTS_NETGROUP,
     317             :                        &id_opts->netgroup_map);
     318           0 :     if (ret != EOK) {
     319           0 :         goto done;
     320             :     }
     321             : 
     322             :     /* Services map */
     323           0 :     ret = sdap_get_map(id_opts,
     324             :                        cdb, conf_path,
     325             :                        ad_service_map,
     326             :                        SDAP_OPTS_SERVICES,
     327             :                        &id_opts->service_map);
     328           0 :     if (ret != EOK) {
     329           0 :         goto done;
     330             :     }
     331             : 
     332           0 :     ret = EOK;
     333           0 :     *_id_opts = id_opts;
     334             : done:
     335           0 :     return ret;
     336             : }
     337             : 
     338             : errno_t
     339           0 : ad_get_common_options(TALLOC_CTX *mem_ctx,
     340             :                       struct confdb_ctx *cdb,
     341             :                       const char *conf_path,
     342             :                       struct sss_domain_info *dom,
     343             :                       struct ad_options **_opts)
     344             : {
     345             :     errno_t ret;
     346             :     int gret;
     347           0 :     struct ad_options *opts = NULL;
     348             :     char *domain;
     349             :     char *server;
     350             :     char *realm;
     351             :     char *ad_hostname;
     352             :     char hostname[HOST_NAME_MAX + 1];
     353             :     char *case_sensitive_opt;
     354             :     const char *opt_override;
     355             : 
     356           0 :     opts = talloc_zero(mem_ctx, struct ad_options);
     357           0 :     if (!opts) return ENOMEM;
     358             : 
     359           0 :     ret = dp_get_options(opts, cdb, conf_path,
     360             :                          ad_basic_opts,
     361             :                          AD_OPTS_BASIC,
     362             :                          &opts->basic);
     363           0 :     if (ret != EOK) {
     364           0 :         goto done;
     365             :     }
     366             : 
     367             :     /* If the AD domain name wasn't explicitly set, assume that it
     368             :      * matches the SSSD domain name
     369             :      */
     370           0 :     domain = dp_opt_get_string(opts->basic, AD_DOMAIN);
     371           0 :     if (!domain) {
     372           0 :         ret = dp_opt_set_string(opts->basic, AD_DOMAIN, dom->name);
     373           0 :         if (ret != EOK) {
     374           0 :             goto done;
     375             :         }
     376           0 :         domain = dom->name;
     377             :     }
     378             : 
     379             :     /* Did we get an explicit server name, or are we discovering it? */
     380           0 :     server = dp_opt_get_string(opts->basic, AD_SERVER);
     381           0 :     if (!server) {
     382           0 :         DEBUG(SSSDBG_CONF_SETTINGS,
     383             :               "No AD server set, will use service discovery!\n");
     384             :     }
     385             : 
     386             :     /* Set the machine's hostname to the local host name if it
     387             :      * wasn't explicitly specified.
     388             :      */
     389           0 :     ad_hostname = dp_opt_get_string(opts->basic, AD_HOSTNAME);
     390           0 :     if (ad_hostname == NULL) {
     391           0 :         gret = gethostname(hostname, HOST_NAME_MAX);
     392           0 :         if (gret != 0) {
     393           0 :             ret = errno;
     394           0 :             DEBUG(SSSDBG_FATAL_FAILURE,
     395             :                   "gethostname failed [%s].\n",
     396             :                    strerror(ret));
     397           0 :             goto done;
     398             :         }
     399           0 :         hostname[HOST_NAME_MAX] = '\0';
     400           0 :         DEBUG(SSSDBG_CONF_SETTINGS,
     401             :               "Setting ad_hostname to [%s].\n", hostname);
     402           0 :         ret = dp_opt_set_string(opts->basic, AD_HOSTNAME, hostname);
     403           0 :         if (ret != EOK) {
     404           0 :             DEBUG(SSSDBG_FATAL_FAILURE,
     405             :                   "Setting ad_hostname failed [%s].\n",
     406             :                    strerror(ret));
     407           0 :             goto done;
     408             :         }
     409             :     }
     410             : 
     411             : 
     412             :     /* Always use the upper-case AD domain for the kerberos realm */
     413           0 :     realm = get_uppercase_realm(opts, domain);
     414           0 :     if (!realm) {
     415           0 :         ret = ENOMEM;
     416           0 :         goto done;
     417             :     }
     418             : 
     419           0 :     ret = dp_opt_set_string(opts->basic, AD_KRB5_REALM, realm);
     420           0 :     if (ret != EOK) {
     421           0 :         goto done;
     422             :     }
     423             : 
     424             :     /* Active Directory is always case-insensitive */
     425           0 :     ret = confdb_get_string(cdb, mem_ctx, conf_path,
     426             :                             CONFDB_DOMAIN_CASE_SENSITIVE, "false",
     427             :                             &case_sensitive_opt);
     428           0 :     if (ret != EOK) {
     429           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "condb_get_string failed.\n");
     430           0 :         goto done;
     431             :     }
     432             : 
     433           0 :     if (strcasecmp(case_sensitive_opt, "true") == 0) {
     434           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     435             :               "Warning: AD domain can not be set as case-sensitive.\n");
     436           0 :         dom->case_sensitive = false;
     437           0 :         dom->case_preserve = false;
     438           0 :     } else if (strcasecmp(case_sensitive_opt, "false") == 0) {
     439           0 :         dom->case_sensitive = false;
     440           0 :         dom->case_preserve = false;
     441           0 :     } else if (strcasecmp(case_sensitive_opt, "preserving") == 0) {
     442           0 :         dom->case_sensitive = false;
     443           0 :         dom->case_preserve = true;
     444             :     } else {
     445           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     446             :               "Invalid value for %s\n", CONFDB_DOMAIN_CASE_SENSITIVE);
     447           0 :         goto done;
     448             :     }
     449             : 
     450           0 :     opt_override = dom->case_preserve ? "preserving" : "false";
     451             : 
     452             :     /* Set this in the confdb so that the responders pick it
     453             :      * up when they start up.
     454             :      */
     455           0 :     ret = confdb_set_string(cdb, conf_path, "case_sensitive", opt_override);
     456           0 :     if (ret != EOK) {
     457           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     458             :               "Could not set domain option case_sensitive: [%s]\n",
     459             :                strerror(ret));
     460           0 :         goto done;
     461             :     }
     462             : 
     463           0 :     DEBUG(SSSDBG_CONF_SETTINGS,
     464             :           "Setting domain option case_sensitive to [%s]\n", opt_override);
     465             : 
     466           0 :     ret = EOK;
     467           0 :     *_opts = opts;
     468             : 
     469             : done:
     470           0 :     if (ret != EOK) {
     471           0 :         talloc_zfree(opts);
     472             :     }
     473           0 :     return ret;
     474             : }
     475             : 
     476             : static void
     477             : ad_resolve_callback(void *private_data, struct fo_server *server);
     478             : 
     479             : static errno_t
     480          12 : _ad_servers_init(struct ad_service *service,
     481             :                  struct be_ctx *bectx,
     482             :                  const char *fo_service,
     483             :                  const char *fo_gc_service,
     484             :                  const char *servers,
     485             :                  const char *ad_domain,
     486             :                  bool primary)
     487             : {
     488             :     size_t i;
     489          12 :     errno_t ret = 0;
     490             :     char **list;
     491             :     struct ad_server_data *sdata;
     492             :     TALLOC_CTX *tmp_ctx;
     493             : 
     494          12 :     tmp_ctx = talloc_new(NULL);
     495          12 :     if (!tmp_ctx) return ENOMEM;
     496             : 
     497             :     /* Split the server list */
     498          12 :     ret = split_on_separator(tmp_ctx, servers, ',', true, true, &list, NULL);
     499          12 :     if (ret != EOK) {
     500           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse server list!\n");
     501           0 :         goto done;
     502             :     }
     503             : 
     504             :     /* Add each of these servers to the failover service */
     505          24 :     for (i = 0; list[i]; i++) {
     506          12 :         if (be_fo_is_srv_identifier(list[i])) {
     507          12 :             if (!primary) {
     508           0 :                 DEBUG(SSSDBG_MINOR_FAILURE,
     509             :                       "Failed to add server [%s] to failover service: "
     510             :                        "SRV resolution only allowed for primary servers!\n",
     511             :                        list[i]);
     512           0 :                 continue;
     513             :             }
     514             : 
     515          12 :             sdata = talloc(service, struct ad_server_data);
     516          12 :             if (sdata == NULL) {
     517           0 :                 ret = ENOMEM;
     518           0 :                 goto done;
     519             :             }
     520          12 :             sdata->gc = true;
     521             : 
     522          12 :             ret = be_fo_add_srv_server(bectx, fo_gc_service, "gc",
     523             :                                        ad_domain, BE_FO_PROTO_TCP,
     524             :                                        false, sdata);
     525          12 :             if (ret != EOK) {
     526           0 :                 DEBUG(SSSDBG_FATAL_FAILURE,
     527             :                       "Failed to add service discovery to failover: [%s]\n",
     528             :                       strerror(ret));
     529           0 :                 goto done;
     530             :             }
     531             : 
     532          12 :             sdata = talloc(service, struct ad_server_data);
     533          12 :             if (sdata == NULL) {
     534           0 :                 ret = ENOMEM;
     535           0 :                 goto done;
     536             :             }
     537          12 :             sdata->gc = false;
     538             : 
     539          12 :             ret = be_fo_add_srv_server(bectx, fo_service, "ldap",
     540             :                                        ad_domain, BE_FO_PROTO_TCP,
     541             :                                        false, sdata);
     542          12 :             if (ret != EOK) {
     543           0 :                 DEBUG(SSSDBG_FATAL_FAILURE,
     544             :                       "Failed to add service discovery to failover: [%s]\n",
     545             :                       strerror(ret));
     546           0 :                 goto done;
     547             :             }
     548             : 
     549          12 :             DEBUG(SSSDBG_CONF_SETTINGS, "Added service discovery for AD\n");
     550          12 :             continue;
     551             :         }
     552             : 
     553             :         /* It could be ipv6 address in square brackets. Remove
     554             :          * the brackets if needed. */
     555           0 :         ret = remove_ipv6_brackets(list[i]);
     556           0 :         if (ret != EOK) {
     557           0 :             goto done;
     558             :         }
     559             : 
     560           0 :         sdata = talloc(service, struct ad_server_data);
     561           0 :         if (sdata == NULL) {
     562           0 :             ret = ENOMEM;
     563           0 :             goto done;
     564             :         }
     565           0 :         sdata->gc = true;
     566             : 
     567           0 :         ret = be_fo_add_server(bectx, fo_gc_service, list[i], 0, sdata, primary);
     568           0 :         if (ret && ret != EEXIST) {
     569           0 :             DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add server\n");
     570           0 :             goto done;
     571             :         }
     572             : 
     573           0 :         sdata = talloc(service, struct ad_server_data);
     574           0 :         if (sdata == NULL) {
     575           0 :             ret = ENOMEM;
     576           0 :             goto done;
     577             :         }
     578           0 :         sdata->gc = false;
     579             : 
     580           0 :         ret = be_fo_add_server(bectx, fo_service, list[i], 0, sdata, primary);
     581           0 :         if (ret && ret != EEXIST) {
     582           0 :             DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add server\n");
     583           0 :             goto done;
     584             :         }
     585             : 
     586           0 :         DEBUG(SSSDBG_CONF_SETTINGS, "Added failover server %s\n", list[i]);
     587             :     }
     588             : done:
     589          12 :     talloc_free(tmp_ctx);
     590          12 :     return ret;
     591             : }
     592             : 
     593             : static inline errno_t
     594          12 : ad_primary_servers_init(struct ad_service *service,
     595             :                         struct be_ctx *bectx, const char *servers,
     596             :                         const char *fo_service, const char *fo_gc_service,
     597             :                         const char *ad_domain)
     598             : {
     599          12 :     return _ad_servers_init(service, bectx, fo_service,
     600             :                             fo_gc_service, servers, ad_domain, true);
     601             : }
     602             : 
     603             : static inline errno_t
     604           0 : ad_backup_servers_init(struct ad_service *service,
     605             :                         struct be_ctx *bectx, const char *servers,
     606             :                         const char *fo_service, const char *fo_gc_service,
     607             :                         const char *ad_domain)
     608             : {
     609           0 :     return _ad_servers_init(service, bectx, fo_service,
     610             :                             fo_gc_service, servers, ad_domain, false);
     611             : }
     612             : 
     613           0 : static int ad_user_data_cmp(void *ud1, void *ud2)
     614             : {
     615             :     struct ad_server_data *sd1, *sd2;
     616             : 
     617           0 :     sd1 = talloc_get_type(ud1, struct ad_server_data);
     618           0 :     sd2 = talloc_get_type(ud2, struct ad_server_data);
     619           0 :     if (sd1 == NULL || sd2 == NULL) {
     620           0 :         DEBUG(SSSDBG_TRACE_FUNC, "No user data\n");
     621           0 :         return sd1 == sd2 ? 0 : 1;
     622             :     }
     623             : 
     624           0 :     DEBUG(SSSDBG_TRACE_LIBS, "Comparing %s with %s\n",
     625             :           sd1->gc ? "GC" : "LDAP",
     626             :           sd2->gc ? "GC" : "LDAP");
     627             : 
     628           0 :     if (sd1->gc == sd2->gc) {
     629           0 :         return 0;
     630             :     }
     631             : 
     632           0 :     return 1;
     633             : }
     634             : 
     635           0 : static void ad_online_cb(void *pvt)
     636             : {
     637           0 :     struct ad_service *service = talloc_get_type(pvt, struct ad_service);
     638             : 
     639           0 :     if (service == NULL) {
     640           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid private pointer\n");
     641           0 :         return;
     642             :     }
     643             : 
     644           0 :     DEBUG(SSSDBG_TRACE_FUNC, "The AD provider is online\n");
     645             : }
     646             : 
     647             : errno_t
     648          12 : ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx,
     649             :                  const char *primary_servers,
     650             :                  const char *backup_servers,
     651             :                  const char *krb5_realm,
     652             :                  const char *ad_service,
     653             :                  const char *ad_gc_service,
     654             :                  const char *ad_domain,
     655             :                  struct ad_service **_service)
     656             : {
     657             :     errno_t ret;
     658             :     TALLOC_CTX *tmp_ctx;
     659             :     struct ad_service *service;
     660             : 
     661          12 :     tmp_ctx = talloc_new(mem_ctx);
     662          12 :     if (!tmp_ctx) return ENOMEM;
     663             : 
     664          12 :     service = talloc_zero(tmp_ctx, struct ad_service);
     665          12 :     if (!service) {
     666           0 :         ret = ENOMEM;
     667           0 :         goto done;
     668             :     }
     669             : 
     670          12 :     service->sdap = talloc_zero(service, struct sdap_service);
     671          12 :     service->gc = talloc_zero(service, struct sdap_service);
     672          12 :     if (!service->sdap || !service->gc) {
     673           0 :         ret = ENOMEM;
     674           0 :         goto done;
     675             :     }
     676             : 
     677          12 :     service->sdap->name = talloc_strdup(service->sdap, ad_service);
     678          12 :     service->gc->name = talloc_strdup(service->gc, ad_gc_service);
     679          12 :     if (!service->sdap->name || !service->gc->name) {
     680           0 :         ret = ENOMEM;
     681           0 :         goto done;
     682             :     }
     683             : 
     684          12 :     service->krb5_service = talloc_zero(service, struct krb5_service);
     685          12 :     if (!service->krb5_service) {
     686           0 :         ret = ENOMEM;
     687           0 :         goto done;
     688             :     }
     689             : 
     690          12 :     ret = be_fo_add_service(bectx, ad_service, ad_user_data_cmp);
     691          12 :     if (ret != EOK) {
     692           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create failover service!\n");
     693           0 :         goto done;
     694             :     }
     695             : 
     696          12 :     ret = be_fo_add_service(bectx, ad_gc_service, ad_user_data_cmp);
     697          12 :     if (ret != EOK) {
     698           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create GC failover service!\n");
     699           0 :         goto done;
     700             :     }
     701             : 
     702          12 :     service->krb5_service->name = talloc_strdup(service->krb5_service,
     703             :                                                 ad_service);
     704          12 :     if (!service->krb5_service->name) {
     705           0 :         ret = ENOMEM;
     706           0 :         goto done;
     707             :     }
     708          12 :     service->sdap->kinit_service_name = service->krb5_service->name;
     709          12 :     service->gc->kinit_service_name = service->krb5_service->name;
     710             : 
     711          12 :     if (!krb5_realm) {
     712           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm set\n");
     713           0 :         ret = EINVAL;
     714           0 :         goto done;
     715             :     }
     716          24 :     service->krb5_service->realm =
     717          12 :         talloc_strdup(service->krb5_service, krb5_realm);
     718          12 :     if (!service->krb5_service->realm) {
     719           0 :         ret = ENOMEM;
     720           0 :         goto done;
     721             :     }
     722             : 
     723          12 :     if (!primary_servers) {
     724          12 :         DEBUG(SSSDBG_CONF_SETTINGS,
     725             :               "No primary servers defined, using service discovery\n");
     726          12 :         primary_servers = BE_SRV_IDENTIFIER;
     727             :     }
     728             : 
     729          12 :     ret = ad_primary_servers_init(service, bectx,
     730             :                                   primary_servers, ad_service,
     731             :                                   ad_gc_service, ad_domain);
     732          12 :     if (ret != EOK) {
     733           0 :         goto done;
     734             :     }
     735             : 
     736          12 :     if (backup_servers) {
     737           0 :         ret = ad_backup_servers_init(service, bectx,
     738             :                                      backup_servers, ad_service,
     739             :                                      ad_gc_service, ad_domain);
     740           0 :         if (ret != EOK) {
     741           0 :             goto done;
     742             :         }
     743             :     }
     744             : 
     745          12 :     ret = be_add_online_cb(bectx, bectx, ad_online_cb, service, NULL);
     746          12 :     if (ret != EOK) {
     747           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up AD online callback\n");
     748           0 :         goto done;
     749             :     }
     750             : 
     751          12 :     ret = be_fo_service_add_callback(mem_ctx, bectx, ad_service,
     752             :                                      ad_resolve_callback, service);
     753          12 :     if (ret != EOK) {
     754           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     755             :               "Failed to add failover callback! [%s]\n", strerror(ret));
     756           0 :         goto done;
     757             :     }
     758             : 
     759          12 :     ret = be_fo_service_add_callback(mem_ctx, bectx, ad_gc_service,
     760             :                                      ad_resolve_callback, service);
     761          12 :     if (ret != EOK) {
     762           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     763             :               "Failed to add failover callback! [%s]\n", strerror(ret));
     764           0 :         goto done;
     765             :     }
     766             : 
     767          12 :     *_service = talloc_steal(mem_ctx, service);
     768             : 
     769          12 :     ret = EOK;
     770             : 
     771             : done:
     772          12 :     talloc_free(tmp_ctx);
     773          12 :     return ret;
     774             : }
     775             : 
     776             : static void
     777           0 : ad_resolve_callback(void *private_data, struct fo_server *server)
     778             : {
     779             :     errno_t ret;
     780             :     TALLOC_CTX *tmp_ctx;
     781             :     struct ad_service *service;
     782             :     struct resolv_hostent *srvaddr;
     783             :     struct sockaddr_storage *sockaddr;
     784             :     char *address;
     785             :     const char *safe_address;
     786             :     char *new_uri;
     787             :     int new_port;
     788             :     const char *srv_name;
     789           0 :     struct ad_server_data *sdata = NULL;
     790             : 
     791           0 :     tmp_ctx = talloc_new(NULL);
     792           0 :     if (!tmp_ctx) {
     793           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n");
     794           0 :         return;
     795             :     }
     796             : 
     797           0 :     sdata = fo_get_server_user_data(server);
     798           0 :     if (fo_is_srv_lookup(server) == false && sdata == NULL) {
     799           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "No user data?\n");
     800           0 :         ret = EINVAL;
     801           0 :         goto done;
     802             :     }
     803             : 
     804           0 :     service = talloc_get_type(private_data, struct ad_service);
     805           0 :     if (!service) {
     806           0 :         ret = EINVAL;
     807           0 :         goto done;
     808             :     }
     809             : 
     810           0 :     srvaddr = fo_get_server_hostent(server);
     811           0 :     if (!srvaddr) {
     812           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     813             :               "No hostent available for server (%s)\n",
     814             :                fo_get_server_str_name(server));
     815           0 :         ret = EINVAL;
     816           0 :         goto done;
     817             :     }
     818             : 
     819           0 :     address = resolv_get_string_address(tmp_ctx, srvaddr);
     820           0 :     if (address == NULL) {
     821           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "resolv_get_string_address failed.\n");
     822           0 :         ret = EIO;
     823           0 :         goto done;
     824             :     }
     825             : 
     826           0 :     srv_name = fo_get_server_name(server);
     827           0 :     if (srv_name == NULL) {
     828           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Could not get server host name\n");
     829           0 :         ret = EINVAL;
     830           0 :         goto done;
     831             :     }
     832             : 
     833           0 :     new_uri = talloc_asprintf(service->sdap, "ldap://%s", srv_name);
     834           0 :     if (!new_uri) {
     835           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy URI\n");
     836           0 :         ret = ENOMEM;
     837           0 :         goto done;
     838             :     }
     839           0 :     DEBUG(SSSDBG_CONF_SETTINGS, "Constructed uri '%s'\n", new_uri);
     840             : 
     841           0 :     sockaddr = resolv_get_sockaddr_address(tmp_ctx, srvaddr, LDAP_PORT);
     842           0 :     if (sockaddr == NULL) {
     843           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "resolv_get_sockaddr_address failed.\n");
     844           0 :         ret = EIO;
     845           0 :         goto done;
     846             :     }
     847             : 
     848             :     /* free old one and replace with new one */
     849           0 :     talloc_zfree(service->sdap->uri);
     850           0 :     service->sdap->uri = new_uri;
     851           0 :     talloc_zfree(service->sdap->sockaddr);
     852           0 :     service->sdap->sockaddr = talloc_steal(service->sdap, sockaddr);
     853             : 
     854           0 :     talloc_zfree(service->gc->uri);
     855           0 :     talloc_zfree(service->gc->sockaddr);
     856           0 :     if (sdata && sdata->gc) {
     857           0 :         new_port = fo_get_server_port(server);
     858           0 :         new_port = (new_port == 0) ? AD_GC_PORT : new_port;
     859             : 
     860           0 :         service->gc->uri = talloc_asprintf(service->gc, "%s:%d",
     861             :                                            new_uri, new_port);
     862             : 
     863           0 :         service->gc->sockaddr = resolv_get_sockaddr_address(service->gc,
     864             :                                                             srvaddr,
     865             :                                                             new_port);
     866             :     } else {
     867             :         /* Make sure there always is an URI even if we know that this
     868             :          * server doesn't support GC. That way the lookup would go through
     869             :          * just not return anything
     870             :          */
     871           0 :         service->gc->uri = talloc_strdup(service->gc, service->sdap->uri);
     872           0 :         service->gc->sockaddr = talloc_memdup(service->gc, service->sdap->sockaddr,
     873             :                                               sizeof(struct sockaddr_storage));
     874             :     }
     875             : 
     876           0 :     if (!service->gc->uri) {
     877           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to append to URI\n");
     878           0 :         ret = ENOMEM;
     879           0 :         goto done;
     880             :     }
     881           0 :     DEBUG(SSSDBG_CONF_SETTINGS, "Constructed GC uri '%s'\n", service->gc->uri);
     882             : 
     883           0 :     if (service->gc->sockaddr == NULL) {
     884           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     885             :                 "resolv_get_sockaddr_address failed.\n");
     886           0 :         ret = EIO;
     887           0 :         goto done;
     888             :     }
     889             : 
     890             :     /* Only write kdcinfo files for local servers */
     891           0 :     if ((sdata == NULL || sdata->gc == false) &&
     892           0 :         service->krb5_service->write_kdcinfo) {
     893             :         /* Write krb5 info files */
     894           0 :         safe_address = sss_escape_ip_address(tmp_ctx,
     895             :                                             srvaddr->family,
     896             :                                             address);
     897           0 :         if (safe_address == NULL) {
     898           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "sss_escape_ip_address failed.\n");
     899           0 :             ret = ENOMEM;
     900           0 :             goto done;
     901             :         }
     902             : 
     903           0 :         ret = write_krb5info_file(service->krb5_service->realm, safe_address,
     904             :                                 SSS_KRB5KDC_FO_SRV);
     905           0 :         if (ret != EOK) {
     906           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
     907             :                 "write_krb5info_file failed, authentication might fail.\n");
     908             :         }
     909             :     }
     910             : 
     911           0 :     ret = EOK;
     912             : done:
     913           0 :     if (ret != EOK) {
     914           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     915             :               "Error: [%s]\n", strerror(ret));
     916             :     }
     917           0 :     talloc_free(tmp_ctx);
     918           0 :     return;
     919             : }
     920             : 
     921             : static errno_t
     922          18 : ad_set_sdap_options(struct ad_options *ad_opts,
     923             :                     struct sdap_options *id_opts)
     924             : {
     925             :     errno_t ret;
     926             :     char *krb5_realm;
     927             :     char *keytab_path;
     928             : 
     929             :     /* We only support Kerberos password policy with AD, so
     930             :      * force that on.
     931             :      */
     932          18 :     ret = dp_opt_set_string(id_opts->basic,
     933             :                             SDAP_PWD_POLICY,
     934             :                             PWD_POL_OPT_MIT);
     935          18 :     if (ret != EOK) {
     936           0 :         DEBUG(SSSDBG_FATAL_FAILURE, "Could not set password policy\n");
     937           0 :         goto done;
     938             :     }
     939             : 
     940             :     /* Set the Kerberos Realm for GSSAPI */
     941          18 :     krb5_realm = dp_opt_get_string(ad_opts->basic, AD_KRB5_REALM);
     942          18 :     if (!krb5_realm) {
     943             :         /* Should be impossible, this is set in ad_get_common_options() */
     944           0 :         DEBUG(SSSDBG_FATAL_FAILURE, "No Kerberos realm\n");
     945           0 :         ret = EINVAL;
     946           0 :         goto done;
     947             :     }
     948             : 
     949          18 :     ret = dp_opt_set_string(id_opts->basic, SDAP_KRB5_REALM, krb5_realm);
     950          18 :     if (ret != EOK) goto done;
     951          18 :     DEBUG(SSSDBG_CONF_SETTINGS,
     952             :           "Option %s set to %s\n",
     953             :            id_opts->basic[SDAP_KRB5_REALM].opt_name,
     954             :            krb5_realm);
     955             : 
     956          18 :     keytab_path = dp_opt_get_string(ad_opts->basic, AD_KEYTAB);
     957          18 :     if (keytab_path) {
     958           9 :         ret = dp_opt_set_string(id_opts->basic, SDAP_KRB5_KEYTAB,
     959             :                                 keytab_path);
     960           9 :         if (ret != EOK) goto done;
     961           9 :         DEBUG(SSSDBG_CONF_SETTINGS,
     962             :               "Option %s set to %s\n",
     963             :                id_opts->basic[SDAP_KRB5_KEYTAB].opt_name,
     964             :                keytab_path);
     965             :     }
     966             : 
     967          18 :     ret = sdap_set_sasl_options(id_opts,
     968             :                                 dp_opt_get_string(ad_opts->basic,
     969             :                                                   AD_HOSTNAME),
     970             :                                 dp_opt_get_string(ad_opts->basic,
     971             :                                                   AD_KRB5_REALM),
     972             :                                 keytab_path);
     973          18 :     if (ret != EOK) {
     974           0 :         DEBUG(SSSDBG_OP_FAILURE, "Cannot set the SASL-related options\n");
     975           0 :         goto done;
     976             :     }
     977             : 
     978             :     /* fix schema to AD  */
     979          18 :     id_opts->schema_type = SDAP_SCHEMA_AD;
     980             : 
     981          18 :     ad_opts->id = id_opts;
     982          18 :     ret = EOK;
     983             : done:
     984          18 :     return ret;
     985             : }
     986             : 
     987             : errno_t
     988           0 : ad_get_id_options(struct ad_options *ad_opts,
     989             :                   struct confdb_ctx *cdb,
     990             :                   const char *conf_path,
     991             :                   struct sdap_options **_opts)
     992             : {
     993             :     struct sdap_options *id_opts;
     994             :     errno_t ret;
     995             : 
     996           0 :     ret = ad_create_sdap_options(ad_opts, cdb, conf_path, &id_opts);
     997           0 :     if (ret != EOK) {
     998           0 :         return ENOMEM;
     999             :     }
    1000             : 
    1001           0 :     ret = ad_set_sdap_options(ad_opts, id_opts);
    1002           0 :     if (ret != EOK) {
    1003           0 :         talloc_free(id_opts);
    1004           0 :         return ret;
    1005             :     }
    1006             : 
    1007           0 :     ret = sdap_domain_add(id_opts,
    1008           0 :                           ad_opts->id_ctx->sdap_id_ctx->be->domain,
    1009             :                           NULL);
    1010           0 :     if (ret != EOK) {
    1011           0 :         talloc_free(id_opts);
    1012           0 :         return ret;
    1013             :     }
    1014             : 
    1015             :     /* Set up search bases if they were assigned explicitly */
    1016           0 :     ret = ad_set_search_bases(id_opts);
    1017           0 :     if (ret != EOK) {
    1018           0 :         talloc_free(id_opts);
    1019           0 :         return ret;
    1020             :     }
    1021             : 
    1022           0 :     *_opts = id_opts;
    1023           0 :     return EOK;
    1024             : }
    1025             : 
    1026             : errno_t
    1027           0 : ad_set_search_bases(struct sdap_options *id_opts)
    1028             : {
    1029             :     errno_t ret;
    1030             :     char *default_search_base;
    1031             :     size_t o;
    1032           0 :     const int search_base_options[] = { SDAP_USER_SEARCH_BASE,
    1033             :                                         SDAP_GROUP_SEARCH_BASE,
    1034             :                                         SDAP_NETGROUP_SEARCH_BASE,
    1035             :                                         SDAP_SERVICE_SEARCH_BASE,
    1036             :                                         -1 };
    1037             : 
    1038             :     /* AD servers provide defaultNamingContext, so we will
    1039             :      * rely on that to specify the search base unless it has
    1040             :      * been specifically overridden.
    1041             :      */
    1042             : 
    1043           0 :     default_search_base =
    1044           0 :             dp_opt_get_string(id_opts->basic, SDAP_SEARCH_BASE);
    1045             : 
    1046           0 :     if (default_search_base) {
    1047             :         /* set search bases if they are not */
    1048           0 :         for (o = 0; search_base_options[o] != -1; o++) {
    1049           0 :             if (NULL == dp_opt_get_string(id_opts->basic,
    1050             :                                           search_base_options[o])) {
    1051           0 :                 ret = dp_opt_set_string(id_opts->basic,
    1052             :                                         search_base_options[o],
    1053             :                                         default_search_base);
    1054           0 :                 if (ret != EOK) {
    1055           0 :                     goto done;
    1056             :                 }
    1057           0 :                 DEBUG(SSSDBG_CONF_SETTINGS,
    1058             :                       "Option %s set to %s\n",
    1059             :                        id_opts->basic[search_base_options[o]].opt_name,
    1060             :                        dp_opt_get_string(id_opts->basic,
    1061             :                                          search_base_options[o]));
    1062             :             }
    1063             :         }
    1064             :     } else {
    1065           0 :         DEBUG(SSSDBG_CONF_SETTINGS,
    1066             :               "Search base not set. SSSD will attempt to discover it later, "
    1067             :                "when connecting to the LDAP server.\n");
    1068             :     }
    1069             : 
    1070             :     /* Default search */
    1071           0 :     ret = sdap_parse_search_base(id_opts, id_opts->basic,
    1072             :                                  SDAP_SEARCH_BASE,
    1073           0 :                                  &id_opts->sdom->search_bases);
    1074           0 :     if (ret != EOK && ret != ENOENT) goto done;
    1075             : 
    1076             :     /* User search */
    1077           0 :     ret = sdap_parse_search_base(id_opts, id_opts->basic,
    1078             :                                  SDAP_USER_SEARCH_BASE,
    1079           0 :                                  &id_opts->sdom->user_search_bases);
    1080           0 :     if (ret != EOK && ret != ENOENT) goto done;
    1081             : 
    1082             :     /* Group search base */
    1083           0 :     ret = sdap_parse_search_base(id_opts, id_opts->basic,
    1084             :                                  SDAP_GROUP_SEARCH_BASE,
    1085           0 :                                  &id_opts->sdom->group_search_bases);
    1086           0 :     if (ret != EOK && ret != ENOENT) goto done;
    1087             : 
    1088             :     /* Netgroup search */
    1089           0 :     ret = sdap_parse_search_base(id_opts, id_opts->basic,
    1090             :                                  SDAP_NETGROUP_SEARCH_BASE,
    1091           0 :                                  &id_opts->sdom->netgroup_search_bases);
    1092           0 :     if (ret != EOK && ret != ENOENT) goto done;
    1093             : 
    1094             :     /* Service search */
    1095           0 :     ret = sdap_parse_search_base(id_opts, id_opts->basic,
    1096             :                                  SDAP_SERVICE_SEARCH_BASE,
    1097           0 :                                  &id_opts->sdom->service_search_bases);
    1098           0 :     if (ret != EOK && ret != ENOENT) goto done;
    1099             : 
    1100           0 :     ret = EOK;
    1101             : done:
    1102           0 :     return ret;
    1103             : }
    1104             : 
    1105             : errno_t
    1106           0 : ad_get_auth_options(TALLOC_CTX *mem_ctx,
    1107             :                     struct ad_options *ad_opts,
    1108             :                     struct be_ctx *bectx,
    1109             :                     struct dp_option **_opts)
    1110             : {
    1111             :     errno_t ret;
    1112             :     struct dp_option *krb5_options;
    1113             :     const char *ad_servers;
    1114             :     const char *krb5_realm;
    1115             : 
    1116           0 :     TALLOC_CTX *tmp_ctx = talloc_new(NULL);
    1117           0 :     if (!tmp_ctx) return ENOMEM;
    1118             : 
    1119             :     /* Get krb5 options */
    1120           0 :     ret = dp_get_options(tmp_ctx, bectx->cdb, bectx->conf_path,
    1121             :                          ad_def_krb5_opts, KRB5_OPTS,
    1122             :                          &krb5_options);
    1123           0 :     if (ret != EOK) {
    1124           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
    1125             :               "Could not read Kerberos options from the configuration\n");
    1126           0 :         goto done;
    1127             :     }
    1128             : 
    1129           0 :     ad_servers = dp_opt_get_string(ad_opts->basic, AD_SERVER);
    1130             : 
    1131             :     /* Force the krb5_servers to match the ad_servers */
    1132           0 :     ret = dp_opt_set_string(krb5_options, KRB5_KDC, ad_servers);
    1133           0 :     if (ret != EOK) goto done;
    1134           0 :     DEBUG(SSSDBG_CONF_SETTINGS,
    1135             :           "Option %s set to %s\n",
    1136             :            krb5_options[KRB5_KDC].opt_name,
    1137             :            ad_servers);
    1138             : 
    1139             :     /* Set krb5 realm */
    1140             :     /* Set the Kerberos Realm for GSSAPI */
    1141           0 :     krb5_realm = dp_opt_get_string(ad_opts->basic, AD_KRB5_REALM);
    1142           0 :     if (!krb5_realm) {
    1143             :         /* Should be impossible, this is set in ad_get_common_options() */
    1144           0 :         DEBUG(SSSDBG_FATAL_FAILURE, "No Kerberos realm\n");
    1145           0 :         ret = EINVAL;
    1146           0 :         goto done;
    1147             :     }
    1148             : 
    1149             :     /* Force the kerberos realm to match the AD_KRB5_REALM (which may have
    1150             :      * been upper-cased in ad_common_options()
    1151             :      */
    1152           0 :     ret = dp_opt_set_string(krb5_options, KRB5_REALM, krb5_realm);
    1153           0 :     if (ret != EOK) goto done;
    1154           0 :     DEBUG(SSSDBG_CONF_SETTINGS,
    1155             :           "Option %s set to %s\n",
    1156             :            krb5_options[KRB5_REALM].opt_name,
    1157             :            krb5_realm);
    1158             : 
    1159             :     /* Set flag that controls whether we want to write the
    1160             :      * kdcinfo files at all
    1161             :      */
    1162           0 :     ad_opts->service->krb5_service->write_kdcinfo = \
    1163           0 :         dp_opt_get_bool(krb5_options, KRB5_USE_KDCINFO);
    1164           0 :     DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n",
    1165             :           krb5_options[KRB5_USE_KDCINFO].opt_name,
    1166             :           ad_opts->service->krb5_service->write_kdcinfo ? "true" : "false");
    1167             : 
    1168           0 :     *_opts = talloc_steal(mem_ctx, krb5_options);
    1169             : 
    1170           0 :     ret = EOK;
    1171             : 
    1172             : done:
    1173           0 :     talloc_free(tmp_ctx);
    1174           0 :     return ret;
    1175             : }
    1176             : 
    1177           0 : errno_t ad_get_dyndns_options(struct be_ctx *be_ctx,
    1178             :                               struct ad_options *ad_opts)
    1179             : {
    1180             :     errno_t ret;
    1181             : 
    1182           0 :     ret = be_nsupdate_init(ad_opts, be_ctx, ad_dyndns_opts,
    1183             :                            &ad_opts->dyndns_ctx);
    1184           0 :     if (ret != EOK) {
    1185           0 :         DEBUG(SSSDBG_OP_FAILURE,
    1186             :               "Cannot initialize AD dyndns opts [%d]: %s\n",
    1187             :                ret, sss_strerror(ret));
    1188           0 :         return ret;
    1189             :     }
    1190             : 
    1191           0 :     return EOK;
    1192             : }
    1193             : 
    1194             : 
    1195             : struct ad_id_ctx *
    1196          12 : ad_id_ctx_init(struct ad_options *ad_opts, struct be_ctx *bectx)
    1197             : {
    1198             :     struct sdap_id_ctx *sdap_ctx;
    1199             :     struct ad_id_ctx *ad_ctx;
    1200             : 
    1201          12 :     ad_ctx = talloc_zero(ad_opts, struct ad_id_ctx);
    1202          12 :     if (ad_ctx == NULL) {
    1203           0 :         return NULL;
    1204             :     }
    1205          12 :     ad_ctx->ad_options = ad_opts;
    1206             : 
    1207          12 :     sdap_ctx = sdap_id_ctx_new(ad_ctx, bectx, ad_opts->service->sdap);
    1208          12 :     if (sdap_ctx == NULL) {
    1209           0 :         talloc_free(ad_ctx);
    1210           0 :         return NULL;
    1211             :     }
    1212          12 :     ad_ctx->sdap_id_ctx = sdap_ctx;
    1213          12 :     ad_ctx->ldap_ctx = sdap_ctx->conn;
    1214             : 
    1215          12 :     ad_ctx->gc_ctx = sdap_id_ctx_conn_add(sdap_ctx, ad_opts->service->gc);
    1216          12 :     if (ad_ctx->gc_ctx == NULL) {
    1217           0 :         talloc_free(ad_ctx);
    1218           0 :         return NULL;
    1219             :     }
    1220             : 
    1221          12 :     return ad_ctx;
    1222             : }
    1223             : 
    1224             : struct sdap_id_conn_ctx *
    1225          10 : ad_get_dom_ldap_conn(struct ad_id_ctx *ad_ctx, struct sss_domain_info *dom)
    1226             : {
    1227             :     struct sdap_id_conn_ctx *conn;
    1228             :     struct sdap_domain *sdom;
    1229             :     struct ad_id_ctx *subdom_id_ctx;
    1230             : 
    1231          10 :     sdom = sdap_domain_get(ad_ctx->sdap_id_ctx->opts, dom);
    1232          10 :     if (sdom == NULL || sdom->pvt == NULL) {
    1233           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "No ID ctx available for [%s].\n",
    1234             :                                     dom->name);
    1235           0 :         return NULL;
    1236             :     }
    1237          10 :     subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx);
    1238          10 :     conn = subdom_id_ctx->ldap_ctx;
    1239             : 
    1240          10 :     if (IS_SUBDOMAIN(sdom->dom) == true && conn != NULL) {
    1241             :         /* Regardless of connection types, a subdomain error must not be
    1242             :          * allowed to set the whole back end offline, rather report an error
    1243             :          * and let the caller deal with it (normally disable the subdomain
    1244             :          */
    1245           5 :         conn->ignore_mark_offline = true;
    1246             :     }
    1247             : 
    1248          10 :     return conn;
    1249             : }
    1250             : 
    1251             : struct sdap_id_conn_ctx **
    1252           4 : ad_gc_conn_list(TALLOC_CTX *mem_ctx, struct ad_id_ctx *ad_ctx,
    1253             :                 struct sss_domain_info *dom)
    1254             : {
    1255             :     struct sdap_id_conn_ctx **clist;
    1256           4 :     int cindex = 0;
    1257             : 
    1258           4 :     clist = talloc_zero_array(mem_ctx, struct sdap_id_conn_ctx *, 3);
    1259           4 :     if (clist == NULL) return NULL;
    1260             : 
    1261             :     /* Always try GC first */
    1262           4 :     if (dp_opt_get_bool(ad_ctx->ad_options->basic, AD_ENABLE_GC)) {
    1263           2 :         clist[cindex] = ad_ctx->gc_ctx;
    1264           2 :         clist[cindex]->ignore_mark_offline = true;
    1265           2 :         cindex++;
    1266             :     }
    1267             : 
    1268           4 :     clist[cindex] = ad_get_dom_ldap_conn(ad_ctx, dom);
    1269             : 
    1270           4 :     return clist;
    1271             : }
    1272             : 
    1273             : struct sdap_id_conn_ctx **
    1274           2 : ad_ldap_conn_list(TALLOC_CTX *mem_ctx,
    1275             :                   struct ad_id_ctx *ad_ctx,
    1276             :                   struct sss_domain_info *dom)
    1277             : {
    1278             :     struct sdap_id_conn_ctx **clist;
    1279             : 
    1280           2 :     clist = talloc_zero_array(mem_ctx, struct sdap_id_conn_ctx *, 2);
    1281           2 :     if (clist == NULL) {
    1282           0 :         return NULL;
    1283             :     }
    1284             : 
    1285           2 :     clist[0] = ad_get_dom_ldap_conn(ad_ctx, dom);
    1286             : 
    1287           2 :     clist[1] = NULL;
    1288           2 :     return clist;
    1289             : }
    1290             : 
    1291             : struct sdap_id_conn_ctx **
    1292           2 : ad_user_conn_list(TALLOC_CTX *mem_ctx,
    1293             :                   struct ad_id_ctx *ad_ctx,
    1294             :                   struct sss_domain_info *dom)
    1295             : {
    1296             :     struct sdap_id_conn_ctx **clist;
    1297           2 :     int cindex = 0;
    1298             : 
    1299           2 :     clist = talloc_zero_array(ad_ctx, struct sdap_id_conn_ctx *, 3);
    1300           2 :     if (clist == NULL) {
    1301           0 :         return NULL;
    1302             :     }
    1303             : 
    1304             :     /* Try GC first for users from trusted domains, but go to LDAP
    1305             :      * for users from non-trusted domains to get all POSIX attrs
    1306             :      */
    1307           2 :     if (dp_opt_get_bool(ad_ctx->ad_options->basic, AD_ENABLE_GC)
    1308           2 :             && IS_SUBDOMAIN(dom)) {
    1309           1 :         clist[cindex] = ad_ctx->gc_ctx;
    1310           1 :         clist[cindex]->ignore_mark_offline = true;
    1311           1 :         cindex++;
    1312             :     }
    1313             : 
    1314             :     /* Users from primary domain can be just downloaded from LDAP.
    1315             :      * The domain's LDAP connection also works as a fallback
    1316             :      */
    1317           2 :     clist[cindex] = ad_get_dom_ldap_conn(ad_ctx, dom);
    1318             : 
    1319           2 :     return clist;
    1320             : }

Generated by: LCOV version 1.10