From 62058c50abd7df7769fd4e152488197b7e4e2054 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 28 Jun 2017 15:52:16 +0200 Subject: pam_tty_audit: Support matching users by uid range. * modules/pam_tty_audit/pam_tty_audit.c (parse_uid_range): New function to parse the uid range. (pam_sm_open_session): Call parse_uid_range() and behave according to its result. * modules/pam_tty_audit/pam_tty_audit.8.xml: Document the uid range matching. --- modules/pam_tty_audit/pam_tty_audit.8.xml | 26 +++++++--- modules/pam_tty_audit/pam_tty_audit.c | 85 +++++++++++++++++++++++++++++-- 2 files changed, 99 insertions(+), 12 deletions(-) (limited to 'modules/pam_tty_audit') diff --git a/modules/pam_tty_audit/pam_tty_audit.8.xml b/modules/pam_tty_audit/pam_tty_audit.8.xml index 552353ce..59a3406d 100644 --- a/modules/pam_tty_audit/pam_tty_audit.8.xml +++ b/modules/pam_tty_audit/pam_tty_audit.8.xml @@ -44,10 +44,10 @@ - For each user matching one of comma-separated glob - , disable - TTY auditing. This overrides any previous - option matching the same user name on the command line. + For each user matching , + disable TTY auditing. This overrides any previous + option matching the same user name on the command line. See NOTES + for further description of . @@ -57,10 +57,10 @@ - For each user matching one of comma-separated glob - , enable - TTY auditing. This overrides any previous - option matching the same user name on the command line. + For each user matching , + enable TTY auditing. This overrides any previous + option matching the same user name on the command line. See NOTES + for further description of . @@ -139,6 +139,16 @@ To view the data that was logged by the kernel to audit use the command aureport --tty. + + The are comma separated + lists of glob patterns or ranges of uids. A range is specified as + min_uid:max_uid where + one of these values can be empty. If min_uid is + empty only user with the uid max_uid will be + matched. If max_uid is empty users with the uid + greater than or equal to min_uid will be + matched. + diff --git a/modules/pam_tty_audit/pam_tty_audit.c b/modules/pam_tty_audit/pam_tty_audit.c index bce3ab77..c76026a0 100644 --- a/modules/pam_tty_audit/pam_tty_audit.c +++ b/modules/pam_tty_audit/pam_tty_audit.c @@ -199,6 +199,57 @@ cleanup_old_status (pam_handle_t *pamh, void *data, int error_status) free (data); } +enum uid_range { UID_RANGE_NONE, UID_RANGE_MM, UID_RANGE_MIN, + UID_RANGE_ONE, UID_RANGE_ERR }; + +static enum uid_range +parse_uid_range(pam_handle_t *pamh, const char *s, + uid_t *min_uid, uid_t *max_uid) +{ + const char *range = s; + char *pmax; + char *endptr; + enum uid_range rv = UID_RANGE_MM; + + if ((pmax=strchr(range, ':')) == NULL) + return UID_RANGE_NONE; + ++pmax; + + if (range[0] == '@' || range[0] == '%') + ++range; + + if (range[0] == ':') + rv = UID_RANGE_ONE; + else { + errno = 0; + *min_uid = strtoul (range, &endptr, 10); + if (errno != 0 || (range == endptr) || *endptr != ':') { + pam_syslog(pamh, LOG_DEBUG, + "wrong min_uid value in '%s'", s); + return UID_RANGE_ERR; + } + } + + if (*pmax == '\0') { + if (rv == UID_RANGE_ONE) + return UID_RANGE_ERR; + + return UID_RANGE_MIN; + } + + errno = 0; + *max_uid = strtoul (pmax, &endptr, 10); + if (errno != 0 || (pmax == endptr) || *endptr != '\0') { + pam_syslog(pamh, LOG_DEBUG, + "wrong max_uid value in '%s'", s); + return UID_RANGE_ERR; + } + + if (rv == UID_RANGE_ONE) + *min_uid = *max_uid; + return rv; +} + int pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv) { @@ -208,6 +259,7 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv) struct audit_tty_status *old_status, new_status; const char *user; int i, fd, open_only; + struct passwd *pwd; #ifdef HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD int log_passwd; #endif /* HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD */ @@ -220,6 +272,14 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv) return PAM_SESSION_ERR; } + pwd = pam_modutil_getpwnam(pamh, user); + if (pwd == NULL) + { + pam_syslog(pamh, LOG_WARNING, + "open_session unknown user '%s'", user); + return PAM_SESSION_ERR; + } + command = CMD_NONE; open_only = 0; #ifdef HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD @@ -237,13 +297,30 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv) copy = strdup (strchr (argv[i], '=') + 1); if (copy == NULL) return PAM_SESSION_ERR; - for (tok = strtok_r (copy, ",", &tok_data); tok != NULL; + for (tok = strtok_r (copy, ",", &tok_data); + tok != NULL && command == CMD_NONE; tok = strtok_r (NULL, ",", &tok_data)) { - if (fnmatch (tok, user, 0) == 0) + uid_t min_uid = 0, max_uid = 0; + switch (parse_uid_range(pamh, tok, &min_uid, &max_uid)) { - command = this_command; - break; + case UID_RANGE_NONE: + if (fnmatch (tok, user, 0) == 0) + command = this_command; + break; + case UID_RANGE_MM: + if (pwd->pw_uid >= min_uid && pwd->pw_uid <= max_uid) + command = this_command; + break; + case UID_RANGE_MIN: + if (pwd->pw_uid >= min_uid) + command = this_command; + break; + case UID_RANGE_ONE: + if (pwd->pw_uid == max_uid) + command = this_command; + case UID_RANGE_ERR: + break; } } free (copy); -- cgit v1.2.3 From 94f529d4f239362dea6e43a0bd3f6323b429a712 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 9 Oct 2017 17:37:56 +0200 Subject: pam_tty_audit: Fix regression introduced by adding the uid range support. * modules/pam_tty_audit/pam_tty_audit.c (parse_uid_range): Fix constification and remove unneeded code carried from pam_limits. (pam_sm_open_session): When multiple enable/disable options are present do not stop after first match. --- modules/pam_tty_audit/pam_tty_audit.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'modules/pam_tty_audit') diff --git a/modules/pam_tty_audit/pam_tty_audit.c b/modules/pam_tty_audit/pam_tty_audit.c index c76026a0..79e5d511 100644 --- a/modules/pam_tty_audit/pam_tty_audit.c +++ b/modules/pam_tty_audit/pam_tty_audit.c @@ -207,7 +207,7 @@ parse_uid_range(pam_handle_t *pamh, const char *s, uid_t *min_uid, uid_t *max_uid) { const char *range = s; - char *pmax; + const char *pmax; char *endptr; enum uid_range rv = UID_RANGE_MM; @@ -215,9 +215,6 @@ parse_uid_range(pam_handle_t *pamh, const char *s, return UID_RANGE_NONE; ++pmax; - if (range[0] == '@' || range[0] == '%') - ++range; - if (range[0] == ':') rv = UID_RANGE_ONE; else { @@ -298,7 +295,7 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv) if (copy == NULL) return PAM_SESSION_ERR; for (tok = strtok_r (copy, ",", &tok_data); - tok != NULL && command == CMD_NONE; + tok != NULL && command != this_command; tok = strtok_r (NULL, ",", &tok_data)) { uid_t min_uid = 0, max_uid = 0; @@ -319,6 +316,7 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv) case UID_RANGE_ONE: if (pwd->pw_uid == max_uid) command = this_command; + break; case UID_RANGE_ERR: break; } -- cgit v1.2.3