]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
login: use original FQDN for PAM_RHOST
authorKarel Zak <kzak@redhat.com>
Thu, 19 Feb 2026 11:20:28 +0000 (12:20 +0100)
committerKarel Zak <kzak@redhat.com>
Thu, 19 Feb 2026 11:20:28 +0000 (12:20 +0100)
When login -h <remotehost> is invoked, init_remote_info() strips the
local domain suffix from the hostname (FQDN to short name) before
storing it in cxt->hostname. This truncated value is then used for
PAM_RHOST, which can bypass pam_access host deny rules that match on
the FQDN.

Preserve the original -h hostname in a new cmd_hostname field and use
it for PAM_RHOST, while keeping the truncated hostname for utmp/wtmp
and logging unchanged.

Note, the real-world impact is low -- login -h is only used by legacy
telnet/rlogin daemons, and exploitation requires FQDN-specific
pam_access rules on a system still using these obsolete services.

Reported-by: Asim Viladi Oglu Manizada <manizada@pm.me>
Signed-off-by: Karel Zak <kzak@redhat.com>
login-utils/login.c

index 74c42f422ee475ee9b12799f13ab09a03a34863a..0990d5e8ff1ce55a54c0f7ba4f48454ecf086fb3 100644 (file)
@@ -130,6 +130,7 @@ struct login_context {
        char            *thishost;              /* this machine */
        char            *thisdomain;            /* this machine's domain */
        char            *hostname;              /* remote machine */
+       char            *cmd_hostname;          /* remote machine as specified on command line */
        char            hostaddress[16];        /* remote address */
 
        pid_t           pid;
@@ -912,7 +913,7 @@ static pam_handle_t *init_loginpam(struct login_context *cxt)
 
        /* hostname & tty are either set to NULL or their correct values,
         * depending on how much we know. */
-       rc = pam_set_item(pamh, PAM_RHOST, cxt->hostname);
+       rc = pam_set_item(pamh, PAM_RHOST, cxt->cmd_hostname);
        if (is_pam_failure(rc))
                loginpam_err(pamh, rc);
 
@@ -1250,6 +1251,8 @@ static void init_remote_info(struct login_context *cxt, char *remotehost)
 
        get_thishost(cxt, &domain);
 
+       cxt->cmd_hostname = xstrdup(remotehost);
+
        if (domain && (p = strchr(remotehost, '.')) &&
            strcasecmp(p + 1, domain) == 0)
                *p = '\0';