The goal of this project is to improve the likelihood that a GSS server application will be able to use the correct entries from a keytab when accepting authentication. Specifically:
- We will stop using the domain_realm map or default realm to determine the realm of host-based GSS acceptor names. Instead, we will allow any keytab entry matching the other constraints of the host-based name, regardless of realm.
- If the host-based acceptor name contains a service name but no hostname, we will allow any keytab entry matching the service name, regardless of its hostname or realm.
- If the host-based acceptor name contains a service name and hostname, and the new profile variable ignore_acceptor_hostname is set, we will disregard the hostname and allow any keytab entry matching the service name.
A GSSAPI server may invoke gss_accept_context with GSS_C_NO_CREDENTIAL, or with a credential acquired with GSS_C_NO_NAME, then we place no restrictions on the keytab entry used to decrypt the sender's ticket; we scan each keytab entry until we find one which can decrypt it. No changes are proposed to this behavior.
If a server calls gss_import_name with the name type GSS_C_NT_HOSTBASED_SERVICE, it supplies a service name and optionally a hostname. When a credential is acquired with this name, the mechglue will invoke krb5_gss_import_name() to create the mechanism name. This function calls krb5_sname_to_principal() to construct the principal, passing NULL for the hostname if none was supplied. krb5_sname_to_principal() does the following:
- If the hostname is NULL, calls gethostname() to get an initial value for the hostname.
- Canonicalizes the hostname using getaddrinfo() and possibly getnameinfo().
- Attempts to map the hostname to a realm using krb5_get_host_realm(). This will consult the profile domain_realm map, and will return the referral (empty) realm if no mapping exists.
- Constructs a principal servicename/canonicalized-hostname@realm.
When acceptor credentials are acquired using the mechanism name, acquire_init_cred() looks up the principal in the host's keytab, and returns an error if it is not found. The keytab lookup code translates from the empty realm to the default realm.
When gss_accept_sec_context() is invoked, krb5_rd_req() looks up the principal in the host's keytab again, and uses it to decrypt the ticket.
Note that the principal resulting from krb5_sname_to_principal() may be used in the initiator code path as either an initiator or target name. If used as an initiator name, it is looked up in the credential cache, or passed to krb5_get_init_creds_password(). If used as a target name, it is passed to krb5_get_credentials() as the server name.
The principal resulting from krb5_sname_to_principal() may also be used by gss_export_name(). RFC 2744 section 5.5 mandates that gss_canonicalize_name and gss_export_name produce the same result as would be produced by using the name as an initiator name, establishing a security context, and exporting the authenticated name on the acceptor. There are no requirements for names used as acceptor names.