From 61ed1ee492ffb411887fd5b9cbb51715f1eb1e1e Mon Sep 17 00:00:00 2001 From: "Andrew G. Morgan" Date: Sat, 19 Jan 2002 07:10:45 +0000 Subject: Relevant BUGIDs: 493294 Purpose of commit: bugfix and document Commit summary: --------------- The login limit counting seemed to have its math incorrect. The default has been changed to the sane one, and a new module argument has been added "utmp_early" that returns the module to its old behavior. Thanks to Berend De Schouwe for getting to the bottom of this issue. --- modules/pam_limits/README | 7 ++++ modules/pam_limits/pam_limits.c | 79 +++++++++++++++++++++++++++-------------- 2 files changed, 59 insertions(+), 27 deletions(-) (limited to 'modules') diff --git a/modules/pam_limits/README b/modules/pam_limits/README index c0dba581..023b9575 100644 --- a/modules/pam_limits/README +++ b/modules/pam_limits/README @@ -81,6 +81,13 @@ ARGUMENTS RECOGNIZED: no processes. Be warned that something else may break when you do this. + utmp_early some broken applications actually allocate a + utmp entry for the user before the user is + admitted to the system. If the service you are + configuring PAM for does this, you can use + this module argument to compensate for this + brokenness. + MODULE SERVICES PROVIDED: session _open_session and _close_session (blank) diff --git a/modules/pam_limits/pam_limits.c b/modules/pam_limits/pam_limits.c index 303ed661..f85c5f05 100644 --- a/modules/pam_limits/pam_limits.c +++ b/modules/pam_limits/pam_limits.c @@ -2,7 +2,7 @@ * pam_limits - impose resource limits when opening a user session * * 1.6 - modified for PLD (added process priority settings) - * by Marcin Korzonek * 1.5 - Elliot Lee's "max system logins patch" * 1.4 - addressed bug in configuration file parser * 1.3 - modified the configuration file format @@ -71,6 +71,7 @@ struct pam_limit_s { int supported[RLIM_NLIMITS]; struct user_limits_struct limits[RLIM_NLIMITS]; char conf_file[BUFSIZ]; + int utmp_after_pam_call; }; #define LIMIT_LOGIN RLIM_NLIMITS+1 @@ -102,29 +103,32 @@ static void _pam_log(int err, const char *format, ...) #define PAM_DEBUG_ARG 0x0001 #define PAM_DO_SETREUID 0x0002 +#define PAM_UTMP_EARLY 0x0004 static int _pam_parse(int argc, const char **argv, struct pam_limit_s *pl) { - int ctrl=0; - - /* step through arguments */ - for (ctrl=0; argc-- > 0; ++argv) { - - /* generic options */ - - if (!strcmp(*argv,"debug")) - ctrl |= PAM_DEBUG_ARG; - else if (!strncmp(*argv,"conf=",5)) - strncpy(pl->conf_file,*argv+5,sizeof(pl->conf_file)-1); - else if (!strncmp(*argv,"change_uid",10)) - ctrl |= PAM_DO_SETREUID; - else { - _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv); - } - } - pl->conf_file[sizeof(pl->conf_file) - 1] = '\0'; + int ctrl=0; + + /* step through arguments */ + for (ctrl=0; argc-- > 0; ++argv) { + + /* generic options */ - return ctrl; + if (!strcmp(*argv,"debug")) { + ctrl |= PAM_DEBUG_ARG; + } else if (!strncmp(*argv,"conf=",5)) { + strncpy(pl->conf_file,*argv+5,sizeof(pl->conf_file)-1); + } else if (!strncmp(*argv,"change_uid",10)) { + ctrl |= PAM_DO_SETREUID; + } else if (!strcmp(*argv,"utmp_early")) { + ctrl |= PAM_UTMP_EARLY; + } else { + _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv); + } + } + pl->conf_file[sizeof(pl->conf_file) - 1] = '\0'; + + return ctrl; } @@ -212,24 +216,45 @@ static int check_logins(const char *name, int limit, int ctrl, } setutent(); - count = 0; + + /* Because there is no definition about when an application + actually adds a utmp entry, some applications bizarrely do the + utmp call before the have PAM authenticate them to the system: + you're logged it, sort of...? Anyway, you can use the + "utmp_early" module argument in your PAM config file to make + allowances for this sort of problem. (There should be a PAM + standard for this, since if a module wants to actually map a + username then any early utmp entry will be for the unmapped + name = broken.) */ + + if (ctrl & PAM_UTMP_EARLY) { + count = 0; + } else { + count = 1; + } + while((ut = getutent())) { #ifdef USER_PROCESS - if (ut->ut_type != USER_PROCESS) + if (ut->ut_type != USER_PROCESS) { continue; + } #endif - if (ut->UT_USER[0] == '\0') + if (ut->UT_USER[0] == '\0') { continue; + } if (!pl->flag_numsyslogins) { if ((pl->login_limit_def == LIMITS_DEF_USER) - && strncmp(name, ut->UT_USER, sizeof(ut->UT_USER)) != 0) + && strncmp(name, ut->UT_USER, sizeof(ut->UT_USER)) != 0) { continue; + } if ((pl->login_limit_def == LIMITS_DEF_GROUP) - && !is_in_group(ut->UT_USER, name)) + && !is_in_group(ut->UT_USER, name)) { continue; + } + } + if (++count > limit) { + break; } - if (++count > limit) - break; } endutent(); if (count > limit) { -- cgit v1.2.3