Blame SOURCES/pam-1.1.8-tty-audit-uid-range.patch

c22a38
diff -up Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.c.uid-range Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.c
c22a38
--- Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.c.uid-range	2017-09-08 14:46:58.869496414 +0200
c22a38
+++ Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.c	2017-10-09 17:42:13.947599041 +0200
c22a38
@@ -198,6 +198,54 @@ cleanup_old_status (pam_handle_t *pamh,
c22a38
   free (data);
c22a38
 }
c22a38
 
c22a38
+enum uid_range { UID_RANGE_NONE, UID_RANGE_MM, UID_RANGE_MIN,
c22a38
+    UID_RANGE_ONE, UID_RANGE_ERR };
c22a38
+
c22a38
+static enum uid_range
c22a38
+parse_uid_range(pam_handle_t *pamh, const char *s,
c22a38
+                uid_t *min_uid, uid_t *max_uid)
c22a38
+{
c22a38
+    const char *range = s;
c22a38
+    const char *pmax;
c22a38
+    char *endptr;
c22a38
+    enum uid_range rv = UID_RANGE_MM;
c22a38
+
c22a38
+    if ((pmax=strchr(range, ':')) == NULL)
c22a38
+        return UID_RANGE_NONE;
c22a38
+    ++pmax;
c22a38
+
c22a38
+    if (range[0] == ':')
c22a38
+        rv = UID_RANGE_ONE;
c22a38
+    else {
c22a38
+            errno = 0;
c22a38
+            *min_uid = strtoul (range, &endptr, 10);
c22a38
+            if (errno != 0 || (range == endptr) || *endptr != ':') {
c22a38
+                pam_syslog(pamh, LOG_DEBUG,
c22a38
+                           "wrong min_uid value in '%s'", s);
c22a38
+                return UID_RANGE_ERR;
c22a38
+            }
c22a38
+    }
c22a38
+
c22a38
+    if (*pmax == '\0') {
c22a38
+        if (rv == UID_RANGE_ONE)
c22a38
+            return UID_RANGE_ERR;
c22a38
+
c22a38
+        return UID_RANGE_MIN;
c22a38
+    }
c22a38
+
c22a38
+    errno = 0;
c22a38
+    *max_uid = strtoul (pmax, &endptr, 10);
c22a38
+    if (errno != 0 || (pmax == endptr) || *endptr != '\0') {
c22a38
+        pam_syslog(pamh, LOG_DEBUG,
c22a38
+                   "wrong max_uid value in '%s'", s);
c22a38
+        return UID_RANGE_ERR;
c22a38
+    }
c22a38
+
c22a38
+    if (rv == UID_RANGE_ONE)
c22a38
+        *min_uid = *max_uid;
c22a38
+    return rv;
c22a38
+}
c22a38
+
c22a38
 int
c22a38
 pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv)
c22a38
 {
c22a38
@@ -207,6 +255,7 @@ pam_sm_open_session (pam_handle_t *pamh,
c22a38
   struct audit_tty_status *old_status, new_status;
c22a38
   const char *user;
c22a38
   int i, fd, open_only;
c22a38
+  struct passwd *pwd;
c22a38
 #ifdef HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD
c22a38
   int log_passwd;
c22a38
 #endif /* HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD */
c22a38
@@ -219,6 +268,14 @@ pam_sm_open_session (pam_handle_t *pamh,
c22a38
       return PAM_SESSION_ERR;
c22a38
     }
c22a38
 
c22a38
+  pwd = pam_modutil_getpwnam(pamh, user);
c22a38
+  if (pwd == NULL)
c22a38
+    {
c22a38
+      pam_syslog(pamh, LOG_WARNING,
c22a38
+                 "open_session unknown user '%s'", user);
c22a38
+      return PAM_SESSION_ERR;
c22a38
+    }
c22a38
+
c22a38
   command = CMD_NONE;
c22a38
   open_only = 0;
c22a38
 #ifdef HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD
c22a38
@@ -236,13 +293,31 @@ pam_sm_open_session (pam_handle_t *pamh,
c22a38
 	  copy = strdup (strchr (argv[i], '=') + 1);
c22a38
 	  if (copy == NULL)
c22a38
 	    return PAM_SESSION_ERR;
c22a38
-	  for (tok = strtok_r (copy, ",", &tok_data); tok != NULL;
c22a38
+	  for (tok = strtok_r (copy, ",", &tok_data);
c22a38
+	       tok != NULL && command != this_command;
c22a38
 	       tok = strtok_r (NULL, ",", &tok_data))
c22a38
 	    {
c22a38
-	      if (fnmatch (tok, user, 0) == 0)
c22a38
+	      uid_t min_uid = 0, max_uid = 0;
c22a38
+	      switch (parse_uid_range(pamh, tok, &min_uid, &max_uid))
c22a38
 		{
c22a38
-		  command = this_command;
c22a38
-		  break;
c22a38
+		case UID_RANGE_NONE:
c22a38
+		    if (fnmatch (tok, user, 0) == 0)
c22a38
+			command = this_command;
c22a38
+		    break;
c22a38
+		case UID_RANGE_MM:
c22a38
+		    if (pwd->pw_uid >= min_uid && pwd->pw_uid <= max_uid)
c22a38
+			command = this_command;
c22a38
+		    break;
c22a38
+		case UID_RANGE_MIN:
c22a38
+		    if (pwd->pw_uid >= min_uid)
c22a38
+			command = this_command;
c22a38
+		    break;
c22a38
+		case UID_RANGE_ONE:
c22a38
+		    if (pwd->pw_uid == max_uid)
c22a38
+			command = this_command;
c22a38
+		    break;
c22a38
+		case UID_RANGE_ERR:
c22a38
+		    break;
c22a38
 		}
c22a38
 	    }
c22a38
 	  free (copy);
c22a38
diff -up Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.8.xml.uid-range Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.8.xml
c22a38
--- Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.8.xml.uid-range	2013-08-28 10:53:40.000000000 +0200
c22a38
+++ Linux-PAM-1.1.8/modules/pam_tty_audit/pam_tty_audit.8.xml	2017-09-08 14:46:58.895497022 +0200
c22a38
@@ -44,10 +44,10 @@
c22a38
         </term>
c22a38
         <listitem>
c22a38
           <para>
c22a38
-	    For each user matching one of comma-separated glob
c22a38
-	    <option><replaceable>patterns</replaceable></option>, disable
c22a38
-	    TTY auditing.  This overrides any previous <option>enable</option>
c22a38
-	    option matching the same user name on the command line.
c22a38
+	    For each user matching <option><replaceable>patterns</replaceable></option>,
c22a38
+	    disable TTY auditing.  This overrides any previous <option>enable</option>
c22a38
+	    option matching the same user name on the command line. See NOTES
c22a38
+	    for further description of <option><replaceable>patterns</replaceable></option>.
c22a38
           </para>
c22a38
         </listitem>
c22a38
       </varlistentry>
c22a38
@@ -57,10 +57,10 @@
c22a38
         </term>
c22a38
         <listitem>
c22a38
           <para>
c22a38
-	    For each user matching one of comma-separated glob
c22a38
-	    <option><replaceable>patterns</replaceable></option>, enable
c22a38
-	    TTY auditing.  This overrides any previous <option>disable</option>
c22a38
-	    option matching the same user name on the command line.
c22a38
+	    For each user matching <option><replaceable>patterns</replaceable></option>,
c22a38
+	    enable TTY auditing.  This overrides any previous <option>disable</option>
c22a38
+	    option matching the same user name on the command line. See NOTES
c22a38
+	    for further description of <option><replaceable>patterns</replaceable></option>.
c22a38
           </para>
c22a38
         </listitem>
c22a38
       </varlistentry>
c22a38
@@ -139,6 +139,16 @@
c22a38
       To view the data that was logged by the kernel to audit use
c22a38
       the command <command>aureport --tty</command>.
c22a38
     </para>
c22a38
+    <para>
c22a38
+      The <option><replaceable>patterns</replaceable></option> are comma separated
c22a38
+      lists of glob patterns or ranges of uids. A range is specified as
c22a38
+      <replaceable>min_uid</replaceable>:<replaceable>max_uid</replaceable> where
c22a38
+      one of these values can be empty. If <replaceable>min_uid</replaceable> is
c22a38
+      empty only user with the uid <replaceable>max_uid</replaceable> will be
c22a38
+      matched. If <replaceable>max_uid</replaceable> is empty users with the uid
c22a38
+      greater than or equal to <replaceable>min_uid</replaceable> will be
c22a38
+      matched.
c22a38
+    </para>
c22a38
   </refsect1>
c22a38
 
c22a38
   <refsect1 id='pam_tty_audit-examples'>