mirror of
https://github.com/samba-team/samba.git
synced 2025-02-02 09:47:23 +03:00
dsdb audit_log: Add windows event codes to password changes
Add a new "eventId" element to the PasswordChange JSON log messages. This contains a Windows Event Code Id either: 4723 Password changed 4724 Password reset Signed-off-by: Gary Lockyer <gary@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
105cdd6c1c
commit
e97acc714d
@ -10,7 +10,9 @@ interface windows_events
|
||||
|
||||
typedef [v1_enum,public] enum {
|
||||
EVT_ID_SUCCESSFUL_LOGON = 4624,
|
||||
EVT_ID_UNSUCCESSFUL_LOGON = 4625
|
||||
EVT_ID_UNSUCCESSFUL_LOGON = 4625,
|
||||
EVT_ID_PASSWORD_CHANGE = 4723,
|
||||
EVT_ID_PASSWORD_RESET = 4724
|
||||
} event_id_type;
|
||||
|
||||
typedef [v1_enum,public] enum {
|
||||
|
@ -28,6 +28,11 @@ from samba.tests.audit_log_base import AuditLogTestBase
|
||||
from samba.tests import delete_force
|
||||
from samba.net import Net
|
||||
from ldb import ERR_INSUFFICIENT_ACCESS_RIGHTS
|
||||
from samba.dcerpc.windows_event_ids import (
|
||||
EVT_ID_PASSWORD_CHANGE,
|
||||
EVT_ID_PASSWORD_RESET
|
||||
)
|
||||
|
||||
|
||||
USER_NAME = "auditlogtestuser"
|
||||
USER_PASS = samba.generate_random_password(32, 32)
|
||||
@ -119,6 +124,7 @@ class AuditLogPassChangeTests(AuditLogTestBase):
|
||||
len(messages),
|
||||
"Did not receive the expected number of messages")
|
||||
audit = messages[0]["passwordChange"]
|
||||
self.assertEquals(EVT_ID_PASSWORD_CHANGE, audit["eventId"])
|
||||
self.assertEquals("Change", audit["action"])
|
||||
self.assertEquals(dn, audit["dn"])
|
||||
self.assertRegexpMatches(audit["remoteAddress"],
|
||||
@ -147,6 +153,7 @@ class AuditLogPassChangeTests(AuditLogTestBase):
|
||||
"Did not receive the expected number of messages")
|
||||
|
||||
audit = messages[0]["passwordChange"]
|
||||
self.assertEquals(EVT_ID_PASSWORD_RESET, audit["eventId"])
|
||||
self.assertEquals("Reset", audit["action"])
|
||||
self.assertEquals(dn, audit["dn"])
|
||||
self.assertRegexpMatches(audit["remoteAddress"],
|
||||
@ -187,6 +194,7 @@ class AuditLogPassChangeTests(AuditLogTestBase):
|
||||
"Did not receive the expected number of messages")
|
||||
|
||||
audit = messages[0]["passwordChange"]
|
||||
self.assertEquals(EVT_ID_PASSWORD_RESET, audit["eventId"])
|
||||
self.assertEquals("Reset", audit["action"])
|
||||
self.assertEquals(dn, audit["dn"])
|
||||
self.assertRegexpMatches(audit["remoteAddress"],
|
||||
@ -223,6 +231,7 @@ class AuditLogPassChangeTests(AuditLogTestBase):
|
||||
"Did not receive the expected number of messages")
|
||||
|
||||
audit = messages[0]["passwordChange"]
|
||||
self.assertEquals(EVT_ID_PASSWORD_RESET, audit["eventId"])
|
||||
self.assertEquals("Reset", audit["action"])
|
||||
self.assertEquals(dn, audit["dn"])
|
||||
self.assertRegexpMatches(audit["remoteAddress"],
|
||||
@ -256,6 +265,7 @@ class AuditLogPassChangeTests(AuditLogTestBase):
|
||||
"Did not receive the expected number of messages")
|
||||
|
||||
audit = messages[0]["passwordChange"]
|
||||
self.assertEquals(EVT_ID_PASSWORD_CHANGE, audit["eventId"])
|
||||
self.assertEquals("Change", audit["action"])
|
||||
self.assertEquals(dn, audit["dn"])
|
||||
self.assertRegexpMatches(audit["remoteAddress"],
|
||||
@ -286,6 +296,7 @@ class AuditLogPassChangeTests(AuditLogTestBase):
|
||||
"Did not receive the expected number of messages")
|
||||
|
||||
audit = messages[0]["passwordChange"]
|
||||
self.assertEquals(EVT_ID_PASSWORD_RESET, audit["eventId"])
|
||||
self.assertEquals("Reset", audit["action"])
|
||||
self.assertEquals(dn, audit["dn"])
|
||||
self.assertRegexpMatches(audit["remoteAddress"],
|
||||
@ -312,6 +323,7 @@ class AuditLogPassChangeTests(AuditLogTestBase):
|
||||
# The first message should be the reset from the Setup code.
|
||||
#
|
||||
audit = messages[0]["passwordChange"]
|
||||
self.assertEquals(EVT_ID_PASSWORD_RESET, audit["eventId"])
|
||||
self.assertEquals("Reset", audit["action"])
|
||||
self.assertEquals(dn, audit["dn"])
|
||||
self.assertRegexpMatches(audit["remoteAddress"],
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "libcli/security/dom_sid.h"
|
||||
#include "auth/common_auth.h"
|
||||
#include "param/param.h"
|
||||
#include "librpc/gen_ndr/windows_event_ids.h"
|
||||
|
||||
#define OPERATION_JSON_TYPE "dsdbChange"
|
||||
#define OPERATION_HR_TAG "DSDB Change"
|
||||
@ -43,7 +44,7 @@
|
||||
#define PASSWORD_JSON_TYPE "passwordChange"
|
||||
#define PASSWORD_HR_TAG "Password Change"
|
||||
#define PASSWORD_MAJOR 1
|
||||
#define PASSWORD_MINOR 0
|
||||
#define PASSWORD_MINOR 1
|
||||
#define PASSWORD_LOG_LVL 5
|
||||
|
||||
#define TRANSACTION_JSON_TYPE "dsdbTransaction"
|
||||
@ -121,6 +122,47 @@ static bool has_password_changed(const struct ldb_message *message)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief get the password change windows event id
|
||||
*
|
||||
* Get the Windows Event Id for the action being performed on the user password.
|
||||
*
|
||||
* This routine assumes that the request contains password attributes and that the
|
||||
* password ACL checks have been performed by acl.c
|
||||
*
|
||||
* @param request the ldb_request to inspect
|
||||
* @param reply the ldb_reply, will contain the password controls
|
||||
*
|
||||
* @return The windows event code.
|
||||
*/
|
||||
static enum event_id_type get_password_windows_event_id(
|
||||
const struct ldb_request *request,
|
||||
const struct ldb_reply *reply)
|
||||
{
|
||||
if(request->operation == LDB_ADD) {
|
||||
return EVT_ID_PASSWORD_RESET;
|
||||
} else {
|
||||
struct ldb_control *pav_ctrl = NULL;
|
||||
struct dsdb_control_password_acl_validation *pav = NULL;
|
||||
|
||||
pav_ctrl = ldb_reply_get_control(
|
||||
discard_const(reply),
|
||||
DSDB_CONTROL_PASSWORD_ACL_VALIDATION_OID);
|
||||
if (pav_ctrl == NULL) {
|
||||
return EVT_ID_PASSWORD_RESET;
|
||||
}
|
||||
|
||||
pav = talloc_get_type_abort(
|
||||
pav_ctrl->data,
|
||||
struct dsdb_control_password_acl_validation);
|
||||
|
||||
if (pav->pwd_reset) {
|
||||
return EVT_ID_PASSWORD_RESET;
|
||||
} else {
|
||||
return EVT_ID_PASSWORD_CHANGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* @brief Is the request a password "Change" or a "Reset"
|
||||
*
|
||||
@ -455,6 +497,7 @@ static struct json_object password_change_json(
|
||||
= talloc_get_type_abort(ldb_module_get_private(module),
|
||||
struct audit_private);
|
||||
int rc = 0;
|
||||
enum event_id_type event_id;
|
||||
|
||||
ldb = ldb_module_get_ctx(module);
|
||||
|
||||
@ -463,6 +506,7 @@ static struct json_object password_change_json(
|
||||
dn = dsdb_audit_get_primary_dn(request);
|
||||
action = get_password_action(request, reply);
|
||||
unique_session_token = dsdb_audit_get_unique_session_token(module);
|
||||
event_id = get_password_windows_event_id(request, reply);
|
||||
|
||||
audit = json_new_object();
|
||||
if (json_is_invalid(&audit)) {
|
||||
@ -472,6 +516,10 @@ static struct json_object password_change_json(
|
||||
if (rc != 0) {
|
||||
goto failure;
|
||||
}
|
||||
rc = json_add_int(&audit, "eventId", event_id);
|
||||
if (rc != 0) {
|
||||
goto failure;
|
||||
}
|
||||
rc = json_add_int(&audit, "statusCode", reply->error);
|
||||
if (rc != 0) {
|
||||
goto failure;
|
||||
|
@ -828,11 +828,14 @@ static void test_password_change_json_empty(void **state)
|
||||
audit = json_object_get(json.root, "passwordChange");
|
||||
assert_non_null(audit);
|
||||
assert_true(json_is_object(audit));
|
||||
assert_int_equal(9, json_object_size(audit));
|
||||
assert_int_equal(10, json_object_size(audit));
|
||||
|
||||
o = json_object_get(audit, "version");
|
||||
assert_non_null(o);
|
||||
|
||||
v = json_object_get(audit, "eventId");
|
||||
assert_non_null(v);
|
||||
|
||||
v = json_object_get(audit, "statusCode");
|
||||
assert_non_null(v);
|
||||
|
||||
@ -950,12 +953,17 @@ static void test_password_change_json(void **state)
|
||||
audit = json_object_get(json.root, "passwordChange");
|
||||
assert_non_null(audit);
|
||||
assert_true(json_is_object(audit));
|
||||
assert_int_equal(9, json_object_size(audit));
|
||||
assert_int_equal(10, json_object_size(audit));
|
||||
|
||||
o = json_object_get(audit, "version");
|
||||
assert_non_null(o);
|
||||
check_version(o, PASSWORD_MAJOR,PASSWORD_MINOR);
|
||||
|
||||
v = json_object_get(audit, "eventId");
|
||||
assert_non_null(v);
|
||||
assert_true(json_is_integer(v));
|
||||
assert_int_equal(EVT_ID_PASSWORD_RESET, json_integer_value(v));
|
||||
|
||||
v = json_object_get(audit, "statusCode");
|
||||
assert_non_null(v);
|
||||
assert_true(json_is_integer(v));
|
||||
|
Loading…
x
Reference in New Issue
Block a user