LCOV - code coverage report
Current view: top level - libcli/samsync - decrypt.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 0 77 0.0 %
Date: 2024-04-21 15:09:00 Functions: 0 3 0.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Extract the user/system database from a remote SamSync server
       5             : 
       6             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
       7             :    Copyright (C) Guenther Deschner <gd@samba.org> 2008
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : 
      24             : #include "includes.h"
      25             : #include "../libcli/auth/libcli_auth.h"
      26             : #include "../libcli/samsync/samsync.h"
      27             : #include "librpc/gen_ndr/ndr_netlogon.h"
      28             : #include "lib/crypto/gnutls_helpers.h"
      29             : 
      30             : /**
      31             :  * Decrypt and extract the user's passwords.
      32             :  *
      33             :  * The writes decrypted (no longer 'RID encrypted' or arcfour encrypted)
      34             :  * passwords back into the structure
      35             :  */
      36             : 
      37           0 : static NTSTATUS fix_user(TALLOC_CTX *mem_ctx,
      38             :                          struct netlogon_creds_CredentialState *creds,
      39             :                          enum netr_SamDatabaseID database_id,
      40             :                          struct netr_DELTA_ENUM *delta)
      41             : {
      42             : 
      43           0 :         uint32_t rid = delta->delta_id_union.rid;
      44           0 :         struct netr_DELTA_USER *user = delta->delta_union.user;
      45           0 :         struct samr_Password lm_hash;
      46           0 :         struct samr_Password nt_hash;
      47           0 :         int rc;
      48             : 
      49             :         /* Note that win2000 may send us all zeros
      50             :          * for the hashes if it doesn't
      51             :          * think this channel is secure enough. */
      52           0 :         if (user->lm_password_present) {
      53           0 :                 if (!all_zero(user->lmpassword.hash, 16)) {
      54           0 :                         rc = sam_rid_crypt(rid, user->lmpassword.hash,
      55             :                                             lm_hash.hash, SAMBA_GNUTLS_DECRYPT);
      56           0 :                         if (rc != 0) {
      57           0 :                                 return gnutls_error_to_ntstatus(rc,
      58             :                                                                 NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
      59             :                         }
      60             :                 } else {
      61           0 :                         memset(lm_hash.hash, '\0', sizeof(lm_hash.hash));
      62             :                 }
      63           0 :                 user->lmpassword = lm_hash;
      64             :         }
      65             : 
      66           0 :         if (user->nt_password_present) {
      67           0 :                 if (!all_zero(user->ntpassword.hash, 16)) {
      68           0 :                         rc = sam_rid_crypt(rid, user->ntpassword.hash,
      69             :                                             nt_hash.hash, SAMBA_GNUTLS_DECRYPT);
      70           0 :                         if (rc != 0) {
      71           0 :                                 return gnutls_error_to_ntstatus(rc,
      72             :                                                                 NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
      73             :                         }
      74             :                 } else {
      75           0 :                         memset(nt_hash.hash, '\0', sizeof(nt_hash.hash));
      76             :                 }
      77           0 :                 user->ntpassword = nt_hash;
      78             :         }
      79             : 
      80           0 :         if (user->user_private_info.SensitiveData) {
      81           0 :                 DATA_BLOB data;
      82           0 :                 struct netr_USER_KEYS keys;
      83           0 :                 enum ndr_err_code ndr_err;
      84           0 :                 NTSTATUS status;
      85             : 
      86           0 :                 data.data = user->user_private_info.SensitiveData;
      87           0 :                 data.length = user->user_private_info.DataLength;
      88             : 
      89           0 :                 status = netlogon_creds_arcfour_crypt(creds,
      90             :                                                       data.data,
      91             :                                                       data.length);
      92           0 :                 if (!NT_STATUS_IS_OK(status)) {
      93           0 :                         return status;
      94             :                 }
      95             : 
      96           0 :                 user->user_private_info.SensitiveData = data.data;
      97           0 :                 user->user_private_info.DataLength = data.length;
      98             : 
      99           0 :                 ndr_err = ndr_pull_struct_blob(&data, mem_ctx, &keys,
     100             :                         (ndr_pull_flags_fn_t)ndr_pull_netr_USER_KEYS);
     101           0 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     102           0 :                         dump_data(10, data.data, data.length);
     103           0 :                         return ndr_map_error2ntstatus(ndr_err);
     104             :                 }
     105             : 
     106             :                 /* Note that win2000 may send us all zeros
     107             :                  * for the hashes if it doesn't
     108             :                  * think this channel is secure enough. */
     109           0 :                 if (keys.keys.keys2.lmpassword.length == 16) {
     110           0 :                         if (!all_zero(keys.keys.keys2.lmpassword.pwd.hash,
     111             :                                       16)) {
     112           0 :                                 rc = sam_rid_crypt(rid,
     113             :                                                    keys.keys.keys2.lmpassword.pwd.hash,
     114             :                                                    lm_hash.hash, SAMBA_GNUTLS_DECRYPT);
     115           0 :                                 if (rc != 0) {
     116           0 :                                         return gnutls_error_to_ntstatus(rc,
     117             :                                                                         NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
     118             :                                 }
     119             :                         } else {
     120           0 :                                 memset(lm_hash.hash, '\0', sizeof(lm_hash.hash));
     121             :                         }
     122           0 :                         user->lmpassword = lm_hash;
     123           0 :                         user->lm_password_present = true;
     124             :                 }
     125           0 :                 if (keys.keys.keys2.ntpassword.length == 16) {
     126           0 :                         if (!all_zero(keys.keys.keys2.ntpassword.pwd.hash,
     127             :                                       16)) {
     128           0 :                                 rc = sam_rid_crypt(rid,
     129             :                                                    keys.keys.keys2.ntpassword.pwd.hash,
     130             :                                                    nt_hash.hash, SAMBA_GNUTLS_DECRYPT);
     131           0 :                                 if (rc != 0) {
     132           0 :                                         return gnutls_error_to_ntstatus(rc,
     133             :                                                                         NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
     134             :                                 }
     135             :                         } else {
     136           0 :                                 memset(nt_hash.hash, '\0', sizeof(nt_hash.hash));
     137             :                         }
     138           0 :                         user->ntpassword = nt_hash;
     139           0 :                         user->nt_password_present = true;
     140             :                 }
     141             :                 /* TODO: rid decrypt history fields */
     142             :         }
     143           0 :         return NT_STATUS_OK;
     144             : }
     145             : 
     146             : /**
     147             :  * Decrypt and extract the secrets
     148             :  * 
     149             :  * The writes decrypted secrets back into the structure
     150             :  */
     151           0 : static NTSTATUS fix_secret(TALLOC_CTX *mem_ctx,
     152             :                            struct netlogon_creds_CredentialState *creds,
     153             :                            enum netr_SamDatabaseID database,
     154             :                            struct netr_DELTA_ENUM *delta) 
     155             : {
     156           0 :         struct netr_DELTA_SECRET *secret = delta->delta_union.secret;
     157           0 :         NTSTATUS status;
     158             : 
     159           0 :         status = netlogon_creds_arcfour_crypt(creds,
     160             :                                               secret->current_cipher.cipher_data,
     161           0 :                                               secret->current_cipher.maxlen);
     162           0 :         if (!NT_STATUS_IS_OK(status)) {
     163           0 :                 return status;
     164             :         }
     165             : 
     166           0 :         status = netlogon_creds_arcfour_crypt(creds,
     167             :                                               secret->old_cipher.cipher_data,
     168           0 :                                               secret->old_cipher.maxlen);
     169           0 :         if (!NT_STATUS_IS_OK(status)) {
     170           0 :                 return status;
     171             :         }
     172             : 
     173           0 :         return NT_STATUS_OK;
     174             : }
     175             : 
     176             : /**
     177             :  * Fix up the delta, dealing with encryption issues so that the final
     178             :  * callback need only do the printing or application logic
     179             :  */
     180             : 
     181           0 : NTSTATUS samsync_fix_delta(TALLOC_CTX *mem_ctx,
     182             :                            struct netlogon_creds_CredentialState *creds,
     183             :                            enum netr_SamDatabaseID database_id,
     184             :                            struct netr_DELTA_ENUM *delta)
     185             : {
     186           0 :         NTSTATUS status = NT_STATUS_OK;
     187             : 
     188           0 :         switch (delta->delta_type) {
     189           0 :                 case NETR_DELTA_USER:
     190             : 
     191           0 :                         status = fix_user(mem_ctx,
     192             :                                           creds,
     193             :                                           database_id,
     194             :                                           delta);
     195           0 :                         break;
     196           0 :                 case NETR_DELTA_SECRET:
     197             : 
     198           0 :                         status = fix_secret(mem_ctx,
     199             :                                             creds,
     200             :                                             database_id,
     201             :                                             delta);
     202           0 :                         break;
     203           0 :                 default:
     204           0 :                         break;
     205             :         }
     206             : 
     207           0 :         return status;
     208             : }
     209             : 

Generated by: LCOV version 1.14