LCOV - code coverage report
Current view: top level - source3/librpc/crypto - gse_krb5.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 123 313 39.3 %
Date: 2024-05-31 13:13:24 Functions: 4 6 66.7 %

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

Generated by: LCOV version 1.14