1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-08 21:18:16 +03:00

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 <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
Gary Lockyer 2018-12-19 09:08:22 +13:00 committed by Andrew Bartlett
parent b99b51400c
commit 87a8325a0d
6 changed files with 462 additions and 158 deletions

View File

@ -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. " {"

View File

@ -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 {

View File

@ -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
@ -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"]

View File

@ -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.
*/
const char *user = NULL;
enum event_id_type event_id;
user = ldb_dn_get_linearized(
old_val->dsdb_dn->dn);
log_membership_change(
module,
request,
"Removed",
user,
status);
event_id = get_remove_member_event(group_type);
log_membership_change(module,
request,
"Removed",
user,
event_id,
status);
} else {
/*
* DN has been re-added
*/
const char *user = NULL;
enum event_id_type event_id;
user = ldb_dn_get_linearized(
new_val->dsdb_dn->dn);
log_membership_change(
module,
request,
"Added",
user,
status);
event_id = get_add_member_event(group_type);
log_membership_change(module,
request,
"Added",
user,
event_id,
status);
}
old_i++;
new_i++;
@ -769,6 +840,7 @@ static void log_membership_changes(
* original, so it must have been added.
*/
const char *user = NULL;
enum event_id_type event_id;
if ( new_val->dsdb_dn == NULL) {
really_parse_trusted_dn(
ctx,
@ -777,12 +849,9 @@ static void log_membership_changes(
LDB_SYNTAX_DN);
}
user = ldb_dn_get_linearized(new_val->dsdb_dn->dn);
event_id = get_add_member_event(group_type);
log_membership_change(
module,
request,
"Added",
user,
status);
module, request, "Added", user, event_id, status);
new_i++;
}
}
@ -790,6 +859,46 @@ static void log_membership_changes(
TALLOC_FREE(ctx);
}
/*
* @brief log a group change message for a newly added user.
*
* When a user is added we need to generate a GroupChange Add message to
* log that the user has been added to their PrimaryGroup
*/
static void log_new_user_added_to_primary_group(
TALLOC_CTX *ctx,
struct audit_callback_context *acc,
const char *group,
const int status)
{
uint32_t group_type;
enum event_id_type event_id = EVT_ID_NONE;
struct ldb_result *res = NULL;
struct ldb_dn *group_dn = NULL;
struct ldb_context *ldb = NULL;
int ret;
ldb = ldb_module_get_ctx(acc->module);
group_dn = ldb_dn_new(ctx, ldb, group);
ret = dsdb_module_search_dn(acc->module,
ctx,
&res,
group_dn,
group_type_attr,
DSDB_FLAG_NEXT_MODULE |
DSDB_SEARCH_REVEAL_INTERNALS |
DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT,
NULL);
if (ret == LDB_SUCCESS) {
const char *user = NULL;
group_type =
ldb_msg_find_attr_as_uint(res->msgs[0], "groupType", 0);
event_id = get_add_member_event(group_type);
user = dsdb_audit_get_primary_dn(acc->request);
log_membership_change(
acc->module, acc->request, "Added", user, event_id, status);
}
}
/*
* @brief Log the details of a primary group change.
@ -811,6 +920,7 @@ static void log_user_primary_group_change(
struct dom_sid *account_sid = NULL;
int ret;
const struct ldb_message *msg = dsdb_audit_get_message(acc->request);
if (status == LDB_SUCCESS && msg != NULL) {
struct ldb_result *res = NULL;
ret = dsdb_module_search_dn(
@ -853,6 +963,16 @@ static void log_user_primary_group_change(
"PrimaryGroup",
group,
status);
/*
* Are we adding a new user with the primaryGroupID
* set. If so and we're generating JSON audit logs, will need to
* generate an "Add" message with the appropriate windows
* event id.
*/
if (acc->request->operation == LDB_ADD) {
log_new_user_added_to_primary_group(
ctx, acc, group, status);
}
}
TALLOC_FREE(ctx);
}
@ -866,7 +986,6 @@ static void log_user_primary_group_change(
* @param acc details of the group memberships before the operation.
* @param status The status code returned by the operation.
*
* @return an LDB status code.
*/
static void log_group_membership_changes(
struct audit_callback_context *acc,
@ -875,6 +994,7 @@ static void log_group_membership_changes(
TALLOC_CTX *ctx = talloc_new(NULL);
struct ldb_message_element *new_val = NULL;
int ret;
uint32_t group_type;
const struct ldb_message *msg = dsdb_audit_get_message(acc->request);
if (status == LDB_SUCCESS && msg != NULL) {
struct ldb_result *res = NULL;
@ -883,21 +1003,23 @@ static void log_group_membership_changes(
ctx,
&res,
msg->dn,
member_attr,
group_attrs,
DSDB_FLAG_NEXT_MODULE |
DSDB_SEARCH_REVEAL_INTERNALS |
DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT,
NULL);
if (ret == LDB_SUCCESS) {
new_val = ldb_msg_find_element(res->msgs[0], "member");
}
group_type = ldb_msg_find_attr_as_uint(
res->msgs[0], "groupType", 0);
log_membership_changes(acc->module,
acc->request,
new_val,
acc->members,
group_type,
status);
}
}
log_membership_changes(
acc->module,
acc->request,
new_val,
acc->members,
status);
TALLOC_FREE(ctx);
}
@ -1300,7 +1422,7 @@ static int set_group_modify_callback(
context,
&res,
req->op.add.message->dn,
member_attr,
group_attrs,
DSDB_FLAG_NEXT_MODULE |
DSDB_SEARCH_REVEAL_INTERNALS |
DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT,

View File

@ -82,8 +82,8 @@ void audit_message_send(
messages_sent++;
}
#define check_group_change_message(m, u, a)\
_check_group_change_message(m, u, a, __FILE__, __LINE__);
#define check_group_change_message(m, u, a, e) \
_check_group_change_message(m, u, a, e, __FILE__, __LINE__);
/*
* declare the internal cmocka cm_print_error so that we can output messages
* in sub unit format
@ -102,17 +102,18 @@ void cm_print_error(const char * const format, ...);
* There should be a user element matching the expected value
* There should be an action matching the expected value
*/
static void _check_group_change_message(
const int message,
const char *user,
const char *action,
const char *file,
const int line)
static void _check_group_change_message(const int message,
const char *user,
const char *action,
enum event_id_type event_id,
const char *file,
const int line)
{
struct json_object json;
json_t *audit = NULL;
json_t *v = NULL;
const char* value;
int int_value;
int cmp;
json = messages[message];
@ -157,12 +158,11 @@ static void _check_group_change_message(
/*
* Validate the groupChange element
*/
if (json_object_size(audit) != 10) {
cm_print_error(
"Unexpected number of elements in groupChange "
"%zu != %d\n",
json_object_size(audit),
10);
if (json_object_size(audit) != 11) {
cm_print_error("Unexpected number of elements in groupChange "
"%zu != %d\n",
json_object_size(audit),
11);
_fail(file, line);
}
/*
@ -183,7 +183,6 @@ static void _check_group_change_message(
user);
_fail(file, line);
}
/*
* Validate the action element
*/
@ -202,6 +201,23 @@ static void _check_group_change_message(
action);
_fail(file, line);
}
/*
* Validate the eventId element
*/
v = json_object_get(audit, "eventId");
if (v == NULL) {
cm_print_error("No eventId element\n");
_fail(file, line);
}
int_value = json_integer_value(v);
if (int_value != event_id) {
cm_print_error("Unexpected eventId \"%d\" != \"%d\"\n",
int_value,
event_id);
_fail(file, line);
}
}
#define check_timestamp(b, t)\
@ -752,6 +768,7 @@ static void test_audit_group_json(void **state)
struct GUID transaction_id;
const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
enum event_id_type event_id = EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP;
struct json_object json;
json_t *audit = NULL;
@ -779,13 +796,13 @@ static void test_audit_group_json(void **state)
add_transaction_id(req, TRANSACTION);
before = time(NULL);
json = audit_group_json(
module,
req,
"the-action",
"the-user-name",
"the-group-name",
LDB_ERR_OPERATIONS_ERROR);
json = audit_group_json(module,
req,
"the-action",
"the-user-name",
"the-group-name",
event_id,
LDB_ERR_OPERATIONS_ERROR);
assert_int_equal(3, json_object_size(json.root));
v = json_object_get(json.root, "type");
@ -800,12 +817,18 @@ static void test_audit_group_json(void **state)
audit = json_object_get(json.root, "groupChange");
assert_non_null(audit);
assert_true(json_is_object(audit));
assert_int_equal(10, json_object_size(audit));
assert_int_equal(11, json_object_size(audit));
o = json_object_get(audit, "version");
assert_non_null(o);
check_version(o, AUDIT_MAJOR, AUDIT_MINOR);
v = json_object_get(audit, "eventId");
assert_non_null(v);
assert_true(json_is_integer(v));
assert_int_equal(EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP,
json_integer_value(v));
v = json_object_get(audit, "statusCode");
assert_non_null(v);
assert_true(json_is_integer(v));
@ -887,6 +910,7 @@ static void test_log_membership_changes_removed(void **state)
struct ldb_request *req = NULL;
struct ldb_message_element *new_el = NULL;
struct ldb_message_element *old_el = NULL;
uint32_t group_type = GTYPE_SECURITY_GLOBAL_GROUP;
int status = 0;
TALLOC_CTX *ctx = talloc_new(NULL);
@ -931,7 +955,7 @@ static void test_log_membership_changes_removed(void **state)
* call log_membership_changes
*/
messages_sent = 0;
log_membership_changes(module, req, new_el, old_el, status);
log_membership_changes(module, req, new_el, old_el, group_type, status);
/*
* Check the results
@ -941,7 +965,8 @@ static void test_log_membership_changes_removed(void **state)
check_group_change_message(
0,
"cn=grpadttstuser01,cn=users,DC=addom,DC=samba,DC=example,DC=com",
"Removed");
"Removed",
EVT_ID_USER_REMOVED_FROM_GLOBAL_SEC_GROUP);
/*
* Clean up
@ -969,6 +994,7 @@ static void test_log_membership_changes_remove_all(void **state)
struct ldb_message_element *new_el = NULL;
struct ldb_message_element *old_el = NULL;
int status = 0;
uint32_t group_type = GTYPE_SECURITY_BUILTIN_LOCAL_GROUP;
TALLOC_CTX *ctx = talloc_new(NULL);
setup_ldb(ctx, &ldb, &module, IP, SESSION, SID);
@ -1007,7 +1033,7 @@ static void test_log_membership_changes_remove_all(void **state)
* call log_membership_changes
*/
messages_sent = 0;
log_membership_changes( module, req, new_el, old_el, status);
log_membership_changes(module, req, new_el, old_el, group_type, status);
/*
* Check the results
@ -1017,12 +1043,14 @@ static void test_log_membership_changes_remove_all(void **state)
check_group_change_message(
0,
"cn=grpadttstuser01,cn=users,DC=addom,DC=samba,DC=example,DC=com",
"Removed");
"Removed",
EVT_ID_USER_REMOVED_FROM_LOCAL_SEC_GROUP);
check_group_change_message(
1,
"CN=testuser131953,CN=Users,DC=addom,DC=samba,DC=example,DC=com",
"Removed");
"Removed",
EVT_ID_USER_REMOVED_FROM_LOCAL_SEC_GROUP);
/*
* Clean up
@ -1052,6 +1080,7 @@ static void test_log_membership_changes_added(void **state)
struct ldb_request *req = NULL;
struct ldb_message_element *new_el = NULL;
struct ldb_message_element *old_el = NULL;
uint32_t group_type = GTYPE_SECURITY_DOMAIN_LOCAL_GROUP;
int status = 0;
TALLOC_CTX *ctx = talloc_new(NULL);
@ -1095,7 +1124,7 @@ static void test_log_membership_changes_added(void **state)
* call log_membership_changes
*/
messages_sent = 0;
log_membership_changes( module, req, new_el, old_el, status);
log_membership_changes(module, req, new_el, old_el, group_type, status);
/*
* Check the results
@ -1105,7 +1134,8 @@ static void test_log_membership_changes_added(void **state)
check_group_change_message(
0,
"cn=grpadttstuser01,cn=users,DC=addom,DC=samba,DC=example,DC=com",
"Added");
"Added",
EVT_ID_USER_ADDED_TO_LOCAL_SEC_GROUP);
/*
* Clean up
@ -1133,6 +1163,7 @@ static void test_log_membership_changes_add_to_empty(void **state)
struct ldb_request *req = NULL;
struct ldb_message_element *new_el = NULL;
struct ldb_message_element *old_el = NULL;
uint32_t group_type = GTYPE_SECURITY_UNIVERSAL_GROUP;
int status = 0;
TALLOC_CTX *ctx = talloc_new(NULL);
@ -1174,18 +1205,20 @@ static void test_log_membership_changes_add_to_empty(void **state)
* Run log membership changes
*/
messages_sent = 0;
log_membership_changes( module, req, new_el, old_el, status);
log_membership_changes(module, req, new_el, old_el, group_type, status);
assert_int_equal(2, messages_sent);
check_group_change_message(
0,
"cn=grpadttstuser01,cn=users,DC=addom,DC=samba,DC=example,DC=com",
"Added");
"Added",
EVT_ID_USER_ADDED_TO_UNIVERSAL_SEC_GROUP);
check_group_change_message(
1,
"CN=testuser131953,CN=Users,DC=addom,DC=samba,DC=example,DC=com",
"Added");
"CN=testuser131953,CN=Users,DC=addom,DC=samba,DC=example,DC=com",
"Added",
EVT_ID_USER_ADDED_TO_UNIVERSAL_SEC_GROUP);
json_free(&messages[0]);
json_free(&messages[1]);
@ -1216,6 +1249,7 @@ static void test_log_membership_changes_rmd_flags(void **state)
struct ldb_request *req = NULL;
struct ldb_message_element *new_el = NULL;
struct ldb_message_element *old_el = NULL;
uint32_t group_type = GTYPE_SECURITY_GLOBAL_GROUP;
int status = 0;
TALLOC_CTX *ctx = talloc_new(NULL);
@ -1286,7 +1320,7 @@ static void test_log_membership_changes_rmd_flags(void **state)
* call log_membership_changes
*/
messages_sent = 0;
log_membership_changes( module, req, new_el, old_el, status);
log_membership_changes(module, req, new_el, old_el, group_type, status);
/*
* Check the results
@ -1296,11 +1330,13 @@ static void test_log_membership_changes_rmd_flags(void **state)
check_group_change_message(
0,
"cn=grpadttstuser03,cn=users,DC=addom,DC=samba,DC=example,DC=com",
"Removed");
"Removed",
EVT_ID_USER_REMOVED_FROM_GLOBAL_SEC_GROUP);
check_group_change_message(
1,
"cn=grpadttstuser04,cn=users,DC=addom,DC=samba,DC=example,DC=com",
"Added");
"Added",
EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP);
/*
* Clean up
@ -1310,6 +1346,71 @@ static void test_log_membership_changes_rmd_flags(void **state)
TALLOC_FREE(ctx);
}
static void test_get_add_member_event(void **state)
{
assert_int_equal(
EVT_ID_USER_ADDED_TO_LOCAL_SEC_GROUP,
get_add_member_event(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP));
assert_int_equal(EVT_ID_USER_ADDED_TO_GLOBAL_SEC_GROUP,
get_add_member_event(GTYPE_SECURITY_GLOBAL_GROUP));
assert_int_equal(
EVT_ID_USER_ADDED_TO_LOCAL_SEC_GROUP,
get_add_member_event(GTYPE_SECURITY_DOMAIN_LOCAL_GROUP));
assert_int_equal(EVT_ID_USER_ADDED_TO_UNIVERSAL_SEC_GROUP,
get_add_member_event(GTYPE_SECURITY_UNIVERSAL_GROUP));
assert_int_equal(EVT_ID_USER_ADDED_TO_GLOBAL_GROUP,
get_add_member_event(GTYPE_DISTRIBUTION_GLOBAL_GROUP));
assert_int_equal(
EVT_ID_USER_ADDED_TO_LOCAL_GROUP,
get_add_member_event(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP));
assert_int_equal(
EVT_ID_USER_ADDED_TO_UNIVERSAL_GROUP,
get_add_member_event(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP));
assert_int_equal(EVT_ID_NONE, get_add_member_event(0));
assert_int_equal(EVT_ID_NONE, get_add_member_event(UINT32_MAX));
}
static void test_get_remove_member_event(void **state)
{
assert_int_equal(
EVT_ID_USER_REMOVED_FROM_LOCAL_SEC_GROUP,
get_remove_member_event(GTYPE_SECURITY_BUILTIN_LOCAL_GROUP));
assert_int_equal(EVT_ID_USER_REMOVED_FROM_GLOBAL_SEC_GROUP,
get_remove_member_event(GTYPE_SECURITY_GLOBAL_GROUP));
assert_int_equal(
EVT_ID_USER_REMOVED_FROM_LOCAL_SEC_GROUP,
get_remove_member_event(GTYPE_SECURITY_DOMAIN_LOCAL_GROUP));
assert_int_equal(
EVT_ID_USER_REMOVED_FROM_UNIVERSAL_SEC_GROUP,
get_remove_member_event(GTYPE_SECURITY_UNIVERSAL_GROUP));
assert_int_equal(
EVT_ID_USER_REMOVED_FROM_GLOBAL_GROUP,
get_remove_member_event(GTYPE_DISTRIBUTION_GLOBAL_GROUP));
assert_int_equal(
EVT_ID_USER_REMOVED_FROM_LOCAL_GROUP,
get_remove_member_event(GTYPE_DISTRIBUTION_DOMAIN_LOCAL_GROUP));
assert_int_equal(
EVT_ID_USER_REMOVED_FROM_UNIVERSAL_GROUP,
get_remove_member_event(GTYPE_DISTRIBUTION_UNIVERSAL_GROUP));
assert_int_equal(EVT_ID_NONE, get_remove_member_event(0));
assert_int_equal(EVT_ID_NONE, get_remove_member_event(UINT32_MAX));
}
/*
* Note: to run under valgrind us:
* valgrind --suppressions=test_group_audit.valgrind bin/test_group_audit
@ -1319,17 +1420,19 @@ static void test_log_membership_changes_rmd_flags(void **state)
*/
int main(void) {
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_audit_group_json),
cmocka_unit_test(test_get_transaction_id),
cmocka_unit_test(test_audit_group_hr),
cmocka_unit_test(test_get_parsed_dns),
cmocka_unit_test(test_dn_compare),
cmocka_unit_test(test_get_primary_group_dn),
cmocka_unit_test(test_log_membership_changes_removed),
cmocka_unit_test(test_log_membership_changes_remove_all),
cmocka_unit_test(test_log_membership_changes_added),
cmocka_unit_test(test_log_membership_changes_add_to_empty),
cmocka_unit_test(test_log_membership_changes_rmd_flags),
cmocka_unit_test(test_audit_group_json),
cmocka_unit_test(test_get_transaction_id),
cmocka_unit_test(test_audit_group_hr),
cmocka_unit_test(test_get_parsed_dns),
cmocka_unit_test(test_dn_compare),
cmocka_unit_test(test_get_primary_group_dn),
cmocka_unit_test(test_log_membership_changes_removed),
cmocka_unit_test(test_log_membership_changes_remove_all),
cmocka_unit_test(test_log_membership_changes_added),
cmocka_unit_test(test_log_membership_changes_add_to_empty),
cmocka_unit_test(test_log_membership_changes_rmd_flags),
cmocka_unit_test(test_get_add_member_event),
cmocka_unit_test(test_get_remove_member_event),
};
cmocka_set_message_output(CM_OUTPUT_SUBUNIT);

View File

@ -139,6 +139,7 @@ static void test_audit_group_json(void **state)
struct GUID transaction_id;
const char *const TRANSACTION = "7130cb06-2062-6a1b-409e-3514c26b1773";
enum event_id_type event_id = EVT_ID_USER_REMOVED_FROM_GLOBAL_SEC_GROUP;
struct json_object json;
@ -166,13 +167,13 @@ static void test_audit_group_json(void **state)
will_return(__wrap_json_new_object, false);
json = audit_group_json(
module,
req,
"the-action",
"the-user-name",
"the-group-name",
LDB_ERR_OPERATIONS_ERROR);
json = audit_group_json(module,
req,
"the-action",
"the-user-name",
"the-group-name",
event_id,
LDB_ERR_OPERATIONS_ERROR);
assert_true(json_is_invalid(&json));
/*
@ -182,13 +183,13 @@ static void test_audit_group_json(void **state)
will_return(__wrap_json_new_object, true);
will_return(__wrap_json_add_version, JSON_ERROR);
json = audit_group_json(
module,
req,
"the-action",
"the-user-name",
"the-group-name",
LDB_ERR_OPERATIONS_ERROR);
json = audit_group_json(module,
req,
"the-action",
"the-user-name",
"the-group-name",
event_id,
LDB_ERR_OPERATIONS_ERROR);
assert_true(json_is_invalid(&json));
/*
@ -199,13 +200,13 @@ static void test_audit_group_json(void **state)
will_return(__wrap_json_add_version, 0);
will_return(__wrap_json_new_object, false);
json = audit_group_json(
module,
req,
"the-action",
"the-user-name",
"the-group-name",
LDB_ERR_OPERATIONS_ERROR);
json = audit_group_json(module,
req,
"the-action",
"the-user-name",
"the-group-name",
event_id,
LDB_ERR_OPERATIONS_ERROR);
assert_true(json_is_invalid(&json));
/*
@ -216,13 +217,13 @@ static void test_audit_group_json(void **state)
will_return(__wrap_json_new_object, true);
will_return(__wrap_json_add_timestamp, JSON_ERROR);
json = audit_group_json(
module,
req,
"the-action",
"the-user-name",
"the-group-name",
LDB_ERR_OPERATIONS_ERROR);
json = audit_group_json(module,
req,
"the-action",
"the-user-name",
"the-group-name",
event_id,
LDB_ERR_OPERATIONS_ERROR);
assert_true(json_is_invalid(&json));
@ -234,13 +235,13 @@ static void test_audit_group_json(void **state)
will_return(__wrap_json_new_object, true);
will_return(__wrap_json_add_timestamp, 0);
json = audit_group_json(
module,
req,
"the-action",
"the-user-name",
"the-group-name",
LDB_ERR_OPERATIONS_ERROR);
json = audit_group_json(module,
req,
"the-action",
"the-user-name",
"the-group-name",
event_id,
LDB_ERR_OPERATIONS_ERROR);
assert_false(json_is_invalid(&json));
json_free(&json);