The branch, master has been updated via 42dde0bdd3a group_audit: Ensure we still log membership changes (with an error) where status != LDB_SUCCESS via 27273a55dd0 tests group_audit: PEP8 cleanup. via 87a8325a0d5 s4 group_audit: Add Windows Event Id's to Group membership changes via b99b51400c3 build: Remove --timestamp-dependencies (BROKEN) from 22f1c4005ca paged results: testing suite for new paged results module
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 42dde0bdd3af8aaa6350fec36fb99b98ab501aa1 Author: Andrew Bartlett <abart...@samba.org> Date: Fri Dec 21 14:51:54 2018 +1300 group_audit: Ensure we still log membership changes (with an error) where status != LDB_SUCCESS This restores the previous behaviour. It causes (only) the event ID to be omitted if status != LDB_SUCCESS or there was a problem getting the group type. Errors at this stage are exceedingly rare, because the values have already been checked by the repl_meta_data module, but this is cosistent with the rest of the module again. Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Autobuild-User(master): Andrew Bartlett <abart...@samba.org> Autobuild-Date(master): Sat Dec 22 01:58:48 CET 2018 on sn-devel-144 commit 27273a55dd0634db9324c74a73b80a1989a64372 Author: Gary Lockyer <g...@catalyst.net.nz> Date: Wed Dec 19 09:29:23 2018 +1300 tests group_audit: PEP8 cleanup. Remove Flake8 warnings from the group audit JSON log tests. Signed-off-by: Gary Lockyer <g...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit 87a8325a0d511ec2177ef501828b50deb0ce50b9 Author: Gary Lockyer <g...@catalyst.net.nz> Date: Wed Dec 19 09:08:22 2018 +1300 s4 group_audit: Add Windows Event Id's to Group membership changes Generate a GroupChange event when a user is created with a PrimaryGroup membership. Log the windows event id in the JSON GroupChange message. Event Id's supported are: 4728 A member was added to a security enabled global group 4729 A member was removed from a security enabled global group 4732 A member was added to a security enabled local group 4733 A member was removed from a security enabled local group 4746 A member was added to a security disabled local group 4747 A member was removed from a security disabled local group 4751 A member was added to a security disabled global group 4752 A member was removed from a security disabled global group 4756 A member was added to a security enabled universal group 4757 A member was removed from a security enabled universal group 4761 A member was added to a security disabled universal group 4762 A member was removed from a security disabled universal group Signed-off-by: Gary Lockyer <g...@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abart...@samba.org> commit b99b51400c3e3e40b848d57d01f67b8d72d772b5 Author: Andrew Bartlett <abart...@samba.org> Date: Tue Dec 18 16:27:14 2018 +1300 build: Remove --timestamp-dependencies (BROKEN) Remove this code marked as broken, we do not need broken configure options making Samba appear to be more complex than it already is. Signed-off-by: Andrew Bartlett <abart...@samba.org> Reviewed-by: Gary Lockyer <g...@catalyst.net.nz> ----------------------------------------------------------------------- Summary of changes: WHATSNEW.txt | 24 +- buildtools/wafsamba/wafsamba.py | 16 -- buildtools/wafsamba/wscript | 6 - librpc/idl/windows_event_ids.idl | 21 +- python/samba/tests/group_audit.py | 53 ++++- source4/dsdb/samdb/ldb_modules/group_audit.c | 252 +++++++++++++++------ .../samdb/ldb_modules/tests/test_group_audit.c | 199 ++++++++++++---- .../ldb_modules/tests/test_group_audit_errors.c | 71 +++--- 8 files changed, 462 insertions(+), 180 deletions(-) Changeset truncated at 500 lines: diff --git a/WHATSNEW.txt b/WHATSNEW.txt index 6698b09d8bc..5f237713015 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -118,17 +118,39 @@ type "logonType". The supported event codes and logon types are: 2 Interactive 3 Network 8 NetworkCleartext + The version number for Authentication messages is now 1.1, changed from 1.0 Password change messages now contain the Windows Event Id "eventId", the supported event Id's are: 4723 Password changed 4724 Password reset + The version number for PasswordChange messages is now 1.1, changed from 1.0 +Group membership change messages now contain the Windows Event Id "eventId", +the supported event Id's are: + 4728 A member was added to a security enabled global group + 4729 A member was removed from a security enabled global group + 4732 A member was added to a security enabled local group + 4733 A member was removed from a security enabled local group + 4746 A member was added to a security disabled local group + 4747 A member was removed from a security disabled local group + 4751 A member was added to a security disabled global group + 4752 A member was removed from a security disabled global group + 4756 A member was added to a security enabled universal group + 4757 A member was removed from a security enabled universal group + 4761 A member was added to a security disabled universal group + 4762 A member was removed from a security disabled universal group + + +The version number for GroupChange messages is now 1.1, changed from 1.0. Also +A GroupChange message is generated when a new user is created to log that the +user has been added to their primary group. + The leading "JSON <message type>:" and source file prefix of the JSON formatted log entries has been removed to make the parsing of the JSON log messages -easier. JSON log entries now start with 2 spaces folowed by an opening brace +easier. JSON log entries now start with 2 spaces followed by an opening brace i.e. " {" diff --git a/buildtools/wafsamba/wafsamba.py b/buildtools/wafsamba/wafsamba.py index 230a76d8f2c..a077026c690 100644 --- a/buildtools/wafsamba/wafsamba.py +++ b/buildtools/wafsamba/wafsamba.py @@ -721,22 +721,6 @@ Build.BuildContext.SET_BUILD_GROUP = SET_BUILD_GROUP -@conf -def ENABLE_TIMESTAMP_DEPENDENCIES(conf): - """use timestamps instead of file contents for deps - this currently doesn't work""" - def h_file(filename): - import stat - st = os.stat(filename) - if stat.S_ISDIR(st[stat.ST_MODE]): raise IOError('not a file') - m = Utils.md5() - m.update(str(st.st_mtime)) - m.update(str(st.st_size)) - m.update(filename) - return m.digest() - Utils.h_file = h_file - - def SAMBA_SCRIPT(bld, name, pattern, installdir, installname=None): '''used to copy scripts from the source tree into the build directory for use by selftest''' diff --git a/buildtools/wafsamba/wscript b/buildtools/wafsamba/wscript index 164a9ff6dda..7b8fb01db5e 100644 --- a/buildtools/wafsamba/wscript +++ b/buildtools/wafsamba/wscript @@ -115,9 +115,6 @@ def options(opt): gr.add_option('--enable-gccdeps', help=("Enable use of gcc -MD dependency module"), action="store_true", dest='enable_gccdeps', default=True) - gr.add_option('--timestamp-dependencies', - help=("use file timestamps instead of content for build dependencies (BROKEN)"), - action="store_true", dest='timestamp_dependencies', default=False) gr.add_option('--pedantic', help=("Enable even more compiler warnings"), action='store_true', dest='pedantic', default=False) @@ -220,9 +217,6 @@ def configure(conf): conf.define('SRCDIR', conf.env['srcdir']) - if Options.options.timestamp_dependencies: - conf.ENABLE_TIMESTAMP_DEPENDENCIES() - conf.SETUP_CONFIGURE_CACHE(Options.options.enable_configure_cache) # load our local waf extensions diff --git a/librpc/idl/windows_event_ids.idl b/librpc/idl/windows_event_ids.idl index c711db1b30f..240ad9e56ff 100644 --- a/librpc/idl/windows_event_ids.idl +++ b/librpc/idl/windows_event_ids.idl @@ -9,10 +9,23 @@ interface windows_events { typedef [v1_enum,public] enum { - EVT_ID_SUCCESSFUL_LOGON = 4624, - EVT_ID_UNSUCCESSFUL_LOGON = 4625, - EVT_ID_PASSWORD_CHANGE = 4723, - EVT_ID_PASSWORD_RESET = 4724 + EVT_ID_NONE = 0, + EVT_ID_SUCCESSFUL_LOGON = 4624, + EVT_ID_UNSUCCESSFUL_LOGON = 4625, + EVT_ID_PASSWORD_CHANGE = 4723, + EVT_ID_PASSWORD_RESET = 4724, + EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP = 4728, + EVT_ID_USER_REMOVED_FROM_GLOBAL_SEC_GROUP = 4729, + EVT_ID_USER_ADDED_TO_LOCAL_SEC_GROUP = 4732, + EVT_ID_USER_REMOVED_FROM_LOCAL_SEC_GROUP = 4733, + EVT_ID_USER_ADDED_TO_LOCAL_GROUP = 4746, + EVT_ID_USER_REMOVED_FROM_LOCAL_GROUP = 4747, + EVT_ID_USER_ADDED_TO_GLOBAL_GROUP = 4751, + EVT_ID_USER_REMOVED_FROM_GLOBAL_GROUP = 4752, + EVT_ID_USER_ADDED_TO_UNIVERSAL_SEC_GROUP = 4756, + EVT_ID_USER_REMOVED_FROM_UNIVERSAL_SEC_GROUP = 4757, + EVT_ID_USER_ADDED_TO_UNIVERSAL_GROUP = 4761, + EVT_ID_USER_REMOVED_FROM_UNIVERSAL_GROUP = 4762 } event_id_type; typedef [v1_enum,public] enum { diff --git a/python/samba/tests/group_audit.py b/python/samba/tests/group_audit.py index 53a8bf6afaf..b8c90a325d5 100644 --- a/python/samba/tests/group_audit.py +++ b/python/samba/tests/group_audit.py @@ -21,6 +21,10 @@ from __future__ import print_function import samba.tests from samba.dcerpc.messaging import MSG_GROUP_LOG, DSDB_GROUP_EVENT_NAME +from samba.dcerpc.windows_event_ids import ( + EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP, + EVT_ID_USER_REMOVED_FROM_GLOBAL_SEC_GROUP +) from samba.samdb import SamDB from samba.auth import system_session import os @@ -43,7 +47,7 @@ class GroupAuditTests(AuditLogTestBase): def setUp(self): self.message_type = MSG_GROUP_LOG - self.event_type = DSDB_GROUP_EVENT_NAME + self.event_type = DSDB_GROUP_EVENT_NAME super(GroupAuditTests, self).setUp() self.remoteAddress = os.environ["CLIENT_IP"] @@ -100,9 +104,9 @@ class GroupAuditTests(AuditLogTestBase): # # Wait for the primary group change for the created user. # - messages = self.waitForMessages(1) + messages = self.waitForMessages(2) print("Received %d messages" % len(messages)) - self.assertEquals(1, + self.assertEquals(2, len(messages), "Did not receive the expected number of messages") audit = messages[0]["groupChange"] @@ -120,6 +124,21 @@ class GroupAuditTests(AuditLogTestBase): service_description = self.get_service_description() self.assertEquals(service_description, "LDAP") + # Check the Add message for the new users primary group + audit = messages[1]["groupChange"] + + self.assertEqual("Added", audit["action"]) + user_dn = "cn=" + USER_NAME + ",cn=users," + self.base_dn + group_dn = "cn=domain users,cn=users," + self.base_dn + self.assertTrue(user_dn.lower(), audit["user"].lower()) + self.assertTrue(group_dn.lower(), audit["group"].lower()) + self.assertRegexpMatches(audit["remoteAddress"], + self.remoteAddress) + self.assertTrue(self.is_guid(audit["sessionId"])) + session_id = self.get_session() + self.assertEquals(session_id, audit["sessionId"]) + self.assertEquals(EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP, + audit["eventId"]) # # Add the user to a group # @@ -231,11 +250,13 @@ class GroupAuditTests(AuditLogTestBase): # # Wait for the primary group change for the created user. # - messages = self.waitForMessages(1) + messages = self.waitForMessages(2) print("Received %d messages" % len(messages)) - self.assertEquals(1, + self.assertEquals(2, len(messages), "Did not receive the expected number of messages") + + # Check the PrimaryGroup message audit = messages[0]["groupChange"] self.assertEqual("PrimaryGroup", audit["action"]) @@ -251,6 +272,22 @@ class GroupAuditTests(AuditLogTestBase): service_description = self.get_service_description() self.assertEquals(service_description, "LDAP") + # Check the Add message for the new users primary group + audit = messages[1]["groupChange"] + + self.assertEqual("Added", audit["action"]) + user_dn = "cn=" + USER_NAME + ",cn=users," + self.base_dn + group_dn = "cn=domain users,cn=users," + self.base_dn + self.assertTrue(user_dn.lower(), audit["user"].lower()) + self.assertTrue(group_dn.lower(), audit["group"].lower()) + self.assertRegexpMatches(audit["remoteAddress"], + self.remoteAddress) + self.assertTrue(self.is_guid(audit["sessionId"])) + session_id = self.get_session() + self.assertEquals(session_id, audit["sessionId"]) + self.assertEquals(EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP, + audit["eventId"]) + # # Add the user to a group, the user needs to be a member of a group # before there primary group can be set to that group. @@ -277,6 +314,8 @@ class GroupAuditTests(AuditLogTestBase): self.assertEquals(session_id, audit["sessionId"]) service_description = self.get_service_description() self.assertEquals(service_description, "LDAP") + self.assertEquals(EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP, + audit["eventId"]) # # Change the primary group of a user @@ -323,6 +362,8 @@ class GroupAuditTests(AuditLogTestBase): self.assertEquals(session_id, audit["sessionId"]) service_description = self.get_service_description() self.assertEquals(service_description, "LDAP") + self.assertEquals(EVT_ID_USER_REMOVED_FROM_GLOBAL_SEC_GROUP, + audit["eventId"]) audit = messages[1]["groupChange"] @@ -338,6 +379,8 @@ class GroupAuditTests(AuditLogTestBase): self.assertEquals(session_id, audit["sessionId"]) service_description = self.get_service_description() self.assertEquals(service_description, "LDAP") + self.assertEquals(EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP, + audit["eventId"]) audit = messages[2]["groupChange"] diff --git a/source4/dsdb/samdb/ldb_modules/group_audit.c b/source4/dsdb/samdb/ldb_modules/group_audit.c index 7e6e16de137..4356046f675 100644 --- a/source4/dsdb/samdb/ldb_modules/group_audit.c +++ b/source4/dsdb/samdb/ldb_modules/group_audit.c @@ -25,6 +25,7 @@ #include "includes.h" #include "ldb_module.h" #include "lib/audit_logging/audit_logging.h" +#include "librpc/gen_ndr/windows_event_ids.h" #include "dsdb/samdb/samdb.h" #include "dsdb/samdb/ldb_modules/util.h" @@ -36,10 +37,11 @@ #define AUDIT_JSON_TYPE "groupChange" #define AUDIT_HR_TAG "Group Change" #define AUDIT_MAJOR 1 -#define AUDIT_MINOR 0 +#define AUDIT_MINOR 1 #define GROUP_LOG_LVL 5 -static const char * const member_attr[] = {"member", NULL}; +static const char *const group_attrs[] = {"member", "groupType", NULL}; +static const char *const group_type_attr[] = {"groupType", NULL}; static const char * const primary_group_attr[] = { "primaryGroupID", "objectSID", @@ -105,13 +107,13 @@ static struct GUID *get_transaction_id( * @return A json object containing the details. * NULL if an error was detected */ -static struct json_object audit_group_json( - const struct ldb_module *module, - const struct ldb_request *request, - const char *action, - const char *user, - const char *group, - const int status) +static struct json_object audit_group_json(const struct ldb_module *module, + const struct ldb_request *request, + const char *action, + const char *user, + const char *group, + const enum event_id_type event_id, + const int status) { struct ldb_context *ldb = NULL; const struct dom_sid *sid = NULL; @@ -137,6 +139,12 @@ static struct json_object audit_group_json( if (rc != 0) { goto failure; } + if (event_id != EVT_ID_NONE) { + rc = json_add_int(&audit, "eventId", event_id); + if (rc != 0) { + goto failure; + } + } rc = json_add_int(&audit, "statusCode", status); if (rc != 0) { goto failure; @@ -449,9 +457,11 @@ static const char *get_primary_group_dn( * @brief Log details of a change to a users primary group. * * Log details of a change to a users primary group. + * There is no windows event id associated with a Primary Group change. + * However for a new user we generate an added to group event. * * @param module The ldb module. - * @param request The request deing logged. + * @param request The request being logged. * @param action Description of the action being performed. * @param group The linearized for of the group DN * @param status the LDB status code for the processing of the request. @@ -497,12 +507,7 @@ static void log_primary_group_change( struct json_object json; json = audit_group_json( - module, - request, - action, - user, - group, - status); + module, request, action, user, group, EVT_ID_NONE, status); audit_log_json( &json, DBGC_DSDB_GROUP_AUDIT_JSON, @@ -515,6 +520,13 @@ static void log_primary_group_change( &json); } json_free(&json); + if (request->operation == LDB_ADD) { + /* + * Have just added a user, generate a groupChange + * message indicating the user has been added to thier + * new PrimaryGroup. + */ + } } TALLOC_FREE(ctx); } @@ -532,12 +544,12 @@ static void log_primary_group_change( * @param status the LDB status code for the processing of the request. * */ -static void log_membership_change( - struct ldb_module *module, - const struct ldb_request *request, - const char *action, - const char *user, - const int status) +static void log_membership_change(struct ldb_module *module, + const struct ldb_request *request, + const char *action, + const char *user, + const enum event_id_type event_id, + const int status) { const char *group = NULL; struct audit_context *ac = @@ -569,12 +581,7 @@ static void log_membership_change( (ac->msg_ctx && ac->send_events)) { struct json_object json; json = audit_group_json( - module, - request, - action, - user, - group, - status); + module, request, action, user, group, event_id, status); audit_log_json( &json, DBGC_DSDB_GROUP_AUDIT_JSON, @@ -591,6 +598,68 @@ static void log_membership_change( TALLOC_FREE(ctx); } +/* + * @brief Get the windows event type id for removing a user from a group type. + * + * @param group_type the type of the current group, see libds/common/flags.h + * + * @return the Windows Event Id + * + */ +static enum event_id_type get_remove_member_event(uint32_t group_type) +{ + + switch (group_type) { + case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP: + return EVT_ID_USER_REMOVED_FROM_LOCAL_SEC_GROUP; + case GTYPE_SECURITY_GLOBAL_GROUP: + return EVT_ID_USER_REMOVED_FROM_GLOBAL_SEC_GROUP; + case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP: + return EVT_ID_USER_REMOVED_FROM_LOCAL_SEC_GROUP; + case GTYPE_SECURITY_UNIVERSAL_GROUP: + return EVT_ID_USER_REMOVED_FROM_UNIVERSAL_SEC_GROUP; + case GTYPE_DISTRIBUTION_GLOBAL_GROUP: + return EVT_ID_USER_REMOVED_FROM_GLOBAL_GROUP; + case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP: + return EVT_ID_USER_REMOVED_FROM_LOCAL_GROUP; + case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP: + return EVT_ID_USER_REMOVED_FROM_UNIVERSAL_GROUP; + default: + return EVT_ID_NONE; + } +} + +/* + * @brief Get the windows event type id for adding a user to a group type. + * + * @param group_type the type of the current group, see libds/common/flags.h + * + * @return the Windows Event Id + * + */ +static enum event_id_type get_add_member_event(uint32_t group_type) +{ + + switch (group_type) { + case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP: + return EVT_ID_USER_ADDED_TO_LOCAL_SEC_GROUP; + case GTYPE_SECURITY_GLOBAL_GROUP: + return EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP; + case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP: + return EVT_ID_USER_ADDED_TO_LOCAL_SEC_GROUP; + case GTYPE_SECURITY_UNIVERSAL_GROUP: + return EVT_ID_USER_ADDED_TO_UNIVERSAL_SEC_GROUP; + case GTYPE_DISTRIBUTION_GLOBAL_GROUP: + return EVT_ID_USER_ADDED_TO_GLOBAL_GROUP; + case GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP: + return EVT_ID_USER_ADDED_TO_LOCAL_GROUP; + case GTYPE_DISTRIBUTION_UNIVERSAL_GROUP: + return EVT_ID_USER_ADDED_TO_UNIVERSAL_GROUP; + default: + return EVT_ID_NONE; + } +} + /* * @brief Log all the changes to a users group membership. * @@ -604,12 +673,12 @@ static void log_membership_change( * @param status the LDB status code for the processing of the request. * */ -static void log_membership_changes( - struct ldb_module *module, - const struct ldb_request *request, - struct ldb_message_element *el, - struct ldb_message_element *old_el, - int status) +static void log_membership_changes(struct ldb_module *module, + const struct ldb_request *request, + struct ldb_message_element *el, + struct ldb_message_element *old_el, + uint32_t group_type, + int status) { unsigned int i, old_i, new_i; unsigned int old_num_values; @@ -674,6 +743,7 @@ static void log_membership_changes( * the new record. So it's been deleted */ const char *user = NULL; + enum event_id_type event_id; if (old_val->dsdb_dn == NULL) { really_parse_trusted_dn( ctx, @@ -682,12 +752,9 @@ static void log_membership_changes( LDB_SYNTAX_DN); } user = ldb_dn_get_linearized(old_val->dsdb_dn->dn); + event_id = get_remove_member_event(group_type); log_membership_change( - module, - request, - "Removed", - user, - status); + module, request, "Removed", user, event_id, status); old_i++; } else if (cmp == BINARY_EQUAL) { /* @@ -739,27 +806,31 @@ static void log_membership_changes( * DN has been deleted. */ -- Samba Shared Repository