LCOV - code coverage report
Current view: top level - providers/krb5 - krb5_common.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 8 384 2.1 %
Date: 2012-11-29 Functions: 1 16 6.2 %
Branches: 12 1061 1.1 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :     SSSD
       3                 :            : 
       4                 :            :     Kerberos Provider Common Functions
       5                 :            : 
       6                 :            :     Authors:
       7                 :            :         Sumit Bose <sbose@redhat.com>
       8                 :            : 
       9                 :            :     Copyright (C) 2008-2009 Red Hat
      10                 :            : 
      11                 :            :     This program is free software; you can redistribute it and/or modify
      12                 :            :     it under the terms of the GNU General Public License as published by
      13                 :            :     the Free Software Foundation; either version 3 of the License, or
      14                 :            :     (at your option) any later version.
      15                 :            : 
      16                 :            :     This program is distributed in the hope that it will be useful,
      17                 :            :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :     GNU General Public License for more details.
      20                 :            : 
      21                 :            :     You should have received a copy of the GNU General Public License
      22                 :            :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23                 :            : */
      24                 :            : #include <sys/types.h>
      25                 :            : #include <sys/stat.h>
      26                 :            : #include <unistd.h>
      27                 :            : #include <netdb.h>
      28                 :            : #include <arpa/inet.h>
      29                 :            : #include <ctype.h>
      30                 :            : 
      31                 :            : #include "providers/dp_backend.h"
      32                 :            : #include "providers/krb5/krb5_common.h"
      33                 :            : #include "providers/krb5/krb5_opts.h"
      34                 :            : #include "providers/krb5/krb5_utils.h"
      35                 :            : 
      36                 :          0 : errno_t check_and_export_lifetime(struct dp_option *opts, const int opt_id,
      37                 :            :                                   const char *env_name)
      38                 :            : {
      39                 :            :     int ret;
      40                 :            :     char *str;
      41                 :            :     krb5_deltat lifetime;
      42                 :          0 :     bool free_str = false;
      43                 :            : 
      44                 :          0 :     str = dp_opt_get_string(opts, opt_id);
      45 [ #  # ][ #  # ]:          0 :     if (str == NULL || *str == '\0') {
      46 [ #  # ][ #  # ]:          0 :         DEBUG(5, ("No lifetime configured.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
      47                 :            :         return EOK;
      48                 :            :     }
      49                 :            : 
      50         [ #  # ]:          0 :     if (isdigit(str[strlen(str)-1])) {
      51                 :          0 :         str = talloc_asprintf(opts, "%ss", str);
      52         [ #  # ]:          0 :         if (str == NULL) {
      53 [ #  # ][ #  # ]:          0 :             DEBUG(1, ("talloc_asprintf failed\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
      54                 :            :             return ENOMEM;
      55                 :            :         }
      56                 :          0 :         free_str = true;
      57                 :            : 
      58                 :          0 :         ret = dp_opt_set_string(opts, opt_id, str);
      59         [ #  # ]:          0 :         if (ret != EOK) {
      60 [ #  # ][ #  # ]:          0 :             DEBUG(1, ("dp_opt_set_string failed\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
      61                 :            :             goto done;
      62                 :            :         }
      63                 :            :     }
      64                 :            : 
      65                 :          0 :     ret = krb5_string_to_deltat(str, &lifetime);
      66         [ #  # ]:          0 :     if (ret != 0) {
      67 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Invalid value [%s] for a lifetime.\n", str));
         [ #  # ][ #  # ]
                 [ #  # ]
      68                 :            :         ret = EINVAL;
      69                 :            :         goto done;
      70                 :            :     }
      71                 :            : 
      72                 :          0 :     ret = setenv(env_name, str, 1);
      73         [ #  # ]:          0 :     if (ret != EOK) {
      74                 :          0 :         ret = errno;
      75 [ #  # ][ #  # ]:          0 :         DEBUG(2, ("setenv [%s] failed.\n", env_name));
         [ #  # ][ #  # ]
                 [ #  # ]
      76                 :            :         goto done;
      77                 :            :     }
      78                 :            : 
      79                 :            :     ret = EOK;
      80                 :            : 
      81                 :            : done:
      82         [ #  # ]:          0 :     if (free_str) {
      83                 :          0 :         talloc_free(str);
      84                 :            :     }
      85                 :            : 
      86                 :            :     return ret;
      87                 :            : }
      88                 :            : 
      89                 :            : 
      90                 :          0 : errno_t check_and_export_options(struct dp_option *opts,
      91                 :            :                                  struct sss_domain_info *dom,
      92                 :            :                                  struct krb5_ctx *krb5_ctx)
      93                 :            : {
      94                 :            :     int ret;
      95                 :            :     const char *realm;
      96                 :            :     const char *dummy;
      97                 :            :     char *use_fast_str;
      98                 :            :     char *fast_principal;
      99                 :            :     enum sss_krb5_cc_type cc_be;
     100                 :            : 
     101                 :          0 :     realm = dp_opt_get_cstring(opts, KRB5_REALM);
     102         [ #  # ]:          0 :     if (realm == NULL) {
     103                 :          0 :         ret = dp_opt_set_string(opts, KRB5_REALM, dom->name);
     104         [ #  # ]:          0 :         if (ret != EOK) {
     105 [ #  # ][ #  # ]:          0 :             DEBUG(1, ("dp_opt_set_string failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     106                 :          0 :             return ret;
     107                 :            :         }
     108                 :          0 :         realm = dom->name;
     109                 :            :     }
     110                 :            : 
     111                 :          0 :     ret = setenv(SSSD_KRB5_REALM, realm, 1);
     112         [ #  # ]:          0 :     if (ret != EOK) {
     113 [ #  # ][ #  # ]:          0 :         DEBUG(2, ("setenv %s failed, authentication might fail.\n",
         [ #  # ][ #  # ]
                 [ #  # ]
     114                 :            :                   SSSD_KRB5_REALM));
     115                 :            :     }
     116                 :            : 
     117                 :          0 :     ret = check_and_export_lifetime(opts, KRB5_RENEWABLE_LIFETIME,
     118                 :            :                                     SSSD_KRB5_RENEWABLE_LIFETIME);
     119         [ #  # ]:          0 :     if (ret != EOK) {
     120 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Failed to check value of krb5_renewable_lifetime. [%d][%s]\n",
         [ #  # ][ #  # ]
                 [ #  # ]
     121                 :            :                   ret, strerror(ret)));
     122                 :          0 :         return ret;
     123                 :            :     }
     124                 :            : 
     125                 :          0 :     ret = check_and_export_lifetime(opts, KRB5_LIFETIME,
     126                 :            :                                     SSSD_KRB5_LIFETIME);
     127         [ #  # ]:          0 :     if (ret != EOK) {
     128 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Failed to check value of krb5_lifetime. [%d][%s]\n",
         [ #  # ][ #  # ]
                 [ #  # ]
     129                 :            :                   ret, strerror(ret)));
     130                 :          0 :         return ret;
     131                 :            :     }
     132                 :            : 
     133                 :            : 
     134                 :          0 :     use_fast_str = dp_opt_get_string(opts, KRB5_USE_FAST);
     135         [ #  # ]:          0 :     if (use_fast_str != NULL) {
     136                 :          0 :         ret = check_fast(use_fast_str, &krb5_ctx->use_fast);
     137         [ #  # ]:          0 :         if (ret != EOK) {
     138 [ #  # ][ #  # ]:          0 :             DEBUG(1, ("check_fast failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     139                 :          0 :             return ret;
     140                 :            :         }
     141                 :            : 
     142         [ #  # ]:          0 :         if (krb5_ctx->use_fast) {
     143                 :          0 :             ret = setenv(SSSD_KRB5_USE_FAST, use_fast_str, 1);
     144         [ #  # ]:          0 :             if (ret != EOK) {
     145 [ #  # ][ #  # ]:          0 :                 DEBUG(2, ("setenv [%s] failed.\n", SSSD_KRB5_USE_FAST));
         [ #  # ][ #  # ]
                 [ #  # ]
     146                 :            :             } else {
     147                 :          0 :                 fast_principal = dp_opt_get_string(opts, KRB5_FAST_PRINCIPAL);
     148         [ #  # ]:          0 :                 if (fast_principal != NULL) {
     149                 :          0 :                     ret = setenv(SSSD_KRB5_FAST_PRINCIPAL, fast_principal, 1);
     150         [ #  # ]:          0 :                     if (ret != EOK) {
     151 [ #  # ][ #  # ]:          0 :                         DEBUG(2, ("setenv [%s] failed.\n", SSSD_KRB5_FAST_PRINCIPAL));
         [ #  # ][ #  # ]
                 [ #  # ]
     152                 :            :                     }
     153                 :            :                 }
     154                 :            :             }
     155                 :            :         }
     156                 :            :     }
     157                 :            : 
     158         [ #  # ]:          0 :     if (dp_opt_get_bool(opts, KRB5_CANONICALIZE)) {
     159                 :          0 :         ret = setenv(SSSD_KRB5_CANONICALIZE, "true", 1);
     160                 :            :     } else {
     161                 :          0 :         ret = setenv(SSSD_KRB5_CANONICALIZE, "false", 1);
     162                 :            :     }
     163         [ #  # ]:          0 :     if (ret != EOK) {
     164 [ #  # ][ #  # ]:          0 :         DEBUG(2, ("setenv [%s] failed.\n", SSSD_KRB5_CANONICALIZE));
         [ #  # ][ #  # ]
                 [ #  # ]
     165                 :            :     }
     166                 :            : 
     167                 :          0 :     dummy = dp_opt_get_cstring(opts, KRB5_KDC);
     168         [ #  # ]:          0 :     if (dummy == NULL) {
     169 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CONF_SETTINGS, ("No KDC explicitly configured, using defaults.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     170                 :            :     }
     171                 :            : 
     172                 :          0 :     dummy = dp_opt_get_cstring(opts, KRB5_KPASSWD);
     173         [ #  # ]:          0 :     if (dummy == NULL) {
     174 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CONF_SETTINGS, ("No kpasswd server explicitly configured, "
         [ #  # ][ #  # ]
                 [ #  # ]
     175                 :            :                                      "using the KDC or defaults.\n"));
     176                 :            :     }
     177                 :            : 
     178                 :          0 :     dummy = dp_opt_get_cstring(opts, KRB5_CCNAME_TMPL);
     179         [ #  # ]:          0 :     if (dummy == NULL) {
     180 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Missing credential cache name template.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     181                 :            :         return EINVAL;
     182                 :            :     }
     183                 :            : 
     184                 :          0 :     cc_be = sss_krb5_get_type(dummy);
     185      [ #  #  # ]:          0 :     switch (cc_be) {
     186                 :            :     case SSS_KRB5_TYPE_FILE:
     187 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CONF_SETTINGS, ("ccache is of type FILE\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     188                 :          0 :         krb5_ctx->cc_be = &file_cc;
     189         [ #  # ]:          0 :         if (dummy[0] != '/') {
     190                 :            :             /* FILE:/path/to/cc */
     191                 :            :             break;
     192                 :            :         }
     193                 :            : 
     194 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CONF_SETTINGS, ("The ccname template was "
         [ #  # ][ #  # ]
                 [ #  # ]
     195                 :            :               "missing an explicit type, but is an absolute "
     196                 :            :               "path specifier. Assuming FILE:\n"));
     197                 :            : 
     198                 :          0 :         dummy = talloc_asprintf(opts, "FILE:%s", dummy);
     199         [ #  # ]:          0 :         if (!dummy) return ENOMEM;
     200                 :            : 
     201                 :          0 :         ret = dp_opt_set_string(opts, KRB5_CCNAME_TMPL, dummy);
     202         [ #  # ]:          0 :         if (ret != EOK) {
     203 [ #  # ][ #  # ]:          0 :             DEBUG(SSSDBG_CRIT_FAILURE, ("dp_opt_set_string failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     204                 :          0 :             return ret;
     205                 :            :         }
     206                 :            :         break;
     207                 :            : 
     208                 :            : #ifdef HAVE_KRB5_DIRCACHE
     209                 :            :     case SSS_KRB5_TYPE_DIR:
     210 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CONF_SETTINGS, ("ccache is of type DIR\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     211                 :          0 :         krb5_ctx->cc_be = &dir_cc;
     212                 :          0 :         break;
     213                 :            : #endif
     214                 :            : 
     215                 :            :     default:
     216 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_OP_FAILURE, ("Unknown ccname database\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     217                 :            :         return EINVAL;
     218                 :            :         break;
     219                 :            :     }
     220                 :            : 
     221                 :            :     return EOK;
     222                 :            : }
     223                 :            : 
     224                 :          0 : errno_t krb5_try_kdcip(struct confdb_ctx *cdb, const char *conf_path,
     225                 :            :                        struct dp_option *opts, int opt_id)
     226                 :            : {
     227                 :          0 :     char *krb5_servers = NULL;
     228                 :            :     errno_t ret;
     229                 :            : 
     230                 :          0 :     krb5_servers = dp_opt_get_string(opts, opt_id);
     231         [ #  # ]:          0 :     if (krb5_servers == NULL) {
     232 [ #  # ][ #  # ]:          0 :         DEBUG(4, ("No KDC found in configuration, trying legacy option\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     233                 :          0 :         ret = confdb_get_string(cdb, NULL, conf_path,
     234                 :            :                                 "krb5_kdcip", NULL, &krb5_servers);
     235         [ #  # ]:          0 :         if (ret != EOK) {
     236 [ #  # ][ #  # ]:          0 :             DEBUG(1, ("confdb_get_string failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     237                 :            :             return ret;
     238                 :            :         }
     239                 :            : 
     240         [ #  # ]:          0 :         if (krb5_servers != NULL)
     241                 :            :         {
     242                 :          0 :             ret = dp_opt_set_string(opts, opt_id, krb5_servers);
     243         [ #  # ]:          0 :             if (ret != EOK) {
     244 [ #  # ][ #  # ]:          0 :                 DEBUG(1, ("dp_opt_set_string failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     245                 :          0 :                 talloc_free(krb5_servers);
     246                 :            :                 return ret;
     247                 :            :             }
     248                 :            : 
     249 [ #  # ][ #  # ]:          0 :             DEBUG(SSSDBG_CONF_SETTINGS,
         [ #  # ][ #  # ]
                 [ #  # ]
     250                 :            :                   ("Set krb5 server [%s] based on legacy krb5_kdcip option\n",
     251                 :            :                    krb5_servers));
     252 [ #  # ][ #  # ]:          0 :             DEBUG(SSSDBG_FATAL_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
     253                 :            :                   ("Your configuration uses the deprecated option "
     254                 :            :                    "'krb5_kdcip' to specify the KDC. Please change the "
     255                 :            :                    "configuration to use the 'krb5_server' option "
     256                 :            :                    "instead.\n"));
     257                 :          0 :             talloc_free(krb5_servers);
     258                 :            :         }
     259                 :            :     }
     260                 :            : 
     261                 :            :     return EOK;
     262                 :            : }
     263                 :            : 
     264                 :          0 : errno_t krb5_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb,
     265                 :            :                          const char *conf_path, struct dp_option **_opts)
     266                 :            : {
     267                 :            :     int ret;
     268                 :            :     struct dp_option *opts;
     269                 :            : 
     270                 :          0 :     opts = talloc_zero(memctx, struct dp_option);
     271         [ #  # ]:          0 :     if (opts == NULL) {
     272 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("talloc_zero failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     273                 :            :         return ENOMEM;
     274                 :            :     }
     275                 :            : 
     276                 :          0 :     ret = dp_get_options(opts, cdb, conf_path, default_krb5_opts,
     277                 :            :                          KRB5_OPTS, &opts);
     278         [ #  # ]:          0 :     if (ret != EOK) {
     279 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("dp_get_options failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     280                 :            :         goto done;
     281                 :            :     }
     282                 :            : 
     283                 :            :     /* If there is no KDC, try the deprecated krb5_kdcip option, too */
     284                 :            :     /* FIXME - this can be removed in a future version */
     285                 :          0 :     ret = krb5_try_kdcip(cdb, conf_path, opts, KRB5_KDC);
     286         [ #  # ]:          0 :     if (ret != EOK) {
     287 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("sss_krb5_try_kdcip failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     288                 :            :         goto done;
     289                 :            :     }
     290                 :            : 
     291                 :          0 :     *_opts = opts;
     292                 :          0 :     ret = EOK;
     293                 :            : 
     294                 :            : done:
     295         [ #  # ]:          0 :     if (ret != EOK) {
     296                 :          0 :         talloc_zfree(opts);
     297                 :            :     }
     298                 :            : 
     299                 :            :     return ret;
     300                 :            : }
     301                 :            : 
     302                 :          0 : errno_t write_krb5info_file(const char *realm, const char *server,
     303                 :            :                            const char *service)
     304                 :            : {
     305                 :            :     int ret;
     306                 :          0 :     int fd = -1;
     307                 :          0 :     char *tmp_name = NULL;
     308                 :          0 :     char *krb5info_name = NULL;
     309                 :          0 :     TALLOC_CTX *tmp_ctx = NULL;
     310                 :          0 :     const char *name_tmpl = NULL;
     311                 :            :     int server_len;
     312                 :            :     ssize_t written;
     313                 :            :     mode_t old_umask;
     314                 :            : 
     315 [ #  # ][ #  # ]:          0 :     if (realm == NULL || *realm == '\0' || server == NULL || *server == '\0' ||
         [ #  # ][ #  # ]
     316         [ #  # ]:          0 :         service == NULL || service == '\0') {
     317 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Missing or empty realm, server or service.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     318                 :            :         return EINVAL;
     319                 :            :     }
     320                 :            : 
     321         [ #  # ]:          0 :     if (strcmp(service, SSS_KRB5KDC_FO_SRV) == 0) {
     322                 :            :         name_tmpl = KDCINFO_TMPL;
     323         [ #  # ]:          0 :     } else if (strcmp(service, SSS_KRB5KPASSWD_FO_SRV) == 0) {
     324                 :            :         name_tmpl = KPASSWDINFO_TMPL;
     325                 :            :     } else {
     326 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Unsupported service [%s]\n.", service));
         [ #  # ][ #  # ]
                 [ #  # ]
     327                 :            :         return EINVAL;
     328                 :            :     }
     329                 :            : 
     330                 :          0 :     server_len = strlen(server);
     331                 :            : 
     332                 :          0 :     tmp_ctx = talloc_new(NULL);
     333         [ #  # ]:          0 :     if (tmp_ctx == NULL) {
     334 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("talloc_new failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     335                 :            :         return ENOMEM;
     336                 :            :     }
     337                 :            : 
     338                 :          0 :     tmp_name = talloc_asprintf(tmp_ctx, PUBCONF_PATH"/.krb5info_dummy_XXXXXX");
     339         [ #  # ]:          0 :     if (tmp_name == NULL) {
     340 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("talloc_asprintf failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     341                 :            :         ret = ENOMEM;
     342                 :            :         goto done;
     343                 :            :     }
     344                 :            : 
     345                 :          0 :     krb5info_name = talloc_asprintf(tmp_ctx, name_tmpl, realm);
     346         [ #  # ]:          0 :     if (krb5info_name == NULL) {
     347 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("talloc_asprintf failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     348                 :            :         ret = ENOMEM;
     349                 :            :         goto done;
     350                 :            :     }
     351                 :            : 
     352                 :          0 :     old_umask = umask(077);
     353                 :          0 :     fd = mkstemp(tmp_name);
     354                 :          0 :     umask(old_umask);
     355         [ #  # ]:          0 :     if (fd == -1) {
     356                 :          0 :         ret = errno;
     357 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("mkstemp failed [%d][%s].\n", ret, strerror(ret)));
         [ #  # ][ #  # ]
                 [ #  # ]
     358                 :            :         goto done;
     359                 :            :     }
     360                 :            : 
     361                 :          0 :     errno = 0;
     362                 :          0 :     written = sss_atomic_write_s(fd, discard_const(server), server_len);
     363         [ #  # ]:          0 :     if (written == -1) {
     364                 :          0 :         ret = errno;
     365 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CRIT_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
     366                 :            :               ("write failed [%d][%s].\n", ret, strerror(ret)));
     367                 :            :         goto done;
     368                 :            :     }
     369                 :            : 
     370         [ #  # ]:          0 :     if (written != server_len) {
     371 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CRIT_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
     372                 :            :               ("Write error, wrote [%d] bytes, expected [%d]\n",
     373                 :            :                written, server_len));
     374                 :            :         ret = EIO;
     375                 :            :         goto done;
     376                 :            :     }
     377                 :            : 
     378                 :          0 :     ret = fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
     379         [ #  # ]:          0 :     if (ret == -1) {
     380                 :          0 :         ret = errno;
     381 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("fchmod failed [%d][%s].\n", ret, strerror(ret)));
         [ #  # ][ #  # ]
                 [ #  # ]
     382                 :            :         goto done;
     383                 :            :     }
     384                 :            : 
     385                 :          0 :     ret = close(fd);
     386         [ #  # ]:          0 :     if (ret == -1) {
     387                 :          0 :         ret = errno;
     388 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("close failed [%d][%s].\n", ret, strerror(ret)));
         [ #  # ][ #  # ]
                 [ #  # ]
     389                 :            :         goto done;
     390                 :            :     }
     391                 :            : 
     392                 :          0 :     ret = rename(tmp_name, krb5info_name);
     393         [ #  # ]:          0 :     if (ret == -1) {
     394                 :          0 :         ret = errno;
     395 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("rename failed [%d][%s].\n", ret, strerror(ret)));
         [ #  # ][ #  # ]
                 [ #  # ]
     396                 :            :         goto done;
     397                 :            :     }
     398                 :            : 
     399                 :            : done:
     400                 :          0 :     talloc_free(tmp_ctx);
     401                 :          0 :     return ret;
     402                 :            : }
     403                 :            : 
     404                 :          0 : static void krb5_resolve_callback(void *private_data, struct fo_server *server)
     405                 :            : {
     406                 :            :     struct krb5_service *krb5_service;
     407                 :            :     struct resolv_hostent *srvaddr;
     408                 :            :     char *address;
     409                 :            :     char *safe_address;
     410                 :            :     int ret;
     411                 :          0 :     TALLOC_CTX *tmp_ctx = NULL;
     412                 :            : 
     413                 :          0 :     tmp_ctx = talloc_new(NULL);
     414         [ #  # ]:          0 :     if (tmp_ctx == NULL) {
     415 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("talloc_new failed\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     416                 :            :         return;
     417                 :            :     }
     418                 :            : 
     419                 :          0 :     krb5_service = talloc_get_type(private_data, struct krb5_service);
     420         [ #  # ]:          0 :     if (!krb5_service) {
     421 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("FATAL: Bad private_data\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     422                 :          0 :         talloc_free(tmp_ctx);
     423                 :          0 :         return;
     424                 :            :     }
     425                 :            : 
     426                 :          0 :     srvaddr = fo_get_server_hostent(server);
     427         [ #  # ]:          0 :     if (!srvaddr) {
     428 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("FATAL: No hostent available for server (%s)\n",
         [ #  # ][ #  # ]
                 [ #  # ]
     429                 :            :                   fo_get_server_str_name(server)));
     430                 :          0 :         talloc_free(tmp_ctx);
     431                 :          0 :         return;
     432                 :            :     }
     433                 :            : 
     434                 :          0 :     address = resolv_get_string_address(tmp_ctx, srvaddr);
     435         [ #  # ]:          0 :     if (address == NULL) {
     436 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("resolv_get_string_address failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     437                 :          0 :         talloc_free(tmp_ctx);
     438                 :          0 :         return;
     439                 :            :     }
     440                 :            : 
     441                 :          0 :     safe_address = sss_escape_ip_address(tmp_ctx,
     442                 :            :                                          srvaddr->family,
     443                 :            :                                          address);
     444         [ #  # ]:          0 :     if (safe_address == NULL) {
     445 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("sss_escape_ip_address failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     446                 :          0 :         talloc_free(tmp_ctx);
     447                 :          0 :         return;
     448                 :            :     }
     449                 :            : 
     450                 :          0 :     safe_address = talloc_asprintf_append(safe_address, ":%d",
     451                 :            :                                           fo_get_server_port(server));
     452         [ #  # ]:          0 :     if (safe_address == NULL) {
     453 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("talloc_asprintf_append failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     454                 :          0 :         talloc_free(tmp_ctx);
     455                 :          0 :         return;
     456                 :            :     }
     457                 :            : 
     458                 :          0 :     ret = write_krb5info_file(krb5_service->realm, safe_address,
     459                 :          0 :                               krb5_service->name);
     460         [ #  # ]:          0 :     if (ret != EOK) {
     461 [ #  # ][ #  # ]:          0 :         DEBUG(2, ("write_krb5info_file failed, authentication might fail.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     462                 :            :     }
     463                 :            : 
     464                 :          0 :     talloc_free(tmp_ctx);
     465                 :          0 :     return;
     466                 :            : }
     467                 :            : 
     468                 :          0 : errno_t krb5_servers_init(struct be_ctx *ctx,
     469                 :            :                           struct krb5_service *service,
     470                 :            :                           const char *service_name,
     471                 :            :                           const char *servers,
     472                 :            :                           bool primary)
     473                 :            : {
     474                 :            :     TALLOC_CTX *tmp_ctx;
     475                 :          0 :     char **list = NULL;
     476                 :          0 :     errno_t ret = 0;
     477                 :            :     int i;
     478                 :            :     char *port_str;
     479                 :            :     long port;
     480                 :            :     char *server_spec;
     481                 :            :     char *endptr;
     482                 :            :     struct servent *servent;
     483                 :            : 
     484                 :          0 :     tmp_ctx = talloc_new(NULL);
     485         [ #  # ]:          0 :     if (!tmp_ctx) {
     486                 :            :         return ENOMEM;
     487                 :            :     }
     488                 :            : 
     489                 :          0 :     ret = split_on_separator(tmp_ctx, servers, ',', true, &list, NULL);
     490         [ #  # ]:          0 :     if (ret != EOK) {
     491 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to parse server list!\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     492                 :            :         goto done;
     493                 :            :     }
     494                 :            : 
     495         [ #  # ]:          0 :     for (i = 0; list[i]; i++) {
     496                 :          0 :         talloc_steal(service, list[i]);
     497                 :          0 :         server_spec = talloc_strdup(service, list[i]);
     498         [ #  # ]:          0 :         if (!server_spec) {
     499                 :            :             ret = ENOMEM;
     500                 :            :             goto done;
     501                 :            :         }
     502                 :            : 
     503         [ #  # ]:          0 :         if (be_fo_is_srv_identifier(server_spec)) {
     504         [ #  # ]:          0 :             if (!primary) {
     505 [ #  # ][ #  # ]:          0 :                 DEBUG(SSSDBG_MINOR_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
     506                 :            :                       ("Failed to add server [%s] to failover service: "
     507                 :            :                        "SRV resolution only allowed for primary servers!\n",
     508                 :            :                        list[i]));
     509                 :          0 :                 continue;
     510                 :            :             }
     511                 :            : 
     512                 :          0 :             ret = be_fo_add_srv_server(ctx, service_name, service_name, NULL,
     513                 :            :                                        BE_FO_PROTO_UDP, true, NULL);
     514         [ #  # ]:          0 :             if (ret) {
     515 [ #  # ][ #  # ]:          0 :                 DEBUG(SSSDBG_FATAL_FAILURE, ("Failed to add server\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     516                 :            :                 goto done;
     517                 :            :             }
     518                 :            : 
     519 [ #  # ][ #  # ]:          0 :             DEBUG(SSSDBG_TRACE_FUNC, ("Added service lookup\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     520                 :          0 :             continue;
     521                 :            :         }
     522                 :            : 
     523                 :            :         /* Do not try to get port number if last character is ']' */
     524         [ #  # ]:          0 :         if (server_spec[strlen(server_spec) - 1] != ']') {
     525                 :          0 :             port_str = strrchr(server_spec, ':');
     526                 :            :         } else {
     527                 :            :             port_str = NULL;
     528                 :            :         }
     529                 :            : 
     530         [ #  # ]:          0 :         if (port_str == NULL) {
     531                 :            :             port = 0;
     532                 :            :         } else {
     533                 :          0 :             *port_str = '\0';
     534                 :          0 :             ++port_str;
     535         [ #  # ]:          0 :             if (isdigit(*port_str)) {
     536                 :          0 :                 errno = 0;
     537                 :          0 :                 port = strtol(port_str, &endptr, 10);
     538         [ #  # ]:          0 :                 if (errno != 0) {
     539                 :          0 :                     ret = errno;
     540 [ #  # ][ #  # ]:          0 :                     DEBUG(SSSDBG_CRIT_FAILURE, ("strtol failed on [%s]: [%d][%s].\n", port_str,
         [ #  # ][ #  # ]
                 [ #  # ]
     541                 :            :                               ret, strerror(ret)));
     542                 :            :                     goto done;
     543                 :            :                 }
     544         [ #  # ]:          0 :                 if (*endptr != '\0') {
     545 [ #  # ][ #  # ]:          0 :                     DEBUG(SSSDBG_CRIT_FAILURE, ("Found additional characters [%s] in port number "
         [ #  # ][ #  # ]
                 [ #  # ]
     546                 :            :                               "[%s].\n", endptr, port_str));
     547                 :            :                     ret = EINVAL;
     548                 :            :                     goto done;
     549                 :            :                 }
     550                 :            : 
     551         [ #  # ]:          0 :                 if (port < 1 || port > 65535) {
     552 [ #  # ][ #  # ]:          0 :                     DEBUG(SSSDBG_CRIT_FAILURE, ("Illegal port number [%d].\n", port));
         [ #  # ][ #  # ]
                 [ #  # ]
     553                 :            :                     ret = EINVAL;
     554                 :            :                     goto done;
     555                 :            :                 }
     556         [ #  # ]:          0 :             } else if (isalpha(*port_str)) {
     557                 :          0 :                 servent = getservbyname(port_str, NULL);
     558         [ #  # ]:          0 :                 if (servent == NULL) {
     559 [ #  # ][ #  # ]:          0 :                     DEBUG(SSSDBG_CRIT_FAILURE, ("getservbyname cannot find service [%s].\n",
         [ #  # ][ #  # ]
                 [ #  # ]
     560                 :            :                               port_str));
     561                 :            :                     ret = EINVAL;
     562                 :            :                     goto done;
     563                 :            :                 }
     564                 :            : 
     565                 :          0 :                 port = servent->s_port;
     566                 :            :             } else {
     567 [ #  # ][ #  # ]:          0 :                 DEBUG(SSSDBG_CRIT_FAILURE, ("Unsupported port specifier in [%s].\n", list[i]));
         [ #  # ][ #  # ]
                 [ #  # ]
     568                 :            :                 ret = EINVAL;
     569                 :            :                 goto done;
     570                 :            :             }
     571                 :            :         }
     572                 :            : 
     573                 :            :         /* It could be ipv6 address in square brackets. Remove
     574                 :            :          * the brackets if needed. */
     575                 :          0 :         ret = remove_ipv6_brackets(server_spec);
     576         [ #  # ]:          0 :         if (ret != EOK) {
     577                 :            :             goto done;
     578                 :            :         }
     579                 :            : 
     580                 :          0 :         ret = be_fo_add_server(ctx, service_name, server_spec, (int) port,
     581                 :          0 :                                list[i], primary);
     582         [ #  # ]:          0 :         if (ret && ret != EEXIST) {
     583 [ #  # ][ #  # ]:          0 :             DEBUG(SSSDBG_FATAL_FAILURE, ("Failed to add server\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     584                 :            :             goto done;
     585                 :            :         }
     586                 :            : 
     587 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_TRACE_FUNC, ("Added Server %s\n", list[i]));
         [ #  # ][ #  # ]
                 [ #  # ]
     588                 :            :     }
     589                 :            : 
     590                 :            : done:
     591                 :          0 :     talloc_free(tmp_ctx);
     592                 :            :     return ret;
     593                 :            : }
     594                 :            : 
     595                 :          0 : static int krb5_user_data_cmp(void *ud1, void *ud2)
     596                 :            : {
     597                 :          0 :     return strcasecmp((char*) ud1, (char*) ud2);
     598                 :            : }
     599                 :            : 
     600                 :          0 : int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
     601                 :            :                       const char *service_name,
     602                 :            :                       const char *primary_servers,
     603                 :            :                       const char *backup_servers,
     604                 :            :                       const char *realm, struct krb5_service **_service)
     605                 :            : {
     606                 :            :     TALLOC_CTX *tmp_ctx;
     607                 :            :     struct krb5_service *service;
     608                 :            :     int ret;
     609                 :            : 
     610                 :          0 :     tmp_ctx = talloc_new(memctx);
     611         [ #  # ]:          0 :     if (!tmp_ctx) {
     612                 :            :         return ENOMEM;
     613                 :            :     }
     614                 :            : 
     615                 :          0 :     service = talloc_zero(tmp_ctx, struct krb5_service);
     616         [ #  # ]:          0 :     if (!service) {
     617                 :            :         ret = ENOMEM;
     618                 :            :         goto done;
     619                 :            :     }
     620                 :            : 
     621                 :          0 :     ret = be_fo_add_service(ctx, service_name, krb5_user_data_cmp);
     622         [ #  # ]:          0 :     if (ret != EOK) {
     623 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Failed to create failover service!\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     624                 :            :         goto done;
     625                 :            :     }
     626                 :            : 
     627                 :          0 :     service->name = talloc_strdup(service, service_name);
     628         [ #  # ]:          0 :     if (!service->name) {
     629                 :            :         ret = ENOMEM;
     630                 :            :         goto done;
     631                 :            :     }
     632                 :            : 
     633                 :          0 :     service->realm = talloc_strdup(service, realm);
     634         [ #  # ]:          0 :     if (!service->realm) {
     635                 :            :         ret = ENOMEM;
     636                 :            :         goto done;
     637                 :            :     }
     638                 :            : 
     639         [ #  # ]:          0 :     if (!primary_servers) {
     640 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CONF_SETTINGS,
         [ #  # ][ #  # ]
                 [ #  # ]
     641                 :            :               ("No primary servers defined, using service discovery\n"));
     642                 :            :         primary_servers = BE_SRV_IDENTIFIER;
     643                 :            :     }
     644                 :            : 
     645                 :          0 :     ret = krb5_servers_init(ctx, service, service_name, primary_servers, true);
     646         [ #  # ]:          0 :     if (ret != EOK) {
     647                 :            :         goto done;
     648                 :            :     }
     649                 :            : 
     650         [ #  # ]:          0 :     if (backup_servers) {
     651                 :          0 :         ret = krb5_servers_init(ctx, service, service_name, backup_servers, false);
     652         [ #  # ]:          0 :         if (ret != EOK) {
     653                 :            :             goto done;
     654                 :            :         }
     655                 :            :     }
     656                 :            : 
     657                 :          0 :     ret = be_fo_service_add_callback(memctx, ctx, service_name,
     658                 :            :                                      krb5_resolve_callback, service);
     659         [ #  # ]:          0 :     if (ret != EOK) {
     660 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Failed to add failover callback!\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     661                 :            :         goto done;
     662                 :            :     }
     663                 :            : 
     664                 :            :     ret = EOK;
     665                 :            : 
     666                 :            : done:
     667         [ #  # ]:          0 :     if (ret == EOK) {
     668                 :          0 :         *_service = talloc_steal(memctx, service);
     669                 :            :     }
     670                 :          0 :     talloc_zfree(tmp_ctx);
     671                 :          0 :     return ret;
     672                 :            : }
     673                 :            : 
     674                 :            : 
     675                 :          0 : errno_t remove_krb5_info_files(TALLOC_CTX *mem_ctx, const char *realm)
     676                 :            : {
     677                 :            :     int ret;
     678                 :            :     errno_t err;
     679                 :            :     char *file;
     680                 :            : 
     681                 :          0 :     file = talloc_asprintf(mem_ctx, KDCINFO_TMPL, realm);
     682         [ #  # ]:          0 :     if(file == NULL) {
     683 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("talloc_asprintf failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     684                 :            :         return ENOMEM;
     685                 :            :     }
     686                 :            : 
     687                 :          0 :     errno = 0;
     688                 :          0 :     ret = unlink(file);
     689         [ #  # ]:          0 :     if (ret == -1) {
     690                 :          0 :         err = errno;
     691 [ #  # ][ #  # ]:          0 :         DEBUG(5, ("Could not remove [%s], [%d][%s]\n", file,
         [ #  # ][ #  # ]
                 [ #  # ]
     692                 :            :                   err, strerror(err)));
     693                 :            :     }
     694                 :            : 
     695                 :          0 :     file = talloc_asprintf(mem_ctx, KPASSWDINFO_TMPL, realm);
     696         [ #  # ]:          0 :     if(file == NULL) {
     697 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("talloc_asprintf failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     698                 :            :         return ENOMEM;
     699                 :            :     }
     700                 :            : 
     701                 :          0 :     errno = 0;
     702                 :          0 :     ret = unlink(file);
     703         [ #  # ]:          0 :     if (ret == -1) {
     704                 :          0 :         err = errno;
     705 [ #  # ][ #  # ]:          0 :         DEBUG(5, ("Could not remove [%s], [%d][%s]\n", file,
         [ #  # ][ #  # ]
                 [ #  # ]
     706                 :            :                   err, strerror(err)));
     707                 :            :     }
     708                 :            : 
     709                 :            :     return EOK;
     710                 :            : }
     711                 :            : 
     712                 :          0 : void remove_krb5_info_files_callback(void *pvt)
     713                 :            : {
     714                 :            :     int ret;
     715                 :          0 :     TALLOC_CTX *tmp_ctx = NULL;
     716                 :          0 :     struct remove_info_files_ctx *ctx = talloc_get_type(pvt,
     717                 :            :                                                   struct remove_info_files_ctx);
     718                 :            : 
     719                 :          0 :     ret = be_fo_run_callbacks_at_next_request(ctx->be_ctx,
     720                 :            :                                               ctx->kdc_service_name);
     721         [ #  # ]:          0 :     if (ret != EOK) {
     722 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("be_fo_run_callbacks_at_next_request failed, "
         [ #  # ][ #  # ]
                 [ #  # ]
     723                 :            :                   "krb5 info files will not be removed, because "
     724                 :            :                   "it is unclear if they will be recreated properly.\n"));
     725                 :            :         return;
     726                 :            :     }
     727         [ #  # ]:          0 :     if (ctx->kpasswd_service_name != NULL) {
     728                 :          0 :         ret = be_fo_run_callbacks_at_next_request(ctx->be_ctx,
     729                 :            :                                             ctx->kpasswd_service_name);
     730         [ #  # ]:          0 :         if (ret != EOK) {
     731 [ #  # ][ #  # ]:          0 :             DEBUG(1, ("be_fo_run_callbacks_at_next_request failed, "
         [ #  # ][ #  # ]
                 [ #  # ]
     732                 :            :                       "krb5 info files will not be removed, because "
     733                 :            :                       "it is unclear if they will be recreated properly.\n"));
     734                 :            :             return;
     735                 :            :         }
     736                 :            :     }
     737                 :            : 
     738                 :          0 :     tmp_ctx = talloc_new(NULL);
     739         [ #  # ]:          0 :     if (tmp_ctx == NULL) {
     740 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("talloc_new failed, cannot remove krb5 info files.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     741                 :            :         return;
     742                 :            :     }
     743                 :            : 
     744                 :          0 :     ret = remove_krb5_info_files(tmp_ctx, ctx->realm);
     745         [ #  # ]:          0 :     if (ret != EOK) {
     746 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("remove_krb5_info_files failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     747                 :            :     }
     748                 :            : 
     749                 :          0 :     talloc_zfree(tmp_ctx);
     750                 :            : }
     751                 :            : 
     752                 :          0 : void krb5_finalize(struct tevent_context *ev,
     753                 :            :                    struct tevent_signal *se,
     754                 :            :                    int signum,
     755                 :            :                    int count,
     756                 :            :                    void *siginfo,
     757                 :            :                    void *private_data)
     758                 :            : {
     759                 :          0 :     char *realm = (char *)private_data;
     760                 :            :     int ret;
     761                 :            : 
     762                 :          0 :     ret = remove_krb5_info_files(se, realm);
     763         [ #  # ]:          0 :     if (ret != EOK) {
     764 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("remove_krb5_info_files failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     765                 :            :     }
     766                 :            : 
     767                 :          0 :     sig_term(signum);
     768                 :          0 : }
     769                 :            : 
     770                 :          0 : errno_t krb5_install_offline_callback(struct be_ctx *be_ctx,
     771                 :            :                                       struct krb5_ctx *krb5_ctx)
     772                 :            : {
     773                 :            :     int ret;
     774                 :            :     struct remove_info_files_ctx *ctx;
     775                 :            :     const char *krb5_realm;
     776                 :            : 
     777 [ #  # ][ #  # ]:          0 :     if (krb5_ctx->service == NULL || krb5_ctx->service->name == NULL) {
     778 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Missing KDC service name!\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     779                 :            :         return EINVAL;
     780                 :            :     }
     781                 :            : 
     782                 :          0 :     ctx = talloc_zero(krb5_ctx, struct remove_info_files_ctx);
     783         [ #  # ]:          0 :     if (ctx == NULL) {
     784 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("talloc_zfree failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     785                 :            :         return ENOMEM;
     786                 :            :     }
     787                 :            : 
     788                 :          0 :     krb5_realm = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM);
     789         [ #  # ]:          0 :     if (krb5_realm == NULL) {
     790 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Missing krb5_realm option!\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     791                 :            :         ret = EINVAL;
     792                 :            :         goto done;
     793                 :            :     }
     794                 :            : 
     795                 :          0 :     ctx->realm = talloc_strdup(ctx, krb5_realm);
     796         [ #  # ]:          0 :     if (ctx->realm == NULL) {
     797 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("talloc_strdup failed!\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     798                 :            :         ret = ENOMEM;
     799                 :            :         goto done;
     800                 :            :     }
     801                 :            : 
     802                 :          0 :     ctx->be_ctx = be_ctx;
     803                 :          0 :     ctx->kdc_service_name = krb5_ctx->service->name;
     804         [ #  # ]:          0 :     if (krb5_ctx->kpasswd_service == NULL) {
     805                 :          0 :         ctx->kpasswd_service_name =NULL;
     806                 :            :     } else {
     807                 :          0 :         ctx->kpasswd_service_name = krb5_ctx->kpasswd_service->name;
     808                 :            :     }
     809                 :            : 
     810                 :          0 :     ret = be_add_offline_cb(ctx, be_ctx, remove_krb5_info_files_callback, ctx,
     811                 :            :                             NULL);
     812         [ #  # ]:          0 :     if (ret != EOK) {
     813 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("be_add_offline_cb failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     814                 :            :         goto done;
     815                 :            :     }
     816                 :            : 
     817                 :            :     ret = EOK;
     818                 :            : 
     819                 :            : done:
     820         [ #  # ]:          0 :     if (ret != EOK) {
     821                 :          0 :         talloc_zfree(ctx);
     822                 :            :     }
     823                 :            : 
     824                 :          0 :     return ret;
     825                 :            : }
     826                 :            : 
     827                 :          0 : errno_t krb5_install_sigterm_handler(struct tevent_context *ev,
     828                 :            :                                      struct krb5_ctx *krb5_ctx)
     829                 :            : {
     830                 :            :     const char *krb5_realm;
     831                 :            :     char *sig_realm;
     832                 :            :     struct tevent_signal *sige;
     833                 :            : 
     834                 :          0 :     BlockSignals(false, SIGTERM);
     835                 :            : 
     836                 :          0 :     krb5_realm = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM);
     837         [ #  # ]:          0 :     if (krb5_realm == NULL) {
     838 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Missing krb5_realm option!\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     839                 :            :         return EINVAL;
     840                 :            :     }
     841                 :            : 
     842                 :          0 :     sig_realm = talloc_strdup(krb5_ctx, krb5_realm);
     843         [ #  # ]:          0 :     if (sig_realm == NULL) {
     844 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("talloc_strdup failed!\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     845                 :            :         return ENOMEM;
     846                 :            :     }
     847                 :            : 
     848                 :          0 :     sige = tevent_add_signal(ev, krb5_ctx, SIGTERM, SA_SIGINFO, krb5_finalize,
     849                 :            :                              sig_realm);
     850         [ #  # ]:          0 :     if (sige == NULL) {
     851 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("tevent_add_signal failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     852                 :          0 :         talloc_free(sig_realm);
     853                 :          0 :         return ENOMEM;
     854                 :            :     }
     855                 :          0 :     talloc_steal(sige, sig_realm);
     856                 :            : 
     857                 :          0 :     return EOK;
     858                 :            : }
     859                 :            : 
     860                 :          0 : errno_t krb5_get_simple_upn(TALLOC_CTX *mem_ctx, struct krb5_ctx *krb5_ctx,
     861                 :            :                             const char *domain_name, const char *username,
     862                 :            :                             const char *user_dom, char **_upn)
     863                 :            : {
     864                 :          0 :     const char *realm = NULL;
     865                 :          0 :     char *uc_dom = NULL;
     866                 :            :     char *upn;
     867                 :            : 
     868 [ #  # ][ #  # ]:          0 :     if (user_dom != NULL && domain_name != NULL &&
     869                 :          0 :         strcasecmp(domain_name,user_dom) != 0) {
     870                 :          0 :         uc_dom = get_uppercase_realm(mem_ctx, user_dom);
     871         [ #  # ]:          0 :         if (uc_dom == NULL) {
     872 [ #  # ][ #  # ]:          0 :             DEBUG(SSSDBG_OP_FAILURE, ("get_uppercase_realm failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     873                 :            :             return ENOMEM;
     874                 :            :         }
     875                 :            :     } else {
     876                 :          0 :         realm = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM);
     877         [ #  # ]:          0 :         if (realm == NULL) {
     878 [ #  # ][ #  # ]:          0 :             DEBUG(SSSDBG_OP_FAILURE, ("Missing Kerberos realm.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     879                 :            :             return ENOENT;
     880                 :            :         }
     881                 :            :     }
     882                 :            : 
     883                 :            :     /* NOTE: this is a hack, works only in some environments */
     884         [ #  # ]:          0 :     upn = talloc_asprintf(mem_ctx, "%s@%s",  username,
     885                 :            :                                              realm != NULL ? realm : uc_dom);
     886                 :          0 :     talloc_free(uc_dom);
     887         [ #  # ]:          0 :     if (upn == NULL) {
     888 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("talloc_asprintf failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     889                 :            :         return ENOMEM;
     890                 :            :     }
     891                 :            : 
     892 [ #  # ][ #  # ]:          0 :     DEBUG(9, ("Using simple UPN [%s].\n", upn));
         [ #  # ][ #  # ]
                 [ #  # ]
     893                 :            : 
     894                 :          0 :     *_upn = upn;
     895                 :          0 :     return EOK;
     896                 :            : }
     897                 :            : 
     898                 :         10 : errno_t compare_principal_realm(const char *upn, const char *realm,
     899                 :            :                                 bool *different_realm)
     900                 :            : {
     901                 :            :     char *at_sign;
     902                 :            : 
     903 [ +  + ][ +  + ]:         10 :     if (upn == NULL || realm == NULL || different_realm == NULL ||
                 [ +  + ]
     904         [ +  + ]:          6 :         *upn == '\0' || *realm == '\0') {
     905                 :            :         return EINVAL;
     906                 :            :     }
     907                 :            : 
     908                 :          5 :     at_sign = strchr(upn, '@');
     909                 :            : 
     910         [ +  + ]:          5 :     if (at_sign == NULL) {
     911                 :            :         return EINVAL;
     912                 :            :     }
     913                 :            : 
     914         [ +  + ]:          3 :     if (strcmp(realm, at_sign + 1) == 0) {
     915                 :          1 :         *different_realm = false;
     916                 :            :     } else {
     917                 :         10 :         *different_realm = true;
     918                 :            :     }
     919                 :            : 
     920                 :            :     return EOK;
     921                 :            : }

Generated by: LCOV version 1.9