diff options
author | Tomas Mraz <tmraz@fedoraproject.org> | 2017-06-28 15:52:16 +0200 |
---|---|---|
committer | Tomas Mraz <tmraz@fedoraproject.org> | 2017-06-28 15:52:16 +0200 |
commit | 62058c50abd7df7769fd4e152488197b7e4e2054 (patch) | |
tree | 88ad63a03d3114086a403721900a15ed65613222 /modules | |
parent | 7d0c508a52ebc9c702e1b6e66f46e4a6dc028c4a (diff) | |
download | pam-62058c50abd7df7769fd4e152488197b7e4e2054.tar.gz pam-62058c50abd7df7769fd4e152488197b7e4e2054.tar.bz2 pam-62058c50abd7df7769fd4e152488197b7e4e2054.zip |
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.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/pam_tty_audit/pam_tty_audit.8.xml | 26 | ||||
-rw-r--r-- | modules/pam_tty_audit/pam_tty_audit.c | 85 |
2 files changed, 99 insertions, 12 deletions
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 @@ </term> <listitem> <para> - For each user matching one of comma-separated glob - <option><replaceable>patterns</replaceable></option>, disable - TTY auditing. This overrides any previous <option>enable</option> - option matching the same user name on the command line. + For each user matching <option><replaceable>patterns</replaceable></option>, + disable TTY auditing. This overrides any previous <option>enable</option> + option matching the same user name on the command line. See NOTES + for further description of <option><replaceable>patterns</replaceable></option>. </para> </listitem> </varlistentry> @@ -57,10 +57,10 @@ </term> <listitem> <para> - For each user matching one of comma-separated glob - <option><replaceable>patterns</replaceable></option>, enable - TTY auditing. This overrides any previous <option>disable</option> - option matching the same user name on the command line. + For each user matching <option><replaceable>patterns</replaceable></option>, + enable TTY auditing. This overrides any previous <option>disable</option> + option matching the same user name on the command line. See NOTES + for further description of <option><replaceable>patterns</replaceable></option>. </para> </listitem> </varlistentry> @@ -139,6 +139,16 @@ To view the data that was logged by the kernel to audit use the command <command>aureport --tty</command>. </para> + <para> + The <option><replaceable>patterns</replaceable></option> are comma separated + lists of glob patterns or ranges of uids. A range is specified as + <replaceable>min_uid</replaceable>:<replaceable>max_uid</replaceable> where + one of these values can be empty. If <replaceable>min_uid</replaceable> is + empty only user with the uid <replaceable>max_uid</replaceable> will be + matched. If <replaceable>max_uid</replaceable> is empty users with the uid + greater than or equal to <replaceable>min_uid</replaceable> will be + matched. + </para> </refsect1> <refsect1 id='pam_tty_audit-examples'> 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); |