Преглед на файлове

[core] Split auth Pass-through username and password in respective apps

Move from a unique common username of the hue user for LDAP, PAM.. authentications to some default common ones
and by app. Can be overridden in respective apps.

We keep it backward compatible with old syntax but do not document this one anymore.

We can now have Hive using LDAP why Impala is using PAM or standard auth for example.

Old:

[desktop]
  ldap_password
  ldap_password_script
  ldap_username

New:

[desktop]
  auth_password
  auth_password_script
  auth_username

[beeswax]
  auth_password
  auth_password_script
  auth_username

[impala]
  auth_password
  auth_password_script
  auth_username
Romain Rigaux преди 10 години
родител
ревизия
daae285

+ 31 - 1
apps/beeswax/src/beeswax/conf.py

@@ -22,7 +22,8 @@ import beeswax.hive_site
 
 from django.utils.translation import ugettext_lazy as _t, ugettext as _
 
-from desktop.conf import default_ssl_cacerts, default_ssl_validate
+from desktop.conf import default_ssl_cacerts, default_ssl_validate, AUTH_PASSWORD as DEFAULT_AUTH_PASSWORD,\
+  coerce_password_from_script, AUTH_USERNAME as DEFAULT_AUTH_USERNAME
 from desktop.lib.conf import ConfigSection, Config, coerce_bool
 
 from beeswax.settings import NICE_NAME
@@ -141,6 +142,35 @@ SSL = ConfigSection(
   )
 )
 
+def get_auth_username():
+  """Get from top level default from desktop"""
+  return DEFAULT_AUTH_USERNAME.get()
+
+AUTH_USERNAME = Config(
+  key="auth_username",
+  help=_t("Auth username of the hue user used for authentications."),
+  dynamic_default=get_auth_username)
+
+def get_auth_password():
+  password = AUTH_PASSWORD_SCRIPT.get()
+  if not password:
+    password = DEFAULT_AUTH_PASSWORD.get()
+  return password
+
+AUTH_PASSWORD = Config(
+  key="auth_password",
+  help=_t("LDAP/PAM/.. password of the hue user used for authentications."),
+  private=True,
+  dynamic_default=get_auth_password)
+
+AUTH_PASSWORD_SCRIPT = Config(
+  key="auth_password_script",
+  help=_t("Execute this script to produce the auth password. This will be used when `auth_password` is not set."),
+  private=True,
+  type=coerce_password_from_script,
+  default=None)
+
+
 def config_validator(user):
   # dbms is dependent on beeswax.conf (this file)
   # import in method to avoid circular dependency

+ 10 - 4
apps/beeswax/src/beeswax/server/dbms.py

@@ -29,8 +29,8 @@ from desktop.lib.parameterization import substitute_variables
 from filebrowser.views import location_to_url
 
 from beeswax import hive_site
-from beeswax.conf import HIVE_SERVER_HOST, HIVE_SERVER_PORT, BROWSE_PARTITIONED_TABLE_LIMIT, SERVER_CONN_TIMEOUT, \
-                         APPLY_NATURAL_SORT_MAX
+from beeswax.conf import HIVE_SERVER_HOST, HIVE_SERVER_PORT, BROWSE_PARTITIONED_TABLE_LIMIT, SERVER_CONN_TIMEOUT, get_auth_username, get_auth_password, \
+  APPLY_NATURAL_SORT_MAX
 from beeswax.common import apply_natural_sort
 from beeswax.design import hql_query
 from beeswax.hive_site import hiveserver2_use_ssl
@@ -68,7 +68,7 @@ def get(user, query_server=None):
 def get_query_server_config(name='beeswax', server=None):
   if name == 'impala':
     from impala.conf import SERVER_HOST as IMPALA_SERVER_HOST, SERVER_PORT as IMPALA_SERVER_PORT, \
-        IMPALA_PRINCIPAL, IMPERSONATION_ENABLED, QUERYCACHE_ROWS, QUERY_TIMEOUT_S
+        IMPALA_PRINCIPAL, IMPERSONATION_ENABLED, QUERYCACHE_ROWS, QUERY_TIMEOUT_S, get_auth_username as get_impala_auth_username, get_auth_password as get_impala_auth_password
 
     query_server = {
         'server_name': 'impala',
@@ -78,6 +78,8 @@ def get_query_server_config(name='beeswax', server=None):
         'impersonation_enabled': IMPERSONATION_ENABLED.get(),
         'querycache_rows': QUERYCACHE_ROWS.get(),
         'QUERY_TIMEOUT_S': QUERY_TIMEOUT_S.get(),
+        'auth_username': get_impala_auth_username(),
+        'auth_password': get_impala_auth_password()
     }
   else:
     kerberos_principal = hive_site.get_hiveserver2_kerberos_principal(HIVE_SERVER_HOST.get())
@@ -94,9 +96,13 @@ def get_query_server_config(name='beeswax', server=None):
             'end_point': hive_site.hiveserver2_thrift_http_path()
         },
         'transport_mode': 'http' if hive_site.hiveserver2_transport_mode() == 'HTTP' else 'socket',
+        'auth_username': get_auth_username(),
+        'auth_password': get_auth_password()
     }
 
-  LOG.debug("Query Server: %s" % query_server)
+  debug_query_server = query_server.copy()
+  debug_query_server['auth_password_used'] = bool(debug_query_server.pop('auth_password'))
+  LOG.debug("Query Server: %s" % debug_query_server)
 
   return query_server
 

+ 18 - 16
apps/beeswax/src/beeswax/server/hive_server2_lib.py

@@ -26,7 +26,6 @@ from operator import itemgetter
 from django.utils.translation import ugettext as _
 
 from desktop.lib import thrift_util
-from desktop.conf import get_ldap_password, LDAP_USERNAME
 from desktop.conf import DEFAULT_USER
 from hadoop import cluster
 
@@ -413,15 +412,21 @@ class HiveServerTColumnDesc:
 
 
 class HiveServerClient:
-  HS2_MECHANISMS = {'KERBEROS': 'GSSAPI', 'NONE': 'PLAIN', 'NOSASL': 'NOSASL', 'LDAP': 'PLAIN'}
+  HS2_MECHANISMS = {
+      'KERBEROS': 'GSSAPI',
+      'NONE': 'PLAIN',
+      'NOSASL': 'NOSASL',
+      'LDAP': 'PLAIN',
+      'PAM': 'PLAIN'
+  }
 
   def __init__(self, query_server, user):
     self.query_server = query_server
     self.user = user
 
-    use_sasl, mechanism, kerberos_principal_short_name, impersonation_enabled, ldap_username, ldap_password = self.get_security()
-    LOG.info('use_sasl=%s, mechanism=%s, kerberos_principal_short_name=%s, impersonation_enabled=%s' % (
-             use_sasl, mechanism, kerberos_principal_short_name, impersonation_enabled))
+    use_sasl, mechanism, kerberos_principal_short_name, impersonation_enabled, auth_username, auth_password = self.get_security()
+    LOG.info('use_sasl=%s, mechanism=%s, kerberos_principal_short_name=%s, impersonation_enabled=%s, auth_username=%s' % (
+             use_sasl, mechanism, kerberos_principal_short_name, impersonation_enabled, auth_username))
 
     self.use_sasl = use_sasl
     self.kerberos_principal_short_name = kerberos_principal_short_name
@@ -444,9 +449,9 @@ class HiveServerClient:
       validate = beeswax_conf.SSL.VALIDATE.get()
       timeout = beeswax_conf.SERVER_CONN_TIMEOUT.get()
 
-    if ldap_username:
-      username = ldap_username
-      password = ldap_password
+    if auth_username:
+      username = auth_username
+      password = auth_password
     else:
       username = user.username
       password = None
@@ -474,11 +479,8 @@ class HiveServerClient:
   def get_security(self):
     principal = self.query_server['principal']
     impersonation_enabled = False
-    ldap_username = None
-    ldap_password = get_ldap_password()
-
-    if ldap_password is not None: # Pass-through LDAP authentication
-      ldap_username = LDAP_USERNAME.get()
+    auth_username = self.query_server['auth_username'] # Pass-through LDAP/PAM authentication
+    auth_password = self.query_server['auth_password']
 
     if principal:
       kerberos_principal_short_name = principal.split('/', 1)[0]
@@ -486,7 +488,7 @@ class HiveServerClient:
       kerberos_principal_short_name = None
 
     if self.query_server['server_name'] == 'impala':
-      if ldap_password: # Force LDAP auth if ldap_password is provided
+      if auth_password: # Force LDAP/PAM.. auth if auth_password is provided
         use_sasl = True
         mechanism = HiveServerClient.HS2_MECHANISMS['NONE']
       else:
@@ -498,11 +500,11 @@ class HiveServerClient:
       hive_mechanism = hive_site.get_hiveserver2_authentication()
       if hive_mechanism not in HiveServerClient.HS2_MECHANISMS:
         raise Exception(_('%s server authentication not supported. Valid are %s.') % (hive_mechanism, HiveServerClient.HS2_MECHANISMS.keys()))
-      use_sasl = hive_mechanism in ('KERBEROS', 'NONE', 'LDAP')
+      use_sasl = hive_mechanism in ('KERBEROS', 'NONE', 'LDAP', 'PAM')
       mechanism = HiveServerClient.HS2_MECHANISMS[hive_mechanism]
       impersonation_enabled = hive_site.hiveserver2_impersonation_enabled()
 
-    return use_sasl, mechanism, kerberos_principal_short_name, impersonation_enabled, ldap_username, ldap_password
+    return use_sasl, mechanism, kerberos_principal_short_name, impersonation_enabled, auth_username, auth_password
 
 
   def open_session(self, user):

+ 128 - 19
apps/beeswax/src/beeswax/tests.py

@@ -40,7 +40,7 @@ from django.core.urlresolvers import reverse
 from django.db import transaction
 
 from desktop.lib.exceptions_renderable import PopupException
-from desktop.conf import LDAP_USERNAME, LDAP_PASSWORD
+from desktop.conf import AUTH_USERNAME as DEFAULT_AUTH_USERNAME, AUTH_PASSWORD as DEFAULT_AUTH_PASSWORD, LDAP_USERNAME, LDAP_PASSWORD
 from desktop import redaction
 from desktop.redaction import logfilter
 from desktop.redaction.engine import RedactionPolicy, RedactionRule
@@ -60,7 +60,7 @@ import beeswax.views
 
 from beeswax import conf, hive_site
 from beeswax.common import apply_natural_sort
-from beeswax.conf import HIVE_SERVER_HOST
+from beeswax.conf import HIVE_SERVER_HOST, AUTH_USERNAME, AUTH_PASSWORD, AUTH_PASSWORD_SCRIPT
 from beeswax.views import collapse_whitespace, _save_design
 from beeswax.test_base import make_query, wait_for_query_to_finish, verify_history, get_query_server_config,\
   fetch_query_result_data
@@ -2599,39 +2599,34 @@ def test_hiveserver2_get_security():
     default_query_server = {'server_host': 'my_host', 'server_port': 12345}
 
     # Beeswax
-    beeswax_query_server = {'server_name': 'beeswax', 'principal': 'hive'}
+    beeswax_query_server = {'server_name': 'beeswax', 'principal': 'hive', 'auth_username': 'hue', 'auth_password': None}
     beeswax_query_server.update(default_query_server)
-    assert_equal((True, 'PLAIN', 'hive', False, None, None), HiveServerClient(beeswax_query_server, user).get_security())
+    assert_equal((True, 'PLAIN', 'hive', False, 'hue', None), HiveServerClient(beeswax_query_server, user).get_security())
 
     # HiveServer2 LDAP passthrough
-    finish = []
-    finish.append(LDAP_USERNAME.set_for_testing('hueabcd'))
-    finish.append(LDAP_PASSWORD.set_for_testing('abcd'))
-    try:
-      assert_equal((True, 'PLAIN', 'hive', False, 'hueabcd', 'abcd'), HiveServerClient(beeswax_query_server, user).get_security())
-    finally:
-      for f in finish:
-        f()
+    beeswax_query_server.update({'auth_username': 'hueabcd', 'auth_password': 'abcd'})
+    assert_equal((True, 'PLAIN', 'hive', False, 'hueabcd', 'abcd'), HiveServerClient(beeswax_query_server, user).get_security())
+    beeswax_query_server.update({'auth_username': 'hue', 'auth_password': None})
 
     hive_site._HIVE_SITE_DICT[hive_site._CNF_HIVESERVER2_AUTHENTICATION] = 'NOSASL'
     hive_site._HIVE_SITE_DICT[hive_site._CNF_HIVESERVER2_IMPERSONATION] = 'true'
-    assert_equal((False, 'NOSASL', 'hive', True, None, None), HiveServerClient(beeswax_query_server, user).get_security())
+    assert_equal((False, 'NOSASL', 'hive', True, 'hue', None), HiveServerClient(beeswax_query_server, user).get_security())
     hive_site._HIVE_SITE_DICT[hive_site._CNF_HIVESERVER2_AUTHENTICATION] = 'KERBEROS'
-    assert_equal((True, 'GSSAPI', 'hive', True, None, None), HiveServerClient(beeswax_query_server, user).get_security())
+    assert_equal((True, 'GSSAPI', 'hive', True, 'hue', None), HiveServerClient(beeswax_query_server, user).get_security())
 
     # Impala
-    impala_query_server = {'server_name': 'impala', 'principal': 'impala', 'impersonation_enabled': False}
+    impala_query_server = {'server_name': 'impala', 'principal': 'impala', 'impersonation_enabled': False, 'auth_username': 'hue', 'auth_password': None}
     impala_query_server.update(default_query_server)
-    assert_equal((False, 'GSSAPI', 'impala', False, None, None), HiveServerClient(impala_query_server, user).get_security())
+    assert_equal((False, 'GSSAPI', 'impala', False, 'hue', None), HiveServerClient(impala_query_server, user).get_security())
 
-    impala_query_server = {'server_name': 'impala', 'principal': 'impala', 'impersonation_enabled': True}
+    impala_query_server = {'server_name': 'impala', 'principal': 'impala', 'impersonation_enabled': True, 'auth_username': 'hue', 'auth_password': None}
     impala_query_server.update(default_query_server)
-    assert_equal((False, 'GSSAPI', 'impala', True, None, None), HiveServerClient(impala_query_server, user).get_security())
+    assert_equal((False, 'GSSAPI', 'impala', True, 'hue', None), HiveServerClient(impala_query_server, user).get_security())
 
     cluster_conf = hadoop.cluster.get_cluster_conf_for_job_submission()
     finish = cluster_conf.SECURITY_ENABLED.set_for_testing(True)
     try:
-      assert_equal((True, 'GSSAPI', 'impala', True, None, None), HiveServerClient(impala_query_server, user).get_security())
+      assert_equal((True, 'GSSAPI', 'impala', True, 'hue', None), HiveServerClient(impala_query_server, user).get_security())
     finally:
       finish()
   finally:
@@ -2732,6 +2727,120 @@ def test_close_queries_flag():
     finish()
 
 
+def test_auth_pass_through():
+  # Backward compatibility nothing set
+  finish = []
+  finish.append(LDAP_USERNAME.set_for_testing(present=False))
+  finish.append(LDAP_PASSWORD.set_for_testing(present=False))
+
+  finish.append(DEFAULT_AUTH_USERNAME.set_for_testing(present=False))
+  finish.append(DEFAULT_AUTH_PASSWORD.set_for_testing(present=False))
+
+  finish.append(AUTH_USERNAME.set_for_testing(present=False))
+  finish.append(AUTH_PASSWORD.set_for_testing(present=False))
+  try:
+    assert_equal('hue', AUTH_USERNAME.get())
+    assert_equal(None, AUTH_PASSWORD.get())
+  finally:
+    for f in finish:
+      f()
+
+  # Backward compatibility
+  finish = []
+  finish.append(LDAP_USERNAME.set_for_testing('deprecated_default_username'))
+  finish.append(LDAP_PASSWORD.set_for_testing('deprecated_default_password'))
+
+  finish.append(DEFAULT_AUTH_USERNAME.set_for_testing(present=False))
+  finish.append(DEFAULT_AUTH_PASSWORD.set_for_testing(present=False))
+
+  finish.append(AUTH_USERNAME.set_for_testing(present=False))
+  finish.append(AUTH_PASSWORD.set_for_testing(present=False))
+  try:
+    assert_equal('deprecated_default_username', AUTH_USERNAME.get())
+    assert_equal('deprecated_default_password', AUTH_PASSWORD.get())
+  finally:
+    for f in finish:
+      f()
+
+  # Backward compatibility override
+  finish = []
+
+  finish.append(LDAP_USERNAME.set_for_testing('deprecated_default_username'))
+  finish.append(LDAP_PASSWORD.set_for_testing('deprecated_default_password'))
+
+  finish.append(DEFAULT_AUTH_USERNAME.set_for_testing('default_username'))
+  finish.append(DEFAULT_AUTH_PASSWORD.set_for_testing('default_password'))
+  try:
+    assert_equal('default_username', AUTH_USERNAME.get())
+    assert_equal('default_password', AUTH_PASSWORD.get())
+  finally:
+    for f in finish:
+      f()
+
+  # HiveServer2 specific
+  finish = []
+  finish.append(LDAP_USERNAME.set_for_testing('deprecated_default_username'))
+  finish.append(LDAP_PASSWORD.set_for_testing('deprecated_default_password'))
+
+  finish.append(DEFAULT_AUTH_USERNAME.set_for_testing('default_username'))
+  finish.append(DEFAULT_AUTH_PASSWORD.set_for_testing('default_password'))
+
+  finish.append(AUTH_USERNAME.set_for_testing('hive_username'))
+  finish.append(AUTH_PASSWORD.set_for_testing('hive_password'))
+  try:
+    assert_equal('hive_username', AUTH_USERNAME.get())
+    assert_equal('hive_password', AUTH_PASSWORD.get())
+  finally:
+    for f in finish:
+      f()
+
+  # Common
+  finish = []
+  finish.append(LDAP_USERNAME.set_for_testing('deprecated_default_username'))
+  finish.append(LDAP_PASSWORD.set_for_testing('deprecated_default_password'))
+
+  finish.append(DEFAULT_AUTH_USERNAME.set_for_testing('default_username'))
+  finish.append(DEFAULT_AUTH_PASSWORD.set_for_testing('default_password'))
+
+  finish.append(AUTH_USERNAME.set_for_testing(present=False))
+  finish.append(AUTH_PASSWORD.set_for_testing(present=False))
+
+  try:
+    assert_equal('default_username', AUTH_USERNAME.get())
+    assert_equal('default_password', AUTH_PASSWORD.get())
+  finally:
+    for f in finish:
+      f()
+
+  # Password file specific and use common username
+  with tempfile.NamedTemporaryFile(delete=False) as pwd_file:
+    pwd_file.write('''#!/usr/bin/env bash
+
+echo "my_hue_secret"''')
+    pwd_file.flush()
+    pwd_file.close() # Closing as getting "Text file busy" otherwise
+    os.chmod(pwd_file.name, 0770)
+
+    finish = []
+    finish.append(LDAP_USERNAME.set_for_testing('deprecated_default_username'))
+    finish.append(LDAP_PASSWORD.set_for_testing('deprecated_default_password'))
+
+    finish.append(DEFAULT_AUTH_USERNAME.set_for_testing('default_username'))
+    finish.append(DEFAULT_AUTH_PASSWORD.set_for_testing(present=False))
+
+    finish.append(AUTH_USERNAME.set_for_testing(present=False))
+    finish.append(AUTH_PASSWORD.set_for_testing(present=False))
+    finish.append(AUTH_PASSWORD_SCRIPT.set_for_testing(pwd_file.name))
+
+    try:
+      assert_equal('default_username', AUTH_USERNAME.get())
+      assert_equal('my_hue_secret', AUTH_PASSWORD.get())
+    finally:
+      os.remove(pwd_file.name)
+      for f in finish:
+        f()
+
+
 def hive_site_xml(is_local=False, use_sasl=False, thrift_uris='thrift://darkside-1234:9999',
                   warehouse_dir='/abc', kerberos_principal='test/test.com@TEST.COM',
                   hs2_kerberos_principal='hs2test/test.com@TEST.COM',

+ 32 - 1
apps/impala/src/impala/conf.py

@@ -20,7 +20,8 @@ import sys
 import socket
 
 from django.utils.translation import ugettext_lazy as _t, ugettext as _
-from desktop.conf import default_ssl_cacerts, default_ssl_validate
+from desktop.conf import default_ssl_cacerts, default_ssl_validate, AUTH_USERNAME as DEFAULT_AUTH_USERNAME,\
+  AUTH_PASSWORD as DEFAULT_AUTH_PASSWORD, coerce_password_from_script
 from desktop.lib.conf import ConfigSection, Config, coerce_bool
 
 from impala.settings import NICE_NAME
@@ -122,6 +123,36 @@ SSL = ConfigSection(
   )
 )
 
+def get_auth_username():
+  """Get from top level default from desktop"""
+  return DEFAULT_AUTH_USERNAME.get()
+
+AUTH_USERNAME = Config(
+  key="auth_username",
+  help=_t("Auth username of the hue user used for authentications."),
+  private=True,
+  dynamic_default=get_auth_username)
+
+def get_auth_password():
+  password = AUTH_PASSWORD_SCRIPT.get()
+  if not password:
+    password = DEFAULT_AUTH_PASSWORD.get()
+  return password
+
+AUTH_PASSWORD = Config(
+  key="auth_password",
+  help=_t("LDAP/PAM/.. password of the hue user used for authentications."),
+  private=True,
+  dynamic_default=get_auth_password)
+
+AUTH_PASSWORD_SCRIPT = Config(
+  key="auth_password_script",
+  help=_t("Execute this script to produce the auth password. This will be used when `auth_password` is not set."),
+  private=True,
+  type=coerce_password_from_script,
+  default=None)
+
+
 def config_validator(user):
   # dbms is dependent on beeswax.conf (this file)
   # import in method to avoid circular dependency

+ 14 - 4
desktop/conf.dist/hue.ini

@@ -92,10 +92,10 @@
   # Choose whether Hue should validate certificates received from the server.
   ## validate=true
 
-  # LDAP username and password of the hue user used for LDAP authentications.
-  # Set it to use LDAP Authentication with HiveServer2 and Impala.
-  ## ldap_username=hue
-  ## ldap_password=
+  # Default LDAP/PAM/.. username and password of the hue user used for authentications with other services.
+  # e.g. LDAP pass-through authentication for HiveServer2 or Impala. Apps can override them individually.
+  ## auth_username=hue
+  ## auth_password=
 
   # Default encoding for site data
   ## default_site_encoding=utf-8
@@ -906,6 +906,11 @@
     # Choose whether Hue should validate certificates received from the server.
     ## validate=true
 
+  # Override the default desktop username and password of the hue user used for authentications with other services.
+  # e.g. LDAP/PAM pass-through authentication.
+  ## auth_username=hue
+  ## auth_password=
+
 
 ###########################################################################
 # Settings to configure Impala
@@ -950,6 +955,11 @@
     # Choose whether Hue should validate certificates received from the server.
     ## validate=true
 
+  # Override the desktop default username and password of the hue user used for authentications with other services.
+  # e.g. LDAP/PAM pass-through authentication.
+  ## auth_username=hue
+  ## auth_password=
+
 
 ###########################################################################
 # Settings to configure Pig

+ 15 - 4
desktop/conf/pseudo-distributed.ini.tmpl

@@ -98,10 +98,11 @@
   # Choose whether Hue should validate certificates received from the server.
   ## validate=true
 
-  # LDAP username and password of the hue user used for LDAP authentications.
-  # Set it to use LDAP Authentication with HiveServer2 and Impala.
-  ## ldap_username=hue
-  ## ldap_password=
+  # Default LDAP/PAM/.. username and password of the hue user used for authentications with other services.
+  # # Inactive if password is empty.
+  # e.g. Used for LDAP pass-through authentication for HiveServer2 or Impala. Apps can override them individually.
+  ## auth_username=hue
+  ## auth_password=
 
   # Default encoding for site data
   ## default_site_encoding=utf-8
@@ -916,6 +917,11 @@
     # Choose whether Hue should validate certificates received from the server.
     ## validate=true
 
+  # Override the default desktop username and password of the hue user used for authentications with other services.
+  # e.g. Used for LDAP/PAM pass-through authentication.
+  ## auth_username=hue
+  ## auth_password=
+
 
 ###########################################################################
 # Settings to configure Impala
@@ -960,6 +966,11 @@
     # Choose whether Hue should validate certificates received from the server.
     ## validate=true
 
+  # Override the desktop default username and password of the hue user used for authentications with other services.
+  # e.g. Used for LDAP/PAM pass-through authentication.
+  ## auth_username=hue
+  ## auth_password=
+
 
 ###########################################################################
 # Settings to configure Pig

+ 37 - 8
desktop/core/src/desktop/conf.py

@@ -158,12 +158,14 @@ SSL_VALIDATE = Config(
   type=coerce_bool,
   default=True)
 
+# Deprecated by AUTH_PASSWORD
 LDAP_PASSWORD = Config(
   key="ldap_password",
   help=_("LDAP password of the hue user used for LDAP authentications. For example for LDAP Authentication with HiveServer2/Impala."),
   private=True,
   default=None)
 
+# Deprecated by AUTH_PASSWORD_SCRIPT
 LDAP_PASSWORD_SCRIPT = Config(
   key="ldap_password_script",
   help=_("Execute this script to produce the LDAP password. This will be used when `ldap_password` is not set."),
@@ -171,12 +173,47 @@ LDAP_PASSWORD_SCRIPT = Config(
   type=coerce_password_from_script,
   default=None)
 
+# Deprecated by by AUTH_USERNAME
 LDAP_USERNAME = Config(
   key="ldap_username",
   help=_("LDAP username of the hue user used for LDAP authentications. For example for LDAP Authentication with HiveServer2/Impala."),
   private=True,
   default="hue")
 
+def get_auth_username():
+  """Backward compatibility"""
+  return LDAP_USERNAME.get()
+
+AUTH_USERNAME = Config(
+  key="auth_username",
+  help=_("Auth username of the hue user used for authentications. For example for LDAP Authentication with HiveServer2/Impala."),
+  dynamic_default=get_auth_username)
+
+def get_auth_password():
+  """Get from script or backward compatibility"""
+  password = AUTH_PASSWORD_SCRIPT.get()
+  if password:
+    return password
+
+  password = LDAP_PASSWORD.get() # 2 levels for backward compatibility
+  if password:
+    return password
+
+  return LDAP_PASSWORD_SCRIPT.get()
+
+AUTH_PASSWORD = Config(
+  key="auth_password",
+  help=_("LDAP/PAM/.. password of the hue user used for authentications. Inactive if empty. For example for LDAP Authentication with HiveServer2/Impala."),
+  private=True,
+  dynamic_default=get_auth_password)
+
+AUTH_PASSWORD_SCRIPT = Config(
+  key="auth_password_script",
+  help=_("Execute this script to produce the auth password. This will be used when `auth_password` is not set."),
+  private=True,
+  type=coerce_password_from_script,
+  default=None)
+
 ENABLE_SERVER = Config(
   key="enable_server",
   help=_("If set to false, runcpserver will not actually start the web server.  Used if Apache is being used as a WSGI container."),
@@ -1164,14 +1201,6 @@ def get_smtp_password():
   return password
 
 
-def get_ldap_password():
-  password = LDAP_PASSWORD.get()
-  if not password:
-    password = LDAP_PASSWORD_SCRIPT.get()
-
-  return password
-
-
 def get_ldap_bind_password(ldap_config):
   password = ldap_config.BIND_PASSWORD.get()
   if not password:

+ 5 - 4
desktop/core/src/desktop/tests.py

@@ -715,7 +715,7 @@ class BaseTestPasswordConfig(object):
     ]
 
     try:
-      assert_equal(self.get_password(), ' password from script ', 'kwargs: %s' % kwargs)
+      assert_equal(self.get_password(), ' password from script ', 'pwd: %s, kwargs: %s' % (self.get_password(), kwargs))
     finally:
       for reset in resets:
         reset()
@@ -785,13 +785,14 @@ class TestDatabasePasswordConfig(BaseTestPasswordConfig):
 class TestLDAPPasswordConfig(BaseTestPasswordConfig):
 
   def get_config_password(self):
-    return desktop.conf.LDAP_PASSWORD
+    return desktop.conf.AUTH_PASSWORD
 
   def get_config_password_script(self):
-    return desktop.conf.LDAP_PASSWORD_SCRIPT
+    return desktop.conf.AUTH_PASSWORD_SCRIPT
 
   def get_password(self):
-    return desktop.conf.get_ldap_password()
+    # We are using dynamic_default now, so we need to cheat for the tests as only using set_for_testing(present=False) will trigger it.
+    return desktop.conf.AUTH_PASSWORD.get() if desktop.conf.AUTH_PASSWORD.get() else self.get_config_password_script().get()
 
 
 class TestLDAPBindPasswordConfig(BaseTestPasswordConfig):