Compare commits
10 Commits
1f8b2b5832
...
c70c07c60b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c70c07c60b | ||
|
|
26162d8876 | ||
|
|
06ecd73501 | ||
|
|
5102e2710b | ||
|
|
1af39ca0e0 | ||
|
|
ef131bca4c | ||
|
|
ed6fda24f9 | ||
|
|
df55e47f28 | ||
|
|
7632cb824a | ||
|
|
a2cfd75da4 |
@ -1,50 +0,0 @@
|
||||
From 3bd5a1244a35974c8a0e21a9ac866cb5935f662e Mon Sep 17 00:00:00 2001
|
||||
From: Hongxun Ren <renhongxun@huawei.com>
|
||||
Date: Wed, 15 Sep 2021 10:05:49 +0800
|
||||
Subject: [PATCH] bugfix cannot open database file
|
||||
|
||||
---
|
||||
modules/pam_userdb/pam_userdb.c | 23 ++++++++++++++++++++---
|
||||
1 file changed, 20 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c
|
||||
index dc2ca23..a9992a7 100644
|
||||
--- a/modules/pam_userdb/pam_userdb.c
|
||||
+++ b/modules/pam_userdb/pam_userdb.c
|
||||
@@ -147,13 +147,30 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode,
|
||||
{
|
||||
DBM *dbm;
|
||||
datum key, data;
|
||||
+ int retval;
|
||||
|
||||
+ /* Init the DB file. */
|
||||
+ retval = dbminit(database);
|
||||
+ if (retval) {
|
||||
+ pam_syslog(pamh, LOG_ERR,
|
||||
+ "user_lookup: could not init database `%s': %m", database);
|
||||
+ return -2;
|
||||
+ }
|
||||
/* Open the DB file. */
|
||||
dbm = dbm_open(database, O_RDONLY, 0644);
|
||||
if (dbm == NULL) {
|
||||
- pam_syslog(pamh, LOG_ERR,
|
||||
- "user_lookup: could not open database `%s': %m", database);
|
||||
- return -2;
|
||||
+ retval = dbminit(database);
|
||||
+ if (retval){
|
||||
+ pam_syslog(pamh, LOG_ERR,
|
||||
+ "user_lookup: could not re-init database `%s': %m", database);
|
||||
+ } else {
|
||||
+ dbm = dbm_open(database, O_RDONLY, 0644);
|
||||
+ if(dbm == NULL) {
|
||||
+ pam_syslog(pamh, LOG_ERR,
|
||||
+ "user_lookup: could not open database `%s': %m", database);
|
||||
+ return -2;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
/* dump out the database contents for debugging */
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -0,0 +1,78 @@
|
||||
From b7b96362087414e52524d3d9d9b3faa21e1db620 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Stoeckmann <tobias@stoeckmann.org>
|
||||
Date: Wed, 24 Jan 2024 18:57:42 +0100
|
||||
Subject: [PATCH] pam_unix: try to set uid to 0 for unix_chkpwd
|
||||
|
||||
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>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/linux-pam/linux-pam/commit/b7b96362087414e52524d3d9d9b3faa21e1db620
|
||||
---
|
||||
modules/pam_unix/pam_unix_acct.c | 17 +++++++++--------
|
||||
modules/pam_unix/support.c | 14 +++++++-------
|
||||
2 files changed, 16 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c
|
||||
index de8d65c..9df961a 100644
|
||||
--- a/modules/pam_unix/pam_unix_acct.c
|
||||
+++ b/modules/pam_unix/pam_unix_acct.c
|
||||
@@ -110,14 +110,15 @@ int _unix_run_verify_binary(pam_handle_t *pamh, unsigned long long ctrl,
|
||||
_exit(PAM_AUTHINFO_UNAVAIL);
|
||||
}
|
||||
|
||||
- if (geteuid() == 0) {
|
||||
- /* must set the real uid to 0 so the helper will not error
|
||||
- out if pam is called from setuid binary (su, sudo...) */
|
||||
- if (setuid(0) == -1) {
|
||||
- pam_syslog(pamh, LOG_ERR, "setuid failed: %m");
|
||||
- printf("-1\n");
|
||||
- fflush(stdout);
|
||||
- _exit(PAM_AUTHINFO_UNAVAIL);
|
||||
+ /* must set the real uid to 0 so the helper will not error
|
||||
+ out if pam is called from setuid binary (su, sudo...) */
|
||||
+ if (setuid(0) == -1) {
|
||||
+ uid_t euid = geteuid();
|
||||
+ pam_syslog(pamh, euid == 0 ? LOG_ERR : LOG_DEBUG, "setuid failed: %m");
|
||||
+ if (euid == 0) {
|
||||
+ printf("-1\n");
|
||||
+ fflush(stdout);
|
||||
+ _exit(PAM_AUTHINFO_UNAVAIL);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c
|
||||
index 2af3aea..f04fcdd 100644
|
||||
--- a/modules/pam_unix/support.c
|
||||
+++ b/modules/pam_unix/support.c
|
||||
@@ -513,13 +513,13 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd,
|
||||
_exit(PAM_AUTHINFO_UNAVAIL);
|
||||
}
|
||||
|
||||
- if (geteuid() == 0) {
|
||||
- /* must set the real uid to 0 so the helper will not error
|
||||
- out if pam is called from setuid binary (su, sudo...) */
|
||||
- if (setuid(0) == -1) {
|
||||
- D(("setuid failed"));
|
||||
- _exit(PAM_AUTHINFO_UNAVAIL);
|
||||
- }
|
||||
+ /* must set the real uid to 0 so the helper will not error
|
||||
+ out if pam is called from setuid binary (su, sudo...) */
|
||||
+ if (setuid(0) == -1) {
|
||||
+ D(("setuid failed"));
|
||||
+ if (geteuid() == 0) {
|
||||
+ _exit(PAM_AUTHINFO_UNAVAIL);
|
||||
+ }
|
||||
}
|
||||
|
||||
/* exec binary helper */
|
||||
--
|
||||
2.46.0
|
||||
94
backport-CVE-2024-10041.patch
Normal file
94
backport-CVE-2024-10041.patch
Normal file
@ -0,0 +1,94 @@
|
||||
From b3020da7da384d769f27a8713257fbe1001878be Mon Sep 17 00:00:00 2001
|
||||
From: "Dmitry V. Levin" <ldv@strace.io>
|
||||
Date: Mon, 1 Jan 2024 12:00:00 +0000
|
||||
Subject: [PATCH] pam_unix/passverify: always run the helper to obtain shadow
|
||||
password file 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
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/linux-pam/linux-pam/commit/b3020da7da384d769f27a8713257fbe1001878be
|
||||
---
|
||||
modules/pam_unix/passverify.c | 21 +++++++++++----------
|
||||
1 file changed, 11 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
|
||||
index eb0fa74..1bb7c89 100644
|
||||
--- a/modules/pam_unix/passverify.c
|
||||
+++ b/modules/pam_unix/passverify.c
|
||||
@@ -239,20 +239,21 @@ PAMH_ARG_DECL(int get_account_info,
|
||||
return PAM_UNIX_RUN_HELPER;
|
||||
#endif
|
||||
} else if (is_pwd_shadowed(*pwd)) {
|
||||
+#ifdef HELPER_COMPILE
|
||||
/*
|
||||
- * ...and shadow password file entry for this user,
|
||||
+ * shadow password file entry for this user,
|
||||
* if shadowing is enabled
|
||||
*/
|
||||
- *spwdent = pam_modutil_getspnam(pamh, name);
|
||||
- if (*spwdent == NULL) {
|
||||
-#ifndef HELPER_COMPILE
|
||||
- /* still a chance the user can authenticate */
|
||||
- return PAM_UNIX_RUN_HELPER;
|
||||
-#endif
|
||||
- return PAM_AUTHINFO_UNAVAIL;
|
||||
- }
|
||||
- if ((*spwdent)->sp_pwdp == NULL)
|
||||
+ *spwdent = getspnam(name);
|
||||
+ if (*spwdent == NULL || (*spwdent)->sp_pwdp == NULL)
|
||||
return PAM_AUTHINFO_UNAVAIL;
|
||||
+#else
|
||||
+ /*
|
||||
+ * The helper has to be invoked to deal with
|
||||
+ * the shadow password file entry.
|
||||
+ */
|
||||
+ return PAM_UNIX_RUN_HELPER;
|
||||
+#endif
|
||||
}
|
||||
} else {
|
||||
return PAM_USER_UNKNOWN;
|
||||
--
|
||||
2.46.0
|
||||
228
backport-CVE-2024-10963.patch
Normal file
228
backport-CVE-2024-10963.patch
Normal file
@ -0,0 +1,228 @@
|
||||
From 940747f88c16e029b69a74e80a2e94f65cb3e628 Mon Sep 17 00:00:00 2001
|
||||
From: Thorsten Kukuk <kukuk@suse.com>
|
||||
Date: Thu, 14 Nov 2024 10:27:28 +0100
|
||||
Subject: [PATCH] pam_access: rework resolving of tokens as hostname
|
||||
|
||||
Conflict:Context adaptation
|
||||
Reference:https://github.com/linux-pam/linux-pam/commit/940747f88c16e029b69a74e80a2e94f65cb3e628
|
||||
|
||||
* modules/pam_access/pam_access.c: separate resolving of IP addresses
|
||||
from hostnames. Don't resolve TTYs or display variables as hostname
|
||||
(#834).
|
||||
Add "nodns" option to disallow resolving of tokens as hostname.
|
||||
* modules/pam_access/pam_access.8.xml: document nodns option
|
||||
* modules/pam_access/access.conf.5.xml: document that hostnames should
|
||||
be written as FQHN.
|
||||
---
|
||||
modules/pam_access/access.conf.5.xml | 4 ++
|
||||
modules/pam_access/pam_access.8.xml | 46 ++++++++++++------
|
||||
modules/pam_access/pam_access.c | 72 +++++++++++++++++++++++++++-
|
||||
3 files changed, 105 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_access/access.conf.5.xml b/modules/pam_access/access.conf.5.xml
|
||||
index 0b93db00..10b8ba92 100644
|
||||
--- a/modules/pam_access/access.conf.5.xml
|
||||
+++ b/modules/pam_access/access.conf.5.xml
|
||||
@@ -226,6 +226,10 @@
|
||||
item and the line will be most probably ignored. For this reason, it is not
|
||||
recommended to put spaces around the ':' characters.
|
||||
</para>
|
||||
+ <para>
|
||||
+ Hostnames should be written as Fully-Qualified Host Name (FQHN) to avoid
|
||||
+ confusion with device names or PAM service names.
|
||||
+ </para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="access.conf-see_also">
|
||||
diff --git a/modules/pam_access/pam_access.8.xml b/modules/pam_access/pam_access.8.xml
|
||||
index c991d7a0..71a4f7ee 100644
|
||||
--- a/modules/pam_access/pam_access.8.xml
|
||||
+++ b/modules/pam_access/pam_access.8.xml
|
||||
@@ -25,11 +25,14 @@
|
||||
<arg choice="opt">
|
||||
debug
|
||||
</arg>
|
||||
+ <arg choice="opt">
|
||||
+ noaudit
|
||||
+ </arg>
|
||||
<arg choice="opt">
|
||||
nodefgroup
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
- noaudit
|
||||
+ nodns
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
accessfile=<replaceable>file</replaceable>
|
||||
@@ -112,6 +115,33 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
+ <varlistentry>
|
||||
+ <term>
|
||||
+ nodefgroup
|
||||
+ </term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ User tokens which are not enclosed in parentheses will not be
|
||||
+ matched against the group database. The backwards compatible default is
|
||||
+ to try the group database match even for tokens not enclosed
|
||||
+ in parentheses.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
+ <varlistentry>
|
||||
+ <term>
|
||||
+ nodns
|
||||
+ </term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ Do not try to resolve tokens as hostnames, only IPv4 and IPv6
|
||||
+ addresses will be resolved. Which means to allow login from a
|
||||
+ remote host, the IP addresses need to be specified in <filename>access.conf</filename>.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>fieldsep=<replaceable>separators</replaceable></option>
|
||||
@@ -153,20 +183,6 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
- <varlistentry>
|
||||
- <term>
|
||||
- <option>nodefgroup</option>
|
||||
- </term>
|
||||
- <listitem>
|
||||
- <para>
|
||||
- User tokens which are not enclosed in parentheses will not be
|
||||
- matched against the group database. The backwards compatible default is
|
||||
- to try the group database match even for tokens not enclosed
|
||||
- in parentheses.
|
||||
- </para>
|
||||
- </listitem>
|
||||
- </varlistentry>
|
||||
-
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c
|
||||
index 48e7c7e9..109115e9 100644
|
||||
--- a/modules/pam_access/pam_access.c
|
||||
+++ b/modules/pam_access/pam_access.c
|
||||
@@ -92,6 +92,7 @@ struct login_info {
|
||||
int debug; /* Print debugging messages. */
|
||||
int only_new_group_syntax; /* Only allow group entries of the form "(xyz)" */
|
||||
int noaudit; /* Do not audit denials */
|
||||
+ int nodns; /* Do not try to resolve tokens as hostnames */
|
||||
const char *fs; /* field separator */
|
||||
const char *sep; /* list-element separator */
|
||||
int from_remote_host; /* If PAM_RHOST was used for from */
|
||||
@@ -143,6 +144,8 @@ parse_args(pam_handle_t *pamh, struct login_info *loginfo,
|
||||
loginfo->only_new_group_syntax = YES;
|
||||
} else if (strcmp (argv[i], "noaudit") == 0) {
|
||||
loginfo->noaudit = YES;
|
||||
+ } else if (strcmp (argv[i], "nodns") == 0) {
|
||||
+ loginfo->nodns = YES;
|
||||
} else {
|
||||
pam_syslog(pamh, LOG_ERR, "unrecognized option [%s]", argv[i]);
|
||||
}
|
||||
@@ -637,7 +640,7 @@ remote_match (pam_handle_t *pamh, char *tok, struct login_info *item)
|
||||
if ((str_len = strlen(string)) > tok_len
|
||||
&& strcasecmp(tok, string + str_len - tok_len) == 0)
|
||||
return YES;
|
||||
- } else if (tok[tok_len - 1] == '.') { /* internet network numbers (end with ".") */
|
||||
+ } else if (tok[tok_len - 1] == '.') { /* internet network numbers/subnet (end with ".") */
|
||||
struct addrinfo hint;
|
||||
|
||||
memset (&hint, '\0', sizeof (hint));
|
||||
@@ -712,6 +715,39 @@ string_match (pam_handle_t *pamh, const char *tok, const char *string,
|
||||
}
|
||||
|
||||
|
||||
+static int
|
||||
+is_device (pam_handle_t *pamh, const char *tok)
|
||||
+{
|
||||
+ struct stat st;
|
||||
+ const char *dev = "/dev/";
|
||||
+ char *devname;
|
||||
+
|
||||
+ devname = malloc (strlen(dev) + strlen (tok) + 1);
|
||||
+ if (devname == NULL) {
|
||||
+ pam_syslog(pamh, LOG_ERR, "Cannot allocate memory for device name: %m");
|
||||
+ /*
|
||||
+ * We should return an error and abort, but pam_access has no good
|
||||
+ * error handling.
|
||||
+ */
|
||||
+ return NO;
|
||||
+ }
|
||||
+
|
||||
+ char *cp = stpcpy (devname, dev);
|
||||
+ strcpy (cp, tok);
|
||||
+
|
||||
+ if (lstat(devname, &st) != 0)
|
||||
+ {
|
||||
+ free (devname);
|
||||
+ return NO;
|
||||
+ }
|
||||
+ free (devname);
|
||||
+
|
||||
+ if (S_ISCHR(st.st_mode))
|
||||
+ return YES;
|
||||
+
|
||||
+ return NO;
|
||||
+}
|
||||
+
|
||||
/* network_netmask_match - match a string against one token
|
||||
* where string is a hostname or ip (v4,v6) address and tok
|
||||
* represents either a hostname, a single ip (v4,v6) address
|
||||
@@ -773,10 +809,42 @@ network_netmask_match (pam_handle_t *pamh,
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
+ else if (isipaddr(tok, NULL, NULL) == YES)
|
||||
+ {
|
||||
+ if (getaddrinfo (tok, NULL, NULL, &ai) != 0)
|
||||
+ {
|
||||
+ if (item->debug)
|
||||
+ pam_syslog(pamh, LOG_DEBUG, "cannot resolve IP address \"%s\"", tok);
|
||||
+
|
||||
+ return NO;
|
||||
+ }
|
||||
+ netmask_ptr = NULL;
|
||||
+ }
|
||||
+ else if (item->nodns)
|
||||
+ {
|
||||
+ /* Only hostnames are left, which we would need to resolve via DNS */
|
||||
+ return NO;
|
||||
+ }
|
||||
else
|
||||
{
|
||||
+ /* Bail out on X11 Display entries and ttys. */
|
||||
+ if (tok[0] == ':')
|
||||
+ {
|
||||
+ if (item->debug)
|
||||
+ pam_syslog (pamh, LOG_DEBUG,
|
||||
+ "network_netmask_match: tok=%s is X11 display", tok);
|
||||
+ return NO;
|
||||
+ }
|
||||
+ if (is_device (pamh, tok))
|
||||
+ {
|
||||
+ if (item->debug)
|
||||
+ pam_syslog (pamh, LOG_DEBUG,
|
||||
+ "network_netmask_match: tok=%s is a TTY", tok);
|
||||
+ return NO;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
- * It is either an IP address or a hostname.
|
||||
+ * It is most likely a hostname.
|
||||
* Let getaddrinfo sort everything out
|
||||
*/
|
||||
if (getaddrinfo (tok, NULL, NULL, &ai) != 0)
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
From 031bb5a5d0d950253b68138b498dc93be69a64cb Mon Sep 17 00:00:00 2001
|
||||
From: Matthias Gerstner <matthias.gerstner@suse.de>
|
||||
Date: Wed, 27 Dec 2023 14:01:59 +0100
|
||||
Subject: [PATCH] pam_namespace: protect_dir(): use O_DIRECTORY to prevent
|
||||
local DoS situations
|
||||
|
||||
Without O_DIRECTORY the path crawling logic is subject to e.g. FIFOs
|
||||
being placed in user controlled directories, causing the PAM module to
|
||||
block indefinitely during `openat()`.
|
||||
|
||||
Pass O_DIRECTORY to cause the `openat()` to fail if the path does not
|
||||
refer to a directory.
|
||||
|
||||
With this the check whether the final path element is a directory
|
||||
becomes unnecessary, drop it.
|
||||
---
|
||||
modules/pam_namespace/pam_namespace.c | 18 +-----------------
|
||||
1 file changed, 1 insertion(+), 17 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c
|
||||
index 2528cff8..f72d6718 100644
|
||||
--- a/modules/pam_namespace/pam_namespace.c
|
||||
+++ b/modules/pam_namespace/pam_namespace.c
|
||||
@@ -1201,7 +1201,7 @@ static int protect_dir(const char *path, mode_t mode, int do_mkdir,
|
||||
int dfd = AT_FDCWD;
|
||||
int dfd_next;
|
||||
int save_errno;
|
||||
- int flags = O_RDONLY;
|
||||
+ int flags = O_RDONLY | O_DIRECTORY;
|
||||
int rv = -1;
|
||||
struct stat st;
|
||||
|
||||
@@ -1255,22 +1255,6 @@ static int protect_dir(const char *path, mode_t mode, int do_mkdir,
|
||||
rv = openat(dfd, dir, flags);
|
||||
}
|
||||
|
||||
- if (rv != -1) {
|
||||
- if (fstat(rv, &st) != 0) {
|
||||
- save_errno = errno;
|
||||
- close(rv);
|
||||
- rv = -1;
|
||||
- errno = save_errno;
|
||||
- goto error;
|
||||
- }
|
||||
- if (!S_ISDIR(st.st_mode)) {
|
||||
- close(rv);
|
||||
- errno = ENOTDIR;
|
||||
- rv = -1;
|
||||
- goto error;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
if (flags & O_NOFOLLOW) {
|
||||
/* we are inside user-owned dir - protect */
|
||||
if (protect_mount(rv, p, idata) == -1) {
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
From f220cace205332a3dc34e7b37a85e7627e097e7d Mon Sep 17 00:00:00 2001
|
||||
From: "Andrew G. Morgan" <morgan@kernel.org>
|
||||
Date: Sat, 26 Jun 2021 14:18:08 -0700
|
||||
Subject: [PATCH] Permit unix_chkpwd & pam_unix.so to run without being
|
||||
setuid-root.
|
||||
|
||||
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>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/linux-pam/linux-pam/commit/f220cace205332a3dc34e7b37a85e7627e097e7d
|
||||
---
|
||||
modules/pam_unix/passverify.c | 12 ++++++++----
|
||||
1 file changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
|
||||
index fc2eaff..5bb518e 100644
|
||||
--- a/modules/pam_unix/passverify.c
|
||||
+++ b/modules/pam_unix/passverify.c
|
||||
@@ -243,12 +243,16 @@ PAMH_ARG_DECL(int get_account_info,
|
||||
* ...and shadow password file entry for this user,
|
||||
* if shadowing is enabled
|
||||
*/
|
||||
+ *spwdent = pam_modutil_getspnam(pamh, name);
|
||||
+ if (*spwdent == NULL) {
|
||||
#ifndef HELPER_COMPILE
|
||||
- if (geteuid() || SELINUX_ENABLED)
|
||||
- return PAM_UNIX_RUN_HELPER;
|
||||
+ /* still a chance the user can authenticate */
|
||||
+ if (errno == EACCES || SELINUX_ENABLED)
|
||||
+ return PAM_UNIX_RUN_HELPER;
|
||||
#endif
|
||||
- *spwdent = pam_modutil_getspnam(pamh, name);
|
||||
- if (*spwdent == NULL || (*spwdent)->sp_pwdp == NULL)
|
||||
+ return PAM_AUTHINFO_UNAVAIL;
|
||||
+ }
|
||||
+ if ((*spwdent)->sp_pwdp == NULL)
|
||||
return PAM_AUTHINFO_UNAVAIL;
|
||||
}
|
||||
} else {
|
||||
--
|
||||
2.46.0
|
||||
@ -0,0 +1,98 @@
|
||||
From 08992030c56c940c0707ccbc442b1c325aa01e6d Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Mraz <tmraz@fedoraproject.org>
|
||||
Date: Tue, 6 Apr 2021 12:27:38 +0200
|
||||
Subject: [PATCH] pam_access: clean up the remote host matching code
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/linux-pam/linux-pam/commit/08992030c56c940c0707ccbc442b1c325aa01e6d
|
||||
|
||||
* modules/pam_access/pam_access.c (from_match): Split out remote_match()
|
||||
function and avoid calling it when matching against LOCAL keyword.
|
||||
There is also no point in doing domain match against TTY or SERVICE.
|
||||
---
|
||||
modules/pam_access/pam_access.c | 44 +++++++++++++++++++++------------
|
||||
1 file changed, 28 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c
|
||||
index 98848c54..277192b9 100644
|
||||
--- a/modules/pam_access/pam_access.c
|
||||
+++ b/modules/pam_access/pam_access.c
|
||||
@@ -160,6 +160,7 @@ static int list_match (pam_handle_t *, char *, char *, struct login_info *,
|
||||
static int user_match (pam_handle_t *, char *, struct login_info *);
|
||||
static int group_match (pam_handle_t *, const char *, const char *, int);
|
||||
static int from_match (pam_handle_t *, char *, struct login_info *);
|
||||
+static int remote_match (pam_handle_t *, char *, struct login_info *);
|
||||
static int string_match (pam_handle_t *, const char *, const char *, int);
|
||||
static int network_netmask_match (pam_handle_t *, const char *, const char *, struct login_info *);
|
||||
|
||||
@@ -589,11 +590,9 @@ group_match (pam_handle_t *pamh, const char *tok, const char* usr,
|
||||
/* from_match - match a host or tty against a list of tokens */
|
||||
|
||||
static int
|
||||
-from_match (pam_handle_t *pamh UNUSED, char *tok, struct login_info *item)
|
||||
+from_match (pam_handle_t *pamh, char *tok, struct login_info *item)
|
||||
{
|
||||
const char *string = item->from;
|
||||
- int tok_len;
|
||||
- int str_len;
|
||||
int rv;
|
||||
|
||||
if (item->debug)
|
||||
@@ -616,14 +615,29 @@ from_match (pam_handle_t *pamh UNUSED, char *tok, struct login_info *item)
|
||||
} else if ((rv = string_match(pamh, tok, string, item->debug)) != NO) {
|
||||
/* ALL or exact match */
|
||||
return rv;
|
||||
- } else if (tok[0] == '.') { /* domain: match last fields */
|
||||
- if ((str_len = strlen(string)) > (tok_len = strlen(tok))
|
||||
- && strcasecmp(tok, string + str_len - tok_len) == 0)
|
||||
- return (YES);
|
||||
- } else if (item->from_remote_host == 0) { /* local: no PAM_RHOSTS */
|
||||
- if (strcasecmp(tok, "LOCAL") == 0)
|
||||
- return (YES);
|
||||
- } else if (tok[(tok_len = strlen(tok)) - 1] == '.') {
|
||||
+ } else if (strcasecmp(tok, "LOCAL") == 0) {
|
||||
+ /* LOCAL matches only local accesses */
|
||||
+ if (!item->from_remote_host)
|
||||
+ return YES;
|
||||
+ return NO;
|
||||
+ } else if (item->from_remote_host) {
|
||||
+ return remote_match(pamh, tok, item);
|
||||
+ }
|
||||
+ return NO;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+remote_match (pam_handle_t *pamh, char *tok, struct login_info *item)
|
||||
+{
|
||||
+ const char *string = item->from;
|
||||
+ size_t tok_len = strlen(tok);
|
||||
+ size_t str_len;
|
||||
+
|
||||
+ if (tok[0] == '.') { /* domain: match last fields */
|
||||
+ if ((str_len = strlen(string)) > tok_len
|
||||
+ && strcasecmp(tok, string + str_len - tok_len) == 0)
|
||||
+ return YES;
|
||||
+ } else if (tok[tok_len - 1] == '.') {
|
||||
struct addrinfo hint;
|
||||
|
||||
memset (&hint, '\0', sizeof (hint));
|
||||
@@ -661,13 +675,11 @@ from_match (pam_handle_t *pamh UNUSED, char *tok, struct login_info *item)
|
||||
runp = runp->ai_next;
|
||||
}
|
||||
}
|
||||
- } else {
|
||||
- /* Assume network/netmask with a IP of a host. */
|
||||
- if (network_netmask_match(pamh, tok, string, item))
|
||||
- return YES;
|
||||
+ return NO;
|
||||
}
|
||||
|
||||
- return NO;
|
||||
+ /* Assume network/netmask with an IP of a host. */
|
||||
+ return network_netmask_match(pamh, tok, string, item);
|
||||
}
|
||||
|
||||
/* string_match - match a string against one token */
|
||||
--
|
||||
2.33.0
|
||||
|
||||
200
backport-pam_access-handle-hostnames-in-access.conf.patch
Normal file
200
backport-pam_access-handle-hostnames-in-access.conf.patch
Normal file
@ -0,0 +1,200 @@
|
||||
From 23393bef92c1e768eda329813d7af55481c6ca9f Mon Sep 17 00:00:00 2001
|
||||
From: Thorsten Kukuk <kukuk@suse.com>
|
||||
Date: Thu, 24 Feb 2022 10:37:32 +0100
|
||||
Subject: [PATCH] pam_access: handle hostnames in access.conf
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/linux-pam/linux-pam/commit/23393bef92c1e768eda329813d7af55481c6ca9f
|
||||
|
||||
According to the manual page, the following entry is valid but does not
|
||||
work:
|
||||
-:root:ALL EXCEPT localhost
|
||||
|
||||
See https://bugzilla.suse.com/show_bug.cgi?id=1019866
|
||||
|
||||
Patched is based on PR#226 from Josef Moellers
|
||||
---
|
||||
modules/pam_access/pam_access.c | 95 ++++++++++++++++++++++++++-------
|
||||
1 file changed, 76 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c
|
||||
index 0d033aa2..3cec542b 100644
|
||||
--- a/modules/pam_access/pam_access.c
|
||||
+++ b/modules/pam_access/pam_access.c
|
||||
@@ -640,7 +640,7 @@ remote_match (pam_handle_t *pamh, char *tok, struct login_info *item)
|
||||
if ((str_len = strlen(string)) > tok_len
|
||||
&& strcasecmp(tok, string + str_len - tok_len) == 0)
|
||||
return YES;
|
||||
- } else if (tok[tok_len - 1] == '.') {
|
||||
+ } else if (tok[tok_len - 1] == '.') { /* internet network numbers (end with ".") */
|
||||
struct addrinfo hint;
|
||||
|
||||
memset (&hint, '\0', sizeof (hint));
|
||||
@@ -681,7 +681,7 @@ remote_match (pam_handle_t *pamh, char *tok, struct login_info *item)
|
||||
return NO;
|
||||
}
|
||||
|
||||
- /* Assume network/netmask with an IP of a host. */
|
||||
+ /* Assume network/netmask, IP address or hostname. */
|
||||
return network_netmask_match(pamh, tok, string, item);
|
||||
}
|
||||
|
||||
@@ -699,7 +699,7 @@ string_match (pam_handle_t *pamh, const char *tok, const char *string,
|
||||
/*
|
||||
* If the token has the magic value "ALL" the match always succeeds.
|
||||
* Otherwise, return YES if the token fully matches the string.
|
||||
- * "NONE" token matches NULL string.
|
||||
+ * "NONE" token matches NULL string.
|
||||
*/
|
||||
|
||||
if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */
|
||||
@@ -717,7 +717,8 @@ string_match (pam_handle_t *pamh, const char *tok, const char *string,
|
||||
|
||||
/* network_netmask_match - match a string against one token
|
||||
* where string is a hostname or ip (v4,v6) address and tok
|
||||
- * represents either a single ip (v4,v6) address or a network/netmask
|
||||
+ * represents either a hostname, a single ip (v4,v6) address
|
||||
+ * or a network/netmask
|
||||
*/
|
||||
static int
|
||||
network_netmask_match (pam_handle_t *pamh,
|
||||
@@ -726,10 +727,12 @@ network_netmask_match (pam_handle_t *pamh,
|
||||
char *netmask_ptr;
|
||||
char netmask_string[MAXHOSTNAMELEN + 1];
|
||||
int addr_type;
|
||||
+ struct addrinfo *ai = NULL;
|
||||
|
||||
if (item->debug)
|
||||
- pam_syslog (pamh, LOG_DEBUG,
|
||||
+ pam_syslog (pamh, LOG_DEBUG,
|
||||
"network_netmask_match: tok=%s, item=%s", tok, string);
|
||||
+
|
||||
/* OK, check if tok is of type addr/mask */
|
||||
if ((netmask_ptr = strchr(tok, '/')) != NULL)
|
||||
{
|
||||
@@ -763,54 +766,108 @@ network_netmask_match (pam_handle_t *pamh,
|
||||
netmask_ptr = number_to_netmask(netmask, addr_type,
|
||||
netmask_string, MAXHOSTNAMELEN);
|
||||
}
|
||||
- }
|
||||
+
|
||||
+ /*
|
||||
+ * Construct an addrinfo list from the IP address.
|
||||
+ * This should not fail as the input is a correct IP address...
|
||||
+ */
|
||||
+ if (getaddrinfo (tok, NULL, NULL, &ai) != 0)
|
||||
+ {
|
||||
+ return NO;
|
||||
+ }
|
||||
+ }
|
||||
else
|
||||
- /* NO, then check if it is only an addr */
|
||||
- if (isipaddr(tok, NULL, NULL) != YES)
|
||||
+ {
|
||||
+ /*
|
||||
+ * It is either an IP address or a hostname.
|
||||
+ * Let getaddrinfo sort everything out
|
||||
+ */
|
||||
+ if (getaddrinfo (tok, NULL, NULL, &ai) != 0)
|
||||
{
|
||||
+ pam_syslog(pamh, LOG_ERR, "cannot resolve hostname \"%s\"", tok);
|
||||
+
|
||||
return NO;
|
||||
}
|
||||
+ netmask_ptr = NULL;
|
||||
+ }
|
||||
|
||||
if (isipaddr(string, NULL, NULL) != YES)
|
||||
{
|
||||
- /* Assume network/netmask with a name of a host. */
|
||||
struct addrinfo hint;
|
||||
|
||||
+ /* Assume network/netmask with a name of a host. */
|
||||
memset (&hint, '\0', sizeof (hint));
|
||||
hint.ai_flags = AI_CANONNAME;
|
||||
hint.ai_family = AF_UNSPEC;
|
||||
|
||||
if (item->gai_rv != 0)
|
||||
+ {
|
||||
+ freeaddrinfo(ai);
|
||||
return NO;
|
||||
+ }
|
||||
else if (!item->res &&
|
||||
(item->gai_rv = getaddrinfo (string, NULL, &hint, &item->res)) != 0)
|
||||
+ {
|
||||
+ freeaddrinfo(ai);
|
||||
return NO;
|
||||
+ }
|
||||
else
|
||||
{
|
||||
struct addrinfo *runp = item->res;
|
||||
+ struct addrinfo *runp1;
|
||||
|
||||
while (runp != NULL)
|
||||
{
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
|
||||
- DIAG_PUSH_IGNORE_CAST_ALIGN;
|
||||
- inet_ntop (runp->ai_family,
|
||||
- runp->ai_family == AF_INET
|
||||
- ? (void *) &((struct sockaddr_in *) runp->ai_addr)->sin_addr
|
||||
- : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr,
|
||||
- buf, sizeof (buf));
|
||||
- DIAG_POP_IGNORE_CAST_ALIGN;
|
||||
+ if (getnameinfo (runp->ai_addr, runp->ai_addrlen, buf, sizeof (buf), NULL, 0, NI_NUMERICHOST) != 0)
|
||||
+ {
|
||||
+ freeaddrinfo(ai);
|
||||
+ return NO;
|
||||
+ }
|
||||
|
||||
- if (are_addresses_equal(buf, tok, netmask_ptr))
|
||||
+ for (runp1 = ai; runp1 != NULL; runp1 = runp1->ai_next)
|
||||
{
|
||||
- return YES;
|
||||
+ char buf1[INET6_ADDRSTRLEN];
|
||||
+
|
||||
+ if (runp->ai_family != runp1->ai_family)
|
||||
+ continue;
|
||||
+
|
||||
+ if (getnameinfo (runp1->ai_addr, runp1->ai_addrlen, buf1, sizeof (buf1), NULL, 0, NI_NUMERICHOST) != 0)
|
||||
+ {
|
||||
+ freeaddrinfo(ai);
|
||||
+ return NO;
|
||||
+ }
|
||||
+
|
||||
+ if (are_addresses_equal (buf, buf1, netmask_ptr))
|
||||
+ {
|
||||
+ freeaddrinfo(ai);
|
||||
+ return YES;
|
||||
+ }
|
||||
}
|
||||
runp = runp->ai_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
- return (are_addresses_equal(string, tok, netmask_ptr));
|
||||
+ {
|
||||
+ struct addrinfo *runp1;
|
||||
+
|
||||
+ for (runp1 = ai; runp1 != NULL; runp1 = runp1->ai_next)
|
||||
+ {
|
||||
+ char buf1[INET6_ADDRSTRLEN];
|
||||
+
|
||||
+ (void) getnameinfo (runp1->ai_addr, runp1->ai_addrlen, buf1, sizeof (buf1), NULL, 0, NI_NUMERICHOST);
|
||||
+
|
||||
+ if (are_addresses_equal(string, buf1, netmask_ptr))
|
||||
+ {
|
||||
+ freeaddrinfo(ai);
|
||||
+ return YES;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ freeaddrinfo(ai);
|
||||
|
||||
return NO;
|
||||
}
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
From 741acf4ff707d53b94947736a01eeeda5e2c7e98 Mon Sep 17 00:00:00 2001
|
||||
From: Thorsten Kukuk <kukuk@suse.com>
|
||||
Date: Fri, 4 Aug 2023 15:46:16 +0200
|
||||
Subject: [PATCH] pam_access: make non-resolveable hostname a debug output
|
||||
(#590)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/linux-pam/linux-pam/commit/741acf4ff707d53b94947736a01eeeda5e2c7e98
|
||||
|
||||
* modules/pam_access/pam_access.c (network_netmask_match): Don't print
|
||||
an error if a string is not resolveable, only a debug message in debug
|
||||
mode. We even don't know if that entry is for remote logins or not.
|
||||
---
|
||||
modules/pam_access/pam_access.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c
|
||||
index f70b7e49..985dc7de 100644
|
||||
--- a/modules/pam_access/pam_access.c
|
||||
+++ b/modules/pam_access/pam_access.c
|
||||
@@ -876,7 +876,8 @@ network_netmask_match (pam_handle_t *pamh,
|
||||
*/
|
||||
if (getaddrinfo (tok, NULL, NULL, &ai) != 0)
|
||||
{
|
||||
- pam_syslog(pamh, LOG_ERR, "cannot resolve hostname \"%s\"", tok);
|
||||
+ if (item->debug)
|
||||
+ pam_syslog(pamh, LOG_DEBUG, "cannot resolve hostname \"%s\"", tok);
|
||||
|
||||
return NO;
|
||||
}
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
From 470823c4aacef5cb3b1180be6ed70846b61a3752 Mon Sep 17 00:00:00 2001
|
||||
From: "Dmitry V. Levin" <ldv@altlinux.org>
|
||||
Date: Thu, 19 Aug 2021 08:00:00 +0000
|
||||
Subject: [PATCH] pam_unix: workaround the problem caused by libnss_systemd
|
||||
|
||||
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
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/linux-pam/linux-pam/commit/470823c4aacef5cb3b1180be6ed70846b61a3752
|
||||
---
|
||||
modules/pam_unix/passverify.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
|
||||
index 5bb518e..eb0fa74 100644
|
||||
--- a/modules/pam_unix/passverify.c
|
||||
+++ b/modules/pam_unix/passverify.c
|
||||
@@ -247,8 +247,7 @@ PAMH_ARG_DECL(int get_account_info,
|
||||
if (*spwdent == NULL) {
|
||||
#ifndef HELPER_COMPILE
|
||||
/* still a chance the user can authenticate */
|
||||
- if (errno == EACCES || SELINUX_ENABLED)
|
||||
- return PAM_UNIX_RUN_HELPER;
|
||||
+ return PAM_UNIX_RUN_HELPER;
|
||||
#endif
|
||||
return PAM_AUTHINFO_UNAVAIL;
|
||||
}
|
||||
--
|
||||
2.46.0
|
||||
@ -0,0 +1,271 @@
|
||||
From b40ca8d7a847d2b089b9562ed3ba94f0f62a2e48 Mon Sep 17 00:00:00 2001
|
||||
From: Charles Lee <lchopn@gmail.com>
|
||||
Date: Mon, 20 Jul 2020 23:29:36 +0200
|
||||
Conflict: NA
|
||||
Reference: https://github.com/linux-pam/linux-pam/commit/b40ca8d7a847d2b089b9562ed3ba94f0f62a2e48
|
||||
Subject: [PATCH 034/221] po: update translations using Weblate (Chinese
|
||||
(Simplified))
|
||||
|
||||
Currently translated at 100.0% (122 of 122 strings).
|
||||
|
||||
Translate-URL: https://translate.fedoraproject.org/projects/linux-pam/master/zh_CN/
|
||||
---
|
||||
po/zh_CN.po | 88 ++++++++++++++++++++++++-----------------------------
|
||||
1 file changed, 39 insertions(+), 49 deletions(-)
|
||||
|
||||
diff --git a/po/zh_CN.po b/po/zh_CN.po
|
||||
index 8836488..c6056f6 100644
|
||||
--- a/po/zh_CN.po
|
||||
+++ b/po/zh_CN.po
|
||||
@@ -41,7 +41,7 @@ msgstr "有错误的转换 (%d)\n"
|
||||
#: libpam/pam_get_authtok.c:39 modules/pam_exec/pam_exec.c:178
|
||||
#: modules/pam_userdb/pam_userdb.c:55
|
||||
msgid "Password: "
|
||||
-msgstr "密码:"
|
||||
+msgstr "密码: "
|
||||
|
||||
#: libpam/pam_get_authtok.c:41
|
||||
#, c-format
|
||||
@@ -55,7 +55,7 @@ msgstr "当前的密码:"
|
||||
#: libpam/pam_get_authtok.c:44
|
||||
#, c-format
|
||||
msgid "New %s password: "
|
||||
-msgstr "新的 %s 密码:"
|
||||
+msgstr "新的 %s 密码: "
|
||||
|
||||
#: libpam/pam_get_authtok.c:45
|
||||
msgid "New password: "
|
||||
@@ -64,11 +64,11 @@ msgstr "新的 密码:"
|
||||
#: libpam/pam_get_authtok.c:47
|
||||
#, c-format
|
||||
msgid "Retype new %s password: "
|
||||
-msgstr "重新输入新的 %s 密码:"
|
||||
+msgstr "重新输入新的 %s 密码: "
|
||||
|
||||
#: libpam/pam_get_authtok.c:48
|
||||
msgid "Retype new password: "
|
||||
-msgstr "重新输入新的 密码:"
|
||||
+msgstr "重新输入新的密码: "
|
||||
|
||||
#: libpam/pam_get_authtok.c:49
|
||||
msgid "Sorry, passwords do not match."
|
||||
@@ -80,9 +80,8 @@ msgid "Retype %s"
|
||||
msgstr "重新输入 %s"
|
||||
|
||||
#: libpam/pam_get_authtok.c:178 libpam/pam_get_authtok.c:258
|
||||
-#, fuzzy
|
||||
msgid "Password change has been aborted."
|
||||
-msgstr "密码更改取消。"
|
||||
+msgstr "密码更改已取消。"
|
||||
|
||||
#: libpam/pam_item.c:311
|
||||
msgid "login:"
|
||||
@@ -150,7 +149,7 @@ msgstr "用户帐户已失效"
|
||||
|
||||
#: libpam/pam_strerror.c:70
|
||||
msgid "Cannot make/remove an entry for the specified session"
|
||||
-msgstr "无法为指定的会话创建/去除项。"
|
||||
+msgstr "无法为指定的会话创建/移除项"
|
||||
|
||||
#: libpam/pam_strerror.c:72
|
||||
msgid "Authentication service cannot retrieve user credentials"
|
||||
@@ -268,15 +267,13 @@ msgstr "以某些形式包含用户名"
|
||||
|
||||
#: modules/pam_cracklib/pam_cracklib.c:684
|
||||
#: modules/pam_unix/pam_unix_passwd.c:563
|
||||
-#, fuzzy
|
||||
msgid "No password has been supplied."
|
||||
-msgstr "密码未提供"
|
||||
+msgstr "未提供密码。"
|
||||
|
||||
#: modules/pam_cracklib/pam_cracklib.c:685
|
||||
#: modules/pam_unix/pam_unix_passwd.c:564
|
||||
-#, fuzzy
|
||||
msgid "The password has not been changed."
|
||||
-msgstr "无法更改 NIS 密码。"
|
||||
+msgstr "密码未被更改。"
|
||||
|
||||
#: modules/pam_cracklib/pam_cracklib.c:706
|
||||
#: modules/pam_cracklib/pam_cracklib.c:788
|
||||
@@ -300,21 +297,21 @@ msgid "%s failed: unknown status 0x%x"
|
||||
msgstr "%s 失败:未知的状态 0x%x"
|
||||
|
||||
#: modules/pam_faillock/main.c:104
|
||||
-#, fuzzy, c-format
|
||||
+#, c-format
|
||||
msgid ""
|
||||
"Usage: %s [--dir /path/to/tally-directory] [--user username] [--reset]\n"
|
||||
-msgstr "%s: [--文件 根文件名] [--用户 用户名] [--重设置[=n]] [--安静]\n"
|
||||
+msgstr "用法:%s [--dir /path/to/tally-directory] [--user username] [--reset]\n"
|
||||
|
||||
#: modules/pam_faillock/pam_faillock.c:645 modules/pam_tally/pam_tally.c:553
|
||||
#: modules/pam_tally2/pam_tally2.c:562
|
||||
-#, fuzzy, c-format
|
||||
+#, c-format
|
||||
msgid "The account is locked due to %u failed logins."
|
||||
-msgstr "因为 %u 失败登录而锁定帐户"
|
||||
+msgstr "由于 %u 次登录失败,此帐户已锁定。"
|
||||
|
||||
#: modules/pam_faillock/pam_faillock.c:650
|
||||
#, c-format
|
||||
msgid "(%d minutes left to unlock)"
|
||||
-msgstr ""
|
||||
+msgstr "(%d 分钟后解锁)"
|
||||
|
||||
#. TRANSLATORS: "strftime options for date of last login"
|
||||
#: modules/pam_lastlog/pam_lastlog.c:318 modules/pam_lastlog/pam_lastlog.c:579
|
||||
@@ -363,14 +360,13 @@ msgid "There were %d failed login attempts since the last successful login."
|
||||
msgstr "最后一次成功登录后有 %d 次失败的登录尝试。"
|
||||
|
||||
#: modules/pam_limits/pam_limits.c:1088
|
||||
-#, fuzzy, c-format
|
||||
+#, c-format
|
||||
msgid "There were too many logins for '%s'."
|
||||
-msgstr "'%s'登录过多。"
|
||||
+msgstr "'%s' 的登录次数过多。"
|
||||
|
||||
#: modules/pam_mail/pam_mail.c:289
|
||||
-#, fuzzy
|
||||
msgid "You have no mail."
|
||||
-msgstr "您有新邮件。"
|
||||
+msgstr "您没有新邮件。"
|
||||
|
||||
#: modules/pam_mail/pam_mail.c:292
|
||||
msgid "You have new mail."
|
||||
@@ -424,9 +420,9 @@ msgid "Password has been already used."
|
||||
msgstr "密码已被使用。"
|
||||
|
||||
#: modules/pam_selinux/pam_selinux.c:172
|
||||
-#, fuzzy, c-format
|
||||
+#, c-format
|
||||
msgid "The default security context is %s."
|
||||
-msgstr "默认安全性环境 %s\n"
|
||||
+msgstr "默认的安全上下文是 %s。"
|
||||
|
||||
#: modules/pam_selinux/pam_selinux.c:176
|
||||
msgid "Would you like to enter a different role or level?"
|
||||
@@ -437,33 +433,32 @@ msgid "role:"
|
||||
msgstr "角色:"
|
||||
|
||||
#: modules/pam_selinux/pam_selinux.c:193
|
||||
-#, fuzzy, c-format
|
||||
+#, c-format
|
||||
msgid "There is no default type for role %s."
|
||||
-msgstr "没有角色 %s 默认类型\n"
|
||||
+msgstr "角色 %s 没有默认类型。"
|
||||
|
||||
#: modules/pam_selinux/pam_selinux.c:225
|
||||
msgid "level:"
|
||||
msgstr "级别:"
|
||||
|
||||
#: modules/pam_selinux/pam_selinux.c:259
|
||||
-#, fuzzy
|
||||
msgid "This is not a valid security context."
|
||||
-msgstr "不是有效的安全性环境"
|
||||
+msgstr "这不是一个有效的安全上下文。"
|
||||
|
||||
#: modules/pam_selinux/pam_selinux.c:509
|
||||
#, c-format
|
||||
msgid "A valid context for %s could not be obtained."
|
||||
-msgstr ""
|
||||
+msgstr "无法取得 %s 的有效上下文。"
|
||||
|
||||
#: modules/pam_selinux/pam_selinux.c:629
|
||||
-#, fuzzy, c-format
|
||||
+#, c-format
|
||||
msgid "Security context %s has been assigned."
|
||||
-msgstr "已指派安全性环境 %s"
|
||||
+msgstr "安全上下文 %s 已指派。"
|
||||
|
||||
#: modules/pam_selinux/pam_selinux.c:645
|
||||
-#, fuzzy, c-format
|
||||
+#, c-format
|
||||
msgid "Key creation context %s has been assigned."
|
||||
-msgstr "已分配密钥生成环境 %s"
|
||||
+msgstr "密钥生成上下文 %s 已分配。"
|
||||
|
||||
#: modules/pam_selinux/pam_selinux_check.c:99
|
||||
#, c-format
|
||||
@@ -481,9 +476,9 @@ msgid "login: failure forking: %m"
|
||||
msgstr "登录:故障派生:%m"
|
||||
|
||||
#: modules/pam_tally/pam_tally.c:528 modules/pam_tally2/pam_tally2.c:580
|
||||
-#, fuzzy, c-format
|
||||
+#, c-format
|
||||
msgid "The account is temporarily locked (%ld seconds left)."
|
||||
-msgstr "帐户暂时锁住(还有 %ld 秒)"
|
||||
+msgstr "帐户暂时锁定(剩余 %ld 秒)。"
|
||||
|
||||
#: modules/pam_tally/pam_tally.c:729 modules/pam_tally2/pam_tally2.c:846
|
||||
msgid "Authentication error"
|
||||
@@ -539,39 +534,36 @@ msgstr ""
|
||||
" [-r] [--reset[=n]] [--quiet]\n"
|
||||
|
||||
#: modules/pam_timestamp/pam_timestamp.c:354
|
||||
-#, fuzzy, c-format
|
||||
+#, c-format
|
||||
msgid "Access has been granted (last access was %ld seconds ago)."
|
||||
-msgstr "可以访问(上次访问是 %ld 秒之前)。"
|
||||
+msgstr "访问已被准许(上次访问是 %ld 秒之前)。"
|
||||
|
||||
#: modules/pam_unix/pam_unix_acct.c:230 modules/pam_unix/pam_unix_acct.c:252
|
||||
-#, fuzzy
|
||||
msgid "Your account has expired; please contact your system administrator."
|
||||
-msgstr "您的帐户已失效;请与系统管理员取得联系"
|
||||
+msgstr "您的帐户已过期;请联系您的系统管理员。"
|
||||
|
||||
#: modules/pam_unix/pam_unix_acct.c:238
|
||||
-#, fuzzy
|
||||
msgid ""
|
||||
"You are required to change your password immediately (administrator "
|
||||
"enforced)."
|
||||
-msgstr "您需要立即更改密码(root 强制)"
|
||||
+msgstr "您必须立即更改密码(管理员强制)。"
|
||||
|
||||
#: modules/pam_unix/pam_unix_acct.c:244
|
||||
-#, fuzzy
|
||||
msgid ""
|
||||
"You are required to change your password immediately (password expired)."
|
||||
-msgstr "您需要立即更改密码(密码过期)"
|
||||
+msgstr "您必须立即更改密码(密码已经过期)。"
|
||||
|
||||
#: modules/pam_unix/pam_unix_acct.c:265 modules/pam_unix/pam_unix_acct.c:272
|
||||
-#, fuzzy, c-format
|
||||
+#, c-format
|
||||
msgid "Warning: your password will expire in %d day."
|
||||
msgid_plural "Warning: your password will expire in %d days."
|
||||
-msgstr[0] "警告:您的密码将在 %d 天后过期"
|
||||
+msgstr[0] "警告:您的密码将在 %d 天后过期。"
|
||||
|
||||
#. TRANSLATORS: only used if dngettext is not supported
|
||||
#: modules/pam_unix/pam_unix_acct.c:277
|
||||
-#, fuzzy, c-format
|
||||
+#, c-format
|
||||
msgid "Warning: your password will expire in %d days."
|
||||
-msgstr "警告:您的密码将在 %d 天后过期"
|
||||
+msgstr "警告:您的密码将在 %d 天后过期。"
|
||||
|
||||
#: modules/pam_unix/pam_unix_passwd.c:465
|
||||
msgid "NIS password could not be changed."
|
||||
@@ -582,9 +574,8 @@ msgid "You must choose a shorter password."
|
||||
msgstr "您必须选择较短的密码。"
|
||||
|
||||
#: modules/pam_unix/pam_unix_passwd.c:585
|
||||
-#, fuzzy
|
||||
msgid "You must choose a longer password."
|
||||
-msgstr "必须选择更长的密码"
|
||||
+msgstr "您必须选择一个更长的密码。"
|
||||
|
||||
#: modules/pam_unix/pam_unix_passwd.c:692
|
||||
#, c-format
|
||||
@@ -592,6 +583,5 @@ msgid "Changing password for %s."
|
||||
msgstr "为 %s 更改 STRESS 密码。"
|
||||
|
||||
#: modules/pam_unix/pam_unix_passwd.c:722
|
||||
-#, fuzzy
|
||||
msgid "You must wait longer to change your password."
|
||||
-msgstr "您必须等待更长时间以更改密码"
|
||||
+msgstr "您必须等待更长时间以更改密码。"
|
||||
--
|
||||
2.27.0
|
||||
|
||||
30
pam.spec
30
pam.spec
@ -4,7 +4,7 @@
|
||||
%define _pamconfdir %{_sysconfdir}/pam.d
|
||||
Name: pam
|
||||
Version: 1.4.0
|
||||
Release: 8
|
||||
Release: 13
|
||||
Summary: Pluggable Authentication Modules for Linux
|
||||
License: BSD and GPLv2+
|
||||
URL: http://www.linux-pam.org/
|
||||
@ -28,12 +28,21 @@ Patch4: pam_faillock-fix-build-on-musl.patch
|
||||
Patch5: pam_modutil_check_user_in_passwd-avoid-timing-attack.patch
|
||||
Patch6: Prevent-SEGFAULT-for-unknown-UID.patch
|
||||
Patch7: change-ndbm-to-gdbm.patch
|
||||
Patch8: backport-CVE-2024-22365-pam_namespace-protect_dir-use-O_DIRECTORY-to-prevent.patch
|
||||
Patch6000: backport-Move-read_passwords-function-from-pam_unix-to-pam_inline.h.patch
|
||||
Patch6001: backport-add-helper-to-handle-SELinux.patch
|
||||
Patch6002: zh_CN_po_fix_str_meaning_error.patch
|
||||
Patch6003: backport-po-update-translations-using-Weblate-Chinese-Simplif.patch
|
||||
Patch6004: backport-pam_access-clean-up-the-remote-host-matching-code.patch
|
||||
Patch6005: backport-pam_access-handle-hostnames-in-access.conf.patch
|
||||
Patch6006: backport-pam_access-make-non-resolveable-hostname-a-debug-out.patch
|
||||
Patch6007: backport-CVE-2024-10963.patch
|
||||
Patch6008: backport-Permit-unix_chkpwd-pam_unix.so-to-run-without-being-setuid-root.patch
|
||||
Patch6009: backport-pam_unix-workaround-the-problem-caused-by-libnss_sys.patch
|
||||
Patch6010: backport-CVE-2024-10041.patch
|
||||
Patch6011: backport-CVE-2024-10041-pam_unix-try-to-set-uid-to-0-for-unix_chkpwd.patch
|
||||
|
||||
Patch9000: 0001-bugfix-cannot-open-database-file.patch
|
||||
Patch9001: add-sm3-crypt-support.patch
|
||||
Patch9000: add-sm3-crypt-support.patch
|
||||
|
||||
BuildRequires: autoconf automake libtool bison flex sed cracklib-devel gdbm-devel
|
||||
BuildRequires: perl-interpreter pkgconfig gettext-devel libtirpc-devel libnsl2-devel
|
||||
@ -186,6 +195,21 @@ fi
|
||||
|
||||
|
||||
%changelog
|
||||
* Tue Dec 17 2024 dongyuzhen <dongyuzhen@h-partners.com> - 1.4.0-13
|
||||
- fix CVE-2024-10041
|
||||
|
||||
* Fri Nov 29 2024 hugel <gengqihu2@h-partners.com> - 1.4.0-12
|
||||
- fix CVE-2024-10963
|
||||
|
||||
* Wed Jan 24 2024 zhangruifang <zhangruifang1@h-partners.com> - 1.4.0-11
|
||||
- fix CVE-2024-22365
|
||||
|
||||
* Thu Mar 09 2023 wangyu <wangyu283@huawei.com> - 1.4.0-10
|
||||
- revert: bugfix with cannot open database file
|
||||
|
||||
* Sat Dec 10 2022 wanglimin<wanglimin@xfusion.com> - 1.4.0-9
|
||||
- update translations for Weblate-Chinese-Simplif
|
||||
|
||||
* Fri Oct 29 2021 houmingyong <houmingyong@huawei.com> - 1.4.0-8
|
||||
- add sm3 crypt support
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user