Blame SOURCES/pam-1.2.1-faillock-admin-group.patch

5c721c
diff -up Linux-PAM-1.3.0/modules/pam_faillock/pam_faillock.c.admin-group Linux-PAM-1.3.0/modules/pam_faillock/pam_faillock.c
5c721c
--- Linux-PAM-1.3.0/modules/pam_faillock/pam_faillock.c.admin-group	2016-04-04 16:37:38.696260359 +0200
5c721c
+++ Linux-PAM-1.3.0/modules/pam_faillock/pam_faillock.c	2017-08-21 16:40:01.624706864 +0200
5c721c
@@ -1,5 +1,5 @@
5c721c
 /*
5c721c
- * Copyright (c) 2010 Tomas Mraz <tmraz@redhat.com>
5c721c
+ * Copyright (c) 2010, 2017 Tomas Mraz <tmraz@redhat.com>
5c721c
  *
5c721c
  * Redistribution and use in source and binary forms, with or without
5c721c
  * modification, are permitted provided that the following conditions
5c721c
@@ -78,9 +78,11 @@ struct options {
5c721c
 	unsigned int root_unlock_time;
5c721c
 	const char *dir;
5c721c
 	const char *user;
5c721c
+	const char *admin_group;
5c721c
 	int failures;
5c721c
 	uint64_t latest_time;
5c721c
 	uid_t uid;
5c721c
+	int is_admin;
5c721c
 	uint64_t now;
5c721c
 };
5c721c
 
5c721c
@@ -152,6 +154,9 @@ args_parse(pam_handle_t *pamh, int argc,
5c721c
 				opts->root_unlock_time = temp;
5c721c
 			}
5c721c
 		}
5c721c
+		else if (strncmp(argv[i], "admin_group=", 12) == 0) {
5c721c
+			opts->admin_group = argv[i] + 12;
5c721c
+		}
5c721c
  		else if (strcmp(argv[i], "preauth") == 0) {
5c721c
 			opts->action = FAILLOCK_ACTION_PREAUTH;
5c721c
 		}
5c721c
@@ -209,6 +214,17 @@ static int get_pam_user(pam_handle_t *pa
5c721c
 	}
5c721c
 	opts->user = user;
5c721c
 	opts->uid = pwd->pw_uid;
5c721c
+
5c721c
+	if (pwd->pw_uid == 0) {
5c721c
+		opts->is_admin = 1;
5c721c
+		return PAM_SUCCESS;
5c721c
+	}
5c721c
+
5c721c
+	if (opts->admin_group && *opts->admin_group) {
5c721c
+		opts->is_admin = pam_modutil_user_in_group_uid_nam(pamh,
5c721c
+			pwd->pw_uid, opts->admin_group);
5c721c
+	}
5c721c
+
5c721c
 	return PAM_SUCCESS;
5c721c
 }
5c721c
 
5c721c
@@ -239,7 +255,7 @@ check_tally(pam_handle_t *pamh, struct o
5c721c
 		return PAM_SYSTEM_ERR;
5c721c
 	}
5c721c
 
5c721c
-	if (opts->uid == 0 && !(opts->flags & FAILLOCK_FLAG_DENY_ROOT)) {
5c721c
+	if (opts->is_admin && !(opts->flags & FAILLOCK_FLAG_DENY_ROOT)) {
5c721c
 		return PAM_SUCCESS;
5c721c
 	}
5c721c
 
5c721c
@@ -262,13 +278,9 @@ check_tally(pam_handle_t *pamh, struct o
5c721c
 
5c721c
 	opts->failures = failures;
5c721c
 
5c721c
-	if (opts->uid == 0 && !(opts->flags & FAILLOCK_FLAG_DENY_ROOT)) {
5c721c
-		return PAM_SUCCESS;
5c721c
-	}
5c721c
-
5c721c
 	if (opts->deny && failures >= opts->deny) {
5c721c
-		if ((opts->uid && opts->unlock_time && latest_time + opts->unlock_time < opts->now) ||
5c721c
-			(!opts->uid && opts->root_unlock_time && latest_time + opts->root_unlock_time < opts->now)) {
5c721c
+		if ((!opts->is_admin && opts->unlock_time && latest_time + opts->unlock_time < opts->now) ||
5c721c
+			(opts->is_admin && opts->root_unlock_time && latest_time + opts->root_unlock_time < opts->now)) {
5c721c
 #ifdef HAVE_LIBAUDIT
5c721c
 			if (opts->action != FAILLOCK_ACTION_PREAUTH) { /* do not audit in preauth */
5c721c
 				char buf[64];
5c721c
@@ -401,7 +413,7 @@ write_tally(pam_handle_t *pamh, struct o
5c721c
 		audit_log_user_message(audit_fd, AUDIT_ANOM_LOGIN_FAILURES, buf,
5c721c
 			NULL, NULL, NULL, 1);
5c721c
 
5c721c
-		if (opts->uid != 0 || (opts->flags & FAILLOCK_FLAG_DENY_ROOT)) {
5c721c
+		if (!opts->is_admin || (opts->flags & FAILLOCK_FLAG_DENY_ROOT)) {
5c721c
 			audit_log_user_message(audit_fd, AUDIT_RESP_ACCT_LOCK, buf,
5c721c
 				NULL, NULL, NULL, 1);
5c721c
 		}
5c721c
@@ -425,11 +437,11 @@ faillock_message(pam_handle_t *pamh, str
5c721c
 	int64_t left;
5c721c
 
5c721c
 	if (!(opts->flags & FAILLOCK_FLAG_SILENT)) {
5c721c
-		if (opts->uid) {
5c721c
-			left = opts->latest_time + opts->unlock_time - opts->now;
5c721c
+		if (opts->is_admin) {
5c721c
+			left = opts->latest_time + opts->root_unlock_time - opts->now;
5c721c
 		}
5c721c
 		else {
5c721c
-			left = opts->latest_time + opts->root_unlock_time - opts->now;
5c721c
+			left = opts->latest_time + opts->unlock_time - opts->now;
5c721c
 		}
5c721c
 
5c721c
 		if (left > 0) {
5c721c
diff -up Linux-PAM-1.3.0/modules/pam_faillock/pam_faillock.8.xml.admin-group Linux-PAM-1.3.0/modules/pam_faillock/pam_faillock.8.xml
5c721c
--- Linux-PAM-1.3.0/modules/pam_faillock/pam_faillock.8.xml.admin-group	2016-05-06 15:24:10.328281818 +0200
5c721c
+++ Linux-PAM-1.3.0/modules/pam_faillock/pam_faillock.8.xml	2017-08-21 16:16:09.448033843 +0200
5c721c
@@ -40,6 +40,9 @@
5c721c
         root_unlock_time=<replaceable>n</replaceable>
5c721c
       </arg>
5c721c
       <arg choice="opt">
5c721c
+        admin_group=<replaceable>name</replaceable>
5c721c
+      </arg>
5c721c
+      <arg choice="opt">
5c721c
         audit
5c721c
       </arg>
5c721c
       <arg choice="opt">
5c721c
@@ -243,6 +246,20 @@
5c721c
                 </para>
5c721c
               </listitem>
5c721c
             </varlistentry>
5c721c
+            <varlistentry>
5c721c
+              <term>
5c721c
+                <option>admin_group=<replaceable>name</replaceable></option>
5c721c
+              </term>
5c721c
+              <listitem>
5c721c
+                <para>
5c721c
+                  If a group name is specified with this option, members
5c721c
+                  of the group will be handled by this module the same as
5c721c
+                  the root account (the options <option>even_deny_root></option>
5c721c
+                  and <option>root_unlock_time</option> will apply to them.
5c721c
+                  By default the option is not set.
5c721c
+                </para>
5c721c
+              </listitem>
5c721c
+            </varlistentry>
5c721c
         </variablelist>
5c721c
   </refsect1>
5c721c