cd37fb
From 72962208c42ea202f1e31f2f3ac1b523cd545b06 Mon Sep 17 00:00:00 2001
cd37fb
From: Steve Grubb <sgrubb@redhat.com>
cd37fb
Date: Fri, 3 Aug 2018 11:33:05 +0200
cd37fb
Subject: [PATCH] Add audit events around user life cycle
cd37fb
cd37fb
---
cd37fb
 Makefile.am        | 18 ++++++-------
cd37fb
 apps/lchage.c      |  5 ++++
cd37fb
 apps/lchsh.c       |  7 +++++
cd37fb
 apps/lgroupadd.c   |  5 ++++
cd37fb
 apps/lgroupdel.c   |  6 +++++
cd37fb
 apps/lgroupmod.c   | 36 +++++++++++++++++++++++++
cd37fb
 apps/luseradd.c    | 16 +++++++++++
cd37fb
 apps/luserdel.c    | 17 ++++++++++++
cd37fb
 apps/lusermod.c    | 38 +++++++++++++++++++++++++-
cd37fb
 configure.ac       | 17 ++++++++++++
cd37fb
 lib/common.c       | 66 +++++++++++++++++++++++++++++++++++++++++++++-
cd37fb
 lib/user_private.h | 15 +++++++++++
cd37fb
 12 files changed, 235 insertions(+), 11 deletions(-)
cd37fb
cd37fb
diff --git a/Makefile.am b/Makefile.am
cd37fb
index 080f97e8cc81a77dd0413c3b6fe7fe8002499393..9f099bd71941a869274a502a3130802731d83c24 100644
cd37fb
--- a/Makefile.am
cd37fb
+++ b/Makefile.am
cd37fb
@@ -116,7 +116,7 @@ apps_libapputil_la_LDFLAGS = $(GOBJECT_LIBS) -lpam -lpam_misc $(SELINUX_LIBS)
cd37fb
 
cd37fb
 apps_lchage_CPPFLAGS = $(AM_CPPFLAGS) $(LOCALEDIR_CPPFLAGS)
cd37fb
 apps_lchage_LDADD = lib/libuser.la $(LTLIBINTL)
cd37fb
-apps_lchage_LDFLAGS = $(GMODULE_LIBS) -lpopt
cd37fb
+apps_lchage_LDFLAGS = $(GMODULE_LIBS) -lpopt $(AUDIT_LIBS)
cd37fb
 
cd37fb
 apps_lchfn_CPPFLAGS = $(AM_CPPFLAGS) $(LOCALEDIR_CPPFLAGS)
cd37fb
 apps_lchfn_LDADD = apps/libapputil.la lib/libuser.la $(LTLIBINTL)
cd37fb
@@ -124,19 +124,19 @@ apps_lchfn_LDFLAGS = $(GMODULE_LIBS) -lpopt
cd37fb
 
cd37fb
 apps_lchsh_CPPFLAGS = $(AM_CPPFLAGS) $(LOCALEDIR_CPPFLAGS)
cd37fb
 apps_lchsh_LDADD = apps/libapputil.la lib/libuser.la $(LTLIBINTL)
cd37fb
-apps_lchsh_LDFLAGS = $(GMODULE_LIBS) -lpopt
cd37fb
+apps_lchsh_LDFLAGS = $(GMODULE_LIBS) -lpopt $(AUDIT_LIBS)
cd37fb
 
cd37fb
 apps_lgroupadd_CPPFLAGS = $(AM_CPPFLAGS) $(LOCALEDIR_CPPFLAGS)
cd37fb
 apps_lgroupadd_LDADD = lib/libuser.la $(LTLIBINTL)
cd37fb
-apps_lgroupadd_LDFLAGS = $(GMODULE_LIBS) -lpopt
cd37fb
+apps_lgroupadd_LDFLAGS = $(GMODULE_LIBS) -lpopt $(AUDIT_LIBS)
cd37fb
 
cd37fb
 apps_lgroupdel_CPPFLAGS = $(AM_CPPFLAGS) $(LOCALEDIR_CPPFLAGS)
cd37fb
 apps_lgroupdel_LDADD = lib/libuser.la $(LTLIBINTL)
cd37fb
-apps_lgroupdel_LDFLAGS = $(GMODULE_LIBS) -lpopt
cd37fb
+apps_lgroupdel_LDFLAGS = $(GMODULE_LIBS) -lpopt $(AUDIT_LIBS)
cd37fb
 
cd37fb
 apps_lgroupmod_CPPFLAGS = $(AM_CPPFLAGS) $(LOCALEDIR_CPPFLAGS)
cd37fb
 apps_lgroupmod_LDADD = lib/libuser.la $(LTLIBINTL)
cd37fb
-apps_lgroupmod_LDFLAGS = $(GMODULE_LIBS) -lpopt
cd37fb
+apps_lgroupmod_LDFLAGS = $(GMODULE_LIBS) -lpopt $(AUDIT_LIBS)
cd37fb
 
cd37fb
 apps_lid_CPPFLAGS = $(AM_CPPFLAGS) $(LOCALEDIR_CPPFLAGS)
cd37fb
 apps_lid_LDADD = lib/libuser.la $(LTLIBINTL)
cd37fb
@@ -152,15 +152,15 @@ apps_lpasswd_LDFLAGS = $(GMODULE_LIBS) -lpopt
cd37fb
 
cd37fb
 apps_luseradd_CPPFLAGS = $(AM_CPPFLAGS) $(LOCALEDIR_CPPFLAGS)
cd37fb
 apps_luseradd_LDADD = lib/libuser.la $(LTLIBINTL)
cd37fb
-apps_luseradd_LDFLAGS = $(GMODULE_LIBS) -lpopt
cd37fb
+apps_luseradd_LDFLAGS = $(GMODULE_LIBS) -lpopt $(AUDIT_LIBS)
cd37fb
 
cd37fb
 apps_luserdel_CPPFLAGS = $(AM_CPPFLAGS) $(LOCALEDIR_CPPFLAGS)
cd37fb
 apps_luserdel_LDADD = lib/libuser.la $(LTLIBINTL)
cd37fb
-apps_luserdel_LDFLAGS = $(GMODULE_LIBS) -lpopt
cd37fb
+apps_luserdel_LDFLAGS = $(GMODULE_LIBS) -lpopt $(AUDIT_LIBS)
cd37fb
 
cd37fb
 apps_lusermod_CPPFLAGS = $(AM_CPPFLAGS) $(LOCALEDIR_CPPFLAGS)
cd37fb
 apps_lusermod_LDADD = lib/libuser.la $(LTLIBINTL)
cd37fb
-apps_lusermod_LDFLAGS = $(GMODULE_LIBS) -lpopt
cd37fb
+apps_lusermod_LDFLAGS = $(GMODULE_LIBS) -lpopt $(AUDIT_LIBS)
cd37fb
 
cd37fb
 lib_libuser_la_SOURCES = lib/common.c lib/config.c lib/entity.c lib/error.c \
cd37fb
 	lib/fs.c lib/getdate.y lib/internal.h lib/misc.c lib/modules.c \
cd37fb
@@ -170,7 +170,7 @@ lib_libuser_la_CPPFLAGS = $(GMODULE_CFLAGS) -Ilib $(LOCALEDIR_CPPFLAGS) \
cd37fb
 	-DMODULEDIR='"$(pkglibdir)"' -DNSCD='"$(NSCD)"' \
cd37fb
 	-DSYSCONFDIR='"$(sysconfdir)"'
cd37fb
 lib_libuser_la_LDFLAGS = $(GMODULE_LIBS) $(CRYPT_LIBS) $(SELINUX_LIBS) \
cd37fb
-	-version-info 6:2:5
cd37fb
+	$(AUDIT_LIBS) -version-info 6:2:5
cd37fb
 lib_libuser_la_LIBADD = $(LTLIBINTL)
cd37fb
 
cd37fb
 modules_libuser_files_la_SOURCES = modules/files.c
cd37fb
diff --git a/apps/lchage.c b/apps/lchage.c
cd37fb
index bad296ccf0755dd6781b1a2e6397dccb1f7dbd12..1a4f04883062cb11f15a2e34d37e127fef2a374e 100644
cd37fb
--- a/apps/lchage.c
cd37fb
+++ b/apps/lchage.c
cd37fb
@@ -29,6 +29,7 @@
cd37fb
 #include <popt.h>
cd37fb
 #include <glib.h>
cd37fb
 #include "../lib/user.h"
cd37fb
+#include "../lib/user_private.h"
cd37fb
 #include "apputil.h"
cd37fb
 
cd37fb
 #define INVALID_LONG LONG_MIN
cd37fb
@@ -239,8 +240,12 @@ main(int argc, const char **argv)
cd37fb
 			fprintf(stderr,
cd37fb
 				_("Failed to modify aging information for %s: "
cd37fb
 				  "%s\n"), user, lu_strerror(error));
cd37fb
+			lu_audit_logger(AUDIT_USER_MGMT, "change-age", user,
cd37fb
+				AUDIT_NO_ID, 0);
cd37fb
 			return 3;
cd37fb
 		}
cd37fb
+		lu_audit_logger(AUDIT_USER_MGMT, "change-age", user,
cd37fb
+				AUDIT_NO_ID, 1);
cd37fb
 
cd37fb
 		lu_nscd_flush_cache(LU_NSCD_CACHE_PASSWD);
cd37fb
 	}
cd37fb
diff --git a/apps/lchsh.c b/apps/lchsh.c
cd37fb
index 7c8a9246d4548a7f6fbacce91cdfdf4372799943..555ed2ea7b0d5a90bf37a7f23c398b382ac45a38 100644
cd37fb
--- a/apps/lchsh.c
cd37fb
+++ b/apps/lchsh.c
cd37fb
@@ -26,6 +26,7 @@
cd37fb
 #include <string.h>
cd37fb
 #include <unistd.h>
cd37fb
 #include "../lib/user.h"
cd37fb
+#include "../lib/user_private.h"
cd37fb
 #include "apputil.h"
cd37fb
 
cd37fb
 int
cd37fb
@@ -120,6 +121,8 @@ main(int argc, const char **argv)
cd37fb
 				      NULL, &error) == FALSE) {
cd37fb
 			fprintf(stderr, _("Shell not changed: %s\n"),
cd37fb
 				lu_strerror(error));
cd37fb
+			lu_audit_logger(AUDIT_USER_MGMT, "change-shell", user,
cd37fb
+				AUDIT_NO_ID, 0);
cd37fb
 			return 1;
cd37fb
 		}
cd37fb
 		/* Modify the in-memory structure's shell attribute. */
cd37fb
@@ -132,9 +135,13 @@ main(int argc, const char **argv)
cd37fb
 		if (lu_user_modify(ctx, ent, &error)) {
cd37fb
 			g_print(_("Shell changed.\n"));
cd37fb
 			lu_nscd_flush_cache(LU_NSCD_CACHE_PASSWD);
cd37fb
+			lu_audit_logger(AUDIT_USER_MGMT, "change-shell", user,
cd37fb
+				AUDIT_NO_ID, 1);
cd37fb
 		} else {
cd37fb
 			fprintf(stderr, _("Shell not changed: %s\n"),
cd37fb
 				lu_strerror(error));
cd37fb
+			lu_audit_logger(AUDIT_USER_MGMT, "change-shell", user,
cd37fb
+				AUDIT_NO_ID, 0);
cd37fb
 			return 1;
cd37fb
 		}
cd37fb
 	}
cd37fb
diff --git a/apps/lgroupadd.c b/apps/lgroupadd.c
cd37fb
index d73ee864adac9e5dbc7d98392190db225d116143..3fa2a1df5ac5838ef256541c07ae6028e4f6a80b 100644
cd37fb
--- a/apps/lgroupadd.c
cd37fb
+++ b/apps/lgroupadd.c
cd37fb
@@ -118,6 +118,8 @@ main(int argc, const char **argv)
cd37fb
 	if (lu_group_add(ctx, ent, &error) == FALSE) {
cd37fb
 		fprintf(stderr, _("Group creation failed: %s\n"),
cd37fb
 			lu_strerror(error));
cd37fb
+		lu_audit_logger(AUDIT_ADD_GROUP, "add-group", name,
cd37fb
+				AUDIT_NO_ID, 0);
cd37fb
 		return 2;
cd37fb
 	}
cd37fb
 
cd37fb
@@ -127,5 +129,8 @@ main(int argc, const char **argv)
cd37fb
 
cd37fb
 	lu_end(ctx);
cd37fb
 
cd37fb
+	lu_audit_logger(AUDIT_ADD_GROUP, "add-group", name,
cd37fb
+				AUDIT_NO_ID, 1);
cd37fb
+
cd37fb
 	return 0;
cd37fb
 }
cd37fb
diff --git a/apps/lgroupdel.c b/apps/lgroupdel.c
cd37fb
index e0fd6c6d42f55eef82f0790f551721972c129b5f..c5ccbed95cb834719cd109a81e6f979bb737dc71 100644
cd37fb
--- a/apps/lgroupdel.c
cd37fb
+++ b/apps/lgroupdel.c
cd37fb
@@ -24,6 +24,7 @@
cd37fb
 #include <locale.h>
cd37fb
 #include <popt.h>
cd37fb
 #include "../lib/user.h"
cd37fb
+#include "../lib/user_private.h"
cd37fb
 #include "apputil.h"
cd37fb
 
cd37fb
 int
cd37fb
@@ -90,6 +91,8 @@ main(int argc, const char **argv)
cd37fb
 	if (lu_group_delete(ctx, ent, &error) == FALSE) {
cd37fb
 		fprintf(stderr, _("Group %s could not be deleted: %s\n"),
cd37fb
 			group, lu_strerror(error));
cd37fb
+		lu_audit_logger(AUDIT_DEL_GROUP, "delete-group", group,
cd37fb
+				AUDIT_NO_ID, 0);
cd37fb
 		return 3;
cd37fb
 	}
cd37fb
 
cd37fb
@@ -99,5 +102,8 @@ main(int argc, const char **argv)
cd37fb
 
cd37fb
 	lu_end(ctx);
cd37fb
 
cd37fb
+	lu_audit_logger(AUDIT_DEL_GROUP, "delete-group", group,
cd37fb
+			AUDIT_NO_ID, 1);
cd37fb
+
cd37fb
 	return 0;
cd37fb
 }
cd37fb
diff --git a/apps/lgroupmod.c b/apps/lgroupmod.c
cd37fb
index 21170e06f37370d7b2f2d936048ae7abf24fd181..0ad0ae4f39d32435b4668ef15ec678d8ea319e5c 100644
cd37fb
--- a/apps/lgroupmod.c
cd37fb
+++ b/apps/lgroupmod.c
cd37fb
@@ -138,8 +138,14 @@ main(int argc, const char **argv)
cd37fb
 		    == FALSE) {
cd37fb
 			fprintf(stderr, _("Failed to set password for group "
cd37fb
 				"%s: %s\n"), group, lu_strerror(error));
cd37fb
+			lu_audit_logger(AUDIT_GRP_MGMT,
cd37fb
+					"changing-group-passwd", group,
cd37fb
+					AUDIT_NO_ID, 0);
cd37fb
 			return 4;
cd37fb
 		}
cd37fb
+		lu_audit_logger(AUDIT_GRP_MGMT,
cd37fb
+				"changing-group-passwd", group,
cd37fb
+				AUDIT_NO_ID, 1);
cd37fb
 	}
cd37fb
 
cd37fb
 	if (cryptedUserPassword) {
cd37fb
@@ -147,8 +153,14 @@ main(int argc, const char **argv)
cd37fb
 				     &error) == FALSE) {
cd37fb
 			fprintf(stderr, _("Failed to set password for group "
cd37fb
 				"%s: %s\n"), group, lu_strerror(error));
cd37fb
+			lu_audit_logger(AUDIT_GRP_MGMT,
cd37fb
+					"changing-group-passwd", group,
cd37fb
+					AUDIT_NO_ID, 0);
cd37fb
 			return 5;
cd37fb
 		}
cd37fb
+		lu_audit_logger(AUDIT_GRP_MGMT,
cd37fb
+				"changing-group-passwd", group,
cd37fb
+				AUDIT_NO_ID, 1);
cd37fb
 	}
cd37fb
 
cd37fb
 	if (lock) {
cd37fb
@@ -156,8 +168,14 @@ main(int argc, const char **argv)
cd37fb
 			fprintf(stderr,
cd37fb
 				_("Group %s could not be locked: %s\n"), group,
cd37fb
 				lu_strerror(error));
cd37fb
+			lu_audit_logger(AUDIT_GRP_MGMT,
cd37fb
+					"changing-group-lock", group,
cd37fb
+					AUDIT_NO_ID, 0);
cd37fb
 			return 6;
cd37fb
 		}
cd37fb
+		lu_audit_logger(AUDIT_GRP_MGMT,
cd37fb
+				"changing-group-lock", group,
cd37fb
+				AUDIT_NO_ID, 1);
cd37fb
 	}
cd37fb
 
cd37fb
 	if (unlock) {
cd37fb
@@ -165,8 +183,14 @@ main(int argc, const char **argv)
cd37fb
 			fprintf(stderr,
cd37fb
 				_("Group %s could not be unlocked: %s\n"),
cd37fb
 				group, lu_strerror(error));
cd37fb
+			lu_audit_logger(AUDIT_GRP_MGMT,
cd37fb
+					"changing-group-lock", group,
cd37fb
+					AUDIT_NO_ID, 0);
cd37fb
 			return 7;
cd37fb
 		}
cd37fb
+		lu_audit_logger(AUDIT_GRP_MGMT,
cd37fb
+				"changing-group-lock", group,
cd37fb
+				AUDIT_NO_ID, 1);
cd37fb
 	}
cd37fb
 
cd37fb
 	change = gid || addAdmins || remAdmins || addMembers || remMembers;
cd37fb
@@ -241,8 +265,14 @@ main(int argc, const char **argv)
cd37fb
 	if (change && lu_group_modify(ctx, ent, &error) == FALSE) {
cd37fb
 		fprintf(stderr, _("Group %s could not be modified: %s\n"),
cd37fb
 			group, lu_strerror(error));
cd37fb
+		lu_audit_logger(AUDIT_GRP_MGMT,
cd37fb
+				"changing-group-members", group,
cd37fb
+				AUDIT_NO_ID, 0);
cd37fb
 		return 8;
cd37fb
 	}
cd37fb
+	lu_audit_logger(AUDIT_GRP_MGMT,
cd37fb
+			"changing-group-members", group,
cd37fb
+			AUDIT_NO_ID, 1);
cd37fb
 	if (gidNumber != LU_VALUE_INVALID_ID) {
cd37fb
 		users = lu_users_enumerate_by_group_full(ctx, gid, &error);
cd37fb
 
cd37fb
@@ -256,8 +286,14 @@ main(int argc, const char **argv)
cd37fb
 			fprintf(stderr,
cd37fb
 				_("Group %s could not be modified: %s\n"),
cd37fb
 				group, lu_strerror(error));
cd37fb
+			lu_audit_logger(AUDIT_GRP_MGMT,
cd37fb
+				"changing-group-id", group,
cd37fb
+				AUDIT_NO_ID, 0);
cd37fb
 			return 8;
cd37fb
 		}
cd37fb
+		lu_audit_logger(AUDIT_GRP_MGMT,
cd37fb
+			"changing-group-id", group,
cd37fb
+			AUDIT_NO_ID, 1);
cd37fb
 	}
cd37fb
 
cd37fb
 	lu_ent_free(ent);
cd37fb
diff --git a/apps/luseradd.c b/apps/luseradd.c
cd37fb
index 7839183c00f892ad50f77f5aed6ada07cd3c125b..9d7f4f10a9c6f849e551f017f05c2e67e4a56259 100644
cd37fb
--- a/apps/luseradd.c
cd37fb
+++ b/apps/luseradd.c
cd37fb
@@ -210,8 +210,12 @@ main(int argc, const char **argv)
cd37fb
 				lu_error_free(&error);
cd37fb
 			}
cd37fb
 			lu_end(ctx);
cd37fb
+			lu_audit_logger(AUDIT_ADD_GROUP, "add-group", name,
cd37fb
+					AUDIT_NO_ID, 0);
cd37fb
 			return 1;
cd37fb
 		}
cd37fb
+		lu_audit_logger(AUDIT_ADD_GROUP, "add-group", name,
cd37fb
+				AUDIT_NO_ID, 1);
cd37fb
 	}
cd37fb
 
cd37fb
 	/* Retrieve the group ID. */
cd37fb
@@ -259,9 +263,13 @@ main(int argc, const char **argv)
cd37fb
 	if (lu_user_add(ctx, ent, &error) == FALSE) {
cd37fb
 		fprintf(stderr, _("Account creation failed: %s.\n"),
cd37fb
 			lu_strerror(error));
cd37fb
+		lu_audit_logger(AUDIT_ADD_USER, "add-user", name,
cd37fb
+					AUDIT_NO_ID, 0);
cd37fb
+
cd37fb
 		return 3;
cd37fb
 	}
cd37fb
         lu_nscd_flush_cache(LU_NSCD_CACHE_PASSWD);
cd37fb
+	lu_audit_logger(AUDIT_ADD_USER, "add-user", name, AUDIT_NO_ID, 1);
cd37fb
 
cd37fb
 	/* If we don't have the the don't-create-home flag, create the user's
cd37fb
 	 * home directory. */
cd37fb
@@ -282,8 +290,12 @@ main(int argc, const char **argv)
cd37fb
 					&error) == FALSE) {
cd37fb
 			fprintf(stderr, _("Error creating %s: %s.\n"),
cd37fb
 				homeDirectory, lu_strerror(error));
cd37fb
+			lu_audit_logger(AUDIT_USER_MGMT, "add-home-dir", name,
cd37fb
+				uidNumber, 0);
cd37fb
 			return 7;
cd37fb
 		}
cd37fb
+		lu_audit_logger(AUDIT_USER_MGMT, "add-home-dir", name,
cd37fb
+				uidNumber, 1);
cd37fb
 
cd37fb
 		/* Create a mail spool for the user. */
cd37fb
 		if (lu_mail_spool_create(ctx, ent, &error) != TRUE) {
cd37fb
@@ -311,8 +323,12 @@ main(int argc, const char **argv)
cd37fb
 			fprintf(stderr, _("Error setting password for user "
cd37fb
 					  "%s: %s.\n"), name,
cd37fb
 				lu_strerror(error));
cd37fb
+			lu_audit_logger(AUDIT_USER_CHAUTHTOK, "updating-password",
cd37fb
+					name, uidNumber, 0);
cd37fb
 			return 3;
cd37fb
 		}
cd37fb
+		lu_audit_logger(AUDIT_USER_CHAUTHTOK, "updating-password",
cd37fb
+					name, uidNumber, 1);
cd37fb
 	}
cd37fb
 	lu_nscd_flush_cache(LU_NSCD_CACHE_PASSWD);
cd37fb
 
cd37fb
diff --git a/apps/luserdel.c b/apps/luserdel.c
cd37fb
index 2f39a4ffb8ae47ac5dc3c84270b54a8ca68c7403..7e20fa7ea9bf4082967bc6931a8557936bfda0a2 100644
cd37fb
--- a/apps/luserdel.c
cd37fb
+++ b/apps/luserdel.c
cd37fb
@@ -26,6 +26,7 @@
cd37fb
 #include <string.h>
cd37fb
 #include <unistd.h>
cd37fb
 #include "../lib/user.h"
cd37fb
+#include "../lib/user_private.h"
cd37fb
 #include "apputil.h"
cd37fb
 
cd37fb
 int
cd37fb
@@ -93,8 +94,12 @@ main(int argc, const char **argv)
cd37fb
 	if (lu_user_delete(ctx, ent, &error) == FALSE) {
cd37fb
 		fprintf(stderr, _("User %s could not be deleted: %s.\n"),
cd37fb
 			user, lu_strerror(error));
cd37fb
+		lu_audit_logger(AUDIT_DEL_USER, "delete-user", user,
cd37fb
+				AUDIT_NO_ID, 0);
cd37fb
 		return 3;
cd37fb
 	}
cd37fb
+	lu_audit_logger(AUDIT_DEL_USER, "delete-user", user,
cd37fb
+			AUDIT_NO_ID, 1);
cd37fb
 
cd37fb
 	lu_nscd_flush_cache(LU_NSCD_CACHE_PASSWD);
cd37fb
 
cd37fb
@@ -126,9 +131,15 @@ main(int argc, const char **argv)
cd37fb
 				fprintf(stderr, _("Group %s could not be "
cd37fb
 						  "deleted: %s.\n"), tmp,
cd37fb
 					lu_strerror(error));
cd37fb
+				lu_audit_logger_with_group (AUDIT_DEL_GROUP,
cd37fb
+					"delete-group", user, AUDIT_NO_ID,
cd37fb
+					tmp, 0);
cd37fb
 				return 7;
cd37fb
 			}
cd37fb
 		}
cd37fb
+		lu_audit_logger_with_group (AUDIT_DEL_GROUP,
cd37fb
+					    "delete-group", user,
cd37fb
+					    AUDIT_NO_ID, tmp, 1);
cd37fb
 		lu_ent_free(group_ent);
cd37fb
 		lu_nscd_flush_cache(LU_NSCD_CACHE_GROUP);
cd37fb
 	}
cd37fb
@@ -138,8 +149,14 @@ main(int argc, const char **argv)
cd37fb
 			fprintf(stderr,
cd37fb
 				_("Error removing home directory: %s.\n"),
cd37fb
 				lu_strerror(error));
cd37fb
+			lu_audit_logger(AUDIT_USER_MGMT,
cd37fb
+					"deleting-home-directory", user,
cd37fb
+					AUDIT_NO_ID, 0);
cd37fb
 			return 9;
cd37fb
 		}
cd37fb
+		lu_audit_logger(AUDIT_USER_MGMT, "deleting-home-directory", user,
cd37fb
+				AUDIT_NO_ID, 1);
cd37fb
+
cd37fb
 		/* Delete the user's mail spool. */
cd37fb
 		if (lu_mail_spool_remove(ctx, ent, &error) != TRUE) {
cd37fb
 			fprintf(stderr, _("Error removing mail spool: %s"),
cd37fb
diff --git a/apps/lusermod.c b/apps/lusermod.c
cd37fb
index afec147475736f0b814b5e1f30c77064f3915c20..143157f114c93960fb879d9e6e0c1fb914f3ffcb 100644
cd37fb
--- a/apps/lusermod.c
cd37fb
+++ b/apps/lusermod.c
cd37fb
@@ -179,8 +179,13 @@ main(int argc, const char **argv)
cd37fb
 			fprintf(stderr,
cd37fb
 				_("Failed to set password for user %s: %s.\n"),
cd37fb
 				user, lu_strerror(error));
cd37fb
+			lu_audit_logger(AUDIT_USER_CHAUTHTOK, 
cd37fb
+					"updating-password", user,
cd37fb
+					uidNumber, 0);
cd37fb
 			return 5;
cd37fb
 		}
cd37fb
+		lu_audit_logger(AUDIT_USER_CHAUTHTOK, "updating-password",
cd37fb
+				user, uidNumber, 0);
cd37fb
 	}
cd37fb
 
cd37fb
 	/* If we need to change a user's crypted password, try to change it,
cd37fb
@@ -192,8 +197,13 @@ main(int argc, const char **argv)
cd37fb
 			fprintf(stderr,
cd37fb
 				_("Failed to set password for user %s: %s.\n"),
cd37fb
 				user, lu_strerror(error));
cd37fb
+			lu_audit_logger(AUDIT_USER_CHAUTHTOK, 
cd37fb
+					"updating-password", user,
cd37fb
+					uidNumber, 0);
cd37fb
 			return 6;
cd37fb
 		}
cd37fb
+		lu_audit_logger(AUDIT_USER_CHAUTHTOK, "updating-password",
cd37fb
+				user, uidNumber, 0);
cd37fb
 	}
cd37fb
 
cd37fb
 	/* If we need to lock/unlock the user's account, do that. */
cd37fb
@@ -202,16 +212,26 @@ main(int argc, const char **argv)
cd37fb
 			fprintf(stderr,
cd37fb
 				_("User %s could not be locked: %s.\n"),
cd37fb
 				user, lu_strerror(error));
cd37fb
+			lu_audit_logger(AUDIT_USER_CHAUTHTOK, 
cd37fb
+					"locking-account", user,
cd37fb
+					uidNumber, 0);
cd37fb
 			return 7;
cd37fb
 		}
cd37fb
+		lu_audit_logger(AUDIT_USER_CHAUTHTOK, "locking-account",
cd37fb
+				user, uidNumber, 0);
cd37fb
 	}
cd37fb
 	if (unlock) {
cd37fb
 		if (lu_user_unlock(ctx, ent, &error) == FALSE) {
cd37fb
 			fprintf(stderr,
cd37fb
 				_("User %s could not be unlocked: %s.\n"),
cd37fb
 				user, lu_strerror(error));
cd37fb
+			lu_audit_logger(AUDIT_USER_CHAUTHTOK, 
cd37fb
+					"unlocking-account", user,
cd37fb
+					uidNumber, 0);
cd37fb
 			return 8;
cd37fb
 		}
cd37fb
+		lu_audit_logger(AUDIT_USER_CHAUTHTOK, "unlocking-account",
cd37fb
+				user, uidNumber, 0);
cd37fb
 	}
cd37fb
 
cd37fb
 	/* Determine if we actually need to change anything. */
cd37fb
@@ -274,8 +294,13 @@ main(int argc, const char **argv)
cd37fb
 	if (change && (lu_user_modify(ctx, ent, &error) == FALSE)) {
cd37fb
 		fprintf(stderr, _("User %s could not be modified: %s.\n"),
cd37fb
 			user, lu_strerror(error));
cd37fb
+			lu_audit_logger(AUDIT_USER_MGMT, 
cd37fb
+					"modify-account", user,
cd37fb
+					uidNumber, 0);
cd37fb
 		return 9;
cd37fb
 	}
cd37fb
+	lu_audit_logger(AUDIT_USER_MGMT, "modify-account",
cd37fb
+			user, uidNumber, 1);
cd37fb
 	lu_nscd_flush_cache(LU_NSCD_CACHE_PASSWD);
cd37fb
 
cd37fb
 	/* If the user's name changed, we need to update supplemental
cd37fb
@@ -322,12 +347,19 @@ main(int argc, const char **argv)
cd37fb
 				}
cd37fb
 			}
cd37fb
 			/* Save the changes to the group. */
cd37fb
-			if (lu_group_modify(ctx, group, &error) == FALSE)
cd37fb
+			if (lu_group_modify(ctx, group, &error) == FALSE) {
cd37fb
 				fprintf(stderr, _("Group %s could not be "
cd37fb
 						  "modified: %s.\n"),
cd37fb
 					lu_ent_get_first_string(group,
cd37fb
 								LU_GROUPNAME),
cd37fb
 					lu_strerror(error));
cd37fb
+				lu_audit_logger_with_group(AUDIT_USER_MGMT, 
cd37fb
+						    "update-member-in-group", user, uidNumber,
cd37fb
+						    lu_ent_get_first_string(group, LU_GROUPNAME),0);
cd37fb
+			} else
cd37fb
+				lu_audit_logger_with_group(AUDIT_USER_MGMT, 
cd37fb
+						    "update-member-in-group", user, uidNumber,
cd37fb
+						    lu_ent_get_first_string(group, LU_GROUPNAME),1);
cd37fb
 			lu_ent_free(group);
cd37fb
 		}
cd37fb
 		g_ptr_array_free(groups, TRUE);
cd37fb
@@ -353,8 +385,12 @@ main(int argc, const char **argv)
cd37fb
 			fprintf(stderr, _("Error moving %s to %s: %s.\n"),
cd37fb
 				oldHomeDirectory, homeDirectory,
cd37fb
 				lu_strerror(error));
cd37fb
+			lu_audit_logger(AUDIT_USER_MGMT, "moving-home-dir",
cd37fb
+					user, uidNumber, 0);
cd37fb
 			return 12;
cd37fb
 		}
cd37fb
+		lu_audit_logger(AUDIT_USER_MGMT, "moving-home-dir",
cd37fb
+				user, uidNumber, 1);
cd37fb
 	}
cd37fb
 	g_free(oldHomeDirectory);
cd37fb
 
cd37fb
diff --git a/configure.ac b/configure.ac
cd37fb
index 3e68b16a1f65ff5e5e3e905c1ffce8993e562176..0bd4a67d4c77fa1b701d74dbeab908a192dbf4d7 100644
cd37fb
--- a/configure.ac
cd37fb
+++ b/configure.ac
cd37fb
@@ -118,6 +118,23 @@ if test "x$selinux" != xno ; then
cd37fb
 fi
cd37fb
 AC_SUBST(SELINUX_LIBS)
cd37fb
 
cd37fb
+AC_ARG_WITH(audit,
cd37fb
+AS_HELP_STRING([--with-audit],[log using Linux Audit in addition to syslog]),
cd37fb
+use_audit=$withval,
cd37fb
+use_audit=auto)
cd37fb
+if test x$use_audit != xno ; then
cd37fb
+        AC_SEARCH_LIBS([audit_open], [audit])
cd37fb
+        if test x$ac_cv_search_audit_open = xno ; then
cd37fb
+                if test x$use_audit != xauto ; then
cd37fb
+                        AC_MSG_ERROR([requested Linux Audit, but libaudit was not found])
cd37fb
+                fi
cd37fb
+        else
cd37fb
+                AC_DEFINE(WITH_AUDIT,1,[Define if you want to use Linux Audit.])
cd37fb
+		AUDIT_LIBS=-laudit
cd37fb
+        fi
cd37fb
+fi
cd37fb
+AC_SUBST(AUDIT_LIBS)
cd37fb
+
cd37fb
 AC_C_CONST
cd37fb
 AC_TYPE_UID_T
cd37fb
 AC_TYPE_MODE_T
cd37fb
diff --git a/lib/common.c b/lib/common.c
cd37fb
index fc5df7461111908ff3eae59608ce0a51d62e155e..dce7e570ec9c92b56b28f15ab503fb7a641b660e 100644
cd37fb
--- a/lib/common.c
cd37fb
+++ b/lib/common.c
cd37fb
@@ -16,9 +16,10 @@
cd37fb
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
cd37fb
  */
cd37fb
 
cd37fb
-#include <config.h>
cd37fb
+#include "config.h"
cd37fb
 #include <glib.h>
cd37fb
 #include <string.h>
cd37fb
+#include <stdlib.h>
cd37fb
 
cd37fb
 #include "internal.h"
cd37fb
 #include "user_private.h"
cd37fb
@@ -111,3 +112,66 @@ lu_common_sgroup_default(struct lu_module *module,
cd37fb
 	g_return_val_if_fail(name != NULL, FALSE);
cd37fb
 	return lu_common_group_default(module, name, is_system, ent, error);
cd37fb
 }
cd37fb
+
cd37fb
+#ifdef WITH_AUDIT
cd37fb
+static int audit_fd = 0;
cd37fb
+
cd37fb
+/* result - 1 is "success" and 0 is "failed" */
cd37fb
+void lu_audit_logger(int type, const char *op, const char *name,
cd37fb
+                        unsigned int id, unsigned int result)
cd37fb
+{
cd37fb
+	if (audit_fd == 0) {
cd37fb
+		/* First time through */
cd37fb
+		audit_fd = audit_open();
cd37fb
+		if (audit_fd < 0) {
cd37fb
+			/* You get these only when the kernel doesn't have
cd37fb
+			 * audit compiled in. */
cd37fb
+			if (	   (errno == EINVAL)
cd37fb
+				|| (errno == EPROTONOSUPPORT)
cd37fb
+				|| (errno == EAFNOSUPPORT))
cd37fb
+					return;
cd37fb
+			fputs("Cannot open audit interface - aborting.\n", stderr);
cd37fb
+			exit(EXIT_FAILURE);
cd37fb
+		}
cd37fb
+	}
cd37fb
+	if (audit_fd < 0)
cd37fb
+		return;
cd37fb
+	audit_log_acct_message(audit_fd, type, NULL, op, name, id,
cd37fb
+		NULL, NULL, NULL, (int) result);
cd37fb
+}
cd37fb
+
cd37fb
+/* result - 1 is "success" and 0 is "failed" */
cd37fb
+void lu_audit_logger_with_group (int type, const char *op, const char *name,
cd37fb
+		unsigned int id, const char *grp, unsigned int result)
cd37fb
+{
cd37fb
+	int len;
cd37fb
+	char enc_group[(LOGIN_NAME_MAX*2)+1], buf[1024];
cd37fb
+
cd37fb
+	if (audit_fd == 0) {
cd37fb
+		/* First time through */
cd37fb
+		audit_fd = audit_open();
cd37fb
+		if (audit_fd < 0) {
cd37fb
+			/* You get these only when the kernel doesn't have
cd37fb
+			 * audit compiled in. */
cd37fb
+			if (	   (errno == EINVAL)
cd37fb
+				|| (errno == EPROTONOSUPPORT)
cd37fb
+				|| (errno == EAFNOSUPPORT))
cd37fb
+					return;
cd37fb
+			fputs("Cannot open audit interface - aborting.\n", stderr);
cd37fb
+			exit(EXIT_FAILURE);
cd37fb
+		}
cd37fb
+	}
cd37fb
+	if (audit_fd < 0)
cd37fb
+		return;
cd37fb
+	len = strnlen(grp, sizeof(enc_group)/2);
cd37fb
+	if (audit_value_needs_encoding(grp, len)) {
cd37fb
+		snprintf(buf, sizeof(buf), "%s grp=%s", op,
cd37fb
+			audit_encode_value(enc_group, grp, len));
cd37fb
+	} else {
cd37fb
+		snprintf(buf, sizeof(buf), "%s grp=\"%s\"", op, grp);
cd37fb
+	}
cd37fb
+	audit_log_acct_message(audit_fd, type, NULL, buf, name, id,
cd37fb
+			NULL, NULL, NULL, (int) result);
cd37fb
+}
cd37fb
+#endif
cd37fb
+
cd37fb
diff --git a/lib/user_private.h b/lib/user_private.h
cd37fb
index a4869c138d51519539b6939406cdb0fee23ab7f6..02b813c47ee359db774bb85a2aa7aa12e18d3067 100644
cd37fb
--- a/lib/user_private.h
cd37fb
+++ b/lib/user_private.h
cd37fb
@@ -34,6 +34,9 @@
cd37fb
 #ifdef WITH_SELINUX
cd37fb
 #include <selinux/selinux.h>
cd37fb
 #endif
cd37fb
+#ifdef WITH_AUDIT
cd37fb
+#include <libaudit.h>
cd37fb
+#endif
cd37fb
 #include "user.h"
cd37fb
 
cd37fb
 G_BEGIN_DECLS
cd37fb
@@ -357,6 +360,18 @@ id_t lu_get_first_unused_id(struct lu_context *ctx, enum lu_entity_type type,
cd37fb
 /* Append a copy of VALUES to DEST */
cd37fb
 void lu_util_append_values(GValueArray *dest, GValueArray *values);
cd37fb
 
cd37fb
+#ifdef WITH_AUDIT
cd37fb
+void lu_audit_logger(int type, const char *op, const char *name,
cd37fb
+		     unsigned int id, unsigned int result);
cd37fb
+void lu_audit_logger_with_group(int type, const char *op, const char *name,
cd37fb
+				 unsigned int id, const char *grp,
cd37fb
+				 unsigned int result);
cd37fb
+#else
cd37fb
+#define lu_audit_logger(a, b, c, d, e)
cd37fb
+#define lu_audit_logger_with_group(a, b, c, d, e, f)
cd37fb
+#endif
cd37fb
+#define AUDIT_NO_ID	((unsigned int) -1)
cd37fb
+
cd37fb
 G_END_DECLS
cd37fb
 
cd37fb
 #endif
cd37fb
-- 
cd37fb
2.17.1
cd37fb