From ebc117df3a59e9cd6e541c6bb5ac17d6527c2204 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= <clement.chigot@atos.net>
Date: Thu, 30 Jan 2020 11:06:59 +0100
Subject: [PATCH] auditbeat/module/file_integrity: port for AIX

---
 .../file_integrity/eventreader_fsnotify.go    |  2 +-
 .../module/file_integrity/eventreader_test.go |  7 ++++-
 .../file_integrity/eventreader_unsupported.go |  4 +--
 .../module/file_integrity/fileinfo_aix.go     | 31 +++++++++++++++++++
 .../module/file_integrity/fileinfo_posix.go   |  2 +-
 .../file_integrity/monitor/monitor_test.go    |  7 ++++-
 6 files changed, 47 insertions(+), 6 deletions(-)
 create mode 100644 auditbeat/module/file_integrity/fileinfo_aix.go

diff --git a/auditbeat/module/file_integrity/eventreader_fsnotify.go b/auditbeat/module/file_integrity/eventreader_fsnotify.go
index b228ebc59..484e9ecb9 100644
--- a/auditbeat/module/file_integrity/eventreader_fsnotify.go
+++ b/auditbeat/module/file_integrity/eventreader_fsnotify.go
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-// +build linux freebsd openbsd netbsd windows
+// +build aix linux freebsd openbsd netbsd windows
 
 package file_integrity
 
diff --git a/auditbeat/module/file_integrity/eventreader_test.go b/auditbeat/module/file_integrity/eventreader_test.go
index 6d9b02f78..eef5fd8a2 100644
--- a/auditbeat/module/file_integrity/eventreader_test.go
+++ b/auditbeat/module/file_integrity/eventreader_test.go
@@ -162,6 +162,11 @@ func TestEventReader(t *testing.T) {
 			t.Skip("skip chown on windows")
 		}
 
+		// fsnotify polling isn't able to detect a chown modification
+		if runtime.GOOS == "aix" {
+			t.Skip("skip chown on aix")
+		}
+
 		gid := changeGID(t, txt2)
 		event := readTimeout(t, events)
 		assertSameFile(t, txt2, event.Path)
@@ -221,7 +226,7 @@ func TestEventReader(t *testing.T) {
 
 		event := readTimeout(t, events)
 		assertSameFile(t, moveIn, event.Path)
-		if runtime.GOOS == "windows" {
+		if runtime.GOOS == "windows" || runtime.GOOS == "aix" {
 			assert.EqualValues(t, Deleted, event.Action)
 		} else {
 			assert.EqualValues(t, Moved, Moved&event.Action)
diff --git a/auditbeat/module/file_integrity/eventreader_unsupported.go b/auditbeat/module/file_integrity/eventreader_unsupported.go
index 530348338..024729891 100644
--- a/auditbeat/module/file_integrity/eventreader_unsupported.go
+++ b/auditbeat/module/file_integrity/eventreader_unsupported.go
@@ -15,12 +15,12 @@
 // specific language governing permissions and limitations
 // under the License.
 
-// +build !linux,!freebsd,!openbsd,!netbsd,!windows,!darwin
+// +build !aix,!linux,!freebsd,!openbsd,!netbsd,!windows,!darwin
 
 package file_integrity
 
 import "github.com/pkg/errors"
 
 func NewEventReader(c Config) (EventProducer, error) {
-	return errors.New("file auditing metricset is not implemented on this system")
+	return nil, errors.New("file auditing metricset is not implemented on this system")
 }
diff --git a/auditbeat/module/file_integrity/fileinfo_aix.go b/auditbeat/module/file_integrity/fileinfo_aix.go
new file mode 100644
index 000000000..973743fdd
--- /dev/null
+++ b/auditbeat/module/file_integrity/fileinfo_aix.go
@@ -0,0 +1,31 @@
+// Licensed to Elasticsearch B.V. under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Elasticsearch B.V. licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+// +build aix
+
+package file_integrity
+
+import (
+	"syscall"
+	"time"
+)
+
+func fileTimes(stat *syscall.Stat_t) (atime, mtime, ctime time.Time) {
+	return time.Unix(0, stat.Atim.Nano()).UTC(),
+		time.Unix(0, stat.Mtim.Nano()).UTC(),
+		time.Unix(0, stat.Ctim.Nano()).UTC()
+}
diff --git a/auditbeat/module/file_integrity/fileinfo_posix.go b/auditbeat/module/file_integrity/fileinfo_posix.go
index 3e6d5e6e8..8a5064b6a 100644
--- a/auditbeat/module/file_integrity/fileinfo_posix.go
+++ b/auditbeat/module/file_integrity/fileinfo_posix.go
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-// +build linux freebsd openbsd netbsd darwin
+// +build aix linux freebsd openbsd netbsd darwin
 
 package file_integrity
 
diff --git a/auditbeat/module/file_integrity/monitor/monitor_test.go b/auditbeat/module/file_integrity/monitor/monitor_test.go
index 9b028bae8..1631bbaa8 100644
--- a/auditbeat/module/file_integrity/monitor/monitor_test.go
+++ b/auditbeat/module/file_integrity/monitor/monitor_test.go
@@ -172,6 +172,11 @@ func TestRecursiveSubdirPermissions(t *testing.T) {
 		t.Skip("Skipping permissions test on Windows")
 	}
 
+	if runtime.GOOS == "aix" && os.Getuid() == 0 {
+		// AIX wil still be able to read "b" if root.
+		t.Skip("Skipping permissions test as root on AIX")
+	}
+
 	// Create dir to be watched
 
 	dir, err := ioutil.TempDir("", "monitor")
@@ -248,7 +253,7 @@ func TestRecursiveSubdirPermissions(t *testing.T) {
 	// File "b/b" is missing because a watch to b couldn't be installed
 
 	expected := map[string]fsnotify.Op{
-		dest:                       fsnotify.Create,
+		dest: fsnotify.Create,
 		filepath.Join(dest, "a"):   fsnotify.Create,
 		filepath.Join(dest, "a/a"): fsnotify.Create,
 		filepath.Join(dest, "b"):   fsnotify.Create,
-- 
2.22.0

