diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index e972439370a..0cb5547fef1 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -232,6 +232,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add ECS categories for system module host dataset. {pull}18031[18031] - Add system module package dataset ECS categorization fields. {pull}18033[18033] - Add system module login dataset ECS categorization fields. {pull}18034[18034] +- Add system module user dataset ECS categorization fields. {pull}18035[18035] *Filebeat* diff --git a/x-pack/auditbeat/module/system/user/user.go b/x-pack/auditbeat/module/system/user/user.go index ffa4e272b83..59f23e566e8 100644 --- a/x-pack/auditbeat/module/system/user/user.go +++ b/x-pack/auditbeat/module/system/user/user.go @@ -76,6 +76,23 @@ func (action eventAction) String() string { } } +func (action eventAction) Type() string { + switch action { + case eventActionExistingUser: + return "info" + case eventActionUserAdded: + return "creation" + case eventActionUserRemoved: + return "deletion" + case eventActionUserChanged: + return "change" + case eventActionPasswordChanged: + return "change" + default: + return "info" + } +} + type passwordType uint8 const ( @@ -164,6 +181,7 @@ func (user User) toMapStr() common.MapStr { groupMapStr = append(groupMapStr, common.MapStr{ "name": group.Name, "gid": group.Gid, + "id": group.Gid, }) } evt.Put("group", groupMapStr) @@ -172,6 +190,15 @@ func (user User) toMapStr() common.MapStr { return evt } +func (user User) PrimaryGroup() *user.Group { + for _, group := range user.Groups { + if group.Gid == user.GID { + return group + } + } + return nil +} + // entityID creates an ID that uniquely identifies this user across machines. func (u User) entityID(hostID string) string { h := system.NewEntityHash() @@ -430,13 +457,18 @@ func (ms *MetricSet) userEvent(user *User, eventType string, action eventAction) event := mb.Event{ RootFields: common.MapStr{ "event": common.MapStr{ - "kind": eventType, - "action": action.String(), + "kind": eventType, + "category": []string{"iam"}, + "type": []string{action.Type()}, + "action": action.String(), }, "user": common.MapStr{ "id": user.UID, "name": user.Name, }, + "related": common.MapStr{ + "user": []string{user.Name}, + }, "message": userMessage(user, action), }, MetricSetFields: user.toMapStr(), @@ -446,6 +478,18 @@ func (ms *MetricSet) userEvent(user *User, eventType string, action eventAction) event.RootFields.Put("user.entity_id", user.entityID(ms.HostID())) } + primaryGroup := user.PrimaryGroup() + if primaryGroup != nil { + event.RootFields.Put("user.group", common.MapStr{ + "id": primaryGroup.Gid, + "name": primaryGroup.Name, + }) + } else if user.GID != "" { // fallback to just filling out the GID + event.RootFields.Put("user.group", common.MapStr{ + "id": user.GID, + }) + } + return event } diff --git a/x-pack/auditbeat/module/system/user/user_test.go b/x-pack/auditbeat/module/system/user/user_test.go index 14708232d29..a8fd6f85238 100644 --- a/x-pack/auditbeat/module/system/user/user_test.go +++ b/x-pack/auditbeat/module/system/user/user_test.go @@ -11,6 +11,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/require" + "github.com/elastic/beats/v7/auditbeat/core" abtest "github.com/elastic/beats/v7/auditbeat/testing" mbtest "github.com/elastic/beats/v7/metricbeat/mb/testing" @@ -36,7 +38,16 @@ func TestData(t *testing.T) { } for _, e := range events { - if name, _ := e.RootFields.GetValue("user.name"); name == "elastic" { + if name, _ := e.RootFields.GetValue("user.name"); name == "__elastic" { + relatedNames, err := e.RootFields.GetValue("related.user") + require.NoError(t, err) + require.Equal(t, []string{"__elastic"}, relatedNames) + groupName, err := e.RootFields.GetValue("user.group.name") + require.NoError(t, err) + require.Equal(t, "__elastic", groupName) + groupID, err := e.RootFields.GetValue("user.group.id") + require.NoError(t, err) + require.Equal(t, "1001", groupID) fullEvent := mbtest.StandardizeEvent(f, e, core.AddDatasetToEvent) mbtest.WriteEventToDataJSON(t, fullEvent, "") return @@ -48,13 +59,13 @@ func TestData(t *testing.T) { func testUser() *User { return &User{ - Name: "elastic", + Name: "__elastic", UID: "9999", GID: "1001", Groups: []*user.Group{ &user.Group{ Gid: "1001", - Name: "elastic", + Name: "__elastic", }, &user.Group{ Gid: "1002",