[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Tue Aug 28 22:05:02 MDT 2012


The branch, master has been updated
       via  5d96498 s4-dsdb: Avoid printing secret attributes in ldb trace logs
       via  395b8e4 lib/ldb: Avoid printing secret attributes in ldb trace logs
       via  17337cf auth/credentials: Remove unused, and un-declared cli_credentials_set_krbtgt()
       via  beafdd6 auth/credentials: Better integrate fetch of secrets.tdb and secrets.ldb records
      from  a0e4bdc auth/credentials: Improve memory handling in cli_credentials_set_machine_account

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 5d96498680ec4209142ea7dc460a3fd921413a5e
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Aug 29 11:32:26 2012 +1000

    s4-dsdb: Avoid printing secret attributes in ldb trace logs
    
    These are printed when Samba has debug level 10, which is often used for debugging.
    
    To indicate that these attributes are secret, we set an opaque.
    
    Andrew Bartlett
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Wed Aug 29 06:04:33 CEST 2012 on sn-devel-104

commit 395b8e4d58e2815d9848f8a6390f23d8c7d10a91
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Aug 29 11:29:44 2012 +1000

    lib/ldb: Avoid printing secret attributes in ldb trace logs
    
    These are printed when Samba has debug level 10, which is often used for debugging.
    
    Instead, print a note to say that this attribute has been skipped.
    
    Andrew Bartlett

commit 17337cfec071f7f82fa4c50ace751d51277a4b20
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Aug 29 09:44:52 2012 +1000

    auth/credentials: Remove unused, and un-declared cli_credentials_set_krbtgt()

commit beafdd6410f122d39c32d51629dd7eaf20a8a6c1
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Aug 29 09:44:12 2012 +1000

    auth/credentials: Better integrate fetch of secrets.tdb and secrets.ldb records
    
    By checking first if there is a secrets.tdb record and passing in the password and last change time
    we avoid setting one series of values and then replacing them.  We also avoid the need to work
    around the setting of anonymous.
    
    Andrew Bartlett

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

Summary of changes:
 auth/credentials/credentials_secrets.c             |  116 ++++++++++----------
 lib/ldb-samba/ldif_handlers.c                      |    8 ++
 lib/ldb/ABI/{ldb-1.1.10.sigs => ldb-1.1.12.sigs}   |    1 +
 ...ldb-util-1.1.10.sigs => pyldb-util-1.1.12.sigs} |    0
 lib/ldb/common/ldb.c                               |   31 ++++-
 lib/ldb/common/ldb_ldif.c                          |   47 +++++++-
 lib/ldb/common/ldb_modules.c                       |   15 +++-
 lib/ldb/include/ldb_module.h                       |    4 +
 lib/ldb/include/ldb_private.h                      |    5 +
 lib/ldb/wscript                                    |    2 +-
 10 files changed, 157 insertions(+), 72 deletions(-)
 copy lib/ldb/ABI/{ldb-1.1.10.sigs => ldb-1.1.12.sigs} (99%)
 copy lib/ldb/ABI/{pyldb-util-1.1.10.sigs => pyldb-util-1.1.12.sigs} (100%)


Changeset truncated at 500 lines:

diff --git a/auth/credentials/credentials_secrets.c b/auth/credentials/credentials_secrets.c
index 8c8c567..a44fe1c 100644
--- a/auth/credentials/credentials_secrets.c
+++ b/auth/credentials/credentials_secrets.c
@@ -46,12 +46,14 @@
  * @param cred Credentials structure to fill in
  * @retval NTSTATUS error detailing any failure
  */
-_PUBLIC_ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred, 
-					      struct loadparm_context *lp_ctx,
-					      struct ldb_context *ldb,
-					      const char *base,
-					      const char *filter, 
-					      char **error_string)
+static NTSTATUS cli_credentials_set_secrets_lct(struct cli_credentials *cred, 
+						struct loadparm_context *lp_ctx,
+						struct ldb_context *ldb,
+						const char *base,
+						const char *filter, 
+						time_t secrets_tdb_last_change_time,
+						const char *secrets_tdb_password,
+						char **error_string)
 {
 	TALLOC_CTX *mem_ctx;
 	
@@ -66,6 +68,7 @@ _PUBLIC_ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
 	const char *salt_principal;
 	char *keytab;
 	const struct ldb_val *whenChanged;
+	time_t lct;
 
 	/* ok, we are going to get it now, don't recurse back here */
 	cred->machine_account_pending = false;
@@ -79,8 +82,6 @@ _PUBLIC_ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
 		/* Local secrets are stored in secrets.ldb */
 		ldb = secrets_db_connect(mem_ctx, lp_ctx);
 		if (!ldb) {
-			/* set anonymous as the fallback, if the machine account won't work */
-			cli_credentials_set_anonymous(cred);
 			*error_string = talloc_strdup(cred, "Could not open secrets.ldb");
 			talloc_free(mem_ctx);
 			return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
@@ -96,14 +97,32 @@ _PUBLIC_ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
 		*error_string = talloc_asprintf(cred, "Could not find entry to match filter: '%s' base: '%s': %s: %s",
 						filter, base ? base : "",
 						ldb_strerror(ldb_ret), ldb_errstring(ldb));
-		/* set anonymous as the fallback, if the machine account won't work */
-		cli_credentials_set_anonymous(cred);
 		talloc_free(mem_ctx);
 		return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
 	}
 
 	password = ldb_msg_find_attr_as_string(msg, "secret", NULL);
 
+	whenChanged = ldb_msg_find_ldb_val(msg, "whenChanged");
+	if (!whenChanged || ldb_val_to_time(whenChanged, &lct) != LDB_SUCCESS) {
+		/* This attribute is mandetory */
+		talloc_free(mem_ctx);
+		return NT_STATUS_NOT_FOUND;
+	}
+
+	/* Don't set secrets.ldb info if the secrets.tdb entry was more recent */
+	if (lct < secrets_tdb_last_change_time) {
+		talloc_free(mem_ctx);
+		return NT_STATUS_NOT_FOUND;
+	}
+	
+	if (lct == secrets_tdb_last_change_time && secrets_tdb_password && strcmp(password, secrets_tdb_password) != 0) {
+		talloc_free(mem_ctx);
+		return NT_STATUS_NOT_FOUND;
+	}
+	
+	cli_credentials_set_password_last_changed_time(cred, lct);
+	
 	machine_account = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
 
 	if (!machine_account) {
@@ -117,8 +136,6 @@ _PUBLIC_ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
 								"'servicePrincipalName' or "
 								"'ldapBindDn' in secrets record: %s",
 								ldb_dn_get_linearized(msg->dn));
-				/* set anonymous as the fallback, if the machine account won't work */
-				cli_credentials_set_anonymous(cred);
 				talloc_free(mem_ctx);
 				return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
 			} else {
@@ -169,14 +186,6 @@ _PUBLIC_ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
 
 	cli_credentials_set_kvno(cred, ldb_msg_find_attr_as_int(msg, "msDS-KeyVersionNumber", 0));
 
-	whenChanged = ldb_msg_find_ldb_val(msg, "whenChanged");
-	if (whenChanged) {
-		time_t lct;
-		if (ldb_val_to_time(whenChanged, &lct) == LDB_SUCCESS) {
-			cli_credentials_set_password_last_changed_time(cred, lct);
-		}
-	}
-	
 	/* If there was an external keytab specified by reference in
 	 * the LDB, then use this.  Otherwise we will make one up
 	 * (chewing CPU time) from the password */
@@ -190,6 +199,28 @@ _PUBLIC_ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
 	return NT_STATUS_OK;
 }
 
+
+/**
+ * Fill in credentials for the machine trust account, from the secrets database.
+ * 
+ * @param cred Credentials structure to fill in
+ * @retval NTSTATUS error detailing any failure
+ */
+_PUBLIC_ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred, 
+					      struct loadparm_context *lp_ctx,
+					      struct ldb_context *ldb,
+					      const char *base,
+					      const char *filter, 
+					      char **error_string)
+{
+	NTSTATUS status = cli_credentials_set_secrets_lct(cred, lp_ctx, ldb, base, filter, 0, NULL, error_string);
+	if (!NT_STATUS_IS_OK(status)) {
+		/* set anonymous as the fallback, if the machine account won't work */
+		cli_credentials_set_anonymous(cred);
+	}
+	return status;
+}
+
 /**
  * Fill in credentials for the machine trust account, from the secrets database.
  * 
@@ -203,7 +234,6 @@ _PUBLIC_ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cr
 	char *filter;
 	char *error_string;
 	const char *domain;
-	const char *realm;
 	bool secrets_tdb_password_more_recent;
 	time_t secrets_tdb_lct = 0;
 	char *secrets_tdb_password = NULL;
@@ -232,7 +262,6 @@ _PUBLIC_ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cr
 	/* We have to do this, as the fallback in
 	 * cli_credentials_set_secrets is to run as anonymous, so the domain is wiped */
 	domain = cli_credentials_get_domain(cred);
-	realm = cli_credentials_get_realm(cred);
 
 	if (db_ctx) {
 		TDB_DATA dbuf;
@@ -259,9 +288,9 @@ _PUBLIC_ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cr
 
 	filter = talloc_asprintf(cred, SECRETS_PRIMARY_DOMAIN_FILTER, 
 				 domain);
-	status = cli_credentials_set_secrets(cred, lp_ctx, NULL,
-					     SECRETS_PRIMARY_DOMAIN_DN,
-					     filter, &error_string);
+	status = cli_credentials_set_secrets_lct(cred, lp_ctx, NULL,
+						 SECRETS_PRIMARY_DOMAIN_DN,
+						 filter, secrets_tdb_lct, secrets_tdb_password, &error_string);
 	if (secrets_tdb_password == NULL) {
 		secrets_tdb_password_more_recent = false;
 	} else if (NT_STATUS_EQUAL(NT_STATUS_CANT_ACCESS_DOMAIN_INFO, status)
@@ -279,8 +308,6 @@ _PUBLIC_ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cr
 		char *machine_account = talloc_asprintf(tmp_ctx, "%s$", lpcfg_netbios_name(lp_ctx));
 		cli_credentials_set_password(cred, secrets_tdb_password, CRED_SPECIFIED);
 		cli_credentials_set_domain(cred, domain, CRED_SPECIFIED);
-		cli_credentials_set_realm(cred, realm, CRED_SPECIFIED);
-		cli_credentials_set_workstation(cred, lpcfg_netbios_name(lp_ctx), CRED_SPECIFIED);
 		cli_credentials_set_username(cred, machine_account, CRED_SPECIFIED);
 	} else if (!NT_STATUS_IS_OK(status)) {
 		if (db_ctx) {
@@ -296,6 +323,8 @@ _PUBLIC_ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cr
 		}
 		DEBUG(1, ("Could not find machine account in secrets database: %s: %s\n", 
 			  error_string, nt_errstr(status)));
+		/* set anonymous as the fallback, if the machine account won't work */
+		cli_credentials_set_anonymous(cred);
 	}
 	
 	TALLOC_FREE(tmp_ctx);
@@ -303,35 +332,6 @@ _PUBLIC_ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cr
 }
 
 /**
- * Fill in credentials for the machine trust account, from the secrets database.
- * 
- * @param cred Credentials structure to fill in
- * @retval NTSTATUS error detailing any failure
- */
-NTSTATUS cli_credentials_set_krbtgt(struct cli_credentials *cred,
-				    struct loadparm_context *lp_ctx)
-{
-	NTSTATUS status;
-	char *filter;
-	char *error_string;
-	/* Bleh, nasty recursion issues: We are setting a machine
-	 * account here, so we don't want the 'pending' flag around
-	 * any more */
-	cred->machine_account_pending = false;
-	filter = talloc_asprintf(cred, SECRETS_KRBTGT_SEARCH,
-				       cli_credentials_get_realm(cred),
-				       cli_credentials_get_domain(cred));
-	status = cli_credentials_set_secrets(cred, lp_ctx, NULL,
-					     SECRETS_PRINCIPALS_DN,
-					     filter, &error_string);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(1, ("Could not find krbtgt (master Kerberos) account in secrets database: %s: %s\n", nt_errstr(status), error_string));
-		talloc_free(error_string);
-	}
-	return status;
-}
-
-/**
  * Fill in credentials for a particular prinicpal, from the secrets database.
  * 
  * @param cred Credentials structure to fill in
@@ -352,9 +352,9 @@ _PUBLIC_ NTSTATUS cli_credentials_set_stored_principal(struct cli_credentials *c
 				 cli_credentials_get_realm(cred),
 				 cli_credentials_get_domain(cred),
 				 serviceprincipal);
-	status = cli_credentials_set_secrets(cred, lp_ctx, NULL,
+	status = cli_credentials_set_secrets_lct(cred, lp_ctx, NULL,
 					     SECRETS_PRINCIPALS_DN, filter,
-					     &error_string);
+					     0, NULL, &error_string);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(1, ("Could not find %s principal in secrets database: %s: %s\n", serviceprincipal, nt_errstr(status), error_string));
 	}
diff --git a/lib/ldb-samba/ldif_handlers.c b/lib/ldb-samba/ldif_handlers.c
index 1cf7df7..c7385f6 100644
--- a/lib/ldb-samba/ldif_handlers.c
+++ b/lib/ldb-samba/ldif_handlers.c
@@ -27,6 +27,7 @@
 #include <ldb_module.h>
 #include "ldb_handlers.h"
 #include "dsdb/samdb/samdb.h"
+#include "dsdb/common/util.h"
 #include "librpc/gen_ndr/ndr_security.h"
 #include "librpc/gen_ndr/ndr_misc.h"
 #include "librpc/gen_ndr/ndr_drsblobs.h"
@@ -1534,6 +1535,8 @@ const struct ldb_schema_syntax *ldb_samba_syntax_by_lDAPDisplayName(struct ldb_c
 	return s;
 }
 
+static const char *secret_attributes[] = {DSDB_SECRET_ATTRIBUTES, NULL};
+
 /*
   register the samba ldif handlers
 */
@@ -1546,6 +1549,11 @@ int ldb_register_samba_handlers(struct ldb_context *ldb)
 		return LDB_SUCCESS;
 	}
 
+	ret = ldb_set_opaque(ldb, LDB_SECRET_ATTRIBUTE_LIST_OPAQUE, discard_const_p(char *, secret_attributes));
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
 	for (i=0; i < ARRAY_SIZE(samba_attributes); i++) {
 		const struct ldb_schema_syntax *s = NULL;
 
diff --git a/lib/ldb/ABI/ldb-1.1.10.sigs b/lib/ldb/ABI/ldb-1.1.12.sigs
similarity index 99%
copy from lib/ldb/ABI/ldb-1.1.10.sigs
copy to lib/ldb/ABI/ldb-1.1.12.sigs
index de5026e..c8ccd25 100644
--- a/lib/ldb/ABI/ldb-1.1.10.sigs
+++ b/lib/ldb/ABI/ldb-1.1.12.sigs
@@ -106,6 +106,7 @@ ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *)
 ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **)
 ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *)
 ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *)
+ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *)
 ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *)
 ldb_load_modules: int (struct ldb_context *, const char **)
 ldb_map_add: int (struct ldb_module *, struct ldb_request *)
diff --git a/lib/ldb/ABI/pyldb-util-1.1.10.sigs b/lib/ldb/ABI/pyldb-util-1.1.12.sigs
similarity index 100%
copy from lib/ldb/ABI/pyldb-util-1.1.10.sigs
copy to lib/ldb/ABI/pyldb-util-1.1.12.sigs
diff --git a/lib/ldb/common/ldb.c b/lib/ldb/common/ldb.c
index 887a896..49eccb9 100644
--- a/lib/ldb/common/ldb.c
+++ b/lib/ldb/common/ldb.c
@@ -726,6 +726,7 @@ static void ldb_trace_request(struct ldb_context *ldb, struct ldb_request *req)
 {
 	TALLOC_CTX *tmp_ctx = talloc_new(req);
 	unsigned int i;
+	struct ldb_ldif ldif;
 
 	switch (req->operation) {
 	case LDB_SEARCH:
@@ -765,18 +766,36 @@ static void ldb_trace_request(struct ldb_context *ldb, struct ldb_request *req)
 		ldb_debug_add(ldb, " data: %s\n", req->op.extended.data?"yes":"no");
 		break;
 	case LDB_ADD:
+		ldif.changetype = LDB_CHANGETYPE_ADD;
+		ldif.msg = discard_const_p(struct ldb_message, req->op.add.message);
+
 		ldb_debug_add(ldb, "ldb_trace_request: ADD\n");
+
+		/* 
+		 * The choice to call
+		 * ldb_ldif_write_redacted_trace_string() is CRITICAL
+		 * for security.  It ensures that we do not output
+		 * passwords into debug logs 
+		 */
+
 		ldb_debug_add(req->handle->ldb, "%s\n", 
-			      ldb_ldif_message_string(req->handle->ldb, tmp_ctx, 
-						      LDB_CHANGETYPE_ADD, 
-						      req->op.add.message));
+			      ldb_ldif_write_redacted_trace_string(req->handle->ldb, tmp_ctx, &ldif));
 		break;
 	case LDB_MODIFY:
+		ldif.changetype = LDB_CHANGETYPE_MODIFY;
+		ldif.msg = discard_const_p(struct ldb_message, req->op.mod.message);
+
 		ldb_debug_add(ldb, "ldb_trace_request: MODIFY\n");
+
+		/* 
+		 * The choice to call
+		 * ldb_ldif_write_redacted_trace_string() is CRITICAL
+		 * for security.  It ensures that we do not output
+		 * passwords into debug logs 
+		 */
+
 		ldb_debug_add(req->handle->ldb, "%s\n", 
-			      ldb_ldif_message_string(req->handle->ldb, tmp_ctx, 
-						      LDB_CHANGETYPE_MODIFY,
-						      req->op.mod.message));
+			      ldb_ldif_write_redacted_trace_string(req->handle->ldb, tmp_ctx, &ldif));
 		break;
 	case LDB_REQ_REGISTER_CONTROL:
 		ldb_debug_add(ldb, "ldb_trace_request: REGISTER_CONTROL\n");
diff --git a/lib/ldb/common/ldb_ldif.c b/lib/ldb/common/ldb_ldif.c
index c083401..419906b 100644
--- a/lib/ldb/common/ldb_ldif.c
+++ b/lib/ldb/common/ldb_ldif.c
@@ -270,18 +270,20 @@ static const struct {
 #define CHECK_RET do { if (ret < 0) { talloc_free(mem_ctx); return ret; } total += ret; } while (0)
 
 /*
-  write to ldif, using a caller supplied write method
+  write to ldif, using a caller supplied write method, and only printing secrets if we are not in a trace
 */
-int ldb_ldif_write(struct ldb_context *ldb,
-		   int (*fprintf_fn)(void *, const char *, ...), 
-		   void *private_data,
-		   const struct ldb_ldif *ldif)
+static int ldb_ldif_write_trace(struct ldb_context *ldb,
+				int (*fprintf_fn)(void *, const char *, ...), 
+				void *private_data,
+				const struct ldb_ldif *ldif, 
+				bool in_trace)
 {
 	TALLOC_CTX *mem_ctx;
 	unsigned int i, j;
 	int total=0, ret;
 	char *p;
 	const struct ldb_message *msg;
+	const char * const * secret_attributes = ldb_get_opaque(ldb, LDB_SECRET_ATTRIBUTE_LIST_OPAQUE);
 
 	mem_ctx = talloc_named_const(NULL, 0, "ldb_ldif_write");
 
@@ -328,6 +330,14 @@ int ldb_ldif_write(struct ldb_context *ldb,
 				break;
 			}
 		}
+		
+		if (in_trace && secret_attributes && ldb_attr_in_list(secret_attributes, msg->elements[i].name)) {
+			/* Deliberatly skip printing this password */
+			ret = fprintf_fn(private_data, "# %s::: REDACTED SECRET ATTRIBUTE",
+					 msg->elements[i].name);
+			CHECK_RET;
+			continue;
+		}
 
 		for (j=0;j<msg->elements[i].num_values;j++) {
 			struct ldb_val v;
@@ -383,6 +393,18 @@ int ldb_ldif_write(struct ldb_context *ldb,
 
 
 /*
+  write to ldif, using a caller supplied write method
+*/
+int ldb_ldif_write(struct ldb_context *ldb,
+		   int (*fprintf_fn)(void *, const char *, ...), 
+		   void *private_data,
+		   const struct ldb_ldif *ldif)
+{
+	return ldb_ldif_write_trace(ldb, fprintf_fn, private_data, ldif, false);
+}
+
+
+/*
   pull a ldif chunk, which is defined as a piece of data ending in \n\n or EOF
   this routine removes any RFC2849 continuations and comments
 
@@ -727,7 +749,6 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb,
 	char *chunk=NULL, *s;
 	struct ldb_val value;
 	unsigned flags = 0;
-
 	value.data = NULL;
 
 	ldif = talloc(ldb, struct ldb_ldif);
@@ -1002,6 +1023,20 @@ static int ldif_printf_string(void *private_data, const char *fmt, ...)
 	return talloc_get_size(state->string) - oldlen;
 }
 
+char *ldb_ldif_write_redacted_trace_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, 
+					   const struct ldb_ldif *ldif)
+{
+	struct ldif_write_string_state state;
+	state.string = talloc_strdup(mem_ctx, "");
+	if (!state.string) {
+		return NULL;
+	}
+	if (ldb_ldif_write_trace(ldb, ldif_printf_string, &state, ldif, true) == -1) {
+		return NULL;
+	}
+	return state.string;
+}
+
 char *ldb_ldif_write_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, 
 			    const struct ldb_ldif *ldif)
 {
diff --git a/lib/ldb/common/ldb_modules.c b/lib/ldb/common/ldb_modules.c
index 8904d5a..4403656 100644
--- a/lib/ldb/common/ldb_modules.c
+++ b/lib/ldb/common/ldb_modules.c
@@ -709,8 +709,21 @@ int ldb_module_send_entry(struct ldb_request *req,
 	if ((req->handle->ldb->flags & LDB_FLG_ENABLE_TRACING) &&
 	    req->handle->nesting == 0) {
 		char *s;
+		struct ldb_ldif ldif;
+		
+		ldif.changetype = LDB_CHANGETYPE_NONE;
+		ldif.msg = discard_const_p(struct ldb_message, msg);
+
 		ldb_debug_add(req->handle->ldb, "ldb_trace_response: ENTRY\n");
-		s = ldb_ldif_message_string(req->handle->ldb, msg, LDB_CHANGETYPE_NONE, msg);
+
+		/* 
+		 * The choice to call
+		 * ldb_ldif_write_redacted_trace_string() is CRITICAL
+		 * for security.  It ensures that we do not output
+		 * passwords into debug logs 
+		 */
+
+		s = ldb_ldif_write_redacted_trace_string(req->handle->ldb, msg, &ldif);
 		ldb_debug_add(req->handle->ldb, "%s\n", s);
 		talloc_free(s);
 		ldb_debug_end(req->handle->ldb, LDB_DEBUG_TRACE);
diff --git a/lib/ldb/include/ldb_module.h b/lib/ldb/include/ldb_module.h
index 6e14f4c..be50c09 100644
--- a/lib/ldb/include/ldb_module.h
+++ b/lib/ldb/include/ldb_module.h
@@ -55,6 +55,10 @@ struct ldb_module;
 /* an extended match rule that always fails to match */
 #define SAMBA_LDAP_MATCH_ALWAYS_FALSE "1.3.6.1.4.1.7165.4.5.1"
 
+/* The const char * const * pointer to a list of secret (password)
+ * attributes, not to be printed in trace messages */
+#define LDB_SECRET_ATTRIBUTE_LIST_OPAQUE "LDB_SECRET_ATTRIBUTE_LIST"
+
 /*
    these function pointers define the operations that a ldb module can intercept
 */
diff --git a/lib/ldb/include/ldb_private.h b/lib/ldb/include/ldb_private.h
index f07bbc9..7de5ab7 100644
--- a/lib/ldb/include/ldb_private.h
+++ b/lib/ldb/include/ldb_private.h
@@ -181,6 +181,8 @@ struct ldb_val ldb_binary_decode(TALLOC_CTX *mem_ctx, const char *str);
 const char *ldb_options_find(struct ldb_context *ldb, const char *options[],
 			     const char *option_name);
 
+/* The following definitions come from lib/ldb/common/ldb_ldif.c  */
+
 struct ldif_read_file_state {
 	FILE *f;
 	size_t line_no;
@@ -189,4 +191,7 @@ struct ldif_read_file_state {
 struct ldb_ldif *ldb_ldif_read_file_state(struct ldb_context *ldb, 
 					  struct ldif_read_file_state *state);
 
+char *ldb_ldif_write_redacted_trace_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, 
+					   const struct ldb_ldif *ldif);
+
 #endif
diff --git a/lib/ldb/wscript b/lib/ldb/wscript
index 3978dd2..fc4ac4f 100755
--- a/lib/ldb/wscript
+++ b/lib/ldb/wscript
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 
 APPNAME = 'ldb'
-VERSION = '1.1.11'
+VERSION = '1.1.12'
 
 blddir = 'bin'


-- 
Samba Shared Repository


More information about the samba-cvs mailing list