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>
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 {
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)
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"],
"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"],
"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"],
"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"],
"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"],
"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"],
# 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"],
#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"
#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"
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"
*
= 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);
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)) {
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;
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);
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));