LCOV - code coverage report
Current view: top level - source3/librpc/crypto - gse_krb5.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 123 285 43.2 %
Date: 2021-08-25 13:27:56 Functions: 4 7 57.1 %

          Line data    Source code
       1             : /*
       2             :  *  GSSAPI Security Extensions
       3             :  *  Krb5 helpers
       4             :  *  Copyright (C) Simo Sorce 2010.
       5             :  *
       6             :  *  This program is free software; you can redistribute it and/or modify
       7             :  *  it under the terms of the GNU General Public License as published by
       8             :  *  the Free Software Foundation; either version 3 of the License, or
       9             :  *  (at your option) any later version.
      10             :  *
      11             :  *  This program is distributed in the hope that it will be useful,
      12             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  *  GNU General Public License for more details.
      15             :  *
      16             :  *  You should have received a copy of the GNU General Public License
      17             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #include "includes.h"
      21             : #include "smb_krb5.h"
      22             : #include "secrets.h"
      23             : #include "librpc/gen_ndr/secrets.h"
      24             : #include "gse_krb5.h"
      25             : #include "lib/param/loadparm.h"
      26             : #include "libads/kerberos_proto.h"
      27             : #include "lib/util/string_wrappers.h"
      28             : 
      29             : #ifdef HAVE_KRB5
      30             : 
      31           0 : static krb5_error_code flush_keytab(krb5_context krbctx, krb5_keytab keytab)
      32             : {
      33             :         krb5_error_code ret;
      34             :         krb5_kt_cursor kt_cursor;
      35             :         krb5_keytab_entry kt_entry;
      36             : 
      37           0 :         ZERO_STRUCT(kt_entry);
      38             : 
      39           0 :         ret = krb5_kt_start_seq_get(krbctx, keytab, &kt_cursor);
      40           0 :         if (ret == KRB5_KT_END || ret == ENOENT ) {
      41             :                 /* no entries */
      42           0 :                 return 0;
      43             :         }
      44             : 
      45           0 :         ret = krb5_kt_next_entry(krbctx, keytab, &kt_entry, &kt_cursor);
      46           0 :         while (ret == 0) {
      47             : 
      48             :                 /* we need to close and reopen enumeration because we modify
      49             :                  * the keytab */
      50           0 :                 ret = krb5_kt_end_seq_get(krbctx, keytab, &kt_cursor);
      51           0 :                 if (ret) {
      52           0 :                         DEBUG(1, (__location__ ": krb5_kt_end_seq_get() "
      53             :                                   "failed (%s)\n", error_message(ret)));
      54           0 :                         goto out;
      55             :                 }
      56             : 
      57             :                 /* remove the entry */
      58           0 :                 ret = krb5_kt_remove_entry(krbctx, keytab, &kt_entry);
      59           0 :                 if (ret) {
      60           0 :                         DEBUG(1, (__location__ ": krb5_kt_remove_entry() "
      61             :                                   "failed (%s)\n", error_message(ret)));
      62           0 :                         goto out;
      63             :                 }
      64           0 :                 smb_krb5_kt_free_entry(krbctx, &kt_entry);
      65           0 :                 ZERO_STRUCT(kt_entry);
      66             : 
      67             :                 /* now reopen */
      68           0 :                 ret = krb5_kt_start_seq_get(krbctx, keytab, &kt_cursor);
      69           0 :                 if (ret) {
      70           0 :                         DEBUG(1, (__location__ ": krb5_kt_start_seq() failed "
      71             :                                   "(%s)\n", error_message(ret)));
      72           0 :                         goto out;
      73             :                 }
      74             : 
      75           0 :                 ret = krb5_kt_next_entry(krbctx, keytab,
      76             :                                          &kt_entry, &kt_cursor);
      77             :         }
      78             : 
      79           0 :         if (ret != KRB5_KT_END && ret != ENOENT) {
      80           0 :                 DEBUG(1, (__location__ ": flushing keytab we got [%s]!\n",
      81             :                           error_message(ret)));
      82             :         }
      83             : 
      84           0 :         ret = 0;
      85             : 
      86           0 : out:
      87           0 :         return ret;
      88             : }
      89             : 
      90        5324 : static krb5_error_code fill_keytab_from_password(krb5_context krbctx,
      91             :                                                  krb5_keytab keytab,
      92             :                                                  krb5_principal princ,
      93             :                                                  krb5_kvno vno,
      94             :                                                  struct secrets_domain_info1_password *pw)
      95             : {
      96             :         krb5_error_code ret;
      97             :         krb5_enctype *enctypes;
      98             :         uint16_t i;
      99             : 
     100        5324 :         ret = smb_krb5_get_allowed_etypes(krbctx, &enctypes);
     101        5324 :         if (ret) {
     102           0 :                 DEBUG(1, (__location__
     103             :                           ": Can't determine permitted enctypes!\n"));
     104           0 :                 return ret;
     105             :         }
     106             : 
     107       21296 :         for (i = 0; i < pw->num_keys; i++) {
     108             :                 krb5_keytab_entry kt_entry;
     109       15972 :                 krb5_keyblock *key = NULL;
     110             :                 unsigned int ei;
     111       15972 :                 bool found_etype = false;
     112             : 
     113       90638 :                 for (ei=0; enctypes[ei] != 0; ei++) {
     114       45319 :                         if ((uint32_t)enctypes[ei] != pw->keys[i].keytype) {
     115       29347 :                                 continue;
     116             :                         }
     117             : 
     118       15972 :                         found_etype = true;
     119       15972 :                         break;
     120             :                 }
     121             : 
     122       15972 :                 if (!found_etype) {
     123           0 :                         continue;
     124             :                 }
     125             : 
     126       15972 :                 ZERO_STRUCT(kt_entry);
     127       15972 :                 kt_entry.principal = princ;
     128       15972 :                 kt_entry.vno = vno;
     129             : 
     130       15972 :                 key = KRB5_KT_KEY(&kt_entry);
     131       15972 :                 KRB5_KEY_TYPE(key) = pw->keys[i].keytype;
     132       15972 :                 KRB5_KEY_DATA(key) = pw->keys[i].value.data;
     133       15972 :                 KRB5_KEY_LENGTH(key) = pw->keys[i].value.length;
     134             : 
     135       15972 :                 ret = krb5_kt_add_entry(krbctx, keytab, &kt_entry);
     136       15972 :                 if (ret) {
     137           0 :                         DEBUG(1, (__location__ ": Failed to add entry to "
     138             :                                   "keytab for enctype %d (error: %s)\n",
     139             :                                   (unsigned)pw->keys[i].keytype,
     140             :                                   error_message(ret)));
     141           0 :                         goto out;
     142             :                 }
     143             :         }
     144             : 
     145        5324 :         ret = 0;
     146             : 
     147        5324 : out:
     148        5324 :         SAFE_FREE(enctypes);
     149        5324 :         return ret;
     150             : }
     151             : 
     152             : #define SRV_MEM_KEYTAB_NAME "MEMORY:cifs_srv_keytab"
     153             : #define CLEARTEXT_PRIV_ENCTYPE -99
     154             : 
     155        2959 : static krb5_error_code fill_mem_keytab_from_secrets(krb5_context krbctx,
     156             :                                                     krb5_keytab *keytab)
     157             : {
     158        2959 :         TALLOC_CTX *frame = talloc_stackframe();
     159             :         krb5_error_code ret;
     160        2959 :         const char *domain = lp_workgroup();
     161        2959 :         struct secrets_domain_info1 *info = NULL;
     162        2959 :         const char *realm = NULL;
     163        2959 :         const DATA_BLOB *ct = NULL;
     164             :         krb5_kt_cursor kt_cursor;
     165             :         krb5_keytab_entry kt_entry;
     166        2959 :         krb5_principal princ = NULL;
     167        2959 :         krb5_kvno kvno = 0; /* FIXME: fetch current vno from KDC ? */
     168             :         NTSTATUS status;
     169             : 
     170        2959 :         if (!secrets_init()) {
     171           0 :                 DEBUG(1, (__location__ ": secrets_init failed\n"));
     172           0 :                 TALLOC_FREE(frame);
     173           0 :                 return KRB5_CONFIG_CANTOPEN;
     174             :         }
     175             : 
     176        2959 :         status = secrets_fetch_or_upgrade_domain_info(domain,
     177             :                                                       frame,
     178             :                                                       &info);
     179        2959 :         if (!NT_STATUS_IS_OK(status)) {
     180           4 :                 DBG_WARNING("secrets_fetch_or_upgrade_domain_info(%s) - %s\n",
     181             :                             domain, nt_errstr(status));
     182           4 :                 TALLOC_FREE(frame);
     183           4 :                 return KRB5_LIBOS_CANTREADPWD;
     184             :         }
     185        2955 :         ct = &info->password->cleartext_blob;
     186             : 
     187        2955 :         if (info->domain_info.dns_domain.string != NULL) {
     188        2955 :                 realm = strupper_talloc(frame,
     189        2955 :                                 info->domain_info.dns_domain.string);
     190        2955 :                 if (realm == NULL) {
     191           0 :                         TALLOC_FREE(frame);
     192           0 :                         return ENOMEM;
     193             :                 }
     194             :         }
     195             : 
     196        2955 :         ZERO_STRUCT(kt_entry);
     197        2955 :         ZERO_STRUCT(kt_cursor);
     198             : 
     199             :         /* check if the keytab already has any entry */
     200        2955 :         ret = krb5_kt_start_seq_get(krbctx, *keytab, &kt_cursor);
     201        2955 :         if (ret != KRB5_KT_END && ret != ENOENT ) {
     202             :                 /* check if we have our special enctype used to hold
     203             :                  * the clear text password. If so, check it out so that
     204             :                  * we can verify if the keytab needs to be upgraded */
     205        5934 :                 while ((ret = krb5_kt_next_entry(krbctx, *keytab,
     206             :                                            &kt_entry, &kt_cursor)) == 0) {
     207          30 :                         if (smb_krb5_kt_get_enctype_from_entry(&kt_entry) ==
     208             :                             CLEARTEXT_PRIV_ENCTYPE) {
     209           6 :                                 break;
     210             :                         }
     211          24 :                         smb_krb5_kt_free_entry(krbctx, &kt_entry);
     212          24 :                         ZERO_STRUCT(kt_entry);
     213             :                 }
     214             : 
     215        2955 :                 if (ret != 0 && ret != KRB5_KT_END && ret != ENOENT ) {
     216             :                         /* Error parsing keytab */
     217           0 :                         DEBUG(1, (__location__ ": Failed to parse memory "
     218             :                                   "keytab!\n"));
     219           0 :                         goto out;
     220             :                 }
     221             : 
     222        2955 :                 if (ret == 0) {
     223             :                         /* found private entry,
     224             :                          * check if keytab is up to date */
     225             : 
     226          12 :                         if ((ct->length == KRB5_KEY_LENGTH(KRB5_KT_KEY(&kt_entry))) &&
     227          12 :                             (memcmp(KRB5_KEY_DATA(KRB5_KT_KEY(&kt_entry)),
     228           6 :                                                 ct->data, ct->length) == 0)) {
     229             :                                 /* keytab is already up to date, return */
     230           6 :                                 smb_krb5_kt_free_entry(krbctx, &kt_entry);
     231           6 :                                 goto out;
     232             :                         }
     233             : 
     234           0 :                         smb_krb5_kt_free_entry(krbctx, &kt_entry);
     235           0 :                         ZERO_STRUCT(kt_entry);
     236             : 
     237             : 
     238             :                         /* flush keytab, we need to regen it */
     239           0 :                         ret = flush_keytab(krbctx, *keytab);
     240           0 :                         if (ret) {
     241           0 :                                 DEBUG(1, (__location__ ": Failed to flush "
     242             :                                           "memory keytab!\n"));
     243           0 :                                 goto out;
     244             :                         }
     245             :                 }
     246             :         }
     247             : 
     248        2949 :         if (!all_zero((uint8_t *)&kt_cursor, sizeof(kt_cursor)) && *keytab) {
     249           0 :                 krb5_kt_end_seq_get(krbctx, *keytab, &kt_cursor);
     250             :         }
     251             : 
     252             :         /* keytab is not up to date, fill it up */
     253             : 
     254        2949 :         ret = smb_krb5_make_principal(krbctx, &princ, realm,
     255        2949 :                                       info->account_name, NULL);
     256        2949 :         if (ret) {
     257           0 :                 DEBUG(1, (__location__ ": Failed to get host principal!\n"));
     258           0 :                 goto out;
     259             :         }
     260             : 
     261        2949 :         ret = fill_keytab_from_password(krbctx, *keytab,
     262             :                                         princ, kvno,
     263        2949 :                                         info->password);
     264        2949 :         if (ret) {
     265           0 :                 DBG_WARNING("fill_keytab_from_password() failed for "
     266             :                             "info->password.\n.");
     267           0 :                 goto out;
     268             :         }
     269             : 
     270        2949 :         if (info->old_password != NULL) {
     271        1303 :                 ret = fill_keytab_from_password(krbctx, *keytab,
     272             :                                                 princ, kvno - 1,
     273        1303 :                                                 info->old_password);
     274        1303 :                 if (ret) {
     275           0 :                         DBG_WARNING("fill_keytab_from_password() failed for "
     276             :                                     "info->old_password.\n.");
     277           0 :                         goto out;
     278             :                 }
     279             :         }
     280             : 
     281        2949 :         if (info->older_password != NULL) {
     282        1072 :                 ret = fill_keytab_from_password(krbctx, *keytab,
     283             :                                                 princ, kvno - 2,
     284        1072 :                                                 info->older_password);
     285        1072 :                 if (ret) {
     286           0 :                         DBG_WARNING("fill_keytab_from_password() failed for "
     287             :                                     "info->older_password.\n.");
     288           0 :                         goto out;
     289             :                 }
     290             :         }
     291             : 
     292        2949 :         if (info->next_change != NULL) {
     293           0 :                 ret = fill_keytab_from_password(krbctx, *keytab,
     294             :                                                 princ, kvno - 3,
     295           0 :                                                 info->next_change->password);
     296           0 :                 if (ret) {
     297           0 :                         DBG_WARNING("fill_keytab_from_password() failed for "
     298             :                                     "info->next_change->password.\n.");
     299           0 :                         goto out;
     300             :                 }
     301             :         }
     302             : 
     303             :         /* add our private enctype + cleartext password so that we can
     304             :          * update the keytab if secrets change later on */
     305        2949 :         ZERO_STRUCT(kt_entry);
     306        2949 :         kt_entry.principal = princ;
     307        2949 :         kt_entry.vno = 0;
     308             : 
     309        2949 :         KRB5_KEY_TYPE(KRB5_KT_KEY(&kt_entry)) = CLEARTEXT_PRIV_ENCTYPE;
     310        2949 :         KRB5_KEY_LENGTH(KRB5_KT_KEY(&kt_entry)) = ct->length;
     311        2949 :         KRB5_KEY_DATA(KRB5_KT_KEY(&kt_entry)) = ct->data;
     312             : 
     313        2949 :         ret = krb5_kt_add_entry(krbctx, *keytab, &kt_entry);
     314        2949 :         if (ret) {
     315           0 :                 DEBUG(1, (__location__ ": Failed to add entry to "
     316             :                           "keytab for private enctype (%d) (error: %s)\n",
     317             :                            CLEARTEXT_PRIV_ENCTYPE, error_message(ret)));
     318           0 :                 goto out;
     319             :         }
     320             : 
     321        2949 :         ret = 0;
     322             : 
     323        2955 : out:
     324        2955 :         if (!all_zero((uint8_t *)&kt_cursor, sizeof(kt_cursor)) && *keytab) {
     325           6 :                 krb5_kt_end_seq_get(krbctx, *keytab, &kt_cursor);
     326             :         }
     327             : 
     328        2955 :         if (princ) {
     329        2949 :                 krb5_free_principal(krbctx, princ);
     330             :         }
     331             : 
     332        2955 :         TALLOC_FREE(frame);
     333        2955 :         return ret;
     334             : }
     335             : 
     336           0 : static krb5_error_code fill_mem_keytab_from_system_keytab(krb5_context krbctx,
     337             :                                                           krb5_keytab *mkeytab)
     338             : {
     339           0 :         krb5_error_code ret = 0;
     340           0 :         krb5_keytab keytab = NULL;
     341           0 :         krb5_kt_cursor kt_cursor = { 0, };
     342           0 :         krb5_keytab_entry kt_entry = { 0, };
     343           0 :         char *valid_princ_formats[7] = { NULL, NULL, NULL,
     344             :                                          NULL, NULL, NULL, NULL };
     345           0 :         char *entry_princ_s = NULL;
     346             :         fstring my_name, my_fqdn;
     347             :         unsigned i;
     348             :         int err;
     349             : 
     350             :         /* Generate the list of principal names which we expect
     351             :          * clients might want to use for authenticating to the file
     352             :          * service.  We allow name$,{host,cifs}/{name,fqdn,name.REALM}. */
     353             : 
     354           0 :         fstrcpy(my_name, lp_netbios_name());
     355             : 
     356           0 :         my_fqdn[0] = '\0';
     357           0 :         name_to_fqdn(my_fqdn, lp_netbios_name());
     358             : 
     359           0 :         err = asprintf(&valid_princ_formats[0],
     360             :                         "%s$@%s", my_name, lp_realm());
     361           0 :         if (err == -1) {
     362           0 :                 ret = ENOMEM;
     363           0 :                 goto out;
     364             :         }
     365           0 :         err = asprintf(&valid_princ_formats[1],
     366             :                         "host/%s@%s", my_name, lp_realm());
     367           0 :         if (err == -1) {
     368           0 :                 ret = ENOMEM;
     369           0 :                 goto out;
     370             :         }
     371           0 :         err = asprintf(&valid_princ_formats[2],
     372             :                         "host/%s@%s", my_fqdn, lp_realm());
     373           0 :         if (err == -1) {
     374           0 :                 ret = ENOMEM;
     375           0 :                 goto out;
     376             :         }
     377           0 :         err = asprintf(&valid_princ_formats[3],
     378             :                         "host/%s.%s@%s", my_name, lp_realm(), lp_realm());
     379           0 :         if (err == -1) {
     380           0 :                 ret = ENOMEM;
     381           0 :                 goto out;
     382             :         }
     383           0 :         err = asprintf(&valid_princ_formats[4],
     384             :                         "cifs/%s@%s", my_name, lp_realm());
     385           0 :         if (err == -1) {
     386           0 :                 ret = ENOMEM;
     387           0 :                 goto out;
     388             :         }
     389           0 :         err = asprintf(&valid_princ_formats[5],
     390             :                         "cifs/%s@%s", my_fqdn, lp_realm());
     391           0 :         if (err == -1) {
     392           0 :                 ret = ENOMEM;
     393           0 :                 goto out;
     394             :         }
     395           0 :         err = asprintf(&valid_princ_formats[6],
     396             :                         "cifs/%s.%s@%s", my_name, lp_realm(), lp_realm());
     397           0 :         if (err == -1) {
     398           0 :                 ret = ENOMEM;
     399           0 :                 goto out;
     400             :         }
     401             : 
     402           0 :         ret = smb_krb5_kt_open_relative(krbctx, NULL, false, &keytab);
     403           0 :         if (ret) {
     404           0 :                 DEBUG(1, ("smb_krb5_kt_open failed (%s)\n",
     405             :                           error_message(ret)));
     406           0 :                 goto out;
     407             :         }
     408             : 
     409             :         /*
     410             :          * Iterate through the keytab.  For each key, if the principal
     411             :          * name case-insensitively matches one of the allowed formats,
     412             :          * copy it to the memory keytab.
     413             :          */
     414             : 
     415           0 :         ret = krb5_kt_start_seq_get(krbctx, keytab, &kt_cursor);
     416           0 :         if (ret) {
     417           0 :                 DEBUG(1, (__location__ ": krb5_kt_start_seq_get failed (%s)\n",
     418             :                           error_message(ret)));
     419             :                 /*
     420             :                  * krb5_kt_start_seq_get() may leaves bogus data
     421             :                  * in kt_cursor. And we want to use the all_zero()
     422             :                  * logic below.
     423             :                  *
     424             :                  * See bug #10490
     425             :                  */
     426           0 :                 ZERO_STRUCT(kt_cursor);
     427           0 :                 goto out;
     428             :         }
     429             : 
     430           0 :         while ((krb5_kt_next_entry(krbctx, keytab,
     431             :                                    &kt_entry, &kt_cursor) == 0)) {
     432           0 :                 ret = smb_krb5_unparse_name(talloc_tos(), krbctx,
     433           0 :                                             kt_entry.principal,
     434             :                                             &entry_princ_s);
     435           0 :                 if (ret) {
     436           0 :                         DEBUG(1, (__location__ ": smb_krb5_unparse_name "
     437             :                                   "failed (%s)\n", error_message(ret)));
     438           0 :                         goto out;
     439             :                 }
     440             : 
     441           0 :                 for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) {
     442             : 
     443           0 :                         if (!strequal(entry_princ_s, valid_princ_formats[i])) {
     444           0 :                                 continue;
     445             :                         }
     446             : 
     447           0 :                         ret = krb5_kt_add_entry(krbctx, *mkeytab, &kt_entry);
     448           0 :                         if (ret) {
     449           0 :                                 DEBUG(1, (__location__ ": smb_krb5_unparse_name "
     450             :                                           "failed (%s)\n", error_message(ret)));
     451           0 :                                 goto out;
     452             :                         }
     453             :                 }
     454             : 
     455             :                 /* Free the name we parsed. */
     456           0 :                 TALLOC_FREE(entry_princ_s);
     457             : 
     458             :                 /* Free the entry we just read. */
     459           0 :                 smb_krb5_kt_free_entry(krbctx, &kt_entry);
     460           0 :                 ZERO_STRUCT(kt_entry);
     461             :         }
     462           0 :         krb5_kt_end_seq_get(krbctx, keytab, &kt_cursor);
     463             : 
     464           0 :         ZERO_STRUCT(kt_cursor);
     465             : 
     466           0 : out:
     467             : 
     468           0 :         for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) {
     469           0 :                 SAFE_FREE(valid_princ_formats[i]);
     470             :         }
     471             : 
     472           0 :         TALLOC_FREE(entry_princ_s);
     473             : 
     474           0 :         if (!all_zero((uint8_t *)&kt_entry, sizeof(kt_entry))) {
     475           0 :                 smb_krb5_kt_free_entry(krbctx, &kt_entry);
     476             :         }
     477             : 
     478           0 :         if (!all_zero((uint8_t *)&kt_cursor, sizeof(kt_cursor)) && keytab) {
     479           0 :                 krb5_kt_end_seq_get(krbctx, keytab, &kt_cursor);
     480             :         }
     481             : 
     482           0 :         if (keytab) {
     483           0 :                 krb5_kt_close(krbctx, keytab);
     484             :         }
     485             : 
     486           0 :         return ret;
     487             : }
     488             : 
     489           6 : static krb5_error_code fill_mem_keytab_from_dedicated_keytab(krb5_context krbctx,
     490             :                                                              krb5_keytab *mkeytab)
     491             : {
     492           6 :         krb5_error_code ret = 0;
     493           6 :         krb5_keytab keytab = NULL;
     494             :         krb5_kt_cursor kt_cursor;
     495             :         krb5_keytab_entry kt_entry;
     496             : 
     497           6 :         ret = smb_krb5_kt_open(krbctx, lp_dedicated_keytab_file(),
     498             :                                    false, &keytab);
     499           6 :         if (ret) {
     500           0 :                 DEBUG(1, ("smb_krb5_kt_open of %s failed (%s)\n",
     501             :                           lp_dedicated_keytab_file(),
     502             :                           error_message(ret)));
     503           0 :                 return ret;
     504             :         }
     505             : 
     506             :         /*
     507             :          * Copy the dedicated keyab to our in-memory keytab.
     508             :          */
     509             : 
     510           6 :         ret = krb5_kt_start_seq_get(krbctx, keytab, &kt_cursor);
     511           6 :         if (ret) {
     512           6 :                 DEBUG(1, (__location__ ": krb5_kt_start_seq_get on %s "
     513             :                           "failed (%s)\n",
     514             :                           lp_dedicated_keytab_file(),
     515             :                           error_message(ret)));
     516           6 :                 goto out;
     517             :         }
     518             : 
     519           0 :         while ((krb5_kt_next_entry(krbctx, keytab,
     520             :                                    &kt_entry, &kt_cursor) == 0)) {
     521             : 
     522           0 :                 ret = krb5_kt_add_entry(krbctx, *mkeytab, &kt_entry);
     523             : 
     524             :                 /* Free the entry we just read. */
     525           0 :                 smb_krb5_kt_free_entry(krbctx, &kt_entry);
     526             : 
     527           0 :                 if (ret) {
     528           0 :                         DEBUG(1, (__location__ ": smb_krb5_unparse_name "
     529             :                                   "failed (%s)\n", error_message(ret)));
     530           0 :                         break;
     531             :                 }
     532             :         }
     533           0 :         krb5_kt_end_seq_get(krbctx, keytab, &kt_cursor);
     534             : 
     535           6 : out:
     536             :         
     537           6 :         krb5_kt_close(krbctx, keytab);
     538             : 
     539           6 :         return ret;
     540             : }
     541             : 
     542        2965 : krb5_error_code gse_krb5_get_server_keytab(krb5_context krbctx,
     543             :                                            krb5_keytab *keytab)
     544             : {
     545        2965 :         krb5_error_code ret = 0;
     546        2965 :         krb5_error_code ret1 = 0;
     547        2965 :         krb5_error_code ret2 = 0;
     548             : 
     549        2965 :         *keytab = NULL;
     550             : 
     551             :         /* create memory keytab */
     552        2965 :         ret = krb5_kt_resolve(krbctx, SRV_MEM_KEYTAB_NAME, keytab);
     553        2965 :         if (ret) {
     554           0 :                 DEBUG(1, (__location__ ": Failed to get memory "
     555             :                           "keytab!\n"));
     556           0 :                 return ret;
     557             :         }
     558             : 
     559        2965 :         switch (lp_kerberos_method()) {
     560        2959 :         default:
     561             :         case KERBEROS_VERIFY_SECRETS:
     562        2959 :                 ret = fill_mem_keytab_from_secrets(krbctx, keytab);
     563        2959 :                 break;
     564           0 :         case KERBEROS_VERIFY_SYSTEM_KEYTAB:
     565           0 :                 ret = fill_mem_keytab_from_system_keytab(krbctx, keytab);
     566           0 :                 break;
     567           6 :         case KERBEROS_VERIFY_DEDICATED_KEYTAB:
     568             :                 /* just use whatever keytab is configured */
     569           6 :                 ret = fill_mem_keytab_from_dedicated_keytab(krbctx, keytab);
     570           6 :                 break;
     571           0 :         case KERBEROS_VERIFY_SECRETS_AND_KEYTAB:
     572           0 :                 ret1 = fill_mem_keytab_from_secrets(krbctx, keytab);
     573           0 :                 if (ret1) {
     574           0 :                         DEBUG(3, (__location__ ": Warning! Unable to set mem "
     575             :                                   "keytab from secrets!\n"));
     576             :                 }
     577             :                 /* Now append system keytab keys too */
     578           0 :                 ret2 = fill_mem_keytab_from_system_keytab(krbctx, keytab);
     579           0 :                 if (ret2) {
     580           0 :                         DEBUG(3, (__location__ ": Warning! Unable to set mem "
     581             :                                   "keytab from system keytab!\n"));
     582             :                 }
     583           0 :                 if (ret1 == 0 || ret2 == 0) {
     584           0 :                         ret = 0;
     585             :                 } else {
     586           0 :                         ret = ret1;
     587             :                 }
     588           0 :                 break;
     589             :         }
     590             : 
     591        2965 :         if (ret) {
     592          10 :                 krb5_kt_close(krbctx, *keytab);
     593          10 :                 *keytab = NULL;
     594          10 :                 DEBUG(1,("%s: Error! Unable to set mem keytab - %d\n",
     595             :                          __location__, ret));
     596             :         }
     597             : 
     598        2965 :         return ret;
     599             : }
     600             : 
     601             : #endif /* HAVE_KRB5 */

Generated by: LCOV version 1.13