LCOV - code coverage report
Current view: top level - providers/krb5 - krb5_keytab.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 53 108 49.1 %
Date: 2015-10-19 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     Kerberos 5 Backend Module -- keytab related utilities
       5             : 
       6             :     Authors:
       7             :         Sumit Bose <sbose@redhat.com>
       8             : 
       9             :     Copyright (C) 2014 Red Hat
      10             : 
      11             :     This program is free software; you can redistribute it and/or modify
      12             :     it under the terms of the GNU General Public License as published by
      13             :     the Free Software Foundation; either version 3 of the License, or
      14             :     (at your option) any later version.
      15             : 
      16             :     This program is distributed in the hope that it will be useful,
      17             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :     GNU General Public License for more details.
      20             : 
      21             :     You should have received a copy of the GNU General Public License
      22             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23             : */
      24             : 
      25             : #include "util/util.h"
      26             : #include "util/sss_krb5.h"
      27             : #include "providers/krb5/krb5_common.h"
      28             : 
      29           4 : static krb5_error_code do_keytab_copy(krb5_context kctx, krb5_keytab s_keytab,
      30             :                                       krb5_keytab d_keytab)
      31             : {
      32             :     krb5_error_code kerr;
      33             :     krb5_error_code kt_err;
      34             :     krb5_kt_cursor cursor;
      35             :     krb5_keytab_entry entry;
      36             : 
      37           4 :     memset(&cursor, 0, sizeof(cursor));
      38           4 :     kerr = krb5_kt_start_seq_get(kctx, s_keytab, &cursor);
      39           4 :     if (kerr != 0) {
      40           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "error reading keytab.\n");
      41           0 :         return kerr;
      42             :     }
      43             : 
      44           4 :     memset(&entry, 0, sizeof(entry));
      45          24 :     while ((kt_err = krb5_kt_next_entry(kctx, s_keytab, &entry,
      46             :                                         &cursor)) == 0) {
      47          16 :         kerr = krb5_kt_add_entry(kctx, d_keytab, &entry);
      48          16 :         if (kerr != 0) {
      49           0 :             DEBUG(SSSDBG_OP_FAILURE, "krb5_kt_add_entry failed.\n");
      50           0 :             kt_err = krb5_kt_end_seq_get(kctx, s_keytab, &cursor);
      51           0 :             if (kt_err != 0) {
      52           0 :                 DEBUG(SSSDBG_TRACE_ALL,
      53             :                       "krb5_kt_end_seq_get failed with [%d], ignored.\n",
      54             :                       kt_err);
      55             :             }
      56           0 :             return kerr;
      57             :         }
      58             : 
      59          16 :         kerr = sss_krb5_free_keytab_entry_contents(kctx, &entry);
      60          16 :         if (kerr != 0) {
      61           0 :             DEBUG(SSSDBG_MINOR_FAILURE, "Failed to free keytab entry.\n");
      62           0 :             kt_err = krb5_kt_end_seq_get(kctx, s_keytab, &cursor);
      63           0 :             if (kt_err != 0) {
      64           0 :                 DEBUG(SSSDBG_TRACE_ALL,
      65             :                       "krb5_kt_end_seq_get failed with [%d], ignored.\n",
      66             :                       kt_err);
      67             :             }
      68           0 :             return kerr;
      69             :         }
      70          16 :         memset(&entry, 0, sizeof(entry));
      71             :     }
      72             : 
      73           4 :     kerr = krb5_kt_end_seq_get(kctx, s_keytab, &cursor);
      74           4 :     if (kerr != 0) {
      75           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "krb5_kt_end_seq_get failed.\n");
      76           0 :         return kerr;
      77             :     }
      78             : 
      79             :     /* check if we got any errors from krb5_kt_next_entry */
      80           4 :     if (kt_err != 0 && kt_err != KRB5_KT_END) {
      81           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "error reading keytab.\n");
      82           0 :         return kt_err;
      83             :     }
      84             : 
      85           4 :     return 0;
      86             : }
      87             : 
      88           2 : krb5_error_code copy_keytab_into_memory(TALLOC_CTX *mem_ctx, krb5_context kctx,
      89             :                                         const char *inp_keytab_file,
      90             :                                         char **_mem_name,
      91             :                                         krb5_keytab *_mem_keytab)
      92             : {
      93             :     krb5_error_code kerr;
      94           2 :     krb5_keytab keytab = NULL;
      95           2 :     krb5_keytab mem_keytab = NULL;
      96           2 :     krb5_keytab tmp_mem_keytab = NULL;
      97             :     char keytab_name[MAX_KEYTAB_NAME_LEN];
      98             :     char *sep;
      99           2 :     char *mem_name = NULL;
     100           2 :     char *tmp_mem_name = NULL;
     101             :     const char *keytab_file;
     102             :     char default_keytab_name[MAX_KEYTAB_NAME_LEN];
     103             : 
     104           2 :     keytab_file = inp_keytab_file;
     105           2 :     if (keytab_file == NULL) {
     106           0 :         kerr = krb5_kt_default_name(kctx, default_keytab_name,
     107             :                                     sizeof(default_keytab_name));
     108           0 :         if (kerr != 0) {
     109           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "krb5_kt_default_name failed.\n");
     110           0 :             return kerr;
     111             :         }
     112             : 
     113           0 :         keytab_file = default_keytab_name;
     114             :     }
     115             : 
     116           2 :     kerr = krb5_kt_resolve(kctx, keytab_file, &keytab);
     117           2 :     if (kerr != 0) {
     118           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "error resolving keytab [%s].\n",
     119             :                                     keytab_file);
     120           0 :         return kerr;
     121             :     }
     122             : 
     123           2 :     kerr = sss_krb5_kt_have_content(kctx, keytab);
     124           2 :     if (kerr != 0) {
     125           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "keytab [%s] has not entries.\n",
     126             :                                     keytab_file);
     127           0 :         goto done;
     128             :     }
     129             : 
     130           2 :     kerr = krb5_kt_get_name(kctx, keytab, keytab_name, sizeof(keytab_name));
     131           2 :     if (kerr != 0) {
     132           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read name for keytab [%s].\n",
     133             :                                     keytab_file);
     134           0 :         goto done;
     135             :     }
     136             : 
     137           2 :     sep = strchr(keytab_name, ':');
     138           2 :     if (sep == NULL || sep[1] == '\0') {
     139           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     140             :               "Keytab name [%s] does not have delimiter[:] .\n", keytab_name);
     141           0 :         kerr = KRB5KRB_ERR_GENERIC;
     142           0 :         goto done;
     143             :     }
     144             : 
     145           2 :     if (strncmp(keytab_name, "MEMORY:", sizeof("MEMORY:") -1) == 0) {
     146           0 :         DEBUG(SSSDBG_TRACE_FUNC, "Keytab [%s] is already memory keytab.\n",
     147             :                                  keytab_name);
     148           0 :         *_mem_name = talloc_strdup(mem_ctx, keytab_name);
     149           0 :         if(*_mem_name == NULL) {
     150           0 :             DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
     151           0 :             kerr = KRB5KRB_ERR_GENERIC;
     152           0 :             goto done;
     153             :         }
     154           0 :         kerr = 0;
     155           0 :         goto done;
     156             :     }
     157             : 
     158           2 :     mem_name = talloc_asprintf(mem_ctx, "MEMORY:%s", sep + 1);
     159           2 :     if (mem_name == NULL) {
     160           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
     161           0 :         kerr = KRB5KRB_ERR_GENERIC;
     162           0 :         goto done;
     163             :     }
     164             : 
     165           2 :     tmp_mem_name = talloc_asprintf(mem_ctx, "MEMORY:%s.tmp", sep + 1);
     166           2 :     if (tmp_mem_name == NULL) {
     167           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
     168           0 :         kerr = KRB5KRB_ERR_GENERIC;
     169           0 :         goto done;
     170             :     }
     171             : 
     172           2 :     kerr = krb5_kt_resolve(kctx, mem_name, &mem_keytab);
     173           2 :     if (kerr != 0) {
     174           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "error resolving keytab [%s].\n",
     175             :                                     mem_name);
     176           0 :         goto done;
     177             :     }
     178             : 
     179           2 :     kerr = krb5_kt_resolve(kctx, tmp_mem_name, &tmp_mem_keytab);
     180           2 :     if (kerr != 0) {
     181           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "error resolving keytab [%s].\n",
     182             :                                     tmp_mem_name);
     183           0 :         goto done;
     184             :     }
     185             : 
     186           2 :     kerr = do_keytab_copy(kctx, keytab, tmp_mem_keytab);
     187           2 :     if (kerr != 0) {
     188           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy keytab [%s] into [%s].\n",
     189             :                                     keytab_file, tmp_mem_name);
     190           0 :         goto done;
     191             :     }
     192             : 
     193             :     /* krb5_kt_add_entry() adds new entries into MEMORY keytabs at the
     194             :      * beginning and not at the end as for FILE keytabs. Since we want to keep
     195             :      * the processing order we have to copy the MEMORY keytab again to retain
     196             :      * the order from the FILE keytab. */
     197             : 
     198           2 :     kerr = do_keytab_copy(kctx, tmp_mem_keytab, mem_keytab);
     199           2 :     if (kerr != 0) {
     200           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy keytab [%s] into [%s].\n",
     201             :                                     tmp_mem_name, mem_name);
     202           0 :         goto done;
     203             :     }
     204             : 
     205           2 :     *_mem_name = mem_name;
     206           2 :     if (_mem_keytab != NULL) {
     207           2 :         *_mem_keytab = mem_keytab;
     208             :     }
     209             : 
     210           2 :     kerr = 0;
     211             : done:
     212             : 
     213           2 :     talloc_free(tmp_mem_name);
     214             : 
     215           2 :     if (kerr != 0) {
     216           0 :         talloc_free(mem_name);
     217             :     }
     218             : 
     219           2 :     if (tmp_mem_keytab != NULL && krb5_kt_close(kctx, tmp_mem_keytab) != 0) {
     220           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "krb5_kt_close failed.\n");
     221             :     }
     222             : 
     223           2 :     if (keytab != NULL && krb5_kt_close(kctx, keytab) != 0) {
     224           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "krb5_kt_close failed.\n");
     225             :     }
     226             : 
     227           2 :     return kerr;
     228             : }

Generated by: LCOV version 1.10