Skip to content

Commit

Permalink
[AIRFLOW-2698] Simplify Kerberos code (apache#3563)
Browse files Browse the repository at this point in the history
Some functions were not used. On top of that, the
`principal_from_username` function was getting the wrong config value
("security" instead of "kerberos").

Since the results were only used by `kerberos.checkPassword`, and the
function can cope with needing a realm in the `username` when `realm` is
provided, we removed the `principal_from_username` function altogether.
  • Loading branch information
gglanzani authored and Alice Berard committed Jan 3, 2019
1 parent 21c243a commit aa7ff0a
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 29 deletions.
12 changes: 10 additions & 2 deletions airflow/contrib/auth/backends/kerberos_auth.py
Expand Up @@ -19,6 +19,7 @@

import logging
import flask_login
from airflow.exceptions import AirflowConfigException
from flask_login import current_user
from flask import flash
from wtforms import Form, PasswordField, StringField
Expand Down Expand Up @@ -56,7 +57,13 @@ def authenticate(username, password):
utils.get_fqdn()
)
realm = configuration.conf.get("kerberos", "default_realm")
user_principal = utils.principal_from_username(username)

try:
user_realm = configuration.conf.get("security", "default_realm")
except AirflowConfigException:
user_realm = realm

user_principal = utils.principal_from_username(username, user_realm)

try:
# this is pykerberos specific, verify = True is needed to prevent KDC spoofing
Expand All @@ -66,7 +73,8 @@ def authenticate(username, password):
raise AuthenticationError()
except kerberos.KrbError as e:
logging.error(
'Password validation for principal %s failed %s', user_principal, e)
'Password validation for user '
'%s in realm %s failed %s', user_principal, realm, e)
raise AuthenticationError(e)

return
Expand Down
33 changes: 6 additions & 27 deletions airflow/security/utils.py
Expand Up @@ -22,21 +22,6 @@

from airflow.utils.net import get_hostname

# Pattern to replace with hostname
HOSTNAME_PATTERN = '_HOST'


def get_kerberos_principal(principal, host):
components = get_components(principal)
if not components or len(components) != 3 or components[1] != HOSTNAME_PATTERN:
return principal
else:
if not host:
raise IOError("Can't replace %s pattern "
"since host is null." % HOSTNAME_PATTERN)
return replace_hostname_pattern(components, host)


def get_components(principal):
"""
get_components(principal) -> (short name, instance (FQDN), realm)
Expand All @@ -51,33 +36,27 @@ def get_components(principal):
def replace_hostname_pattern(components, host=None):
fqdn = host
if not fqdn or fqdn == '0.0.0.0':
fqdn = get_localhost_name()
fqdn = get_hostname()
return '%s/%s@%s' % (components[0], fqdn.lower(), components[2])


def get_localhost_name():
return get_hostname()


def get_fqdn(hostname_or_ip=None):
# Get hostname
try:
if hostname_or_ip:
fqdn = socket.gethostbyaddr(hostname_or_ip)[0]
if fqdn == 'localhost':
fqdn = get_hostname()
else:
fqdn = get_localhost_name()
fqdn = get_hostname()
except IOError:
fqdn = hostname_or_ip

if fqdn == 'localhost':
fqdn = get_localhost_name()

return fqdn


def principal_from_username(username):
realm = conf.get("security", "default_realm")
if '@' not in username and realm:
def principal_from_username(username, realm):
if ('@' not in username) and realm:
username = "{}@{}".format(username, realm)

return username

0 comments on commit aa7ff0a

Please sign in to comment.