]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
login.defs: Add LASTLOG_UID_MAX variable to limit lastlog to small uids.
authorTomas Mraz <tmraz@fedoraproject.org>
Wed, 28 Nov 2018 13:57:16 +0000 (14:57 +0100)
committerSerge Hallyn <shallyn@cisco.com>
Mon, 10 Dec 2018 19:25:56 +0000 (13:25 -0600)
As the large uids are usually provided by remote user identity and
authentication service, which also provide user login tracking,
there is no need to create a huge sparse file for them on every local
machine.

fixup! login.defs: Add LASTLOG_UID_MAX variable to limit lastlog to small uids.

lib/getdef.c
man/Makefile.am
man/lastlog.8.xml
man/login.defs.5.xml
man/login.defs.d/LASTLOG_UID_MAX.xml [new file with mode: 0644]
man/useradd.8.xml
man/usermod.8.xml
src/lastlog.c
src/login.c
src/useradd.c
src/usermod.c

index d57b12decdd79c4bb829ea75dc4854d68ba82807..ece33a78c7aacf1f8178d0b05c8cec37d08aa97a 100644 (file)
@@ -92,6 +92,7 @@ static struct itemdef def_table[] = {
        {"GID_MIN", NULL},
        {"HUSHLOGIN_FILE", NULL},
        {"KILLCHAR", NULL},
+       {"LASTLOG_UID_MAX", NULL},
        {"LOGIN_RETRIES", NULL},
        {"LOGIN_TIMEOUT", NULL},
        {"LOG_OK_LOGINS", NULL},
index 4c3402299b0f2d41a2328dfd78e441d57053e718..3f040e053acd1eff92d561be770d21119ca1b93f 100644 (file)
@@ -137,6 +137,7 @@ login_defs_v = \
        ISSUE_FILE.xml \
        KILLCHAR.xml \
        LASTLOG_ENAB.xml \
+       LASTLOG_UID_MAX.xml \
        LOGIN_RETRIES.xml \
        LOGIN_STRING.xml \
        LOGIN_TIMEOUT.xml \
index 3ee1b3a89e6384069b72dc8dcb98ce621da5d612..fc096c8f912bee615e204a3ba527ffab06177296 100644 (file)
@@ -31,6 +31,7 @@
 -->
 <!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>
index 98d37fdc15919e6bc3b637ed58a2e8f539eb2619..ebf60ba3b671b057613e8bedf74ed1bdde17704f 100644 (file)
@@ -54,6 +54,7 @@
 <!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>
diff --git a/man/login.defs.d/LASTLOG_UID_MAX.xml b/man/login.defs.d/LASTLOG_UID_MAX.xml
new file mode 100644 (file)
index 0000000..ba3025a
--- /dev/null
@@ -0,0 +1,46 @@
+<!--
+   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>
index 582b39c7e14e9f45164f69be013fd3d098da657f..59e53c1fe65fa9a6b48315b09dc39fe67ee7e94e 100644 (file)
@@ -32,6 +32,7 @@
   "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;
index 7fea2981bcc4458ff513bd93d4985d8d99d08fe6..bb8312dbfa9732ec279b8eb727be2d22ece21397 100644 (file)
@@ -30,6 +30,7 @@
 -->
 <!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 -->
index 965691db188aa1c8d12aac4ca3277f1ba9095c7e..c1caedb06ebd458d4089adc085ece66876cfdebb 100644 (file)
@@ -44,6 +44,7 @@
 #include <assert.h>
 #include "defines.h"
 #include "prototypes.h"
+#include "getdef.h"
 /*@-exitarg@*/
 #include "exitcodes.h"
 
@@ -182,6 +183,15 @@ static void print_one (/*@null@*/const struct passwd *pw)
 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 {
@@ -191,6 +201,8 @@ static void print (void)
                            && (   (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);
                }
@@ -246,10 +258,19 @@ static void update_one (/*@null@*/const struct passwd *pw)
 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 {
index 7677adf1651a752831139a69881b430b1f9a1db3..492021a1359413f1bd519f64df0ce7456dfa7204 100644 (file)
@@ -1162,7 +1162,9 @@ int main (int argc, char **argv)
 #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
@@ -1298,6 +1300,7 @@ int main (int argc, char **argv)
                        }
                }
                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;
 
index e074844d000da258e25f3de3cd06c3d7dc103648..41e2ace4a5e1188ef3c7b2df45af3a5eaa0c9f89 100644 (file)
@@ -1863,11 +1863,18 @@ static void lastlog_reset (uid_t uid)
        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);
index fd9a98a63a912fbae5a927e7614a28dcafa8e608..72eeb8b2eddfdd35270e39817589a91b19ac1ffe 100644 (file)
@@ -1864,11 +1864,18 @@ static void update_lastlog (void)
        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) {