LCOV - code coverage report
Current view: top level - source3/librpc/crypto - gse_krb5.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 123 309 39.8 %
Date: 2024-04-21 15:09:00 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        9274 : 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        9274 :         ret = smb_krb5_get_allowed_etypes(krbctx, &enctypes);
     106        9274 :         if (ret) {
     107           0 :                 DEBUG(1, (__location__
     108             :                           ": Can't determine permitted enctypes!\n"));
     109           0 :                 return ret;
     110             :         }
     111             : 
     112       37096 :         for (i = 0; i < pw->num_keys; i++) {
     113             :                 krb5_keytab_entry kt_entry;
     114       27822 :                 krb5_keyblock *key = NULL;
     115             :                 unsigned int ei;
     116       27822 :                 bool found_etype = false;
     117             : 
     118       78944 :                 for (ei=0; enctypes[ei] != 0; ei++) {
     119       78944 :                         if ((uint32_t)enctypes[ei] != pw->keys[i].keytype) {
     120       51122 :                                 continue;
     121             :                         }
     122             : 
     123       27822 :                         found_etype = true;
     124       27822 :                         break;
     125             :                 }
     126             : 
     127       27822 :                 if (!found_etype) {
     128           0 :                         continue;
     129             :                 }
     130             : 
     131       27822 :                 ZERO_STRUCT(kt_entry);
     132       27822 :                 kt_entry.principal = princ;
     133       27822 :                 kt_entry.vno = vno;
     134             : 
     135       27822 :                 key = KRB5_KT_KEY(&kt_entry);
     136       27822 :                 KRB5_KEY_TYPE(key) = pw->keys[i].keytype;
     137       27822 :                 KRB5_KEY_DATA(key) = pw->keys[i].value.data;
     138       27822 :                 KRB5_KEY_LENGTH(key) = pw->keys[i].value.length;
     139             : 
     140       27822 :                 ret = krb5_kt_add_entry(krbctx, keytab, &kt_entry);
     141       27822 :                 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        9274 :         ret = 0;
     151             : 
     152        9274 : out:
     153        9274 :         krb5_free_enctypes(krbctx, enctypes);
     154        9274 :         return ret;
     155             : }
     156             : 
     157             : #define SRV_MEM_KEYTAB_NAME "MEMORY:cifs_srv_keytab"
     158             : #define CLEARTEXT_PRIV_ENCTYPE -99
     159             : 
     160        4393 : static krb5_error_code fill_mem_keytab_from_secrets(krb5_context krbctx,
     161             :                                                     krb5_keytab *keytab)
     162             : {
     163        4393 :         TALLOC_CTX *frame = talloc_stackframe();
     164           0 :         krb5_error_code ret, ret2;
     165        4393 :         const char *domain = lp_workgroup();
     166        4393 :         struct secrets_domain_info1 *info = NULL;
     167        4393 :         const char *realm = NULL;
     168        4393 :         const DATA_BLOB *ct = NULL;
     169           0 :         krb5_kt_cursor kt_cursor;
     170           0 :         krb5_keytab_entry kt_entry;
     171        4393 :         krb5_principal princ = NULL;
     172        4393 :         krb5_kvno kvno = 0; /* FIXME: fetch current vno from KDC ? */
     173           0 :         NTSTATUS status;
     174             : 
     175        4393 :         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        4393 :         status = secrets_fetch_or_upgrade_domain_info(domain,
     182             :                                                       frame,
     183             :                                                       &info);
     184        4393 :         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        4389 :         ct = &info->password->cleartext_blob;
     191             : 
     192        4389 :         if (info->domain_info.dns_domain.string != NULL) {
     193        4389 :                 realm = strupper_talloc(frame,
     194        4389 :                                 info->domain_info.dns_domain.string);
     195        4389 :                 if (realm == NULL) {
     196           0 :                         TALLOC_FREE(frame);
     197           0 :                         return ENOMEM;
     198             :                 }
     199             :         }
     200             : 
     201        4389 :         ZERO_STRUCT(kt_entry);
     202        4389 :         ZERO_STRUCT(kt_cursor);
     203             : 
     204             :         /* check if the keytab already has any entry */
     205        4389 :         ret = krb5_kt_start_seq_get(krbctx, *keytab, &kt_cursor);
     206        4389 :         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        4485 :         while ((ret = krb5_kt_next_entry(krbctx, *keytab,
     214        4485 :                                    &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        4389 :         ret2 = krb5_kt_end_seq_get(krbctx, *keytab, &kt_cursor);
     224        4389 :         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        4389 :         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        4389 :         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        4367 :         ret = smb_krb5_make_principal(krbctx, &princ, realm,
     266        4367 :                                       info->account_name, NULL);
     267        4367 :         if (ret) {
     268           0 :                 DEBUG(1, (__location__ ": Failed to get host principal!\n"));
     269           0 :                 goto out;
     270             :         }
     271             : 
     272        4367 :         ret = fill_keytab_from_password(krbctx, *keytab,
     273             :                                         princ, kvno,
     274        4367 :                                         info->password);
     275        4367 :         if (ret) {
     276           0 :                 DBG_WARNING("fill_keytab_from_password() failed for "
     277             :                             "info->password.\n.");
     278           0 :                 goto out;
     279             :         }
     280             : 
     281        4367 :         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        4367 :         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        4367 :         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        4367 :         ZERO_STRUCT(kt_entry);
     317        4367 :         kt_entry.principal = princ;
     318        4367 :         kt_entry.vno = 0;
     319             : 
     320        4367 :         KRB5_KEY_TYPE(KRB5_KT_KEY(&kt_entry)) = CLEARTEXT_PRIV_ENCTYPE;
     321        4367 :         KRB5_KEY_LENGTH(KRB5_KT_KEY(&kt_entry)) = ct->length;
     322        4367 :         KRB5_KEY_DATA(KRB5_KT_KEY(&kt_entry)) = ct->data;
     323             : 
     324        4367 :         ret = krb5_kt_add_entry(krbctx, *keytab, &kt_entry);
     325        4367 :         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        4367 :         ret = 0;
     333             : 
     334        4389 : out:
     335             : 
     336        4389 :         if (princ) {
     337        4367 :                 krb5_free_principal(krbctx, princ);
     338             :         }
     339             : 
     340        4389 :         TALLOC_FREE(frame);
     341        4389 :         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             : 
     358             :         /* Generate the list of principal names which we expect
     359             :          * clients might want to use for authenticating to the file
     360             :          * service.  We allow name$,{host,cifs}/{name,fqdn,name.REALM}. */
     361             : 
     362           0 :         fstrcpy(my_name, lp_netbios_name());
     363             : 
     364           0 :         my_fqdn[0] = '\0';
     365           0 :         name_to_fqdn(my_fqdn, lp_netbios_name());
     366             : 
     367           0 :         err = asprintf(&valid_princ_formats[0],
     368             :                         "%s$@%s", my_name, lp_realm());
     369           0 :         if (err == -1) {
     370           0 :                 ret = ENOMEM;
     371           0 :                 goto out;
     372             :         }
     373           0 :         err = asprintf(&valid_princ_formats[1],
     374             :                         "host/%s@%s", my_name, lp_realm());
     375           0 :         if (err == -1) {
     376           0 :                 ret = ENOMEM;
     377           0 :                 goto out;
     378             :         }
     379           0 :         err = asprintf(&valid_princ_formats[2],
     380             :                         "host/%s@%s", my_fqdn, lp_realm());
     381           0 :         if (err == -1) {
     382           0 :                 ret = ENOMEM;
     383           0 :                 goto out;
     384             :         }
     385           0 :         err = asprintf(&valid_princ_formats[3],
     386             :                         "host/%s.%s@%s", my_name, lp_realm(), lp_realm());
     387           0 :         if (err == -1) {
     388           0 :                 ret = ENOMEM;
     389           0 :                 goto out;
     390             :         }
     391           0 :         err = asprintf(&valid_princ_formats[4],
     392             :                         "cifs/%s@%s", my_name, lp_realm());
     393           0 :         if (err == -1) {
     394           0 :                 ret = ENOMEM;
     395           0 :                 goto out;
     396             :         }
     397           0 :         err = asprintf(&valid_princ_formats[5],
     398             :                         "cifs/%s@%s", my_fqdn, lp_realm());
     399           0 :         if (err == -1) {
     400           0 :                 ret = ENOMEM;
     401           0 :                 goto out;
     402             :         }
     403           0 :         err = asprintf(&valid_princ_formats[6],
     404             :                         "cifs/%s.%s@%s", my_name, lp_realm(), lp_realm());
     405           0 :         if (err == -1) {
     406           0 :                 ret = ENOMEM;
     407           0 :                 goto out;
     408             :         }
     409             : 
     410           0 :         ret = smb_krb5_kt_open_relative(krbctx, NULL, false, &keytab);
     411           0 :         if (ret) {
     412           0 :                 DEBUG(1, ("smb_krb5_kt_open failed (%s)\n",
     413             :                           error_message(ret)));
     414           0 :                 goto out;
     415             :         }
     416             : 
     417             :         /*
     418             :          * Iterate through the keytab.  For each key, if the principal
     419             :          * name case-insensitively matches one of the allowed formats,
     420             :          * copy it to the memory keytab.
     421             :          */
     422             : 
     423           0 :         ret = krb5_kt_start_seq_get(krbctx, keytab, &kt_cursor);
     424           0 :         if (ret) {
     425           0 :                 DEBUG(1, (__location__ ": krb5_kt_start_seq_get failed (%s)\n",
     426             :                           error_message(ret)));
     427             :                 /*
     428             :                  * krb5_kt_start_seq_get() may leaves bogus data
     429             :                  * in kt_cursor. And we want to use the all_zero()
     430             :                  * logic below.
     431             :                  *
     432             :                  * See bug #10490
     433             :                  */
     434           0 :                 ZERO_STRUCT(kt_cursor);
     435           0 :                 goto out;
     436             :         }
     437             : 
     438           0 :         while ((krb5_kt_next_entry(krbctx, keytab,
     439           0 :                                    &kt_entry, &kt_cursor) == 0)) {
     440           0 :                 ret = smb_krb5_unparse_name(talloc_tos(), krbctx,
     441           0 :                                             kt_entry.principal,
     442             :                                             &entry_princ_s);
     443           0 :                 if (ret) {
     444           0 :                         DEBUG(1, (__location__ ": smb_krb5_unparse_name "
     445             :                                   "failed (%s)\n", error_message(ret)));
     446           0 :                         goto out;
     447             :                 }
     448             : 
     449           0 :                 for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) {
     450             : 
     451           0 :                         if (!strequal(entry_princ_s, valid_princ_formats[i])) {
     452           0 :                                 continue;
     453             :                         }
     454             : 
     455           0 :                         ret = krb5_kt_add_entry(krbctx, *mkeytab, &kt_entry);
     456           0 :                         if (ret) {
     457           0 :                                 DEBUG(1, (__location__ ": smb_krb5_unparse_name "
     458             :                                           "failed (%s)\n", error_message(ret)));
     459           0 :                                 goto out;
     460             :                         }
     461             :                 }
     462             : 
     463             :                 /* Free the name we parsed. */
     464           0 :                 TALLOC_FREE(entry_princ_s);
     465             : 
     466             :                 /* Free the entry we just read. */
     467           0 :                 smb_krb5_kt_free_entry(krbctx, &kt_entry);
     468           0 :                 ZERO_STRUCT(kt_entry);
     469             :         }
     470           0 :         krb5_kt_end_seq_get(krbctx, keytab, &kt_cursor);
     471             : 
     472           0 :         ZERO_STRUCT(kt_cursor);
     473             : 
     474           0 : out:
     475             : 
     476           0 :         for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) {
     477           0 :                 SAFE_FREE(valid_princ_formats[i]);
     478             :         }
     479             : 
     480           0 :         TALLOC_FREE(entry_princ_s);
     481             : 
     482           0 :         if (!all_zero((uint8_t *)&kt_entry, sizeof(kt_entry))) {
     483           0 :                 smb_krb5_kt_free_entry(krbctx, &kt_entry);
     484             :         }
     485             : 
     486           0 :         if (!all_zero((uint8_t *)&kt_cursor, sizeof(kt_cursor)) && keytab) {
     487           0 :                 krb5_kt_end_seq_get(krbctx, keytab, &kt_cursor);
     488             :         }
     489             : 
     490           0 :         if (keytab) {
     491           0 :                 krb5_kt_close(krbctx, keytab);
     492             :         }
     493             : 
     494           0 :         return ret;
     495             : }
     496             : 
     497           6 : static krb5_error_code fill_mem_keytab_from_dedicated_keytab(krb5_context krbctx,
     498             :                                                              krb5_keytab *mkeytab)
     499             : {
     500           6 :         krb5_error_code ret = 0;
     501           6 :         krb5_keytab keytab = NULL;
     502           0 :         krb5_kt_cursor kt_cursor;
     503           0 :         krb5_keytab_entry kt_entry;
     504             : 
     505           6 :         ret = smb_krb5_kt_open(krbctx, lp_dedicated_keytab_file(),
     506             :                                    false, &keytab);
     507           6 :         if (ret) {
     508           0 :                 DEBUG(1, ("smb_krb5_kt_open of %s failed (%s)\n",
     509             :                           lp_dedicated_keytab_file(),
     510             :                           error_message(ret)));
     511           0 :                 return ret;
     512             :         }
     513             : 
     514             :         /*
     515             :          * Copy the dedicated keyab to our in-memory keytab.
     516             :          */
     517             : 
     518           6 :         ret = krb5_kt_start_seq_get(krbctx, keytab, &kt_cursor);
     519           6 :         if (ret) {
     520           6 :                 DEBUG(1, (__location__ ": krb5_kt_start_seq_get on %s "
     521             :                           "failed (%s)\n",
     522             :                           lp_dedicated_keytab_file(),
     523             :                           error_message(ret)));
     524           6 :                 goto out;
     525             :         }
     526             : 
     527           0 :         while ((krb5_kt_next_entry(krbctx, keytab,
     528           0 :                                    &kt_entry, &kt_cursor) == 0)) {
     529             : 
     530           0 :                 ret = krb5_kt_add_entry(krbctx, *mkeytab, &kt_entry);
     531             : 
     532             :                 /* Free the entry we just read. */
     533           0 :                 smb_krb5_kt_free_entry(krbctx, &kt_entry);
     534             : 
     535           0 :                 if (ret) {
     536           0 :                         DEBUG(1, (__location__ ": smb_krb5_unparse_name "
     537             :                                   "failed (%s)\n", error_message(ret)));
     538           0 :                         break;
     539             :                 }
     540             :         }
     541           0 :         krb5_kt_end_seq_get(krbctx, keytab, &kt_cursor);
     542             : 
     543           6 : out:
     544             : 
     545           6 :         krb5_kt_close(krbctx, keytab);
     546             : 
     547           6 :         return ret;
     548             : }
     549             : 
     550        4399 : krb5_error_code gse_krb5_get_server_keytab(krb5_context krbctx,
     551             :                                            krb5_keytab *keytab)
     552             : {
     553        4399 :         krb5_error_code ret = 0;
     554        4399 :         krb5_error_code ret1 = 0;
     555        4399 :         krb5_error_code ret2 = 0;
     556             : 
     557        4399 :         *keytab = NULL;
     558             : 
     559             :         /* create memory keytab */
     560        4399 :         ret = krb5_kt_resolve(krbctx, SRV_MEM_KEYTAB_NAME, keytab);
     561        4399 :         if (ret) {
     562           0 :                 DEBUG(1, (__location__ ": Failed to get memory "
     563             :                           "keytab!\n"));
     564           0 :                 return ret;
     565             :         }
     566             : 
     567        4399 :         switch (lp_kerberos_method()) {
     568        4393 :         default:
     569             :         case KERBEROS_VERIFY_SECRETS:
     570        4393 :                 ret = fill_mem_keytab_from_secrets(krbctx, keytab);
     571        4393 :                 break;
     572           0 :         case KERBEROS_VERIFY_SYSTEM_KEYTAB:
     573           0 :                 ret = fill_mem_keytab_from_system_keytab(krbctx, keytab);
     574           0 :                 break;
     575           6 :         case KERBEROS_VERIFY_DEDICATED_KEYTAB:
     576             :                 /* just use whatever keytab is configured */
     577           6 :                 ret = fill_mem_keytab_from_dedicated_keytab(krbctx, keytab);
     578           6 :                 break;
     579           0 :         case KERBEROS_VERIFY_SECRETS_AND_KEYTAB:
     580           0 :                 ret1 = fill_mem_keytab_from_secrets(krbctx, keytab);
     581           0 :                 if (ret1) {
     582           0 :                         DEBUG(3, (__location__ ": Warning! Unable to set mem "
     583             :                                   "keytab from secrets!\n"));
     584             :                 }
     585             :                 /* Now append system keytab keys too */
     586           0 :                 ret2 = fill_mem_keytab_from_system_keytab(krbctx, keytab);
     587           0 :                 if (ret2) {
     588           0 :                         DEBUG(3, (__location__ ": Warning! Unable to set mem "
     589             :                                   "keytab from system keytab!\n"));
     590             :                 }
     591           0 :                 if (ret1 == 0 || ret2 == 0) {
     592           0 :                         ret = 0;
     593             :                 } else {
     594           0 :                         ret = ret1;
     595             :                 }
     596           0 :                 break;
     597             :         }
     598             : 
     599        4399 :         if (ret) {
     600          10 :                 krb5_kt_close(krbctx, *keytab);
     601          10 :                 *keytab = NULL;
     602          10 :                 DEBUG(1,("%s: Error! Unable to set mem keytab - %d\n",
     603             :                          __location__, ret));
     604             :         }
     605             : 
     606        4399 :         return ret;
     607             : }
     608             : 
     609             : #endif /* HAVE_KRB5 */

Generated by: LCOV version 1.14