[PATCH] Make AD DC build require Jannsson JSON libs, fix fileserver without it

Andrew Bartlett abartlet at samba.org
Thu Jun 21 19:00:47 UTC 2018


On Thu, 2018-06-21 at 12:56 +0200, Volker Lendecke wrote:
> Hi, Andrew!
> 
> ./configure --prefix=/root/vlendec/inst --without-ldb-lmdb --without-json-audit --without-gpgme --without-libarchive
> 
> leads to

> What am I doing wrong? Am I missing another configure switch?

No, but I think we should just require it for the DC.  Too many
variations that are not covered by autobuild will just keep biting us,
and at best the not-JSON case would be untested code (and so broken
code). 

However, I'm not proposing such a rule for the file server, I realise
this needs to go into much more restrictive environments, so per
Jeremy's request I've added an autobuild target and made the changes so
that build can pass. 

I know this isn't the answer you were looking for, but it is the most
reasonable approach in my view.

I've included the auth duration patches again as I had to fix those up
to also compile, the fixup patch is included separately for clarity and
should be folded in:

CI is here:
https://gitlab.com/catalyst-samba/samba/pipelines/24328549

Please review, fold in the fix-up and push if this approach is
acceptable.

Thanks,

Andrew Bartlett

-- 
Andrew Bartlett                       http://samba.org/~abartlet/
Authentication Developer, Samba Team  http://samba.org
Samba Developer, Catalyst IT          http://catalyst.net.nz/services/samba
-------------- next part --------------
From a69a89c712e7092057990694d1afee9ac30cd753 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Sun, 10 Jun 2018 13:00:34 +0200
Subject: [PATCH 1/8] auth: For NTLM and KDC authentication, log the
 authentication duration

This is not a general purpose profiling solution, but these JSON logs are already being
generated and stored, so this is worth adding.

Some administrators are very keen to know how long authentication
takes, particularly due to long replication transactions in other
processes.

This complements a similar patch set to log the transaction duration.

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 auth/auth_log.c                                | 24 +++++++++++++++++++++++-
 auth/common_auth.h                             |  4 ++++
 python/samba/tests/auth_log.py                 |  3 +++
 source3/auth/auth.c                            | 16 ++++++++++++++--
 source3/include/auth.h                         |  3 +++
 source4/auth/ntlm/auth.c                       |  5 ++++-
 source4/auth/ntlm/auth_simple.c                |  1 +
 source4/dsdb/samdb/ldb_modules/password_hash.c |  1 +
 source4/heimdal/kdc/kerberos5.c                |  5 +++++
 source4/heimdal/lib/hdb/hdb.h                  |  1 +
 source4/kdc/hdb-samba4.c                       |  3 +++
 source4/rpc_server/netlogon/dcerpc_netlogon.c  |  1 +
 source4/rpc_server/samr/samr_password.c        |  1 +
 13 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/auth/auth_log.c b/auth/auth_log.c
index 369a5c96162..4a419796120 100644
--- a/auth/auth_log.c
+++ b/auth/auth_log.c
@@ -114,6 +114,7 @@ static void log_json(struct imessaging_context *msg_ctx,
 static void log_authentication_event_json(
 	struct imessaging_context *msg_ctx,
 	struct loadparm_context *lp_ctx,
+	const struct timeval *start_time,
 	const struct auth_usersupplied_info *ui,
 	NTSTATUS status,
 	const char *domain_name,
@@ -180,6 +181,22 @@ static void log_authentication_event_json(
 	json_add_string(&authentication, "passwordType", get_password_type(ui));
 	json_add_object(&wrapper, AUTH_JSON_TYPE, &authentication);
 
+	/*
+	 * While not a general-purpose profiling solution this will
+	 * assist some to determine how long NTLM and KDC
+	 * authentication takes once this process can handle it.  This
+	 * covers transactions elsewhere but not (eg) the delay while
+	 * this is waiting unread on the input socket.
+	 */
+	if (start_time != NULL) {
+		struct timeval current_time = timeval_current();
+		uint64_t duration =  usec_time_diff(&current_time,
+						    start_time);
+		json_add_int(&authentication,
+			     "duration",
+			     duration);
+	}
+	
 	log_json(msg_ctx,
 		 lp_ctx,
 		 &wrapper,
@@ -296,6 +313,7 @@ static void log_no_json(struct imessaging_context *msg_ctx,
 static void log_authentication_event_json(
 	struct imessaging_context *msg_ctx,
 	struct loadparm_context *lp_ctx,
+	const struct timeval *start_time,
 	const struct auth_usersupplied_info *ui,
 	NTSTATUS status,
 	const char *domain_name,
@@ -311,6 +329,7 @@ static void log_authentication_event_json(
 static void log_successful_authz_event_json(
 	struct imessaging_context *msg_ctx,
 	struct loadparm_context *lp_ctx,
+	const struct timeval *start_time,
 	const struct tsocket_address *remote,
 	const struct tsocket_address *local,
 	const char *service_description,
@@ -470,6 +489,7 @@ static void log_authentication_event_human_readable(
 void log_authentication_event(
 	struct imessaging_context *msg_ctx,
 	struct loadparm_context *lp_ctx,
+	const struct timeval *start_time,
 	const struct auth_usersupplied_info *ui,
 	NTSTATUS status,
 	const char *domain_name,
@@ -498,7 +518,9 @@ void log_authentication_event(
 	}
 	if (CHECK_DEBUGLVLC(DBGC_AUTH_AUDIT_JSON, debug_level) ||
 	    (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx))) {
-		log_authentication_event_json(msg_ctx, lp_ctx,
+		log_authentication_event_json(msg_ctx,
+					      lp_ctx,
+					      start_time,
 					      ui,
 					      status,
 					      domain_name,
diff --git a/auth/common_auth.h b/auth/common_auth.h
index 3de227ee354..3a97aff820d 100644
--- a/auth/common_auth.h
+++ b/auth/common_auth.h
@@ -122,6 +122,9 @@ struct auth4_context {
 	/* SAM database for this local machine - to fill in local groups, or to authenticate local NTLM users */
 	struct ldb_context *sam_ctx;
 
+	/* The time this authentication started */
+	struct timeval start_time;
+	
 	/* Private data for the callbacks on this auth context */
 	void *private_data;
 
@@ -178,6 +181,7 @@ struct auth4_context {
  */
 void log_authentication_event(struct imessaging_context *msg_ctx,
 			      struct loadparm_context *lp_ctx,
+			      const struct timeval *start_time,
 			      const struct auth_usersupplied_info *ui,
 			      NTSTATUS status,
 			      const char *account_name,
diff --git a/python/samba/tests/auth_log.py b/python/samba/tests/auth_log.py
index 6cec63a8171..cb524d0ed81 100644
--- a/python/samba/tests/auth_log.py
+++ b/python/samba/tests/auth_log.py
@@ -430,6 +430,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
                           msg["Authentication"]["serviceDescription"])
         self.assertEquals("ENC-TS Pre-authentication",
                           msg["Authentication"]["authDescription"])
+        self.assertTrue(msg["Authentication"]["duration"] > 0)
 
         # Check the second message it should be an Authentication
         msg = messages[1]
@@ -439,6 +440,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
                           msg["Authentication"]["serviceDescription"])
         self.assertEquals("ENC-TS Pre-authentication",
                           msg["Authentication"]["authDescription"])
+        self.assertTrue(msg["Authentication"]["duration"] > 0)
 
     def test_ldap_ntlm(self):
 
@@ -463,6 +465,7 @@ class AuthLogTests(samba.tests.auth_log_base.AuthLogTestBase):
         self.assertEquals("LDAP",
                           msg["Authentication"]["serviceDescription"])
         self.assertEquals("NTLMSSP", msg["Authentication"]["authDescription"])
+        self.assertTrue(msg["Authentication"]["duration"] > 0)
 
     def test_ldap_simple_bind(self):
         def isLastExpectedMessage(msg):
diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index e0011a47eb3..78c72af5ff3 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -300,7 +300,9 @@ NTSTATUS auth_check_ntlm_password(TALLOC_CTX *mem_ctx,
 	}
 
 	log_authentication_event(NULL, NULL,
-				 user_info, nt_status,
+				 &auth_context->start_time,
+				 user_info,
+				 nt_status,
 				 server_info->info3->base.logon_domain.string,
 				 server_info->info3->base.account_name.string,
 				 unix_username, &sid);
@@ -331,7 +333,15 @@ fail:
 		  user_info->client.account_name, user_info->mapped.account_name,
 		  nt_errstr(nt_status), *pauthoritative));
 
-	log_authentication_event(NULL, NULL, user_info, nt_status, NULL, NULL, NULL, NULL);
+	log_authentication_event(NULL,
+				 NULL,
+ 				 &auth_context->start_time,
+				 user_info,
+				 nt_status,
+				 NULL,
+				 NULL,
+				 NULL,
+				 NULL);
 
 	ZERO_STRUCTP(pserver_info);
 
@@ -373,6 +383,8 @@ static NTSTATUS make_auth_context(TALLOC_CTX *mem_ctx,
 		return NT_STATUS_NO_MEMORY;
 	}
 
+	ctx->start_time = timeval_current();
+	
 	talloc_set_destructor((TALLOC_CTX *)ctx, auth_context_destructor);
 
 	*auth_context = ctx;
diff --git a/source3/include/auth.h b/source3/include/auth.h
index 31a1f201835..5b9bc54b9ce 100644
--- a/source3/include/auth.h
+++ b/source3/include/auth.h
@@ -84,6 +84,9 @@ typedef NTSTATUS (*make_auth4_context_fn)(const struct auth_context *auth_contex
 struct auth_context {
 	DATA_BLOB challenge; 
 
+	/* What time did this start */
+	struct timeval start_time;
+	
 	/* Who set this up in the first place? */ 
 	const char *challenge_set_by; 
 
diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
index e560116b941..b6b3be2f2b1 100644
--- a/source4/auth/ntlm/auth.c
+++ b/source4/auth/ntlm/auth.c
@@ -479,6 +479,7 @@ _PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req,
 
 		log_authentication_event(state->auth_ctx->msg_ctx,
 					 state->auth_ctx->lp_ctx,
+					 &state->auth_ctx->start_time,
 					 state->user_info, status,
 					 NULL, NULL, NULL, NULL);
 		tevent_req_received(req);
@@ -493,6 +494,7 @@ _PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req,
 
 	log_authentication_event(state->auth_ctx->msg_ctx,
 				 state->auth_ctx->lp_ctx,
+				 &state->auth_ctx->start_time,
 				 state->user_info, status,
 				 state->user_info_dc->info->domain_name,
 				 state->user_info_dc->info->account_name,
@@ -712,7 +714,8 @@ _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char *
 	ctx->event_ctx			= ev;
 	ctx->msg_ctx			= msg;
 	ctx->lp_ctx			= lp_ctx;
-
+	ctx->start_time                 = timeval_current();
+	
 	if (sam_ctx) {
 		ctx->sam_ctx = sam_ctx;
 	} else {
diff --git a/source4/auth/ntlm/auth_simple.c b/source4/auth/ntlm/auth_simple.c
index 273e4886125..fcd9050979d 100644
--- a/source4/auth/ntlm/auth_simple.c
+++ b/source4/auth/ntlm/auth_simple.c
@@ -112,6 +112,7 @@ _PUBLIC_ struct tevent_req *authenticate_ldap_simple_bind_send(TALLOC_CTX *mem_c
 					     dn, &nt4_domain, &nt4_username);
 	if (!NT_STATUS_IS_OK(status)) {
 		log_authentication_event(msg, lp_ctx,
+					 &state->auth_context->start_time,
 					 user_info, status,
 					 NULL, NULL, NULL, NULL);
 	}
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index 56ecdaf81c0..58ae64537eb 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -2900,6 +2900,7 @@ static int check_password_restrictions_and_log(struct setup_password_fields_io *
 		}
 		log_authentication_event(msg_ctx,
 					 lp_ctx,
+					 NULL,
 					 &ui,
 					 status,
 					 domain_name,
diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c
index 4baf90e41d8..12187dde429 100644
--- a/source4/heimdal/kdc/kerberos5.c
+++ b/source4/heimdal/kdc/kerberos5.c
@@ -1094,6 +1094,7 @@ _kdc_as_rep(krb5_context context,
 	if (config->db[0] && config->db[0]->hdb_auth_status)
 		(config->db[0]->hdb_auth_status)(context, config->db[0], NULL,
 						 from_addr,
+						 &_kdc_now,
 						 client_name,
 						 NULL,
 						 HDB_AUTH_CLIENT_UNKNOWN);
@@ -1204,6 +1205,7 @@ _kdc_as_rep(krb5_context context,
 	    if (clientdb->hdb_auth_status)
 		    (clientdb->hdb_auth_status)(context, clientdb, client,
 						from_addr,
+						&_kdc_now,
 						client_name,
 						"PKINIT",
 						HDB_AUTH_PKINIT_SUCCESS);
@@ -1323,6 +1325,7 @@ _kdc_as_rep(krb5_context context,
 		if (clientdb->hdb_auth_status)
 		    (clientdb->hdb_auth_status)(context, clientdb, client,
 						from_addr,
+						&_kdc_now,
 						client_name,
 						str ? str : "unknown enctype",
 						HDB_AUTH_WRONG_PASSWORD);
@@ -1386,6 +1389,7 @@ _kdc_as_rep(krb5_context context,
 	    if (clientdb->hdb_auth_status)
 		    (clientdb->hdb_auth_status)(context, clientdb, client,
 						from_addr,
+						&_kdc_now,
 						client_name,
 						str ? str : "unknown enctype",
 						HDB_AUTH_CORRECT_PASSWORD);
@@ -1443,6 +1447,7 @@ _kdc_as_rep(krb5_context context,
     if (clientdb->hdb_auth_status)
 	(clientdb->hdb_auth_status)(context, clientdb, client,
 				    from_addr,
+				    &_kdc_now,
 				    client_name,
 				    NULL,
 				    HDB_AUTHZ_SUCCESS);
diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h
index 1af798d3512..6a09ecb6fe1 100644
--- a/source4/heimdal/lib/hdb/hdb.h
+++ b/source4/heimdal/lib/hdb/hdb.h
@@ -249,6 +249,7 @@ typedef struct HDB{
      */
     krb5_error_code (*hdb_auth_status)(krb5_context, struct HDB *,
 				       hdb_entry_ex *, struct sockaddr *from_addr,
+				       struct timeval *start_time,
 				       const char *original_client_name,
 				       const char *auth_type,
 				       int);
diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c
index 50eed445cd5..cff472574d4 100644
--- a/source4/kdc/hdb-samba4.c
+++ b/source4/kdc/hdb-samba4.c
@@ -388,6 +388,7 @@ static void send_bad_password_netlogon(TALLOC_CTX *mem_ctx,
 static krb5_error_code hdb_samba4_auth_status(krb5_context context, HDB *db,
 					      hdb_entry_ex *entry,
 					      struct sockaddr *from_addr,
+					      struct timeval *start_time,
 					      const char *original_client_name,
 					      const char *auth_type,
 					      int hdb_auth_status)
@@ -494,6 +495,7 @@ static krb5_error_code hdb_samba4_auth_status(krb5_context context, HDB *db,
 
 		log_authentication_event(kdc_db_ctx->msg_ctx,
 					 kdc_db_ctx->lp_ctx,
+					 start_time,
 					 &ui,
 					 status,
 					 domain_name,
@@ -519,6 +521,7 @@ static krb5_error_code hdb_samba4_auth_status(krb5_context context, HDB *db,
 
 		log_authentication_event(kdc_db_ctx->msg_ctx,
 					 kdc_db_ctx->lp_ctx,
+					 start_time,
 					 &ui,
 					 NT_STATUS_NO_SUCH_USER,
 					 NULL, NULL,
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index c19d33c8892..b4046bdd203 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -557,6 +557,7 @@ static NTSTATUS dcesrv_netr_ServerAuthenticate3(
 	log_authentication_event(
 		dce_call->conn->msg_ctx,
 		dce_call->conn->dce_ctx->lp_ctx,
+		NULL,
 		&ui,
 		status,
 		lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx),
diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c
index db202cce986..4c656988879 100644
--- a/source4/rpc_server/samr/samr_password.c
+++ b/source4/rpc_server/samr/samr_password.c
@@ -68,6 +68,7 @@ static void log_password_change_event(struct imessaging_context *msg_ctx,
 
 	log_authentication_event(msg_ctx,
 				 lp_ctx,
+				 NULL,
 				 &ui,
 				 status,
 				 ui.mapped.domain_name,
-- 
2.14.4


From 43ad7f89fb8cf66b3e54435cd41d0cc36a013027 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Fri, 22 Jun 2018 05:09:46 +1200
Subject: [PATCH 2/8] FIXUP: fix auth logging not-json case

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 auth/auth_log.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/auth/auth_log.c b/auth/auth_log.c
index 4a419796120..247649e364e 100644
--- a/auth/auth_log.c
+++ b/auth/auth_log.c
@@ -329,7 +329,6 @@ static void log_authentication_event_json(
 static void log_successful_authz_event_json(
 	struct imessaging_context *msg_ctx,
 	struct loadparm_context *lp_ctx,
-	const struct timeval *start_time,
 	const struct tsocket_address *remote,
 	const struct tsocket_address *local,
 	const char *service_description,
-- 
2.14.4


From ba4082a7de0bc867c5e09fa251e80e1c7ce6c719 Mon Sep 17 00:00:00 2001
From: Gary Lockyer <gary at catalyst.net.nz>
Date: Wed, 6 Jun 2018 15:30:44 +0200
Subject: [PATCH 3/8] dsdb: Log the transaction duraton.

This is not a general purpose profiling solution, but these JSON
logs are already being generated and stored, so this is worth adding.

This will allow administrators to identify long running
transactions, and identify potential performance bottlenecks.

This complements a similar patch set to log authentication duration.

Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
---
 python/samba/tests/audit_log_base.py               |  7 +-
 python/samba/tests/audit_log_dsdb.py               | 83 +++++++++++--------
 source4/dsdb/samdb/ldb_modules/audit_log.c         | 95 ++++++++++++++--------
 .../dsdb/samdb/ldb_modules/tests/test_audit_log.c  | 25 ++++--
 4 files changed, 136 insertions(+), 74 deletions(-)

diff --git a/python/samba/tests/audit_log_base.py b/python/samba/tests/audit_log_base.py
index fa51911e765..6bdefe76eec 100644
--- a/python/samba/tests/audit_log_base.py
+++ b/python/samba/tests/audit_log_base.py
@@ -74,9 +74,9 @@ class AuditLogTestBase(samba.tests.TestCase):
                     isRemote(jsonMsg)):
                 context["messages"].append(jsonMsg)
             elif jsonMsg["type"] == "dsdbTransaction":
-                context["txnMessage"] = jsonMsg
+                context["txnMessage"].append(jsonMsg)
 
-        self.context = {"messages": [], "txnMessage": ""}
+        self.context = {"messages": [], "txnMessage": []}
         self.msg_handler_and_context = (messageHandler, self.context)
         self.msg_ctx.register(self.msg_handler_and_context,
                               msg_type=self.message_type)
@@ -158,8 +158,9 @@ class AuditLogTestBase(samba.tests.TestCase):
     # Discard any previously queued messages.
     def discardMessages(self):
         self.msg_ctx.loop_once(0.001)
-        while len(self.context["messages"]):
+        while len(self.context["messages"]) or len(self.context["txnMessage"]):
             self.context["messages"] = []
+            self.context["txnMessage"] = []
             self.msg_ctx.loop_once(0.001)
 
     GUID_RE = "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
diff --git a/python/samba/tests/audit_log_dsdb.py b/python/samba/tests/audit_log_dsdb.py
index 5329af45e69..d0d45458b23 100644
--- a/python/samba/tests/audit_log_dsdb.py
+++ b/python/samba/tests/audit_log_dsdb.py
@@ -21,6 +21,7 @@ from __future__ import print_function
 
 import samba.tests
 from samba.dcerpc.messaging import MSG_DSDB_LOG, DSDB_EVENT_NAME
+from ldb import ERR_NO_SUCH_OBJECT
 from samba.samdb import SamDB
 from samba.auth import system_session
 import os
@@ -33,8 +34,6 @@ from samba.dcerpc import security, lsa
 
 USER_NAME = "auditlogtestuser"
 USER_PASS = samba.generate_random_password(32, 32)
-SECOND_USER_NAME = "auditlogtestuser02"
-SECOND_USER_PASS = samba.generate_random_password(32, 32)
 
 
 class AuditLogDsdbTests(AuditLogTestBase):
@@ -79,9 +78,6 @@ class AuditLogDsdbTests(AuditLogTestBase):
 
         # (Re)adds the test user USER_NAME with password USER_PASS
         delete_force(self.ldb, "cn=" + USER_NAME + ",cn=users," + self.base_dn)
-        delete_force(
-            self.ldb,
-            "cn=" + SECOND_USER_NAME + ",cn=users," + self.base_dn)
         self.ldb.add({
             "dn": "cn=" + USER_NAME + ",cn=users," + self.base_dn,
             "objectclass": "user",
@@ -93,15 +89,21 @@ class AuditLogDsdbTests(AuditLogTestBase):
     # Discard the messages from the setup code
     #
     def discardSetupMessages(self, dn):
-        messages = self.waitForMessages(2, dn=dn)
+        self.waitForMessages(2, dn=dn)
         self.discardMessages()
 
-
     def tearDown(self):
         self.discardMessages()
         super(AuditLogDsdbTests, self).tearDown()
 
-    def waitForTransaction(self, connection=None):
+    def haveExpectedTxns(self, expected):
+        received = len(self.context["txnMessage"])
+        if received >= expected:
+            return True
+        else:
+            return False
+
+    def waitForTransactions(self, expected, connection=None):
         """Wait for a transaction message to arrive
         The connection is passed through to keep the connection alive
         until all the logging messages have been received.
@@ -110,7 +112,7 @@ class AuditLogDsdbTests(AuditLogTestBase):
         self.connection = connection
 
         start_time = time.time()
-        while self.context["txnMessage"] == "":
+        while not self.haveExpectedTxns(expected):
             self.msg_ctx.loop_once(0.1)
             if time.time() - start_time > 1:
                 self.connection = None
@@ -329,55 +331,70 @@ class AuditLogDsdbTests(AuditLogTestBase):
 
         self.ldb.deleteuser(USER_NAME)
 
-        messages = self.waitForMessages(2, dn=dn)
+        messages = self.waitForMessages(1, dn=dn)
         print("Received %d messages" % len(messages))
-        self.assertEquals(2,
+        self.assertEquals(1,
                           len(messages),
                           "Did not receive the expected number of messages")
 
-        audit = messages[1]["dsdbChange"]
+        audit = messages[0]["dsdbChange"]
         self.assertEquals("Delete", audit["operation"])
         self.assertFalse(audit["performedAsSystem"])
         self.assertTrue(dn.lower(), audit["dn"].lower())
         self.assertRegexpMatches(audit["remoteAddress"],
                                  self.remoteAddress)
         self.assertTrue(self.is_guid(audit["sessionId"]))
+        self.assertEquals(0, audit["statusCode"])
+        self.assertEquals("Success", audit["status"])
         session_id = self.get_session()
         self.assertEquals(session_id, audit["sessionId"])
         service_description = self.get_service_description()
         self.assertEquals(service_description, "LDAP")
 
-    def test_net_set_password_user_without_permission(self):
-
-        self.ldb.newuser(SECOND_USER_NAME, SECOND_USER_PASS)
+        messages = self.waitForTransactions(1)
+        audit = messages[0]["dsdbTransaction"]
+        self.assertEquals("commit", audit["action"])
+        self.assertTrue(self.is_guid(audit["transactionId"]))
+        self.assertTrue(audit["duration"] > 0)
 
-        creds = self.insta_creds(
-            template=self.get_credentials(),
-            username=SECOND_USER_NAME,
-            userpass=SECOND_USER_PASS,
-            kerberos_state=None)
+    def test_samdb_delete_non_existent_dn(self):
 
-        lp = self.get_loadparm()
-        net = Net(creds, lp, server=self.server)
-        password = "newPassword!!42"
-        domain = lp.get("workgroup")
+        DOES_NOT_EXIST = "doesNotExist"
+        dn = "cn=" + USER_NAME + ",cn=users," + self.base_dn
+        self.discardSetupMessages(dn)
 
-        #
-        # This operation should fail and trigger a transaction roll back.
-        #
+        dn = "cn=" + DOES_NOT_EXIST + ",cn=users," + self.base_dn
         try:
-            net.set_password(newpassword=password.encode('utf-8'),
-                             account_name=USER_NAME,
-                             domain_name=domain)
-            self.fail("Expected exception not thrown")
+            self.ldb.delete(dn)
+            self.fail("Exception not thrown")
         except Exception:
             pass
 
-        message = self.waitForTransaction(net)
+        messages = self.waitForMessages(1)
+        print("Received %d messages" % len(messages))
+        self.assertEquals(1,
+                          len(messages),
+                          "Did not receive the expected number of messages")
+
+        audit = messages[0]["dsdbChange"]
+        self.assertEquals("Delete", audit["operation"])
+        self.assertFalse(audit["performedAsSystem"])
+        self.assertTrue(dn.lower(), audit["dn"].lower())
+        self.assertRegexpMatches(audit["remoteAddress"],
+                                 self.remoteAddress)
+        self.assertEquals(ERR_NO_SUCH_OBJECT, audit["statusCode"])
+        self.assertEquals("No such object", audit["status"])
+        self.assertTrue(self.is_guid(audit["sessionId"]))
+        session_id = self.get_session()
+        self.assertEquals(session_id, audit["sessionId"])
+        service_description = self.get_service_description()
+        self.assertEquals(service_description, "LDAP")
 
-        audit = message["dsdbTransaction"]
+        messages = self.waitForTransactions(1)
+        audit = messages[0]["dsdbTransaction"]
         self.assertEquals("rollback", audit["action"])
         self.assertTrue(self.is_guid(audit["transactionId"]))
+        self.assertTrue(audit["duration"] > 0)
 
     def test_create_and_delete_secret_over_lsa(self):
 
diff --git a/source4/dsdb/samdb/ldb_modules/audit_log.c b/source4/dsdb/samdb/ldb_modules/audit_log.c
index 23b4651b32d..80914cb8350 100644
--- a/source4/dsdb/samdb/ldb_modules/audit_log.c
+++ b/source4/dsdb/samdb/ldb_modules/audit_log.c
@@ -49,10 +49,8 @@
 #define TRANSACTION_HR_TAG "DSDB Transaction"
 #define TRANSACTION_MAJOR 1
 #define TRANSACTION_MINOR 0
-/*
- * Currently we only log roll backs and prepare commit failures
- */
-#define TRANSACTION_LOG_LVL 5
+#define TRANSACTION_LOG_FAILURE_LVL 5
+#define TRANSACTION_LOG_COMPLETION_LVL 10
 
 #define REPLICATION_JSON_TYPE "replicatedUpdate"
 #define REPLICATION_HR_TAG "Replicated Update"
@@ -91,6 +89,11 @@ struct audit_context {
 	 * Unique transaction id for the current transaction
 	 */
 	struct GUID transaction_guid;
+	/*
+	 * Transaction start time, used to calculate the transaction
+	 * duration.
+	 */
+	struct timeval transaction_start;
 };
 
 /*
@@ -360,12 +363,15 @@ static struct json_object password_change_json(
  *
  * @param action a one word description of the event/action
  * @param transaction_id the GUID identifying the current transaction.
+ * @param status the status code returned by the operation
+ * @param duration the duration of the operation.
  *
  * @return a JSON object detailing the event
  */
 static struct json_object transaction_json(
 	const char *action,
-	struct GUID *transaction_id)
+	struct GUID *transaction_id,
+	const int64_t duration)
 {
 	struct json_object wrapper;
 	struct json_object audit;
@@ -374,6 +380,8 @@ static struct json_object transaction_json(
 	json_add_version(&audit, TRANSACTION_MAJOR, TRANSACTION_MINOR);
 	json_add_string(&audit, "action", action);
 	json_add_guid(&audit, "transactionId", transaction_id);
+	json_add_int(&audit, "duration", duration);
+
 
 	wrapper = json_new_object();
 	json_add_timestamp(&wrapper);
@@ -396,6 +404,7 @@ static struct json_object transaction_json(
  */
 static struct json_object commit_failure_json(
 	const char *action,
+	const int64_t duration,
 	int status,
 	const char *reason,
 	struct GUID *transaction_id)
@@ -407,6 +416,7 @@ static struct json_object commit_failure_json(
 	json_add_version(&audit, TRANSACTION_MAJOR, TRANSACTION_MINOR);
 	json_add_string(&audit, "action", action);
 	json_add_guid(&audit, "transactionId", transaction_id);
+	json_add_int(&audit, "duration", duration);
 	json_add_int(&audit, "statusCode", status);
 	json_add_string(&audit, "status", ldb_strerror(status));
 	json_add_string(&audit, "reason", reason);
@@ -719,13 +729,14 @@ static char *replicated_update_human_readable(
  *
  * @param mem_ctx The talloc context owning the returned string.
  * @param action a one word description of the event/action
- * @param transaction_id the GUID identifying the current transaction.
+ * @param duration the duration of the transaction.
  *
  * @return the log entry
  */
 static char *transaction_human_readable(
 	TALLOC_CTX *mem_ctx,
-	const char* action)
+	const char* action,
+	const int64_t duration)
 {
 	const char *timestamp = NULL;
 	char *log_entry = NULL;
@@ -736,9 +747,10 @@ static char *transaction_human_readable(
 
 	log_entry = talloc_asprintf(
 		mem_ctx,
-		"[%s] at [%s]",
+		"[%s] at [%s] duration [%ld]",
 		action,
-		timestamp);
+		timestamp,
+		duration);
 
 	TALLOC_FREE(ctx);
 	return log_entry;
@@ -759,6 +771,7 @@ static char *transaction_human_readable(
 static char *commit_failure_human_readable(
 	TALLOC_CTX *mem_ctx,
 	const char *action,
+	const int64_t duration,
 	int status,
 	const char *reason)
 {
@@ -771,9 +784,10 @@ static char *commit_failure_human_readable(
 
 	log_entry = talloc_asprintf(
 		mem_ctx,
-		"[%s] at [%s] status [%d] reason [%s]",
+		"[%s] at [%s] duration [%ld] status [%d] reason [%s]",
 		action,
 		timestamp,
+		duration,
 		status,
 		reason);
 
@@ -976,40 +990,47 @@ static void log_operation(
  * and send over the message bus.
  *
  * @param module the ldb_module
- * @param  action the transaction event i.e. begin, commit, roll back.
+ * @param action the transaction event i.e. begin, commit, roll back.
+ * @param log_level the logging level
  *
  */
 static void log_transaction(
 	struct ldb_module *module,
-	const char *action)
+	const char *action,
+	int log_level)
 {
 
 	struct audit_context *ac =
 		talloc_get_type(ldb_module_get_private(module),
 				struct audit_context);
+	const struct timeval now = timeval_current();
+	const int64_t duration = usec_time_diff(&now, &ac->transaction_start);
 
 	TALLOC_CTX *ctx = talloc_new(NULL);
 
-	if (CHECK_DEBUGLVLC(DBGC_DSDB_TXN_AUDIT, TRANSACTION_LOG_LVL)) {
+	if (CHECK_DEBUGLVLC(DBGC_DSDB_TXN_AUDIT, log_level)) {
 		char* entry = NULL;
-		entry = transaction_human_readable(ctx, action);
+		entry = transaction_human_readable(ctx, action, duration);
 		audit_log_human_text(
 			TRANSACTION_HR_TAG,
 			entry,
 			DBGC_DSDB_TXN_AUDIT,
-			TRANSACTION_LOG_LVL);
+			log_level);
 		TALLOC_FREE(entry);
 	}
 #ifdef HAVE_JANSSON
-	if (CHECK_DEBUGLVLC(DBGC_DSDB_TXN_AUDIT_JSON, TRANSACTION_LOG_LVL) ||
+	if (CHECK_DEBUGLVLC(DBGC_DSDB_TXN_AUDIT_JSON, log_level) ||
 		(ac->msg_ctx && ac->send_samdb_events)) {
 		struct json_object json;
-		json = transaction_json(action, &ac->transaction_guid);
+		json = transaction_json(
+			action,
+			&ac->transaction_guid,
+			duration);
 		audit_log_json(
 			TRANSACTION_JSON_TYPE,
 			&json,
 			DBGC_DSDB_TXN_AUDIT_JSON,
-			TRANSACTION_LOG_LVL);
+			log_level);
 		if (ac->send_samdb_events) {
 			audit_message_send(
 				ac->msg_ctx,
@@ -1044,29 +1065,35 @@ static void log_commit_failure(
 		talloc_get_type(ldb_module_get_private(module),
 				struct audit_context);
 	const char* reason = dsdb_audit_get_ldb_error_string(module, status);
+	const int log_level = TRANSACTION_LOG_FAILURE_LVL;
+	const struct timeval now = timeval_current();
+	const int64_t duration = usec_time_diff(&now, &ac->transaction_start);
 
 	TALLOC_CTX *ctx = talloc_new(NULL);
 
-	if (CHECK_DEBUGLVLC(DBGC_DSDB_TXN_AUDIT, TRANSACTION_LOG_LVL)) {
+	if (CHECK_DEBUGLVLC(DBGC_DSDB_TXN_AUDIT, log_level)) {
+
 		char* entry = NULL;
 		entry = commit_failure_human_readable(
 			ctx,
 			action,
+			duration,
 			status,
 			reason);
 		audit_log_human_text(
 			TRANSACTION_HR_TAG,
 			entry,
 			DBGC_DSDB_TXN_AUDIT,
-			TRANSACTION_LOG_LVL);
+			TRANSACTION_LOG_FAILURE_LVL);
 		TALLOC_FREE(entry);
 	}
 #ifdef HAVE_JANSSON
-	if (CHECK_DEBUGLVLC(DBGC_DSDB_TXN_AUDIT_JSON, TRANSACTION_LOG_LVL) ||
+	if (CHECK_DEBUGLVLC(DBGC_DSDB_TXN_AUDIT_JSON, log_level) ||
 		(ac->msg_ctx && ac->send_samdb_events)) {
 		struct json_object json;
 		json = commit_failure_json(
 			action,
+			duration,
 			status,
 			reason,
 			&ac->transaction_guid);
@@ -1074,7 +1101,7 @@ static void log_commit_failure(
 			TRANSACTION_JSON_TYPE,
 			&json,
 			DBGC_DSDB_TXN_AUDIT_JSON,
-			TRANSACTION_LOG_LVL);
+			log_level);
 		if (ac->send_samdb_events) {
 			audit_message_send(ac->msg_ctx,
 					   DSDB_EVENT_NAME,
@@ -1361,10 +1388,12 @@ static int log_start_transaction(struct ldb_module *module)
 
 	/*
 	 * We do not log transaction begins
-	 * however we do generate a new transaction_id
+	 * however we do generate a new transaction_id and record the start
+	 * time so that we can log the transaction duration.
 	 *
 	 */
 	ac->transaction_guid = GUID_random();
+	ac->transaction_start = timeval_current();
 	return ldb_next_start_trans(module);
 }
 
@@ -1410,18 +1439,20 @@ static int log_end_transaction(struct ldb_module *module)
 				struct audit_context);
 	int ret = 0;
 
-	/*
-	 * Clear the transaction id inserted by log_start_transaction
-	 */
-	memset(&ac->transaction_guid, 0, sizeof(struct GUID));
 
 	ret = ldb_next_end_trans(module);
-	if (ret != LDB_SUCCESS) {
-		/*
-		 * We currently only log commit failures
-		 */
+	if (ret == LDB_SUCCESS) {
+		log_transaction(
+			module,
+			"commit",
+			TRANSACTION_LOG_COMPLETION_LVL);
+	} else {
 		log_commit_failure(module, "commit", ret);
 	}
+	/*
+	 * Clear the transaction id inserted by log_start_transaction
+	 */
+	memset(&ac->transaction_guid, 0, sizeof(struct GUID));
 	return ret;
 }
 
@@ -1441,7 +1472,7 @@ static int log_del_transaction(struct ldb_module *module)
 		talloc_get_type(ldb_module_get_private(module),
 				struct audit_context);
 
-	log_transaction(module, "rollback");
+	log_transaction(module, "rollback", TRANSACTION_LOG_FAILURE_LVL);
 	memset(&ac->transaction_guid, 0, sizeof(struct GUID));
 	return ldb_next_del_trans(module);
 }
diff --git a/source4/dsdb/samdb/ldb_modules/tests/test_audit_log.c b/source4/dsdb/samdb/ldb_modules/tests/test_audit_log.c
index 567c5b345d8..6ceea80f155 100644
--- a/source4/dsdb/samdb/ldb_modules/tests/test_audit_log.c
+++ b/source4/dsdb/samdb/ldb_modules/tests/test_audit_log.c
@@ -1016,7 +1016,7 @@ static void test_transaction_json(void **state)
 	GUID_from_string(GUID, &guid);
 
 	before = time(NULL);
-	json = transaction_json("delete", &guid);
+	json = transaction_json("delete", &guid, 10000099);
 
 	assert_int_equal(3, json_object_size(json.root));
 
@@ -1033,7 +1033,7 @@ static void test_transaction_json(void **state)
 	audit = json_object_get(json.root, "dsdbTransaction");
 	assert_non_null(audit);
 	assert_true(json_is_object(audit));
-	assert_int_equal(3, json_object_size(audit));
+	assert_int_equal(4, json_object_size(audit));
 
 	o = json_object_get(audit, "version");
 	assert_non_null(o);
@@ -1049,6 +1049,11 @@ static void test_transaction_json(void **state)
 	assert_true(json_is_string(v));
 	assert_string_equal("delete", json_string_value(v));
 
+	v = json_object_get(audit, "duration");
+	assert_non_null(v);
+	assert_true(json_is_integer(v));
+	assert_int_equal(10000099, json_integer_value(v));
+
 	json_free(&json);
 
 }
@@ -1074,6 +1079,7 @@ static void test_commit_failure_json(void **state)
 	before = time(NULL);
 	json = commit_failure_json(
 		"prepare",
+		987876,
 		LDB_ERR_OPERATIONS_ERROR,
 		"because",
 		&guid);
@@ -1093,7 +1099,7 @@ static void test_commit_failure_json(void **state)
 	audit = json_object_get(json.root, "dsdbTransaction");
 	assert_non_null(audit);
 	assert_true(json_is_object(audit));
-	assert_int_equal(6, json_object_size(audit));
+	assert_int_equal(7, json_object_size(audit));
 
 	o = json_object_get(audit, "version");
 	assert_non_null(o);
@@ -1126,6 +1132,11 @@ static void test_commit_failure_json(void **state)
 	assert_true(json_is_string(v));
 	assert_string_equal("because", json_string_value(v));
 
+	v = json_object_get(audit, "duration");
+	assert_non_null(v);
+	assert_true(json_is_integer(v));
+	assert_int_equal(987876, json_integer_value(v));
+
 	json_free(&json);
 
 }
@@ -1829,14 +1840,14 @@ static void test_transaction_hr(void **state)
 
 	GUID_from_string(GUID, &guid);
 
-	line = transaction_human_readable(ctx, "delete");
+	line = transaction_human_readable(ctx, "delete", 23);
 	assert_non_null(line);
 
 	/*
 	 * We ignore the timestamp to make this test a little easier
 	 * to write.
 	 */
-	rs = "\\[delete] at \\[[^[]*\\]";
+	rs = "\\[delete] at \\[[^[]*\\] duration \\[23\\]";
 
 	ret = regcomp(&regex, rs, 0);
 	assert_int_equal(0, ret);
@@ -1871,6 +1882,7 @@ static void test_commit_failure_hr(void **state)
 	line = commit_failure_human_readable(
 		ctx,
 		"commit",
+		789345,
 		LDB_ERR_OPERATIONS_ERROR,
 		"because");
 
@@ -1880,7 +1892,8 @@ static void test_commit_failure_hr(void **state)
 	 * We ignore the timestamp to make this test a little easier
 	 * to write.
 	 */
-	rs = "\\[commit\\] at \\[[^[]*\\] status \\[1\\] reason \\[because\\]";
+	rs = "\\[commit\\] at \\[[^[]*\\] duration \\[789345\\] "
+	     "status \\[1\\] reason \\[because\\]";
 
 	ret = regcomp(&regex, rs, 0);
 	assert_int_equal(0, ret);
-- 
2.14.4


From f8b031bb9516f36004c44577eaf7a2b87d0f278c Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Fri, 22 Jun 2018 04:47:10 +1200
Subject: [PATCH 4/8] build: Move --without-json-audit and json lib detection
 to lib/audit_logging

This is the common location of the audit logging code now

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 {auth => lib/audit_logging}/wscript | 0
 wscript                             | 5 ++---
 2 files changed, 2 insertions(+), 3 deletions(-)
 rename {auth => lib/audit_logging}/wscript (100%)

diff --git a/auth/wscript b/lib/audit_logging/wscript
similarity index 100%
rename from auth/wscript
rename to lib/audit_logging/wscript
diff --git a/wscript b/wscript
index dbfc1210f7f..b1b69c15a20 100644
--- a/wscript
+++ b/wscript
@@ -35,7 +35,7 @@ def system_mitkrb5_callback(option, opt, value, parser):
 def set_options(opt):
     opt.BUILTIN_DEFAULT('NONE')
     opt.PRIVATE_EXTENSION_DEFAULT('samba4')
-    opt.RECURSE('auth')
+    opt.RECURSE('lib/audit_logging')
     opt.RECURSE('lib/replace')
     opt.RECURSE('dynconfig')
     opt.RECURSE('packaging')
@@ -213,7 +213,7 @@ def configure(conf):
     # system-provided or embedded Heimdal build
     if conf.CONFIG_GET('KRB5_VENDOR') in (None, 'heimdal'):
         conf.RECURSE('source4/heimdal_build')
-    conf.RECURSE('auth')
+    conf.RECURSE('lib/audit_logging')
     conf.RECURSE('source4/lib/tls')
     conf.RECURSE('source4/dsdb/samdb/ldb_modules')
     conf.RECURSE('source4/ntvfs/sysdep')
@@ -251,7 +251,6 @@ def configure(conf):
     if conf.env.with_ctdb:
         conf.RECURSE('ctdb')
     conf.RECURSE('lib/socket')
-    conf.RECURSE('auth')
     conf.RECURSE('packaging')
 
     conf.SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS()
-- 
2.14.4


From ce6f76a3ba03393023061cd1e8106132f30c04a4 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Fri, 22 Jun 2018 04:50:09 +1200
Subject: [PATCH 5/8] lib/audit_logging: Require jansson JSON library for
 building the AD DC

This combination is untested and it is reasonable to require this
broadly available library for the AD DC build.

Doing so keeps the combinational complexity down and ensures we test
what we ship.  (It was failing to compile).

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 lib/audit_logging/wscript | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/lib/audit_logging/wscript b/lib/audit_logging/wscript
index 7b2c65effe0..d40fc6f079f 100644
--- a/lib/audit_logging/wscript
+++ b/lib/audit_logging/wscript
@@ -21,15 +21,16 @@ def configure(conf):
 
     if not conf.CONFIG_GET('HAVE_JSON_OBJECT'):
         if Options.options.with_json_audit != False:
-            conf.fatal("JSON support not found. "
+            conf.fatal("Jansson JSON support not found. "
                        "Try installing libjansson-dev or jansson-devel. "
                        "Otherwise, use --without-json-audit to build without "
                        "JSON support. "
                        "JSON support is required for the JSON "
-                       "formatted audit log feature")
-        if conf.CONFIG_GET('ENABLE_SELFTEST') and \
-          (not Options.options.without_ad_dc):
-            raise Utils.WafError('jansson JSON library required for '
-                                 '--enable-selftest when building the AD DC')
-        Logs.info("Building without jansson json log support")
+                       "formatted audit log feature and the AD DC")
+        if not Options.options.without_ad_dc:
+            raise Utils.WafError('--without-json-audit requires '
+                                 '--without-ad-dc. '
+                                 'Jansson JSON library is required for '
+                                 'building the AD DC')
+        Logs.info("Building without Jansson JSON log support")
 
-- 
2.14.4


From 0c00ea3df0259e731fa7b3eb91da46f2d6266bbe Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Fri, 22 Jun 2018 05:39:08 +1200
Subject: [PATCH 6/8] lib/audit_logging: Only build audit_logging_test for
 --enable-selftest on the AD DC

This allows a --without-ad-dc --enable-selftest build to compile, still testing some
fileserver-only features.

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 lib/audit_logging/wscript_build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/audit_logging/wscript_build b/lib/audit_logging/wscript_build
index fff683788d6..24ac8bb4789 100644
--- a/lib/audit_logging/wscript_build
+++ b/lib/audit_logging/wscript_build
@@ -9,7 +9,7 @@ bld.SAMBA_SUBSYSTEM(
     source='audit_logging.c'
 )
 
-if bld.CONFIG_SET('ENABLE_SELFTEST'):
+if bld.AD_DC_BUILD_IS_ENABLED() and bld.CONFIG_GET('ENABLE_SELFTEST'):
     bld.SAMBA_BINARY(
         'audit_logging_test',
         source='tests/audit_logging_test.c',
-- 
2.14.4


From f9a1222fc80404ec68a587bab56b875c158949ed Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Fri, 22 Jun 2018 05:18:52 +1200
Subject: [PATCH 7/8] dsdb: Ensure a build --without-json-audit --without-ad-dc
 compiles

We still build some of the ldb_modules even when we are not a DC, so we must
split up the DSDB_MODULE_HELPERS.

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 source4/dsdb/samdb/ldb_modules/audit_log.c         |  1 +
 source4/dsdb/samdb/ldb_modules/audit_util.c        |  1 +
 source4/dsdb/samdb/ldb_modules/group_audit.c       |  1 +
 source4/dsdb/samdb/ldb_modules/wscript_build       | 46 +-----------------
 .../dsdb/samdb/ldb_modules/wscript_build_server    | 55 +++++++++++++++++++++-
 5 files changed, 58 insertions(+), 46 deletions(-)

diff --git a/source4/dsdb/samdb/ldb_modules/audit_log.c b/source4/dsdb/samdb/ldb_modules/audit_log.c
index 80914cb8350..fc2eb502361 100644
--- a/source4/dsdb/samdb/ldb_modules/audit_log.c
+++ b/source4/dsdb/samdb/ldb_modules/audit_log.c
@@ -29,6 +29,7 @@
 
 #include "dsdb/samdb/samdb.h"
 #include "dsdb/samdb/ldb_modules/util.h"
+#include "dsdb/samdb/ldb_modules/audit_util_proto.h"
 #include "libcli/security/dom_sid.h"
 #include "auth/common_auth.h"
 #include "param/param.h"
diff --git a/source4/dsdb/samdb/ldb_modules/audit_util.c b/source4/dsdb/samdb/ldb_modules/audit_util.c
index be2c522ace7..766c34c1e23 100644
--- a/source4/dsdb/samdb/ldb_modules/audit_util.c
+++ b/source4/dsdb/samdb/ldb_modules/audit_util.c
@@ -33,6 +33,7 @@
 #include "auth/common_auth.h"
 #include "param/param.h"
 #include "dsdb/samdb/ldb_modules/util.h"
+#include "dsdb/samdb/ldb_modules/audit_util_proto.h"
 
 #define MAX_LENGTH 1024
 
diff --git a/source4/dsdb/samdb/ldb_modules/group_audit.c b/source4/dsdb/samdb/ldb_modules/group_audit.c
index dc586777736..bbd124af156 100644
--- a/source4/dsdb/samdb/ldb_modules/group_audit.c
+++ b/source4/dsdb/samdb/ldb_modules/group_audit.c
@@ -28,6 +28,7 @@
 
 #include "dsdb/samdb/samdb.h"
 #include "dsdb/samdb/ldb_modules/util.h"
+#include "dsdb/samdb/ldb_modules/audit_util_proto.h"
 #include "libcli/security/dom_sid.h"
 #include "auth/common_auth.h"
 #include "param/param.h"
diff --git a/source4/dsdb/samdb/ldb_modules/wscript_build b/source4/dsdb/samdb/ldb_modules/wscript_build
index 1216a1fd99f..9e0ac281cc6 100644
--- a/source4/dsdb/samdb/ldb_modules/wscript_build
+++ b/source4/dsdb/samdb/ldb_modules/wscript_build
@@ -7,9 +7,9 @@ bld.SAMBA_LIBRARY('dsdb-module',
 	grouping_library=True)
 
 bld.SAMBA_SUBSYSTEM('DSDB_MODULE_HELPERS',
-	source='util.c acl_util.c schema_util.c netlogon.c audit_util.c',
+	source='util.c acl_util.c schema_util.c netlogon.c',
 	autoproto='util_proto.h',
-	deps='ldb ndr samdb-common samba-security audit_logging'
+	deps='ldb ndr samdb-common samba-security'
 	)
 
 bld.SAMBA_SUBSYSTEM('DSDB_MODULE_HELPER_RIDALLOC',
@@ -41,47 +41,5 @@ bld.SAMBA_BINARY('test_encrypted_secrets',
         ''',
         install=False)
 
-#
-# These tests require JANSSON, so we only build them if we are doing a selftest
-# build.
-#
-if bld.CONFIG_GET('ENABLE_SELFTEST'):
-    bld.SAMBA_BINARY('test_audit_util',
-            source='tests/test_audit_util.c',
-            deps='''
-                talloc
-                samba-util
-                samdb-common
-                samdb
-                cmocka
-                audit_logging
-                DSDB_MODULE_HELPERS
-            ''',
-            install=False)
-    bld.SAMBA_BINARY('test_audit_log',
-            source='tests/test_audit_log.c',
-            deps='''
-                talloc
-                samba-util
-                samdb-common
-                samdb
-                cmocka
-                audit_logging
-                DSDB_MODULE_HELPERS
-            ''',
-            install=False)
-    bld.SAMBA_BINARY('test_group_audit',
-            source='tests/test_group_audit.c',
-            deps='''
-                talloc
-                samba-util
-                samdb-common
-                samdb
-                cmocka
-                audit_logging
-                DSDB_MODULE_HELPERS
-            ''',
-            install=False)
-
 if bld.AD_DC_BUILD_IS_ENABLED():
     bld.PROCESS_SEPARATE_RULE("server")
diff --git a/source4/dsdb/samdb/ldb_modules/wscript_build_server b/source4/dsdb/samdb/ldb_modules/wscript_build_server
index e5c503239df..39c9477db80 100644
--- a/source4/dsdb/samdb/ldb_modules/wscript_build_server
+++ b/source4/dsdb/samdb/ldb_modules/wscript_build_server
@@ -1,5 +1,56 @@
 #!/usr/bin/env python
 
+bld.SAMBA_SUBSYSTEM('DSDB_MODULE_HELPERS_AUDIT',
+	            source='audit_util.c',
+	            autoproto='audit_util_proto.h',
+	            deps='DSDB_MODULE_HELPERS audit_logging')
+
+#
+# These tests require JANSSON, so we only build them if we are doing a
+# build on the AD DC (where Jansson is required).
+#
+
+bld.SAMBA_BINARY('test_audit_util',
+                 source='tests/test_audit_util.c',
+                 deps='''
+                 talloc
+                 samba-util
+                 samdb-common
+                 samdb
+                 cmocka
+                 audit_logging
+                 DSDB_MODULE_HELPERS
+                 ''',
+                 install=False)
+
+bld.SAMBA_BINARY('test_audit_log',
+                 source='tests/test_audit_log.c',
+                 deps='''
+                 talloc
+                 samba-util
+                 samdb-common
+                 samdb
+                 cmocka
+                 audit_logging
+                 DSDB_MODULE_HELPERS
+                 DSDB_MODULE_HELPERS_AUDIT
+                 ''',
+                 install=False)
+
+bld.SAMBA_BINARY('test_group_audit',
+                 source='tests/test_group_audit.c',
+                 deps='''
+                 talloc
+                 samba-util
+                 samdb-common
+                 samdb
+                 cmocka
+                 audit_logging
+                 DSDB_MODULE_HELPERS
+                 DSDB_MODULE_HELPERS_AUDIT
+                 ''',
+                 install=False)
+
 bld.SAMBA_MODULE('ldb_samba_dsdb',
 	source='samba_dsdb.c',
 	subsystem='ldb',
@@ -437,7 +488,7 @@ bld.SAMBA_MODULE('ldb_audit_log',
             talloc
             samba-util
             samdb-common
-            DSDB_MODULE_HELPERS
+            DSDB_MODULE_HELPERS_AUDIT
             samdb
         '''
 	)
@@ -453,7 +504,7 @@ bld.SAMBA_MODULE('ldb_group_audit_log',
             talloc
             samba-util
             samdb-common
-            DSDB_MODULE_HELPERS
+            DSDB_MODULE_HELPERS_AUDIT
             samdb
         '''
 	)
-- 
2.14.4


From 645619aae09e41255d5ea91fb56cfbbdbaa91b8f Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Fri, 22 Jun 2018 05:32:29 +1200
Subject: [PATCH 8/8] autobuild: Build samba-fileserver --without-json-audit

This build target is already --without-ad-dc and is the one we need to ensure is
compatible with a host without the Jansson JSON library.

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 script/autobuild.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/script/autobuild.py b/script/autobuild.py
index 429d6443792..a13b731b008 100755
--- a/script/autobuild.py
+++ b/script/autobuild.py
@@ -131,7 +131,7 @@ tasks = {
 
     # We split out this so the isolated ad_dc tests do not wait for ad_dc_ntvfs tests (which are long)
     "samba-fileserver" : [ ("random-sleep", "../script/random-sleep.sh 60 600", "text/plain"),
-                      ("configure", "./configure.developer --without-ad-dc --without-ldap --without-ads --with-selftest-prefix=./bin/ab" + samba_configure_params, "text/plain"),
+                      ("configure", "./configure.developer --without-ad-dc --without-ldap --without-ads --without-json-audit --with-selftest-prefix=./bin/ab" + samba_configure_params, "text/plain"),
                       ("make", "make -j", "text/plain"),
                       ("test", "make test FAIL_IMMEDIATELY=1 TESTS='--include-env=fileserver'", "text/plain"),
                       ("check-clean-tree", "script/clean-source-tree.sh", "text/plain")],
-- 
2.14.4



More information about the samba-technical mailing list