{"GID_MIN", NULL},
{"HUSHLOGIN_FILE", NULL},
{"KILLCHAR", NULL},
+ {"LASTLOG_UID_MAX", NULL},
{"LOGIN_RETRIES", NULL},
{"LOGIN_TIMEOUT", NULL},
{"LOG_OK_LOGINS", NULL},
ISSUE_FILE.xml \
KILLCHAR.xml \
LASTLOG_ENAB.xml \
+ LASTLOG_UID_MAX.xml \
LOGIN_RETRIES.xml \
LOGIN_STRING.xml \
LOGIN_TIMEOUT.xml \
-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY LASTLOG_UID_MAX SYSTEM "login.defs.d/LASTLOG_UID_MAX.xml">
<!-- SHADOW-CONFIG-HERE -->
]>
<refentry id='lastlog.8'>
</para>
</refsect1>
+ <refsect1 id='configuration'>
+ <title>CONFIGURATION</title>
+ <para>
+ The following configuration variables in
+ <filename>/etc/login.defs</filename> change the behavior of this
+ tool:
+ </para>
+ <variablelist>
+ &LASTLOG_UID_MAX;
+ </variablelist>
+ </refsect1>
+
<refsect1 id='files'>
<title>FILES</title>
<variablelist>
<!ENTITY ISSUE_FILE SYSTEM "login.defs.d/ISSUE_FILE.xml">
<!ENTITY KILLCHAR SYSTEM "login.defs.d/KILLCHAR.xml">
<!ENTITY LASTLOG_ENAB SYSTEM "login.defs.d/LASTLOG_ENAB.xml">
+<!ENTITY LASTLOG_UID_MAX SYSTEM "login.defs.d/LASTLOG_UID_MAX.xml">
<!ENTITY LOG_OK_LOGINS SYSTEM "login.defs.d/LOG_OK_LOGINS.xml">
<!ENTITY LOG_UNKFAIL_ENAB SYSTEM "login.defs.d/LOG_UNKFAIL_ENAB.xml">
<!ENTITY LOGIN_RETRIES SYSTEM "login.defs.d/LOGIN_RETRIES.xml">
&ISSUE_FILE;
&KILLCHAR;
&LASTLOG_ENAB;
+ &LASTLOG_UID_MAX;
&LOG_OK_LOGINS;
&LOG_UNKFAIL_ENAB;
&LOGIN_RETRIES;
</listitem>
</varlistentry>
<!-- id: no variables -->
- <!-- lastlog: no variables -->
+ <varlistentry>
+ <term>lastlog</term>
+ <listitem>
+ <para>LASTLOG_UID_MAX</para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term>login</term>
<listitem>
HUSHLOGIN_FILE
<phrase condition="no_pam">ISSUE_FILE</phrase>
KILLCHAR
- <phrase condition="no_pam">LASTLOG_ENAB</phrase>
+ <phrase condition="no_pam">LASTLOG_ENAB LASTLOG_UID_MAX</phrase>
LOGIN_RETRIES
<phrase condition="no_pam">LOGIN_STRING</phrase>
LOGIN_TIMEOUT LOG_OK_LOGINS LOG_UNKFAIL_ENAB
<para>
CREATE_HOME
GID_MAX GID_MIN
+ LASTLOG_UID_MAX
MAIL_DIR MAX_MEMBERS_PER_GROUP
PASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE
SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN
<term>usermod</term>
<listitem>
<para>
+ LASTLOG_UID_MAX
MAIL_DIR MAIL_FILE MAX_MEMBERS_PER_GROUP
<phrase condition="tcb">TCB_SYMLINKS USE_TCB</phrase>
</para>
--- /dev/null
+<!--
+ Copyright (c) 1991 - 1993, Julianne Frances Haugh
+ Copyright (c) 1991 - 1993, Chip Rosenthal
+ Copyright (c) 2007 - 2008, Nicolas François
+ Copyright (c) 2018, Red Hat, inc.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the copyright holders or contributors may not be used to
+ endorse or promote products derived from this software without
+ specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<varlistentry>
+ <term><option>LASTLOG_UID_MAX</option> (number)</term>
+ <listitem>
+ <para>
+ Highest user ID number for which the lastlog entries should be
+ updated. As higher user IDs are usually tracked by remote user
+ identity and authentication services there is no need to create
+ a huge sparse lastlog file for them.
+ </para>
+ <para>
+ No <option>LASTLOG_UID_MAX</option> option present in the configuration
+ means that there is no user ID limit for writing lastlog entries.
+ </para>
+ </listitem>
+</varlistentry>
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY CREATE_HOME SYSTEM "login.defs.d/CREATE_HOME.xml">
<!ENTITY GID_MAX SYSTEM "login.defs.d/GID_MAX.xml">
+<!ENTITY LASTLOG_UID_MAX SYSTEM "login.defs.d/LASTLOG_UID_MAX.xml">
<!ENTITY MAIL_DIR SYSTEM "login.defs.d/MAIL_DIR.xml">
<!ENTITY MAX_MEMBERS_PER_GROUP SYSTEM "login.defs.d/MAX_MEMBERS_PER_GROUP.xml">
<!ENTITY PASS_MAX_DAYS SYSTEM "login.defs.d/PASS_MAX_DAYS.xml">
<variablelist>
&CREATE_HOME;
&GID_MAX; <!-- documents also GID_MIN -->
+ &LASTLOG_UID_MAX;
&MAIL_DIR;
&MAX_MEMBERS_PER_GROUP;
&PASS_MAX_DAYS;
-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY LASTLOG_UID_MAX SYSTEM "login.defs.d/LASTLOG_UID_MAX.xml">
<!ENTITY MAIL_DIR SYSTEM "login.defs.d/MAIL_DIR.xml">
<!ENTITY MAX_MEMBERS_PER_GROUP SYSTEM "login.defs.d/MAX_MEMBERS_PER_GROUP.xml">
<!ENTITY SUB_GID_COUNT SYSTEM "login.defs.d/SUB_GID_COUNT.xml">
tool:
</para>
<variablelist>
+ &LASTLOG_UID_MAX;
&MAIL_DIR; <!-- documents also MAIL_FILE -->
&MAX_MEMBERS_PER_GROUP;
&SUB_GID_COUNT; <!-- documents also SUB_GID_MAX and SUB_GID_MIN -->
#include <assert.h>
#include "defines.h"
#include "prototypes.h"
+#include "getdef.h"
/*@-exitarg@*/
#include "exitcodes.h"
static void print (void)
{
const struct passwd *pwent;
+ unsigned long lastlog_uid_max;
+
+ lastlog_uid_max = getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL);
+ if ( (has_umin && umin > lastlog_uid_max)
+ || (has_umax && umax > lastlog_uid_max)) {
+ fprintf (stderr, _("%s: Selected uid(s) are higher than LASTLOG_UID_MAX (%lu),\n"
+ "\tthe output might be incorrect.\n"), Prog, lastlog_uid_max);
+ }
+
if (uflg && has_umin && has_umax && (umin == umax)) {
print_one (getpwuid ((uid_t)umin));
} else {
&& ( (has_umin && (pwent->pw_uid < (uid_t)umin))
|| (has_umax && (pwent->pw_uid > (uid_t)umax)))) {
continue;
+ } else if ( !uflg && pwent->pw_uid > (uid_t) lastlog_uid_max) {
+ continue;
}
print_one (pwent);
}
static void update (void)
{
const struct passwd *pwent;
+ unsigned long lastlog_uid_max;
if (!uflg) /* safety measure */
return;
+ lastlog_uid_max = getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL);
+ if ( (has_umin && umin > lastlog_uid_max)
+ || (has_umax && umax > lastlog_uid_max)) {
+ fprintf (stderr, _("%s: Selected uid(s) are higher than LASTLOG_UID_MAX (%lu),\n"
+ "\tthey will not be updated.\n"), Prog, lastlog_uid_max);
+ return;
+ }
+
if (has_umin && has_umax && (umin == umax)) {
update_one (getpwuid ((uid_t)umin));
} else {
#endif /* WITH_AUDIT */
#ifndef USE_PAM /* pam_lastlog handles this */
- if (getdef_bool ("LASTLOG_ENAB")) { /* give last login and log this one */
+ if ( getdef_bool ("LASTLOG_ENAB")
+ && pwd->pw_uid <= (uid_t) getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL)) {
+ /* give last login and log this one */
dolastlog (&ll, pwd, tty, hostname);
}
#endif
}
}
if ( getdef_bool ("LASTLOG_ENAB")
+ && pwd->pw_uid <= (uid_t) getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL)
&& (ll.ll_time != 0)) {
time_t ll_time = ll.ll_time;
struct lastlog ll;
int fd;
off_t offset_uid = (off_t) (sizeof ll) * uid;
+ uid_t max_uid;
if (access (LASTLOG_FILE, F_OK) != 0) {
return;
}
+ max_uid = (uid_t) getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL);
+ if (uid > max_uid) {
+ /* do not touch lastlog for large uids */
+ return;
+ }
+
memzero (&ll, sizeof (ll));
fd = open (LASTLOG_FILE, O_RDWR);
int fd;
off_t off_uid = (off_t) user_id * sizeof ll;
off_t off_newuid = (off_t) user_newid * sizeof ll;
+ uid_t max_uid;
if (access (LASTLOG_FILE, F_OK) != 0) {
return;
}
+ max_uid = (uid_t) getdef_ulong ("LASTLOG_MAX_UID", 0xFFFFFFFFUL);
+ if (user_newid > max_uid) {
+ /* do not touch lastlog for large uids */
+ return;
+ }
+
fd = open (LASTLOG_FILE, O_RDWR);
if (-1 == fd) {