rpms/pam/devel pam-0.99.8.1-audit-failed.patch, NONE, 1.1 pam.spec, 1.166, 1.167

Tomas Mraz (tmraz) fedora-extras-commits at redhat.com
Tue Jan 22 21:52:49 UTC 2008


Author: tmraz

Update of /cvs/pkgs/rpms/pam/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv751

Modified Files:
	pam.spec 
Added Files:
	pam-0.99.8.1-audit-failed.patch 
Log Message:
* Tue Jan 22 2008 Tomas Mraz <tmraz at redhat.com> 0.99.8.1-16
- add auditing to pam_access, pam_limits, and pam_time
- moved sanity testing code to check script


pam-0.99.8.1-audit-failed.patch:

--- NEW FILE pam-0.99.8.1-audit-failed.patch ---
diff -up Linux-PAM-0.99.8.1/libpam/libpam.map.audit-failed Linux-PAM-0.99.8.1/libpam/libpam.map
--- Linux-PAM-0.99.8.1/libpam/libpam.map.audit-failed	2006-06-14 17:28:44.000000000 +0200
+++ Linux-PAM-0.99.8.1/libpam/libpam.map	2008-01-22 22:24:05.000000000 +0100
@@ -45,3 +45,7 @@ LIBPAM_MODUTIL_1.0 {
     pam_modutil_read;
     pam_modutil_write;
 };
+LIBPAM_MODUTIL_1.1 {
+  global:
+    pam_modutil_audit_write;
+} LIBPAM_MODUTIL_1.0;
diff -up Linux-PAM-0.99.8.1/libpam/pam_audit.c.audit-failed Linux-PAM-0.99.8.1/libpam/pam_audit.c
--- Linux-PAM-0.99.8.1/libpam/pam_audit.c.audit-failed	2008-01-22 22:24:05.000000000 +0100
+++ Linux-PAM-0.99.8.1/libpam/pam_audit.c	2008-01-22 22:24:05.000000000 +0100
@@ -42,39 +42,53 @@ _pam_audit_writelog(pam_handle_t *pamh, 
      best to fix it. */
   errno = -rc;
 
+  if (rc < 0 && errno != old_errno)
+    {
+      old_errno = errno;
+      pam_syslog (pamh, LOG_CRIT, "audit_log_acct_message() failed: %m");
+    }
+
   pamh->audit_state |= PAMAUDIT_LOGGED;
 
-  if (rc < 0) {
-      if (rc == -EPERM && getuid() != 0)
-          return 0;
-      if (errno != old_errno) {
-          old_errno = errno;
-          pam_syslog (pamh, LOG_CRIT, "audit_log_acct_message() failed: %m");
-      }
-  }
-  return rc;
+  if (rc == -EPERM && getuid () != 0)
+    return 0;
+  else
+    return rc;
 }
 
-int
-_pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags)
+static int
+_pam_audit_open(pam_handle_t *pamh)
 {
-  const char *message;
-  int type;
   int audit_fd;
-
   audit_fd = audit_open();
   if (audit_fd < 0) {
     /* You get these error codes only when the kernel doesn't have
      * audit compiled in. */
     if (errno == EINVAL || errno == EPROTONOSUPPORT ||
         errno == EAFNOSUPPORT)
-        return retval;
+        return -2;
 
     /* this should only fail in case of extreme resource shortage,
      * need to prevent login in that case for CAPP compliance.
      */
     pam_syslog(pamh, LOG_CRIT, "audit_open() failed: %m");
+    return -1;
+  }
+
+  return audit_fd;
+}
+
+int
+_pam_auditlog(pam_handle_t *pamh, int action, int retval, int flags)
+{
+  const char *message;
+  int type;
+  int audit_fd;
+
+  if ((audit_fd=_pam_audit_open(pamh)) == -1) {
     return PAM_SYSTEM_ERR;
+  } else if (audit_fd == -2) {
+    return retval;
   }
 
   switch (action) {
@@ -141,4 +155,30 @@ _pam_audit_end(pam_handle_t *pamh, int s
   return 0;
 }
 
+int
+pam_modutil_audit_write(pam_handle_t *pamh, int type,
+    const char *message, int retval)
+{
+  int audit_fd;
+  int rc;
+	
+  if ((audit_fd=_pam_audit_open(pamh)) == -1) {
+    return PAM_SYSTEM_ERR;
+  } else if (audit_fd == -2) {
+    return retval;
+  }
+
+  rc = _pam_audit_writelog(pamh, audit_fd, type, message, retval);
+
+  audit_close(audit_fd);
+  
+  return rc < 0 ? PAM_SYSTEM_ERR : PAM_SUCCESS;
+}
+
+#else
+int pam_modutil_audit_write(pam_handle_t *pamh UNUSED, int type UNUSED,
+    const char *message UNUSED, int retval UNUSED)
+{
+  return PAM_SUCCESS;
+}
 #endif /* HAVE_LIBAUDIT */
diff -up Linux-PAM-0.99.8.1/modules/pam_access/pam_access.8.xml.audit-failed Linux-PAM-0.99.8.1/modules/pam_access/pam_access.8.xml
--- Linux-PAM-0.99.8.1/modules/pam_access/pam_access.8.xml.audit-failed	2007-06-22 10:03:29.000000000 +0200
+++ Linux-PAM-0.99.8.1/modules/pam_access/pam_access.8.xml	2008-01-22 22:24:05.000000000 +0100
@@ -29,6 +29,9 @@
         nodefgroup
       </arg>
       <arg choice="opt">
+        noaudit
+      </arg>
+      <arg choice="opt">
         accessfile=<replaceable>file</replaceable>
       </arg>
       <arg choice="opt">
@@ -54,6 +57,10 @@
       <filename>/etc/security/access.conf</filename> if you don't specify
       another file.
     </para>
+    <para>
+      If Linux PAM is compiled with audit support the module will report
+      when it denies access based on origin (host or tty). 
+    </para>
   </refsect1>
 
   <refsect1 id="pam_access-options">
@@ -87,6 +94,17 @@
 
       <varlistentry>
         <term>
+          <option>noaudit</option>
+        </term>
+        <listitem>
+          <para>
+            Do not report logins from disallowed hosts and ttys to the audit subsystem.
+          </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
           <option>fieldsep=<replaceable>separators</replaceable></option>
         </term>
         <listitem>
diff -up Linux-PAM-0.99.8.1/modules/pam_access/pam_access.c.audit-failed Linux-PAM-0.99.8.1/modules/pam_access/pam_access.c
--- Linux-PAM-0.99.8.1/modules/pam_access/pam_access.c.audit-failed	2007-06-25 11:59:11.000000000 +0200
+++ Linux-PAM-0.99.8.1/modules/pam_access/pam_access.c	2008-01-22 22:24:05.000000000 +0100
@@ -46,6 +46,10 @@
 #include <netdb.h>
 #include <sys/socket.h>
 
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>
+#endif                                                                                                                                         
+
 /*
  * here, we make definitions for the externally accessible functions
  * in this file (these definitions are required for static modules
@@ -81,17 +85,11 @@
 
  /* Delimiters for fields and for lists of users, ttys or hosts. */
 
-static const char *fs = ":";			/* field separator */
-static const char *sep = ", \t";		/* list-element separator */
-
- /* Constants to be used in assignments only, not in comparisons... */
 
+#define ALL             2
 #define YES             1
 #define NO              0
 
-/* Only allow group entries of the form "(xyz)" */
-static int only_new_group_syntax = NO;
-
  /*
   * A structure to bundle up all login-related information to keep the
   * functional interfaces as generic as possible.
@@ -100,12 +98,13 @@ struct login_info {
     const struct passwd *user;
     const char *from;
     const char *config_file;
+    int debug;              		/* Print debugging messages. */
+    int only_new_group_syntax;		/* Only allow group entries of the form "(xyz)" */
+    int noaudit;			/* Do not audit denials */
+    const char *fs;			/* field separator */
+    const char *sep;			/* list-element separator */
 };
 
-/* Print debugging messages.
-   Default is NO which means don't print debugging messages.  */
-static char pam_access_debug = NO;
-
 /* Parse module config arguments */
 
 static int
@@ -113,17 +112,22 @@ parse_args(pam_handle_t *pamh, struct lo
            int argc, const char **argv)
 {
     int i;
-
+    
+    loginfo->noaudit = NO;
+    loginfo->debug = NO;
+    loginfo->only_new_group_syntax = NO;
+    loginfo->fs = ":";
+    loginfo->sep = ", \t";
     for (i=0; i<argc; ++i) {
 	if (!strncmp("fieldsep=", argv[i], 9)) {
 
 	    /* the admin wants to override the default field separators */
-	    fs = argv[i]+9;
+	    loginfo->fs = argv[i]+9;
 
 	} else if (!strncmp("listsep=", argv[i], 8)) {
 
 	    /* the admin wants to override the default list separators */
-	    sep = argv[i]+8;
+	    loginfo->sep = argv[i]+8;
 
 	} else if (!strncmp("accessfile=", argv[i], 11)) {
 	    FILE *fp = fopen(11 + argv[i], "r");
@@ -138,9 +142,11 @@ parse_args(pam_handle_t *pamh, struct lo
 	    }
 
 	} else if (strcmp (argv[i], "debug") == 0) {
-	    pam_access_debug = YES;
+	    loginfo->debug = YES;
 	} else if (strcmp (argv[i], "nodefgroup") == 0) {
-	    only_new_group_syntax = YES;
+	    loginfo->only_new_group_syntax = YES;
+	} else if (strcmp (argv[i], "noaudit") == 0) {
+	    loginfo->noaudit = YES;
 	} else {
 	    pam_syslog(pamh, LOG_ERR, "unrecognized option [%s]", argv[i]);
 	}
@@ -153,13 +159,13 @@ parse_args(pam_handle_t *pamh, struct lo
 
 typedef int match_func (pam_handle_t *, char *, struct login_info *);
 
-static int list_match (pam_handle_t *, char *, struct login_info *,
+static int list_match (pam_handle_t *, char *, char *, struct login_info *,
 		       match_func *);
 static int user_match (pam_handle_t *, char *, struct login_info *);
-static int group_match (pam_handle_t *, const char *, const char *);
+static int group_match (pam_handle_t *, const char *, const char *, int);
 static int from_match (pam_handle_t *, char *, struct login_info *);
-static int string_match (pam_handle_t *, const char *, const char *);
-static int network_netmask_match (pam_handle_t *, const char *, const char *);
+static int string_match (pam_handle_t *, const char *, const char *, int);
+static int network_netmask_match (pam_handle_t *, const char *, const char *, int);
 
 
 /* isipaddr - find out if string provided is an IP address or not */
@@ -325,11 +331,12 @@ login_access (pam_handle_t *pamh, struct
     char   *users;		/* becomes list of login names */
     char   *froms;		/* becomes list of terminals or hosts */
     int     match = NO;
+    int     nonall_match = NO;
     int     end;
     int     lineno = 0;		/* for diagnostics */
     char   *sptr;
 
-    if (pam_access_debug)
+    if (item->debug)
       pam_syslog (pamh, LOG_DEBUG,
 		  "login_access: user=%s, from=%s, file=%s",
 		  item->user->pw_name,
@@ -361,8 +368,8 @@ login_access (pam_handle_t *pamh, struct
 		continue;
 
 	    /* Allow field seperator in last field of froms */
-	    if (!(perm = strtok_r(line, fs, &sptr))
-		|| !(users = strtok_r(NULL, fs, &sptr))
+	    if (!(perm = strtok_r(line, item->fs, &sptr))
+		|| !(users = strtok_r(NULL, item->fs, &sptr))
   	        || !(froms = strtok_r(NULL, "\n", &sptr))) {
 		pam_syslog(pamh, LOG_ERR, "%s: line %d: bad field count",
 			   item->config_file, lineno);
@@ -373,17 +380,22 @@ login_access (pam_handle_t *pamh, struct
 			   item->config_file, lineno);
 		continue;
 	    }
-	    if (pam_access_debug)
+	    if (item->debug)
 	      pam_syslog (pamh, LOG_DEBUG,
 			  "line %d: %s : %s : %s", lineno, perm, users, froms);
-	    match = list_match(pamh, froms, item, from_match);
-	    if (pam_access_debug)
-	      pam_syslog (pamh, LOG_DEBUG,
-			  "from_match=%d, \"%s\"", match, item->from);
-	    match = match && list_match (pamh, users, item, user_match);
-	    if (pam_access_debug)
+	    match = list_match(pamh, users, NULL, item, user_match);
+	    if (item->debug)
 	      pam_syslog (pamh, LOG_DEBUG, "user_match=%d, \"%s\"",
 			  match, item->user->pw_name);
+	    if (match) {
+		match = list_match(pamh, froms, NULL, item, from_match);
+		if (!match && perm[0] == '+') {
+		    nonall_match = YES;
+		}
+		if (item->debug)
+	    	    pam_syslog (pamh, LOG_DEBUG,
+			  "from_match=%d, \"%s\"", match, item->from);
+	    }
 	}
 	(void) fclose(fp);
     } else if (errno == ENOENT) {
@@ -394,20 +406,27 @@ login_access (pam_handle_t *pamh, struct
         pam_syslog(pamh, LOG_ERR, "cannot open %s: %m", item->config_file);
 	return NO;
     }
+#ifdef HAVE_LIBAUDIT
+    if (!item->noaudit && line[0] == '-' && (match == YES || (match == ALL &&
+	nonall_match == YES))) {
+	pam_modutil_audit_write(pamh, AUDIT_ANOM_LOGIN_LOCATION,
+	    "pam_access", 0);
+    }
+#endif
     return (match == NO || (line[0] == '+'));
 }
 
 
 /* list_match - match an item against a list of tokens with exceptions */
 
-static int list_match(pam_handle_t *pamh,
-		      char *list, struct login_info *item, match_func *match_fn)
+static int
+list_match(pam_handle_t *pamh, char *list, char *sptr,
+	   struct login_info *item, match_func *match_fn)
 {
     char   *tok;
     int     match = NO;
-    char   *sptr;
 
-    if (pam_access_debug)
+    if (item->debug && list != NULL)
       pam_syslog (pamh, LOG_DEBUG,
 		  "list_match: list=%s, item=%s", list, item->user->pw_name);
 
@@ -418,8 +437,8 @@ static int list_match(pam_handle_t *pamh
      * the match is affected by any exceptions.
      */
 
-    for (tok = strtok_r(list, sep, &sptr); tok != 0;
-	 tok = strtok_r(NULL, sep, &sptr)) {
+    for (tok = strtok_r(list, item->sep, &sptr); tok != 0;
+	 tok = strtok_r(NULL, item->sep, &sptr)) {
 	if (strcasecmp(tok, "EXCEPT") == 0)	/* EXCEPT: give up */
 	    break;
 	if ((match = (*match_fn) (pamh, tok, item)))	/* YES */
@@ -428,10 +447,12 @@ static int list_match(pam_handle_t *pamh
     /* Process exceptions to matches. */
 
     if (match != NO) {
-	while ((tok = strtok_r(NULL, sep, &sptr)) && strcasecmp(tok, "EXCEPT"))
+	while ((tok = strtok_r(NULL, item->sep, &sptr)) && strcasecmp(tok, "EXCEPT"))
 	     /* VOID */ ;
-	if (tok == 0 || list_match(pamh, sptr, item, match_fn) == NO)
-	    return (match);
+	if (tok == 0)
+	    return match;
+	if (list_match(pamh, NULL, sptr, item, match_fn) == NO)
+	    return YES; /* drop special meaning of ALL */
     }
     return (NO);
 }
@@ -453,7 +474,7 @@ static char *myhostname(void)
 
 static int
 netgroup_match (pam_handle_t *pamh, const char *netgroup,
-		const char *machine, const char *user)
+		const char *machine, const char *user, int debug)
 {
   char *mydomain = NULL;
   int retval;
@@ -462,7 +483,7 @@ netgroup_match (pam_handle_t *pamh, cons
 
 
   retval = innetgr (netgroup, machine, user, mydomain);
-  if (pam_access_debug == YES)
+  if (debug == YES)
     pam_syslog (pamh, LOG_DEBUG,
 		"netgroup_match: %d (netgroup=%s, machine=%s, user=%s, domain=%s)",
 		retval, netgroup ? netgroup : "NULL",
@@ -480,8 +501,9 @@ user_match (pam_handle_t *pamh, char *to
     char   *string = item->user->pw_name;
     struct login_info fake_item;
     char   *at;
+    int    rv;
 
-    if (pam_access_debug)
+    if (item->debug)
       pam_syslog (pamh, LOG_DEBUG,
 		  "user_match: tok=%s, item=%s", tok, string);
 
@@ -500,12 +522,12 @@ user_match (pam_handle_t *pamh, char *to
 	return (user_match (pamh, tok, item) &&
 		from_match (pamh, at + 1, &fake_item));
     } else if (tok[0] == '@') /* netgroup */
-      return (netgroup_match (pamh, tok + 1, (char *) 0, string));
+      return (netgroup_match (pamh, tok + 1, (char *) 0, string, item->debug));
     else if (tok[0] == '(' && tok[strlen(tok) - 1] == ')')
-      return (group_match (pamh, tok, string));
-    else if (string_match (pamh, tok, string)) /* ALL or exact match */
-      return YES;
-    else if (only_new_group_syntax == NO &&
+      return (group_match (pamh, tok, string, item->debug));
+    else if ((rv=string_match (pamh, tok, string, item->debug)) != NO) /* ALL or exact match */
+      return rv;
+    else if (item->only_new_group_syntax == NO &&
 	     pam_modutil_user_in_group_nam_nam (pamh,
 						item->user->pw_name, tok))
       /* try group membership */
@@ -518,11 +540,12 @@ user_match (pam_handle_t *pamh, char *to
 /* group_match - match a username against token named group */
 
 static int
-group_match (pam_handle_t *pamh, const char *tok, const char* usr)
+group_match (pam_handle_t *pamh, const char *tok, const char* usr,
+    int debug)
 {
     char grptok[BUFSIZ];
 
-    if (pam_access_debug)
+    if (debug)
         pam_syslog (pamh, LOG_DEBUG,
 		    "group_match: grp=%s, user=%s", grptok, usr);
 
@@ -548,8 +571,9 @@ from_match (pam_handle_t *pamh UNUSED, c
     const char *string = item->from;
     int        tok_len;
     int        str_len;
+    int        rv;
 
-    if (pam_access_debug)
+    if (item->debug)
       pam_syslog (pamh, LOG_DEBUG,
 		  "from_match: tok=%s, item=%s", tok, string);
 
@@ -565,10 +589,10 @@ from_match (pam_handle_t *pamh UNUSED, c
     if (string == NULL) {
 	return NO;
     } else if (tok[0] == '@') {			/* netgroup */
-        return (netgroup_match (pamh, tok + 1, string, (char *) 0));
-    } else if (string_match(pamh, tok, string)) {
+        return (netgroup_match (pamh, tok + 1, string, (char *) 0, item->debug));
+    } else if ((rv = string_match(pamh, tok, string, item->debug)) != NO) {
         /* ALL or exact match */
-	return (YES);
+	return rv;
     } else if (tok[0] == '.') {			/* domain: match last fields */
 	if ((str_len = strlen(string)) > (tok_len = strlen(tok))
 	    && strcasecmp(tok, string + str_len - tok_len) == 0)
@@ -614,7 +638,7 @@ from_match (pam_handle_t *pamh UNUSED, c
 	}
     } else  if (isipaddr(string, NULL, NULL) == YES) {
       /* Assume network/netmask with a IP of a host.  */
-      if (network_netmask_match(pamh, tok, string))
+      if (network_netmask_match(pamh, tok, string, item->debug))
 	return YES;
     } else {
       /* Assume network/netmask with a name of a host.  */
@@ -641,7 +665,7 @@ from_match (pam_handle_t *pamh UNUSED, c
 			 : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr,
 			 buf, sizeof (buf));
 
-	      if (network_netmask_match(pamh, tok, buf))
+	      if (network_netmask_match(pamh, tok, buf, item->debug))
 		{
 		  freeaddrinfo (res);
 		  return YES;
@@ -658,10 +682,11 @@ from_match (pam_handle_t *pamh UNUSED, c
 /* string_match - match a string against one token */
 
 static int
-string_match (pam_handle_t *pamh, const char *tok, const char *string)
+string_match (pam_handle_t *pamh, const char *tok, const char *string,
+    int debug)
 {
 
-    if (pam_access_debug)
+    if (debug)
         pam_syslog (pamh, LOG_DEBUG,
 		    "string_match: tok=%s, item=%s", tok, string);
 
@@ -672,7 +697,7 @@ string_match (pam_handle_t *pamh, const 
      */
 
     if (strcasecmp(tok, "ALL") == 0) {		/* all: always matches */
-	return (YES);
+	return (ALL);
     } else if (string != NULL) {
 	if (strcasecmp(tok, string) == 0) {	/* try exact match */
 	    return (YES);
@@ -690,9 +715,9 @@ string_match (pam_handle_t *pamh, const 
  */
 static int
 network_netmask_match (pam_handle_t *pamh,
-		       const char *tok, const char *string)
+		       const char *tok, const char *string, int debug)
 {
-  if (pam_access_debug)
+  if (debug)
     pam_syslog (pamh, LOG_DEBUG,
 		"network_netmask_match: tok=%s, item=%s", tok, string);
 
@@ -771,6 +796,22 @@ pam_sm_authenticate (pam_handle_t *pamh,
 	return PAM_USER_UNKNOWN;
     }
 
+    if ((user_pw=pam_modutil_getpwnam(pamh, user))==NULL)
+      return (PAM_USER_UNKNOWN);
+
+    /*
+     * Bundle up the arguments to avoid unnecessary clumsiness later on.
+     */
+    loginfo.user = user_pw;
+    loginfo.config_file = PAM_ACCESS_CONFIG;
+
+    /* parse the argument list */
+
+    if (!parse_args(pamh, &loginfo, argc, argv)) {
+	pam_syslog(pamh, LOG_ERR, "failed to parse the module arguments");
+	return PAM_ABORT;
+    }
+
     /* remote host name */
 
     if (pam_get_item(pamh, PAM_RHOST, &void_from)
@@ -799,7 +840,7 @@ pam_sm_authenticate (pam_handle_t *pamh,
 		return PAM_ABORT;
 	      }
 	      from = void_from;
-	      if (pam_access_debug)
+	      if (loginfo.debug)
 		pam_syslog (pamh, LOG_DEBUG,
 			    "cannot determine tty or remote hostname, using service %s",
 			    from);
@@ -817,22 +858,7 @@ pam_sm_authenticate (pam_handle_t *pamh,
 	}
     }
 
-    if ((user_pw=pam_modutil_getpwnam(pamh, user))==NULL)
-      return (PAM_USER_UNKNOWN);
-
-    /*
-     * Bundle up the arguments to avoid unnecessary clumsiness later on.
-     */
-    loginfo.user = user_pw;
     loginfo.from = from;
-    loginfo.config_file = PAM_ACCESS_CONFIG;
-
-    /* parse the argument list */
-
-    if (!parse_args(pamh, &loginfo, argc, argv)) {
-	pam_syslog(pamh, LOG_ERR, "failed to parse the module arguments");
-	return PAM_ABORT;
-    }
 
     if (login_access(pamh, &loginfo)) {
 	return (PAM_SUCCESS);
diff -up Linux-PAM-0.99.8.1/modules/pam_time/pam_time.c.audit-failed Linux-PAM-0.99.8.1/modules/pam_time/pam_time.c
--- Linux-PAM-0.99.8.1/modules/pam_time/pam_time.c.audit-failed	2006-06-16 08:35:16.000000000 +0200
+++ Linux-PAM-0.99.8.1/modules/pam_time/pam_time.c	2008-01-22 22:24:05.000000000 +0100
@@ -22,9 +22,16 @@
 #include <fcntl.h>
 #include <netdb.h>
 
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>                                                                                                                                            
+#endif
+
 #define PAM_TIME_BUFLEN        1000
 #define FIELD_SEPARATOR        ';'   /* this is new as of .02 */
 
+#define PAM_DEBUG_ARG       0x0001
+#define PAM_NO_AUDIT        0x0002
+
 #ifndef TRUE
 # define TRUE 1
 #endif
@@ -46,6 +53,29 @@ typedef enum { AND, OR } operator;
 #include <security/_pam_macros.h>
 #include <security/pam_modules.h>
 #include <security/pam_ext.h>
+#include <security/pam_modutil.h>
+
+static int
+_pam_parse (const pam_handle_t *pamh, int argc, const char **argv)
+{
+    int ctrl = 0;
+
+    /* step through arguments */
+    for (; argc-- > 0; ++argv) {
+
+	/* generic options */
+
+	if (!strcmp(*argv, "debug")) {
+	    ctrl |= PAM_DEBUG_ARG;
+	} else if (!strcmp(*argv, "noaudit")) {
+	    ctrl |= PAM_NO_AUDIT;
+	} else {
+	    pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
+	}
+    }
+
+    return ctrl;
+}
 
 /* --- static functions for checking whether the user should be let in --- */
 
@@ -59,7 +89,7 @@ shift_bytes(char *mem, int from, int by)
 }
 
 static int
-read_field(pam_handle_t *pamh, int fd, char **buf, int *from, int *to)
+read_field(const pam_handle_t *pamh, int fd, char **buf, int *from, int *to)
 {
     /* is buf set ? */
 
@@ -137,6 +167,7 @@ read_field(pam_handle_t *pamh, int fd, c
 	    switch ((*buf)[i]) {
 		int j,c;
 	    case '#':
+                c = 0;
 		for (j=i; j < *to && (c = (*buf)[j]) != '\n'; ++j);
 		if (j >= *to) {
 		    (*buf)[*to = ++i] = '\0';
@@ -324,6 +355,13 @@ is_same(pam_handle_t *pamh UNUSED, const
 		    return FALSE;
 	  }
      }
+
+     /* Ok, we know that b is a substring from A and does not contain
+        wildcards, but now the length of both strings must be the same,
+        too. */
+     if (strlen (a) != strlen(b))
+          return FALSE;
+
      return ( !len );
 }
 
@@ -559,11 +597,15 @@ check_account(pam_handle_t *pamh, const 
 
 PAM_EXTERN int
 pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED,
-		 int argc UNUSED, const char **argv UNUSED)
+		 int argc, const char **argv)
 {
     const void *service=NULL, *void_tty=NULL;
     const char *tty;
     const char *user=NULL;
+    int ctrl;
+    int rv;
+
+    ctrl = _pam_parse(pamh, argc, argv);
 
     /* set service name */
 
@@ -612,7 +654,19 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int
     D(("user=%s", user));
     D(("tty=%s", tty));
 
-    return check_account(pamh, service, tty, user);
+    rv = check_account(pamh, service, tty, user);
+    if (rv != PAM_SUCCESS) {
+#ifdef HAVE_LIBAUDIT
+	if (!(ctrl & PAM_NO_AUDIT)) {
+            pam_modutil_audit_write(pamh, AUDIT_ANOM_LOGIN_TIME,
+            	    "pam_time", rv); /* ignore return value as we fail anyway */
+        }
+#endif
+	if (ctrl & PAM_DEBUG_ARG) {
+	    pam_syslog(pamh, LOG_DEBUG, "user %s rejected", user);
+	}
+    }
+    return rv;
 }
 
 /* end of module definition */
diff -up Linux-PAM-0.99.8.1/modules/pam_time/pam_time.8.xml.audit-failed Linux-PAM-0.99.8.1/modules/pam_time/pam_time.8.xml
--- Linux-PAM-0.99.8.1/modules/pam_time/pam_time.8.xml.audit-failed	2006-06-22 21:44:30.000000000 +0200
+++ Linux-PAM-0.99.8.1/modules/pam_time/pam_time.8.xml	2008-01-22 22:24:05.000000000 +0100
@@ -22,6 +22,12 @@
   <refsynopsisdiv>
     <cmdsynopsis id="pam_time-cmdsynopsis">
       <command>pam_time.so</command>
+      <arg choice="opt">
+        debug
+      </arg>
+      <arg choice="opt">
+        noaudit
+      </arg>
     </cmdsynopsis>
   </refsynopsisdiv>
 
@@ -41,11 +47,40 @@
       By default rules for time/port access are taken from config file
       <filename>/etc/security/time.conf</filename>.
     </para>
+    <para>
+      If Linux PAM is compiled with audit support the module will report
+      when it denies access. 
+    </para>
   </refsect1>
 
   <refsect1 id="pam_time-options">
     <title>OPTIONS</title>
-    <para>This module does not recognice any options.</para>
+    <variablelist>
+
+      <varlistentry>
+        <term>
+          <option>debug</option>
+        </term>
+        <listitem>
+          <para>
+            Some debug informations are printed with
+            <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+          </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>
+          <option>noaudit</option>
+        </term>
+        <listitem>
+          <para>
+            Do not report logins at disallowed time to the audit subsystem.
+          </para>
+        </listitem>
+      </varlistentry>
+
+    </variablelist>
   </refsect1>
 
   <refsect1 id="pam_time-services">
diff -up Linux-PAM-0.99.8.1/modules/pam_limits/pam_limits.c.audit-failed Linux-PAM-0.99.8.1/modules/pam_limits/pam_limits.c
--- Linux-PAM-0.99.8.1/modules/pam_limits/pam_limits.c.audit-failed	2007-07-10 12:10:56.000000000 +0200
+++ Linux-PAM-0.99.8.1/modules/pam_limits/pam_limits.c	2008-01-22 22:41:40.000000000 +0100
@@ -41,6 +41,10 @@
 #include <pwd.h>
 #include <locale.h>
 
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>                                                                                                                                            
+#endif
+
 /* Module defines */
 #define LINE_LENGTH 1024
 
@@ -101,6 +105,7 @@ struct pam_limit_s {
 #define PAM_DEBUG_ARG       0x0001
 #define PAM_DO_SETREUID     0x0002
 #define PAM_UTMP_EARLY      0x0004
+#define PAM_NO_AUDIT        0x0008
 
 /* Limits from globbed files. */
 #define LIMITS_CONF_GLOB LIMITS_FILE_DIR
@@ -126,6 +131,8 @@ _pam_parse (const pam_handle_t *pamh, in
 	    ctrl |= PAM_DO_SETREUID;
 	} else if (!strcmp(*argv,"utmp_early")) {
 	    ctrl |= PAM_UTMP_EARLY;
+	} else if (!strcmp(*argv,"noaudit")) {
+	    ctrl |= PAM_NO_AUDIT;
 	} else {
 	    pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
 	}
@@ -599,6 +606,13 @@ static int setup_limits(pam_handle_t *pa
 	D(("skip login limit check for uid=0"));
     } else if (pl->login_limit > 0) {
         if (check_logins(pamh, uname, pl->login_limit, ctrl, pl) == LOGIN_ERR) {
+#ifdef HAVE_LIBAUDIT
+	    if (!(ctrl & PAM_NO_AUDIT)) {
+        	pam_modutil_audit_write(pamh, AUDIT_ANOM_LOGIN_SESSIONS,
+            	    "pam_limits", PAM_PERM_DENIED);
+		/* ignore return value as we fail anyway */
+            }
+#endif
             retval |= LOGIN_ERR;
 	}
     } else if (pl->login_limit == 0) {
diff -up Linux-PAM-0.99.8.1/modules/pam_limits/pam_limits.8.xml.audit-failed Linux-PAM-0.99.8.1/modules/pam_limits/pam_limits.8.xml
--- Linux-PAM-0.99.8.1/modules/pam_limits/pam_limits.8.xml.audit-failed	2007-04-30 12:47:26.000000000 +0200
+++ Linux-PAM-0.99.8.1/modules/pam_limits/pam_limits.8.xml	2008-01-22 22:24:05.000000000 +0100
@@ -34,6 +34,9 @@
       <arg choice="opt">
         utmp_early
       </arg>
+      <arg choice="opt">
+        noaudit
+      </arg>
     </cmdsynopsis>
   </refsynopsisdiv>
 
@@ -57,6 +60,11 @@
     <para>
       The module must not be called by a multithreaded application.
     </para>
+    <para>
+      If Linux PAM is compiled with audit support the module will report
+      when it denies access based on limit of maximum number of concurrent
+      login sessions.
+    </para>
   </refsect1>
 
   <refsect1 id="pam_limits-options">
@@ -111,6 +119,16 @@
           </para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term>
+          <option>noaudit</option>
+        </term>
+        <listitem>
+          <para>
+            Do not report exceeded maximum logins count to the audit subsystem.
+          </para>
+        </listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 


Index: pam.spec
===================================================================
RCS file: /cvs/pkgs/rpms/pam/devel/pam.spec,v
retrieving revision 1.166
retrieving revision 1.167
diff -u -r1.166 -r1.167
--- pam.spec	14 Jan 2008 12:49:56 -0000	1.166
+++ pam.spec	22 Jan 2008 21:52:13 -0000	1.167
@@ -11,7 +11,7 @@
 Summary: A security tool which provides authentication for applications
 Name: pam
 Version: 0.99.8.1
-Release: 15%{?dist}
+Release: 16%{?dist}
 # The library is BSD licensed with option to relicense as GPLv2+ - this option is redundant
 # as the BSD license allows that anyway. pam_timestamp and pam_console modules are GPLv2+,
 # pam_rhosts_auth module is BSD with advertising
@@ -46,6 +46,7 @@
 Patch48: pam-0.99.8.1-substack.patch
 Patch49: pam-0.99.8.1-tty-audit.patch
 Patch50: pam-0.99.8.1-tty-audit2.patch
+Patch51: pam-0.99.8.1-audit-failed.patch
 
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 Requires: cracklib, cracklib-dicts >= 2.8
@@ -117,6 +118,7 @@
 %patch48 -p0 -b .substack
 %patch49 -p1 -b .tty-audit
 %patch50 -p1 -b .tty-audit2
+%patch51 -p1 -b .audit-failed
 
 autoreconf
 
@@ -158,6 +160,7 @@
 	--enable-isadir=../../%{_lib}/security \
 	--with-db-uniquename=_pam
 make
+# we do not use _smp_mflags because the build of sources in yacc/flex fails
 
 %install
 rm -rf $RPM_BUILD_ROOT
@@ -188,6 +191,31 @@
 # Install man pages.
 install -m 644 %{SOURCE9} %{SOURCE10} $RPM_BUILD_ROOT%{_mandir}/man5/
 
+for phase in auth acct passwd session ; do
+	ln -sf pam_unix.so $RPM_BUILD_ROOT/%{_lib}/security/pam_unix_${phase}.so 
+done
+
+# Remove .la files and make new .so links -- this depends on the value
+# of _libdir not changing, and *not* being /usr/lib.
+install -d -m 755 $RPM_BUILD_ROOT%{_libdir}
+for lib in libpam libpamc libpam_misc ; do
+pushd $RPM_BUILD_ROOT%{_libdir}
+ln -sf ../../%{_lib}/${lib}.so.*.* ${lib}.so
+popd
+rm -f $RPM_BUILD_ROOT/%{_lib}/${lib}.so
+rm -f $RPM_BUILD_ROOT/%{_lib}/${lib}.la
+done
+rm -f $RPM_BUILD_ROOT/%{_lib}/security/*.la
+
+# Duplicate doc file sets.
+rm -fr $RPM_BUILD_ROOT/usr/share/doc/pam
+
+# Create /lib/security in case it isn't the same as /%{_lib}/security.
+install -m755 -d $RPM_BUILD_ROOT/lib/security
+
+%find_lang Linux-PAM
+
+%check
 # Make sure every module subdirectory gave us a module.  Yes, this is hackish.
 for dir in modules/pam_* ; do
 if [ -d ${dir} ] ; then
@@ -211,36 +239,12 @@
 # libraries, which if loaded in a non-threaded application, can cause Very
 # Bad Things to happen.
 	if env LD_LIBRARY_PATH=$RPM_BUILD_ROOT/%{_lib} \
-	       LD_PRELOAD=$RPM_BUILD_ROOT/%{_lib}/libpam.so ldd -r ${module} | fgrep -q libpthread ; then
+	       LD_PRELOAD=$RPM_BUILD_ROOT%{_libdir}/libpam.so ldd -r ${module} | fgrep -q libpthread ; then
 		echo ERROR module: ${module} pulls threading libraries.
 		exit 1
 	fi
 done
 
-for phase in auth acct passwd session ; do
-	ln -sf pam_unix.so $RPM_BUILD_ROOT/%{_lib}/security/pam_unix_${phase}.so 
-done
-
-# Remove .la files and make new .so links -- this depends on the value
-# of _libdir not changing, and *not* being /usr/lib.
-install -d -m 755 $RPM_BUILD_ROOT%{_libdir}
-for lib in libpam libpamc libpam_misc ; do
-pushd $RPM_BUILD_ROOT%{_libdir}
-ln -sf ../../%{_lib}/${lib}.so.*.* ${lib}.so
-popd
-rm -f $RPM_BUILD_ROOT/%{_lib}/${lib}.so
-rm -f $RPM_BUILD_ROOT/%{_lib}/${lib}.la
-done
-rm -f $RPM_BUILD_ROOT/%{_lib}/security/*.la
-
-# Duplicate doc file sets.
-rm -fr $RPM_BUILD_ROOT/usr/share/doc/pam
-
-# Create /lib/security in case it isn't the same as /%{_lib}/security.
-install -m755 -d $RPM_BUILD_ROOT/lib/security
-
-%find_lang Linux-PAM
-
 %clean
 rm -rf $RPM_BUILD_ROOT
 
@@ -364,6 +368,10 @@
 %doc doc/adg/*.txt doc/adg/html
 
 %changelog
+* Tue Jan 22 2008 Tomas Mraz <tmraz at redhat.com> 0.99.8.1-16
+- add auditing to pam_access, pam_limits, and pam_time
+- moved sanity testing code to check script
+
 * Mon Jan 14 2008 Tomas Mraz <tmraz at redhat.com> 0.99.8.1-15
 - merge review fixes (#226228)
 




More information about the fedora-extras-commits mailing list