aboutsummaryrefslogtreecommitdiff
path: root/modules/pam_unix
Commit message (Collapse)AuthorAgeFilesLines
* build: drop autotools supportDmitry V. Levin2024-10-232-89/+0
| | | | There is no point in supporting two different build systems.
* meson: build Linux-PAM using mesonDmitry V. Levin2024-09-101-0/+1
| | | | | | | | | | On my non-representative hardware, the full build using autotools (./autogen.sh && CFLAGS=-O2 ./configure && make -j`nproc` && make -j`nproc` install) takes about 45 seconds. On the same hardware, the full build using meson (meson setup -Doptimization=2 dir && meson compile -C dir && meson install -C dir) takes just about 7.5 seconds.
* build: consistently include config.h firstDmitry V. Levin2024-08-305-5/+8
| | | | Make sure that config.h is included before any system header.
* pam_unix: do not check for HAVE_PAM_FAIL_DELAYDmitry V. Levin2024-08-291-2/+0
| | | | | Given that pam_fail_delay is always provided by libpam, checking for HAVE_PAM_FAIL_DELAY may have any sense only in third-party modules.
* build: rename SCONFIGDIR config.h macro to SCONFIG_DIRDmitry V. Levin2024-08-252-2/+2
| | | | | | | This way it is visibly different from the configure variable SCONFIGDIR, which is helpful, because their values are slightly different: the macro is quoted while the configure variable is not quoted, and this difference may cause problems with other build systems.
* Include pam_i18n.h where i18n definitions are requiredDmitry V. Levin2024-08-212-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | Do not include <libintl.h> and other i18n stuff via config.h which is included into every compilation unit, include "pam_i18n.h" explicitly where necessary. * configure.ac (AH_BOTTOM): Remove. * libpam/pam_get_authtok.c: Include "pam_i18n.h". * libpam/pam_item.c: Likewise. * libpam/pam_strerror.c: Likewise. * libpam_misc/misc_conv.c: Likewise. * modules/pam_exec/pam_exec.c: Likewise. * modules/pam_faillock/main.c: Likewise. * modules/pam_faillock/pam_faillock.c: Likewise. * modules/pam_lastlog/pam_lastlog.c: Likewise. * modules/pam_limits/pam_limits.c: Likewise. * modules/pam_mail/pam_mail.c: Likewise. * modules/pam_mkhomedir/pam_mkhomedir.c: Likewise. * modules/pam_pwhistory/pam_pwhistory.c: Likewise. * modules/pam_selinux/pam_selinux.c: Likewise. * modules/pam_selinux/pam_selinux_check.c: Likewise. * modules/pam_timestamp/pam_timestamp.c: Likewise. * modules/pam_unix/pam_unix_acct.c: Likewise. * modules/pam_unix/pam_unix_passwd.c: Likewise. * modules/pam_userdb/pam_userdb.c: Likewise.
* Move all historic changelog files to a top-level ChangeLog.old directoryDmitry V. Levin2024-05-151-54/+0
| | | | Move all historic changelog files away to avoid confusion.
* build: do not distribute historic changelog filesDmitry V. Levin2024-05-151-1/+1
| | | | | | | | | | | | | Since 2011, ChangeLog file is generated from git log history. ChangeLog-CVS is a historic changelog file that was maintained before the project was migrated from cvs to git. CHANGELOG is another historic changelog file that was replaced by ChangeLog in 2005. modules/pam_unix/CHANGELOG is the oldest of historic changelog files, it is not maintained since 1999. All these historic changelog files are no longer relevant, so they are no longer included into release tarballs.
* pam_unix: compare password hashes in constant timeChristian Göttsche2024-04-131-2/+2
| | | | | Compare the hashes in constant time as a defense-in-depth mechanism, since performance is not a priority.
* pam_unix: allow empty passwords with non-empty hashesSergei Trofimovich2024-03-291-8/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Before the change pam_unix has different behaviours for a user with empty password for these two `/etc/shadow` entries: nulloktest:$6$Yy4ty2jJ$bsVQWo8qlXC6UHq1/qTC3UR60ZJKmKApJ3Wj7DreAy8FxlVKtlDnplFQ7jMLVlDqordE7e4t49GvTb.aI59TP0:1:::::: nulloktest::1:::::: The entry with a hash was rejected and the entry without was accepted. The rejection happened because 9e74e90147c "pam_unix: avoid determining if user exists" introduced the following rejection check (slightly simplified): ... } else if (p[0] == '\0' && nullok) { if (hash[0] != '\0') { retval = PAM_AUTH_ERR; } We should not reject the user with a hash assuming it's non-empty. The change does that by pushing empty password check into `verify_pwd_hash()`. `NixOS` generates such hashed entries for empty passwords as if they were non-empty using the following perl code: sub hashPassword { my ($password) = @_; my $salt = ""; my @chars = ('.', '/', 0..9, 'A'..'Z', 'a'..'z'); $salt .= $chars[rand 64] for (1..8); return crypt($password, '$6$' . $salt . '$'); } Resolves: https://github.com/linux-pam/linux-pam/issues/758 Fixes: 9e74e90147c "pam_unix: avoid determining if user exists" Signed-off-by: Sergei Trofimovich <slyich@gmail.com>
* pam_unix: use yp functions only if nis requestedTobias Stoeckmann2024-03-031-1/+1
| | | | | | | It can happen that yp functions are found in system but their header files are not available. In this case, do not call them. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: drop cast to same typeChristian Göttsche2024-02-221-1/+1
|
* pam_unix: avoid string formatting of NULLChristian Göttsche2024-02-221-2/+3
| | | | | | | Since the struct member user might be NULL use the same condition for the value as for the preceding key. Reported-by: Yugend
* pam_unix: try to set uid to 0 for unix_chkpwdTobias Stoeckmann2024-01-242-15/+16
| | | | | | | | | | | | | The geteuid check does not cover all cases. If a program runs with elevated capabilities like CAP_SETUID then we can still check credentials of other users. Keep logging for future analysis though. Resolves: https://github.com/linux-pam/linux-pam/issues/747 Fixes: b3020da7da38 ("pam_unix/passverify: always run the helper to obtain shadow password file entries") Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* libpam_internal: supply debug functionalityTobias Stoeckmann2024-01-241-4/+7
| | | | | | | | | | Move function bodies from headers into dedicated object files stored in libpam_internal. This library won't be installed. Keep the debug function body in header, even though disabled when building Linux-PAM, to stay API compatible with previous versions. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* modules: add pamc headers to the search path only when neededTobias Stoeckmann2024-01-211-1/+1
| | | | | | | | | The pam client library libpamc is only needed if libpam_misc is in use. But libpam_misc is only used by an SELinux helper binary. Remove the libpamc includes from the search path in all other cases. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: cleanse crypt dataChristian Göttsche2024-01-211-0/+1
| | | | | Cleanse the crypt data also in the failure branch to sanitize in case of partial data being written.
* modules: zero out crypt_r(3) data before usageChristian Göttsche2024-01-212-6/+3
| | | | The manual page of crypt_r(3) recommends to zero the entire data object.
* pam_unix: do not warn if password aging is disabledTobias Stoeckmann2024-01-191-1/+0
| | | | | | | | | Later checks will print a warning if daysleft is 0. If password aging is disabled, leave daysleft at -1. Resolves: https://github.com/linux-pam/linux-pam/issues/743 Fixes: 9ebc14085a3b ("pam_unix: allow disabled password aging") Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: fix typos in commentsChristian Göttsche2024-01-162-2/+2
|
* pam_unix: do not allow comma as a field separatorTobias Stoeckmann2024-01-162-9/+8
| | | | | | | | | | | The opasswd file shall not use comma as a separator. Enforce colon just like pam_pwhistory does as well. A comma can be part of a user name, although its usage is discouraged. If such a user exists, it could happen that stored passwords of another user are checked. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: declare read-only data array constChristian Göttsche2024-01-151-1/+1
|
* pam_unix: log about failure to execute unix_chkpwd(8)Christian Göttsche2024-01-151-1/+1
|
* pam_unix: clean additional possible sensitive buffersChristian Göttsche2024-01-153-2/+7
|
* pam_unix: use more appropriate typesChristian Göttsche2024-01-152-5/+5
|
* pam_unix: retain const qualifierChristian Göttsche2024-01-151-6/+6
|
* pam_unix: enclose macro argumentsChristian Göttsche2024-01-151-3/+3
|
* pam_unix: set close-on-execChristian Göttsche2024-01-154-24/+13
| | | | | | | | | Since the module operates on sensitive files set the close-on-exec flag, to avoid file descriptor leaks if there is ever any sibling thread. The fopen(3) mode "e" is supported in glibc since version 2.7 (released in 2007), and ignored prior, see: https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=65d834b0add966dbbdb5ed1e916c60b2b2d87f10
* pam_unix: support setgid version of unix_chkpwd(8)Christian Göttsche2024-01-151-2/+7
| | | | | | | | | | | In case unix_chkpwd(8) is not a setuid but a setgid binary, reset to the real group as well. Also check the privileges are permanently lost, see: https://wiki.sei.cmu.edu/confluence/display/c/POS37-C.+Ensure+that+privilege+relinquishment+is+successful See also the current Debian patch: https://sources.debian.org/src/pam/1.5.2-9.1/debian/patches-applied/pam_unix_dont_trust_chkpwd_caller.patch/
* pam_unix: reject unix_update(8) running on different unprivileged userChristian Göttsche2024-01-151-3/+13
| | | | | | In case unix_update(8) is installed as a setuid binary, which Fedora and Debian does not do, prevent unprivileged users to probe (and eventually change) passwords of other users (including root).
* pam_unix: add audit support to unix_update(8)Christian Göttsche2024-01-152-1/+18
| | | | | | | Emit audit reports in the helper unix_update(8) about abnormal executions, unprivileged authentications, and password updates. Also log unprivileged authentication failures to syslog.
* pam_unix: refactor audit loggingChristian Göttsche2024-01-155-36/+61
| | | | | Split the audit logging code into a separate file, to be reused by unix_update(8).
* pam_unix: fix regressionsTobias Stoeckmann2024-01-152-2/+1
| | | | | | | | | | | | The returned value stored in pwd from _unix_getpwnam is inserted into pam handler through pam_set_data. Do not manually free the value. Also check getline return value for != -1 instead of == -1. Fixes 8f2ca5919b26843ef774ef0aeb9bf261dec943a0 and 73d009e9ea8edafc18c7fe3650b25dd6bdce88c1. No release affected. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: annotate declaration with format attributeChristian Göttsche2024-01-152-1/+1
| | | | | Instead of annotating the function definition with the format attribute annotate the declaration, so the annotation is visible at call sites.
* treewide: strictly separate builddir and srcdirTobias Stoeckmann2024-01-121-1/+1
| | | | | | | | | | Building outside of source directory fails if --disable-doc is not explicitly chosen. This happens because generated files are sometimes expected in the source directory, where they won't exist. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: build unix_update only with SELinux enabledChristian Göttsche2024-01-081-3/+16
| | | | | The helper unix_update(8) is only called from code enabled when SELinux support is enabled.
* pam_unix: fix memory leakChristian Göttsche2024-01-081-0/+1
| | | | | | | | The the allocated line buffer on success. Reported by GCC analyzer. Fixes: 4a2d60e9 ("pam_unix: use getline in _unix_getpwnam")
* pam_unix: do not truncate user namesTobias Stoeckmann2024-01-082-6/+2
| | | | | | | | | | | | | | | | This could allow users with very long names to impersonate a user with a 255 characters long name. The check if the argument argv[1] actually matches the user name implies that "user" can unconditionally be set to argv[1]: If they are equal, the strings are obviously equal. If they are not or if null is returned by getuidname, "user" is set to argv[1] anyway. This way, the static buffer can be safely removed because the result of getpwuid() is not stored, which means that subsequent calls to such functions can safely overwrite their internal buffers. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: fix typos in manual pageTobias Stoeckmann2024-01-051-3/+3
| | | | Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix/passverify: always run the helper to obtain shadow password file ↵Dmitry V. Levin2024-01-041-10/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | entries Initially, when pam_unix.so verified the password, it used to try to obtain the shadow password file entry for the given user by invoking getspnam(3), and only when that didn't work and the effective uid was nonzero, pam_unix.so used to invoke the helper as a fallback. When SELinux support was introduced by commit 67aab1ff5515054341a438cf9804e9c9b3a88033, the fallback was extended also for the case when SELinux was enabled. Later, commit f220cace205332a3dc34e7b37a85e7627e097e7d extended the fallback conditions for the case when pam_modutil_getspnam() failed with EACCES. Since commit 470823c4aacef5cb3b1180be6ed70846b61a3752, the helper is invoked as a fallback when pam_modutil_getspnam() fails for any reason. The ultimate solution for the case when pam_unix.so does not have permissions to obtain the shadow password file entry is to stop trying to use pam_modutil_getspnam() and to invoke the helper instead. Here are two recent examples. https://github.com/linux-pam/linux-pam/pull/484 describes a system configuration where libnss_systemd is enabled along with libnss_files in the shadow entry of nsswitch.conf, so when libnss_files is unable to obtain the shadow password file entry for the root user, e.g. when SELinux is enabled, NSS falls back to libnss_systemd which returns a synthesized shadow password file entry for the root user, which in turn locks the root user out. https://bugzilla.redhat.com/show_bug.cgi?id=2150155 describes essentially the same problem in a similar system configuration. This commit is the final step in the direction of addressing the issue: for password verification pam_unix.so now invokes the helper instead of making the pam_modutil_getspnam() call. * modules/pam_unix/passverify.c (get_account_info) [!HELPER_COMPILE]: Always return PAM_UNIX_RUN_HELPER instead of trying to obtain the shadow password file entry. Complements: https://github.com/linux-pam/linux-pam/pull/386 Resolves: https://github.com/linux-pam/linux-pam/pull/484 Link: https://github.com/authselect/authselect/commit/1e78f7e048747024a846fd22d68afc6993734e92
* pam_unix: use getlineTobias Stoeckmann2024-01-032-4/+8
| | | | Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: reduce variable visibilityTobias Stoeckmann2024-01-031-3/+7
| | | | Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: calculate user length only if neededTobias Stoeckmann2024-01-031-3/+4
| | | | Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: use getline in _unix_getpwnamTobias Stoeckmann2024-01-031-12/+18
| | | | | | Use getline instead of fgets to allow arbitrarily long lines. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: unify error handlingTobias Stoeckmann2024-01-031-15/+14
| | | | Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: use calloc instead of malloc/memsetTobias Stoeckmann2024-01-031-2/+1
| | | | Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: use size_t instead of int for sizesTobias Stoeckmann2024-01-031-5/+5
| | | | | | | Also rename buflen to retlen, since it is not associated with the variable buf, but ret. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: avoid reading uninitialized variableTobias Stoeckmann2024-01-031-10/+8
| | | | | | | | | | | | | | | | | | | | | The function _unix_comesfromsource calls _unix_getpwnam internally. When changing the authentication token, it is first called to read local passwd file and optionally contacting NIS. If an entry is found, _unix_getpwnam is called, this time definitely reading passwd file and contacting NIS (if support exists) and parsing the entry. This is meant to check if the entry is not just available but also valid. Since the return value of _unix_getpwnam is not checked and the supplied pointer is only set in case of success, the check for a NULl pointer afterwards can lead to undefined behavior. It is easier to call _unix_getpwnam directly, check its return value and then check if the entry could be parsed. This in turn reduces the amount of /etc/passwd accesses (and fixes a theoretical TOCTOU race). Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* unix_chkpwd, unix_update: Use exit codes 128+ on signalsSolar Designer2023-12-291-1/+1
|
* treewide: use asprintf to construct stringsTobias Stoeckmann2023-12-192-17/+10
| | | | | | | | The asprintf function is considered as given for current code already. Use it instead of calling malloc + strcpy + strcat manually. Reported-by: Benny Baumann <BenBE@geshi.org> Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>