| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
| |
Split the audit logging code into a separate file, to be reused by
unix_update(8).
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
| |
Instead of annotating the function definition with the format attribute
annotate the declaration, so the annotation is visible at call sites.
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
| |
The helper unix_update(8) is only called from code enabled when SELinux
support is enabled.
|
|
|
|
|
|
|
|
| |
The the allocated line buffer on success.
Reported by GCC analyzer.
Fixes: 4a2d60e9 ("pam_unix: use getline in _unix_getpwnam")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
| |
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
| |
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
|
|
|
|
| |
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
|
|
|
|
| |
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
|
|
|
|
|
|
| |
Use getline instead of fgets to allow arbitrarily long lines.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
|
|
|
|
| |
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
|
|
|
|
| |
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
|
|
|
|
|
|
|
| |
Also rename buflen to retlen, since it is not associated with the
variable buf, but ret.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
| |
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
| |
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
| |
The C standard guarantees that if the argument of free() is a null
pointer, no action occurs.
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
| |
Print an error in syslog if an integer could not be converted.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
| |
The value of pp can potentially be NULL. This handles this case when
printing debug output.
Signed-off-by: Benny Baumann <BenBE@geshi.org>
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
| |
It is not required to cast the results of calloc, malloc,
realloc, etc.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
| |
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.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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
| |
* 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
|
|
|
|
|
|
| |
* 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.
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
| |
* 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".
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|