[SCM] Samba Shared Repository - branch v3-2-test updated - release-3-2-0pre2-2567-g1a22e97

Günther Deschner gd at samba.org
Fri Jun 13 10:21:45 GMT 2008


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 <gd at samba.org>
Date:   Fri Jun 13 12:20:01 2008 +0200

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

commit 5b68be96996a710988b1fd1c176cd5dff0f2c6af
Author: Günther Deschner <gd at samba.org>
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 <abartlet at samba.org> 2004-2005
+   Copyright (C) Guenther Deschner <gd at samba.org> 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


More information about the samba-cvs mailing list