LCOV - code coverage report
Current view: top level - source4/libnet - libnet_export_keytab.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 66 86 76.7 %
Date: 2021-09-23 10:06:22 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
       5             :    Copyright (C) Andreas Schneider <asn@samba.org> 2016
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "system/kerberos.h"
      23             : #include "auth/kerberos/kerberos.h"
      24             : #include "kdc/samba_kdc.h"
      25             : #include "libnet/libnet_export_keytab.h"
      26             : 
      27             : #include "kdc/db-glue.h"
      28             : #include "kdc/sdb.h"
      29             : 
      30          13 : static NTSTATUS sdb_kt_copy(TALLOC_CTX *mem_ctx,
      31             :                             krb5_context context,
      32             :                             struct samba_kdc_db_context *db_ctx,
      33             :                             const char *keytab_name,
      34             :                             const char *principal,
      35             :                             const char **error_string)
      36             : {
      37          13 :         struct sdb_entry_ex sentry = {
      38             :                 .free_entry = NULL,
      39             :         };
      40             :         krb5_keytab keytab;
      41          13 :         krb5_error_code code = 0;
      42          13 :         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
      43          13 :         char *entry_principal = NULL;
      44          13 :         bool copy_one_principal = (principal != NULL);
      45             :         krb5_data password;
      46             : 
      47          13 :         code = smb_krb5_kt_open_relative(context,
      48             :                                          keytab_name,
      49             :                                          true, /* write_access */
      50             :                                          &keytab);
      51          13 :         if (code != 0) {
      52           0 :                 *error_string = talloc_asprintf(mem_ctx,
      53             :                                                 "Failed to open keytab: %s",
      54             :                                                 keytab_name);
      55           0 :                 status = NT_STATUS_NO_SUCH_FILE;
      56           0 :                 goto done;
      57             :         }
      58             : 
      59          13 :         if (copy_one_principal) {
      60             :                 krb5_principal k5_princ;
      61             : 
      62          11 :                 code = smb_krb5_parse_name(context, principal, &k5_princ);
      63          11 :                 if (code != 0) {
      64           0 :                         *error_string = smb_get_krb5_error_message(context,
      65             :                                                                    code,
      66             :                                                                    mem_ctx);
      67           0 :                         status = NT_STATUS_UNSUCCESSFUL;
      68           0 :                         goto done;
      69             :                 }
      70             : 
      71          11 :                 code = samba_kdc_fetch(context, db_ctx, k5_princ,
      72             :                                        SDB_F_GET_ANY, 0, &sentry);
      73             : 
      74          11 :                 krb5_free_principal(context, k5_princ);
      75             :         } else {
      76           2 :                 code = samba_kdc_firstkey(context, db_ctx, &sentry);
      77             :         }
      78             : 
      79          45 :         for (; code == 0; code = samba_kdc_nextkey(context, db_ctx, &sentry)) {
      80             :                 int i;
      81             : 
      82          43 :                 code = krb5_unparse_name(context,
      83          43 :                                          sentry.entry.principal,
      84             :                                          &entry_principal);
      85          43 :                 if (code != 0) {
      86           0 :                         *error_string = smb_get_krb5_error_message(context,
      87             :                                                                    code,
      88             :                                                                    mem_ctx);
      89           0 :                         status = NT_STATUS_UNSUCCESSFUL;
      90           0 :                         goto done;
      91             :                 }
      92             : 
      93          43 :                 if (sentry.entry.keys.len == 0) {
      94           8 :                         SAFE_FREE(entry_principal);
      95           8 :                         sdb_free_entry(&sentry);
      96           8 :                         sentry = (struct sdb_entry_ex) {
      97             :                                 .free_entry = NULL,
      98             :                         };
      99             : 
     100           8 :                         continue;
     101             :                 }
     102             : 
     103         138 :                 for (i = 0; i < sentry.entry.keys.len; i++) {
     104         103 :                         struct sdb_key *s = &(sentry.entry.keys.val[i]);
     105             :                         krb5_enctype enctype;
     106             : 
     107         103 :                         enctype = KRB5_KEY_TYPE(&(s->key));
     108         103 :                         password.length = KRB5_KEY_LENGTH(&s->key);
     109         103 :                         password.data = (char *)KRB5_KEY_DATA(&s->key);
     110             : 
     111         103 :                         DBG_INFO("smb_krb5_kt_add_entry for enctype=0x%04x\n",
     112             :                                   (int)enctype);
     113         197 :                         code = smb_krb5_kt_add_entry(context,
     114             :                                                      keytab,
     115          94 :                                                      sentry.entry.kvno,
     116             :                                                      entry_principal,
     117             :                                                      NULL,
     118             :                                                      enctype,
     119             :                                                      &password,
     120             :                                                      true,    /* no_salt */
     121             :                                                      false);  /* keeyp_old_entries */
     122         103 :                         if (code != 0) {
     123           0 :                                 status = NT_STATUS_UNSUCCESSFUL;
     124           0 :                                 *error_string = smb_get_krb5_error_message(context,
     125             :                                                                            code,
     126             :                                                                            mem_ctx);
     127           0 :                                 DEBUG(0, ("smb_krb5_kt_add_entry failed code=%d, error = %s\n",
     128             :                                           code, *error_string));
     129           0 :                                 goto done;
     130             :                         }
     131             :                 }
     132             : 
     133          35 :                 if (copy_one_principal) {
     134          11 :                         break;
     135             :                 }
     136             : 
     137          24 :                 SAFE_FREE(entry_principal);
     138          24 :                 sdb_free_entry(&sentry);
     139          24 :                 sentry = (struct sdb_entry_ex) {
     140             :                         .free_entry = NULL,
     141             :                 };
     142             :         }
     143             : 
     144          13 :         if (code != 0 && code != SDB_ERR_NOENTRY) {
     145           0 :                 *error_string = smb_get_krb5_error_message(context,
     146             :                                                            code,
     147             :                                                            mem_ctx);
     148           0 :                 status = NT_STATUS_NO_SUCH_USER;
     149           0 :                 goto done;
     150             :         }
     151             : 
     152          13 :         status = NT_STATUS_OK;
     153          13 : done:
     154          13 :         SAFE_FREE(entry_principal);
     155          13 :         sdb_free_entry(&sentry);
     156             : 
     157          13 :         return status;
     158             : }
     159             : 
     160          13 : NTSTATUS libnet_export_keytab(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_export_keytab *r)
     161             : {
     162             :         krb5_error_code ret;
     163             :         struct smb_krb5_context *smb_krb5_context;
     164             :         struct samba_kdc_base_context *base_ctx;
     165          13 :         struct samba_kdc_db_context *db_ctx = NULL;
     166          13 :         const char *error_string = NULL;
     167             :         NTSTATUS status;
     168             : 
     169          13 :         ret = smb_krb5_init_context(ctx, ctx->lp_ctx, &smb_krb5_context);
     170          13 :         if (ret) {
     171           0 :                 return NT_STATUS_NO_MEMORY; 
     172             :         }
     173             : 
     174          13 :         base_ctx = talloc_zero(mem_ctx, struct samba_kdc_base_context);
     175          13 :         if (base_ctx == NULL) {
     176           0 :                 return NT_STATUS_NO_MEMORY;
     177             :         }
     178             : 
     179          13 :         base_ctx->ev_ctx = ctx->event_ctx;
     180          13 :         base_ctx->lp_ctx = ctx->lp_ctx;
     181             : 
     182          13 :         status = samba_kdc_setup_db_ctx(mem_ctx, base_ctx, &db_ctx);
     183          13 :         if (!NT_STATUS_IS_OK(status)) {
     184           0 :                 return status;
     185             :         }
     186             : 
     187          13 :         if (r->in.principal != NULL) {
     188          11 :                 DEBUG(0, ("Export one principal to %s\n", r->in.keytab_name));
     189          19 :                 status = sdb_kt_copy(mem_ctx,
     190          11 :                                      smb_krb5_context->krb5_context,
     191             :                                      db_ctx,
     192             :                                      r->in.keytab_name,
     193             :                                      r->in.principal,
     194             :                                      &error_string);
     195             :         } else {
     196           2 :                 unlink(r->in.keytab_name);
     197           2 :                 DEBUG(0, ("Export complete keytab to %s\n", r->in.keytab_name));
     198           4 :                 status = sdb_kt_copy(mem_ctx,
     199           2 :                                      smb_krb5_context->krb5_context,
     200             :                                      db_ctx,
     201             :                                      r->in.keytab_name,
     202             :                                      NULL,
     203             :                                      &error_string);
     204             :         }
     205             : 
     206          13 :         talloc_free(db_ctx);
     207          13 :         talloc_free(base_ctx);
     208             : 
     209          13 :         if (!NT_STATUS_IS_OK(status)) {
     210           0 :                 r->out.error_string = error_string;
     211             :         }
     212             : 
     213          13 :         return status;
     214             : }

Generated by: LCOV version 1.13