aboutsummaryrefslogtreecommitdiff
path: root/modules/pam_unix
Commit message (Collapse)AuthorAgeFilesLines
* 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>
* treewide: fix typos in comments and documentationTobias Stoeckmann2023-12-184-4/+4
| | | | Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* treewide: store strlen results in size_tTobias Stoeckmann2023-12-141-1/+1
| | | | | | | Very long strings could overflow the int data type. Make sure to use the correct data type. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* treewide: assume free(NULL) is no-opDmitry V. Levin2023-12-141-2/+1
| | | | | The C standard guarantees that if the argument of free() is a null pointer, no action occurs.
* pam_unix: sp_min and sp_warn must be at least 1Tobias Stoeckmann2023-12-121-2/+2
| | | | | | | If sp_min or sp_warn are set to 0 or empty (-1), then their respective features are disabled according to shadow(5). Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: allow disabled password agingTobias Stoeckmann2023-12-121-0/+5
| | | | | | | | | According to shadow(5) manual page, an empty sp_lstchg field implies that password aging is disabled. This indeed is in sync with shadow's isexpired function. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: sync expiry checks with shadowTobias Stoeckmann2023-12-121-3/+3
| | | | | | | | | | | The shadow library uses "greater than or equal to" checks instead of current "greater than" checks in pam_unix. The account expiry check is already "greater than or equal to" so this adjustment can even be argued without making references to other projects. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: simplify save_old_passwordTobias Stoeckmann2023-12-121-13/+7
| | | | | | | | The combination of snprintf and fputs is not needed. It is possible to call fprintf directly. The previously ignored return value of snprintf is covered this way as well. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: fix possible shadow signed overflowsTobias Stoeckmann2023-12-111-20/+41
| | | | | | | | | | | | | | | | | | It is possible to trigger signed integer overflows in check_shadow_expiry if /etc/shadow contains very large values. Since these values have to be set by a system administrator, it would already count as a configuration error. Yet, avoid overflows which would consider accounts which are supposed to be valid for a veeery long time as already invalid. Also, it would be undefined behavior for almost all C standards. Also consider every negative value as invalid, not just -1. The shadow project has different ways of handling these values, but this approach is in sync with its lib/isexpired.c implementation. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: check str to integer conversionsTobias Stoeckmann2023-12-112-17/+53
| | | | | | Print an error in syslog if an integer could not be converted. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: use correct number of roundsTobias Stoeckmann2023-12-111-16/+15
| | | | | | | | | | | | | | | | It is possible to have a mismatch between ENCRYPT_METHOD in login.defs and an argument given specifically to pam_unix.so. If pam_unix.so receives the argument "yescrypt" but ENCRYPT_METHOD is set to SHA512, then SHA_CRYPT_MAX_ROUNDS is parsed from login.defs and used as rounds for yescrypt -- except if rounds are specificially given as an argument to pam_unix.so as well. Read the correct rounds from login.defs after all arguments are parsed and no rounds were specified to figure out which one will eventually be used. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: handle invalid names in _unix_getpwnamTobias Stoeckmann2023-12-071-2/+3
| | | | | | | | | | | | It is possible to trigger an out of boundary read with very long usernames (strlen's result is stored in an int) or, with even longer usernames, match other users with same prefix. This would mean that roott[and lots of t's following] could match root user. Also do not allow ':' in names when iterating through the passwd file this way. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* pam_unix: read yescrypt rounds from login.defsNathan Du2023-11-271-2/+7
| | | | | | | | | Retrieves YESCRYPT_COST_FACTOR from /etc/login.defs for yescrypt in a similar fashion to reading number of rounds for SHA-2. Resolves #607. Signed-off-by: Nathan Du <nathandu@outlook.com>
* pam_unix: avoid integer truncation in debug outputBenny Baumann2023-11-141-1/+1
| | | | | | | | When printing the current day and when the password was last changed, a truncation of the value could happen due to incorrect data types used in the format string. Signed-off-by: Benny Baumann <BenBE@geshi.org>
* pam_unix: avoid printing NULL valuesBenny Baumann2023-11-141-1/+1
| | | | | | | The value of pp can potentially be NULL. This handles this case when printing debug output. Signed-off-by: Benny Baumann <BenBE@geshi.org>
* pam_unix: only output length check message on failureBenny Baumann2023-11-141-2/+3
| | | | | | | | | | The debug message was placed outside the password length check and thus if the length check succeeded no message would have been placed. Comparing this location with other occurrences indicates this was by mistake, thus the message is now suppressed if there's nothing to print anyway. Signed-off-by: Benny Baumann <BenBE@geshi.org>
* treewide: do not cast calloc/malloc/reallocTobias Stoeckmann2023-11-121-1/+1
| | | | | | | It is not required to cast the results of calloc, malloc, realloc, etc. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
* modules: cast to unsigned char for character handling functionChristian Göttsche2023-08-071-1/+1
| | | | | | | | Character handling functions, like isspace(3), expect a value representable as unsigned char or equal to EOF. Otherwise the behavior is undefined. See https://wiki.sei.cmu.edu/confluence/display/c/STR37-C.+Arguments+to+character-handling+functions+must+be+representable+as+an+unsigned+char
* pam_unix: improve fallback values for "rounds" for yescrypt and blowfishJulian Kranz2023-07-171-4/+8
| | | | | | | | This change improves the fallback values for the "rounds" parameter for yescrypt and blowfish by using the smallest reasonable value if the user sets a too low value and by using the highest reasonable value if the user sets a too high value. This better realizes user intent and is consistent with the approach taken for SHA256.
* configure: Disable NIS if header files are missingThorsten Kukuk2023-04-062-9/+3
| | | | | | configure.ac: Disable NIS if RPC or YP header files are missing modules/pam_unix/support.c: Use HAVE_NIS to check for header file presence modules/pam_unix/pam_unix_passwd.c: Use HAVE_NIS, too
* modules: make use of secure memory erasureChristian Göttsche2023-02-289-26/+38
| | | | | | | | | | | | | | | | | | | | | | | | | | Use empty initialization of structs to minimize the memset() usage, to reduce the amount of calls which are not sensitive. Non trivial changes: - pam_env: * erase environment variables where possible - pam_exec: * erase responce on error * erase auth token - pam_pwhistory: * erase buffers containing old passwords - pam_selinux: skip overwriting data structure consisting of only pointers to insensitive data, which also gets free'd afterwards (so it currently does not protect against double-free or use-after-free on the member pointers) - pam_unix: erase cipher data in more places - pam_userdb: erase password hashes
* build: use <vendordir>/security directory for installation if it has been setStefan Schubert2023-02-071-0/+4
| | | | | | | | | Otherwise the corresponding files are still installed in /etc/security. * configure.ac (AC_SUBST): Add VENDOR_SCONFIGDIR. (AM_CONDITIONAL): Add HAVE_VENDORDIR. * modules/*/Makefile.am (secureconfdir): Set to VENDOR_SCONFIGDIR if HAVE_VENDORDIR has been set, otherwise to SCONFIGDIR.
* pam_unix: don't link against yppasswd_xdr if NIS is disabledThorsten Kukuk2023-01-312-6/+5
| | | | | | | | | * configure.ac: Define HAVE_NIS if NIS is enabled. * modules/pam_unix/Makefile.am: Don't link against yppasswd_xdr.c if NIS is disabled. * modules/pam_unix/pam_unix_passwd.c: Don't redefine HAVE_NIS. Resolves: https://github.com/linux-pam/linux-pam/issues/523
* Enable undef warningChristian Göttsche2023-01-301-4/+4
| | | | | | * modules/pam_unix/pam_unix_passwd.c: Wrap checks for configure macros into defined() operator. * m4/warn_lang_flags.m4 (gl_WARN_ADD): Add -Wundef.
* pam_unix: regenerate yppasswd.h/yppasswd_xdr.c (#480)Thorsten Kukuk2023-01-242-61/+72
| | | | | | | Regenerate yppasswd.h and yppasswd_xdr.c from yppasswd.x (libnsl) to avoid GPL code in a PAM module. Link: https://github.com/thkukuk/libnsl/blob/master/src/rpcsvc/yppasswd.x
* pam_unix: silence compiler warning in md5.cDmitry V. Levin2023-01-191-13/+12
| | | | | | | | | | | | | | | | | | | | | | | | | clang-14 insists on issuing the following warning: In file included from md5_good.c:4: md5.c:92:15: error: passing 1-byte aligned argument to 4-byte aligned parameter 1 of 'byteReverse' may result in an unaligned pointer access [-Werror,-Walign-mismatch] byteReverse(ctx->in.c, 16); ^ md5.c:101:15: error: passing 1-byte aligned argument to 4-byte aligned parameter 1 of 'byteReverse' may result in an unaligned pointer access [-Werror,-Walign-mismatch] byteReverse(ctx->in.c, 16); ^ md5.c:136:15: error: passing 1-byte aligned argument to 4-byte aligned parameter 1 of 'byteReverse' may result in an unaligned pointer access [-Werror,-Walign-mismatch] byteReverse(ctx->in.c, 16); ^ md5.c:145:14: error: passing 1-byte aligned argument to 4-byte aligned parameter 1 of 'byteReverse' may result in an unaligned pointer access [-Werror,-Walign-mismatch] byteReverse(ctx->in.c, 14); ^ md5.c:151:14: error: passing 1-byte aligned argument to 4-byte aligned parameter 1 of 'byteReverse' may result in an unaligned pointer access [-Werror,-Walign-mismatch] byteReverse(ctx->buf.c, 4); ^ * modules/pam_unix/md5.c (byteReverse): Use uint32 instead of uint8_aligned, update all users. (uint8_aligned): Remove unused type.
* doc: Update PAM documentation from DockBook 4 to DocBook 5Stefan Schubert2022-12-164-95/+72
| | | | | | | | | | | | | | | | | | | | Changed files -------------- Make.xml.rules.in: - Using RNG file instead of DTD file for checking XML files. - Taking the correct stylesheet for README files. doc/sag/Makefile.am, doc/adg/Makefile.am, doc/mwg/Makefile.am: - Using RNG file instead of DTD file for checking XML files. configure.ac: - Adding a new option for selecting RNG check file (-enable-docbook-rng) - Switching stylesheets to docbook 5 - Checking DocBook 5 environment instead of DocBook 4 environment *.xml: Update from DockBook 4 to DocBook 5
* modules: use SCONFIGDIR macroDmitry V. Levin2022-01-232-2/+2
| | | | | | | | | | | | | | | | | Use SCONFIGDIR macro instead of open-coding "/etc/security", the latter is not correct when configured using --enable-sconfigdir with an argument different from /etc/security. * modules/pam_faillock/faillock.h (FAILLOCK_DEFAULT_CONF): Use SCONFIGDIR. * modules/pam_namespace/pam_namespace.h (SECURECONF_DIR): Remove. (PAM_NAMESPACE_CONFIG, NAMESPACE_INIT_SCRIPT, NAMESPACE_D_DIR, NAMESPACE_D_GLOB): Use SCONFIGDIR. * modules/pam_namespace/Makefile.am (AM_CFLAGS): Remove -DSECURECONF_DIR. * modules/pam_pwhistory/opasswd.c (OLD_PASSWORDS_FILE): Use SCONFIGDIR. * modules/pam_unix/passverify.h: Likewise. * modules/pam_unix/passverify.c (OPW_TMPFILE): Use SCONFIGDIR.
* Fix a typo found using codespell toolDmitry V. Levin2021-09-031-3/+3
| | | | | | | * modules/pam_pwhistory/pam_pwhistory.c: Replace "crypted password" with "hashed password" in comment. * modules/pam_unix/passverify.c (create_password_hash): Rename "crypted" local variable to "hashed".
* pam_unix: workaround the problem caused by libnss_systemdDmitry V. Levin2021-08-191-2/+1
| | | | | | | | | | | | | | | | | | | The getspnam(3) manual page says that errno shall be set to EACCES when the caller does not have permission to access the shadow password file. Unfortunately, this contract is broken when libnss_systemd is used in the nss stack. Workaround this problem by falling back to the helper invocation when pam_modutil_getspnam returns NULL regardless of errno. As pam_unix already behaves this way when selinux is enabled, it should be OK for the case when selinux is not enabled, too. * modules/pam_unix/passverify.c (get_account_info): When pam_modutil_getspnam returns NULL, unconditionally fall back to the helper invocation. Complements: f220cace2053 ("Permit unix_chkpwd & pam_unix.so to run without being setuid-root") Resolves: https://github.com/linux-pam/linux-pam/issues/379
* Permit unix_chkpwd & pam_unix.so to run without being setuid-root.Andrew G. Morgan2021-06-291-4/+8
| | | | | | | | | | | | | | | | | | | | | Remove the hard-coding of the idea that the only way pam_unix.so can read the shadow file is if it can, in some way, run setuid-root. Linux capabilities only require cap_dac_override to read the /etc/shadow file. This change achieves two things: it opens a path for a linux-pam application to run without being setuid-root; further, it allows unix_chkpwd to run non-setuid-root if it is installed: sudo setcap cap_dac_override=ep unix_chkpwd If we wanted to link against libcap, we could install this binary with cap_dac_override=p, and use cap_set_proc() to raise the effective bit at runtime. However, some distributions already link unix_chkpwd against libcap-ng for some, likely spurious, reason so "ep" is fine for now. Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
* Remove support for legacy xcryptBjörn Esser2021-06-142-22/+6
| | | | | | | | | | | | | | | | Since many distributions are shipping a version of libxcrypt >= 4.0.0 as a replacement for glibc's libcrypt now, older versions of xcrypt, which could be installed in parallel, are not relevant anymore. * configure.ac (AC_CHECK_HEADERS): Remove xcrypt.h. (AC_SEARCH_LIBS): Remove xcrypt. (AC_CHECK_FUNCS): Remove crypt_gensalt_r. (AC_DEFINE): Remove HAVE_LIBXCRYPT. * modules/pam_pwhistory/opasswd.c [HAVE_LIBXCRYPT]: Remove. * modules/pam_unix/bigcrypt.c [HAVE_LIBXCRYPT]: Likewise. * modules/pam_userdb/pam_userdb.c [HAVE_LIBXCRYPT]: Likewise. * modules/pam_unix/passverify.c [HAVE_LIBXCRYPT]: Likewise. (create_password_hash) [HAVE_LIBXCRYPT]: Likewise.