The branch, v3-2-test has been updated
       via  1a22e975dd1255f3557c1cd873d877aa35822afc (commit)
       via  5b68be96996a710988b1fd1c176cd5dff0f2c6af (commit)
      from  8800afafedccd43e425463045c05934d381e178d (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-2-test


- Log -----------------------------------------------------------------
commit 1a22e975dd1255f3557c1cd873d877aa35822afc
Author: Günther Deschner <[EMAIL PROTECTED]>
Date:   Fri Jun 13 12:20:01 2008 +0200

    net: Fix bug #5542 (samsync contains empty passwords).
    
    Guenther

commit 5b68be96996a710988b1fd1c176cd5dff0f2c6af
Author: Günther Deschner <[EMAIL PROTECTED]>
Date:   Fri Jun 13 11:57:09 2008 +0200

    samsync: add samsync_fix_delta_array()
    
    This code is vastly based on samba4 code.
    
    Guenther

-----------------------------------------------------------------------

Summary of changes:
 source/Makefile.in             |    1 +
 source/libnet/libnet_samsync.c |  188 ++++++++++++++++++++++++++++++++++++++++
 source/utils/net.h             |    1 +
 source/utils/net_ads.c         |    2 -
 source/utils/net_rpc_samsync.c |   27 ++++++
 5 files changed, 217 insertions(+), 2 deletions(-)
 create mode 100644 source/libnet/libnet_samsync.c


Changeset truncated at 500 lines:

diff --git a/source/Makefile.in b/source/Makefile.in
index cb72b94..04ff7cc 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -869,6 +869,7 @@ SMBCONFTORT_OBJ = $(SMBCONFTORT_OBJ0) \
                  $(POPT_LIB_OBJ)
 
 LIBNET_OBJ = libnet/libnet_join.o \
+            libnet/libnet_samsync.o \
             librpc/gen_ndr/ndr_libnet_join.o
 
 NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_help.o \
diff --git a/source/libnet/libnet_samsync.c b/source/libnet/libnet_samsync.c
new file mode 100644
index 0000000..e45a845
--- /dev/null
+++ b/source/libnet/libnet_samsync.c
@@ -0,0 +1,188 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   Extract the user/system database from a remote SamSync server
+
+   Copyright (C) Andrew Bartlett <[EMAIL PROTECTED]> 2004-2005
+   Copyright (C) Guenther Deschner <[EMAIL PROTECTED]> 2008
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include "includes.h"
+
+/**
+ * Decrypt and extract the user's passwords.
+ *
+ * The writes decrypted (no longer 'RID encrypted' or arcfour encrypted)
+ * passwords back into the structure
+ */
+
+static NTSTATUS fix_user(TALLOC_CTX *mem_ctx,
+                        DATA_BLOB *session_key,
+                        bool rid_crypt,
+                        enum netr_SamDatabaseID database_id,
+                        struct netr_DELTA_ENUM *delta)
+{
+
+       uint32_t rid = delta->delta_id_union.rid;
+       struct netr_DELTA_USER *user = delta->delta_union.user;
+       struct samr_Password lm_hash;
+       struct samr_Password nt_hash;
+       const char *username = user->account_name.string;
+
+       if (rid_crypt) {
+               if (user->lm_password_present) {
+                       sam_pwd_hash(rid, user->lmpassword.hash, lm_hash.hash, 
0);
+                       user->lmpassword = lm_hash;
+               }
+
+               if (user->nt_password_present) {
+                       sam_pwd_hash(rid, user->ntpassword.hash, nt_hash.hash, 
0);
+                       user->ntpassword = nt_hash;
+               }
+       }
+
+       if (user->user_private_info.SensitiveData) {
+               DATA_BLOB data;
+               struct netr_USER_KEYS keys;
+               enum ndr_err_code ndr_err;
+               data.data = user->user_private_info.SensitiveData;
+               data.length = user->user_private_info.DataLength;
+               SamOEMhashBlob(data.data, data.length, session_key);
+               user->user_private_info.SensitiveData = data.data;
+               user->user_private_info.DataLength = data.length;
+
+               ndr_err = ndr_pull_struct_blob(&data, mem_ctx, &keys,
+                       (ndr_pull_flags_fn_t)ndr_pull_netr_USER_KEYS);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       dump_data(10, data.data, data.length);
+                       return ndr_map_error2ntstatus(ndr_err);
+               }
+
+               if (keys.keys.keys2.lmpassword.length == 16) {
+                       if (rid_crypt) {
+                               sam_pwd_hash(rid,
+                                            
keys.keys.keys2.lmpassword.pwd.hash,
+                                            lm_hash.hash, 0);
+                               user->lmpassword = lm_hash;
+                       } else {
+                               user->lmpassword = 
keys.keys.keys2.lmpassword.pwd;
+                       }
+                       user->lm_password_present = true;
+               }
+               if (keys.keys.keys2.ntpassword.length == 16) {
+                       if (rid_crypt) {
+                               sam_pwd_hash(rid,
+                                            
keys.keys.keys2.ntpassword.pwd.hash,
+                                            nt_hash.hash, 0);
+                               user->ntpassword = nt_hash;
+                       } else {
+                               user->ntpassword = 
keys.keys.keys2.ntpassword.pwd;
+                       }
+                       user->nt_password_present = true;
+               }
+               /* TODO: rid decrypt history fields */
+       }
+       return NT_STATUS_OK;
+}
+
+/**
+ * Decrypt and extract the secrets
+ *
+ * The writes decrypted secrets back into the structure
+ */
+static NTSTATUS fix_secret(TALLOC_CTX *mem_ctx,
+                          DATA_BLOB *session_key,
+                          enum netr_SamDatabaseID database_id,
+                          struct netr_DELTA_ENUM *delta)
+{
+       struct netr_DELTA_SECRET *secret = delta->delta_union.secret;
+
+       SamOEMhashBlob(secret->current_cipher.cipher_data,
+                      secret->current_cipher.maxlen,
+                      session_key);
+
+       SamOEMhashBlob(secret->old_cipher.cipher_data,
+                      secret->old_cipher.maxlen,
+                      session_key);
+
+       return NT_STATUS_OK;
+}
+
+/**
+ * Fix up the delta, dealing with encryption issues so that the final
+ * callback need only do the printing or application logic
+ */
+
+static NTSTATUS samsync_fix_delta(TALLOC_CTX *mem_ctx,
+                                 DATA_BLOB *session_key,
+                                 bool rid_crypt,
+                                 enum netr_SamDatabaseID database_id,
+                                 struct netr_DELTA_ENUM *delta)
+{
+       NTSTATUS status = NT_STATUS_OK;
+
+       switch (delta->delta_type) {
+               case NETR_DELTA_USER:
+
+                       status = fix_user(mem_ctx,
+                                         session_key,
+                                         rid_crypt,
+                                         database_id,
+                                         delta);
+                       break;
+               case NETR_DELTA_SECRET:
+
+                       status = fix_secret(mem_ctx,
+                                           session_key,
+                                           database_id,
+                                           delta);
+                       break;
+               default:
+                       break;
+       }
+
+       return status;
+}
+
+/**
+ * Fix up the delta, dealing with encryption issues so that the final
+ * callback need only do the printing or application logic
+ */
+
+NTSTATUS samsync_fix_delta_array(TALLOC_CTX *mem_ctx,
+                                DATA_BLOB *session_key,
+                                bool rid_crypt,
+                                enum netr_SamDatabaseID database_id,
+                                struct netr_DELTA_ENUM_ARRAY *r)
+{
+       NTSTATUS status;
+       int i;
+
+       for (i = 0; i < r->num_deltas; i++) {
+
+               status = samsync_fix_delta(mem_ctx,
+                                          session_key,
+                                          rid_crypt,
+                                          database_id,
+                                          &r->delta_enum[i]);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return status;
+               }
+       }
+
+       return NT_STATUS_OK;
+}
diff --git a/source/utils/net.h b/source/utils/net.h
index 68ed179..f043668 100644
--- a/source/utils/net.h
+++ b/source/utils/net.h
@@ -23,6 +23,7 @@
  */
 
 #include "lib/netapi/netapi.h"
+#include "libnet/libnet.h"
 
 typedef NTSTATUS (*rpc_command_fn)(const DOM_SID *,
                                const char *, 
diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c
index 9c6a548..ef6b151 100644
--- a/source/utils/net_ads.c
+++ b/source/utils/net_ads.c
@@ -23,8 +23,6 @@
 #include "includes.h"
 #include "utils/net.h"
 
-#include "libnet/libnet.h"
-
 #ifdef HAVE_ADS
 
 int net_ads_usage(int argc, const char **argv)
diff --git a/source/utils/net_rpc_samsync.c b/source/utils/net_rpc_samsync.c
index 06cde2a..ac0739e 100644
--- a/source/utils/net_rpc_samsync.c
+++ b/source/utils/net_rpc_samsync.c
@@ -336,6 +336,7 @@ static void dump_database(struct rpc_pipe_client *pipe_hnd,
        struct netr_Authenticator return_authenticator;
        uint16_t restart_state = 0;
        uint32_t sync_context = 0;
+       DATA_BLOB session_key;
 
        ZERO_STRUCT(return_authenticator);
 
@@ -386,6 +387,14 @@ static void dump_database(struct rpc_pipe_client *pipe_hnd,
                        break;
                }
 
+               session_key = data_blob_const(pipe_hnd->dc->sess_key, 16);
+
+               samsync_fix_delta_array(mem_ctx,
+                                       &session_key,
+                                       true,
+                                       database_id,
+                                       delta_enum_array);
+
                /* Display results */
                for (i = 0; i < delta_enum_array->num_deltas; i++) {
                        display_sam_entry(&delta_enum_array->delta_enum[i]);
@@ -1197,6 +1206,7 @@ static NTSTATUS fetch_database(struct rpc_pipe_client 
*pipe_hnd, uint32 db_type,
        enum netr_SamDatabaseID database_id = db_type;
        uint16_t restart_state = 0;
        uint32_t sync_context = 0;
+       DATA_BLOB session_key;
 
        if (!(mem_ctx = talloc_init("fetch_database")))
                return NT_STATUS_NO_MEMORY;
@@ -1243,6 +1253,14 @@ static NTSTATUS fetch_database(struct rpc_pipe_client 
*pipe_hnd, uint32 db_type,
                        break;
                }
 
+               session_key = data_blob_const(pipe_hnd->dc->sess_key, 16);
+
+               samsync_fix_delta_array(mem_ctx,
+                                       &session_key,
+                                       true,
+                                       database_id,
+                                       delta_enum_array);
+
                for (i = 0; i < delta_enum_array->num_deltas; i++) {
                        fetch_sam_entry(&delta_enum_array->delta_enum[i], 
dom_sid);
                }
@@ -2018,6 +2036,7 @@ static NTSTATUS fetch_database_to_ldif(struct 
rpc_pipe_client *pipe_hnd,
        enum netr_SamDatabaseID database_id = db_type;
        uint16_t restart_state = 0;
        uint32_t sync_context = 0;
+       DATA_BLOB session_key;
 
        /* Set up array for mapping accounts to groups */
        /* Array element is the group rid */
@@ -2150,6 +2169,14 @@ static NTSTATUS fetch_database_to_ldif(struct 
rpc_pipe_client *pipe_hnd,
                        break;
                }
 
+               session_key = data_blob_const(pipe_hnd->dc->sess_key, 16);
+
+               samsync_fix_delta_array(mem_ctx,
+                                       &session_key,
+                                       true,
+                                       database_id,
+                                       delta_enum_array);
+
                num_deltas = delta_enum_array->num_deltas;
 
                /* Re-allocate memory for groupmap and accountmap arrays */


-- 
Samba Shared Repository

Reply via email to