LCOV - code coverage report
Current view: top level - source4/libnet - libnet_export_keytab.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 64 84 76.2 %
Date: 2024-06-13 04:01:37 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          11 : 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          11 :         struct sdb_entry sentry = {};
      38             :         krb5_keytab keytab;
      39          11 :         krb5_error_code code = 0;
      40          11 :         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
      41          11 :         char *entry_principal = NULL;
      42          11 :         bool copy_one_principal = (principal != NULL);
      43             :         krb5_data password;
      44             : 
      45          11 :         code = smb_krb5_kt_open_relative(context,
      46             :                                          keytab_name,
      47             :                                          true, /* write_access */
      48             :                                          &keytab);
      49          11 :         if (code != 0) {
      50           0 :                 *error_string = talloc_asprintf(mem_ctx,
      51             :                                                 "Failed to open keytab: %s",
      52             :                                                 keytab_name);
      53           0 :                 status = NT_STATUS_NO_SUCH_FILE;
      54           0 :                 goto done;
      55             :         }
      56             : 
      57          11 :         if (copy_one_principal) {
      58             :                 krb5_principal k5_princ;
      59             : 
      60           9 :                 code = smb_krb5_parse_name(context, principal, &k5_princ);
      61           9 :                 if (code != 0) {
      62           0 :                         *error_string = smb_get_krb5_error_message(context,
      63             :                                                                    code,
      64             :                                                                    mem_ctx);
      65           0 :                         status = NT_STATUS_UNSUCCESSFUL;
      66           0 :                         goto done;
      67             :                 }
      68             : 
      69           9 :                 code = samba_kdc_fetch(context, db_ctx, k5_princ,
      70             :                                        SDB_F_GET_ANY | SDB_F_ADMIN_DATA,
      71             :                                        0, &sentry);
      72             : 
      73           9 :                 krb5_free_principal(context, k5_princ);
      74             :         } else {
      75           2 :                 code = samba_kdc_firstkey(context, db_ctx, &sentry);
      76             :         }
      77             : 
      78          43 :         for (; code == 0; code = samba_kdc_nextkey(context, db_ctx, &sentry)) {
      79             :                 int i;
      80             : 
      81          41 :                 code = krb5_unparse_name(context,
      82          41 :                                          sentry.principal,
      83             :                                          &entry_principal);
      84          41 :                 if (code != 0) {
      85           0 :                         *error_string = smb_get_krb5_error_message(context,
      86             :                                                                    code,
      87             :                                                                    mem_ctx);
      88           0 :                         status = NT_STATUS_UNSUCCESSFUL;
      89           0 :                         goto done;
      90             :                 }
      91             : 
      92          41 :                 if (sentry.keys.len == 0) {
      93           8 :                         SAFE_FREE(entry_principal);
      94           8 :                         sdb_entry_free(&sentry);
      95             : 
      96           8 :                         continue;
      97             :                 }
      98             : 
      99         124 :                 for (i = 0; i < sentry.keys.len; i++) {
     100          91 :                         struct sdb_key *s = &(sentry.keys.val[i]);
     101             :                         krb5_enctype enctype;
     102             : 
     103          91 :                         enctype = KRB5_KEY_TYPE(&(s->key));
     104          91 :                         password.length = KRB5_KEY_LENGTH(&s->key);
     105          91 :                         password.data = (char *)KRB5_KEY_DATA(&s->key);
     106             : 
     107          91 :                         DBG_INFO("smb_krb5_kt_add_entry for enctype=0x%04x\n",
     108             :                                   (int)enctype);
     109         178 :                         code = smb_krb5_kt_add_entry(context,
     110             :                                                      keytab,
     111          87 :                                                      sentry.kvno,
     112             :                                                      entry_principal,
     113             :                                                      NULL,
     114             :                                                      enctype,
     115             :                                                      &password,
     116             :                                                      true,    /* no_salt */
     117             :                                                      false);  /* keeyp_old_entries */
     118          91 :                         if (code != 0) {
     119           0 :                                 status = NT_STATUS_UNSUCCESSFUL;
     120           0 :                                 *error_string = smb_get_krb5_error_message(context,
     121             :                                                                            code,
     122             :                                                                            mem_ctx);
     123           0 :                                 DEBUG(0, ("smb_krb5_kt_add_entry failed code=%d, error = %s\n",
     124             :                                           code, *error_string));
     125           0 :                                 goto done;
     126             :                         }
     127             :                 }
     128             : 
     129          33 :                 if (copy_one_principal) {
     130           9 :                         break;
     131             :                 }
     132             : 
     133          24 :                 SAFE_FREE(entry_principal);
     134          24 :                 sdb_entry_free(&sentry);
     135             :         }
     136             : 
     137          11 :         if (code != 0 && code != SDB_ERR_NOENTRY) {
     138           0 :                 *error_string = smb_get_krb5_error_message(context,
     139             :                                                            code,
     140             :                                                            mem_ctx);
     141           0 :                 status = NT_STATUS_NO_SUCH_USER;
     142           0 :                 goto done;
     143             :         }
     144             : 
     145          11 :         status = NT_STATUS_OK;
     146          11 : done:
     147          11 :         SAFE_FREE(entry_principal);
     148          11 :         sdb_entry_free(&sentry);
     149             : 
     150          11 :         return status;
     151             : }
     152             : 
     153          11 : NTSTATUS libnet_export_keytab(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_export_keytab *r)
     154             : {
     155             :         krb5_error_code ret;
     156             :         struct smb_krb5_context *smb_krb5_context;
     157             :         struct samba_kdc_base_context *base_ctx;
     158          11 :         struct samba_kdc_db_context *db_ctx = NULL;
     159          11 :         const char *error_string = NULL;
     160             :         NTSTATUS status;
     161             : 
     162          11 :         ret = smb_krb5_init_context(ctx, ctx->lp_ctx, &smb_krb5_context);
     163          11 :         if (ret) {
     164           0 :                 return NT_STATUS_NO_MEMORY; 
     165             :         }
     166             : 
     167          11 :         base_ctx = talloc_zero(mem_ctx, struct samba_kdc_base_context);
     168          11 :         if (base_ctx == NULL) {
     169           0 :                 return NT_STATUS_NO_MEMORY;
     170             :         }
     171             : 
     172          11 :         base_ctx->ev_ctx = ctx->event_ctx;
     173          11 :         base_ctx->lp_ctx = ctx->lp_ctx;
     174             : 
     175          11 :         status = samba_kdc_setup_db_ctx(mem_ctx, base_ctx, &db_ctx);
     176          11 :         if (!NT_STATUS_IS_OK(status)) {
     177           0 :                 return status;
     178             :         }
     179             : 
     180          11 :         if (r->in.principal != NULL) {
     181           9 :                 DEBUG(0, ("Export one principal to %s\n", r->in.keytab_name));
     182          16 :                 status = sdb_kt_copy(mem_ctx,
     183           9 :                                      smb_krb5_context->krb5_context,
     184             :                                      db_ctx,
     185             :                                      r->in.keytab_name,
     186             :                                      r->in.principal,
     187             :                                      &error_string);
     188             :         } else {
     189           2 :                 unlink(r->in.keytab_name);
     190           2 :                 DEBUG(0, ("Export complete keytab to %s\n", r->in.keytab_name));
     191           4 :                 status = sdb_kt_copy(mem_ctx,
     192           2 :                                      smb_krb5_context->krb5_context,
     193             :                                      db_ctx,
     194             :                                      r->in.keytab_name,
     195             :                                      NULL,
     196             :                                      &error_string);
     197             :         }
     198             : 
     199          11 :         talloc_free(db_ctx);
     200          11 :         talloc_free(base_ctx);
     201             : 
     202          11 :         if (!NT_STATUS_IS_OK(status)) {
     203           0 :                 r->out.error_string = error_string;
     204             :         }
     205             : 
     206          11 :         return status;
     207             : }

Generated by: LCOV version 1.13