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

Generated by: LCOV version 1.14