def setup_ldap()

in ambari-server/src/main/python/ambari_server/setupSecurity.py [0:0]


def setup_ldap(options):
  logger.info("Setup LDAP.")

  properties = get_ambari_properties()

  server_status, pid = is_server_runing()
  if not server_status:
    err = "Ambari Server is not running."
    raise FatalException(1, err)

  enforce_ldap = (
    options.ldap_force_setup if options.ldap_force_setup is not None else False
  )
  if not enforce_ldap:
    current_client_security = get_value_from_properties(
      properties, CLIENT_SECURITY, NO_AUTH_METHOD_CONFIGURED
    )
    if current_client_security != "ldap":
      query = (
        "Currently '{0}' is configured, do you wish to use LDAP instead [y/n] ({1})? "
      )
      ldap_setup_default = (
        "y" if current_client_security == NO_AUTH_METHOD_CONFIGURED else "n"
      )
      if get_YN_input(
        query.format(current_client_security, ldap_setup_default),
        ldap_setup_default == "y",
      ):
        pass
      else:
        err = (
          "Currently '" + current_client_security + "' configured. Can not setup LDAP."
        )
        raise FatalException(1, err)

  admin_login, admin_password = get_ambari_admin_username_password_pair(options)
  ldap_properties = get_ldap_properties_from_db(properties, admin_login, admin_password)
  if ldap_properties:
    properties.update(ldap_properties)
  sys.stdout.write("\n")

  isSecure = get_is_secure(properties)

  if options.ldap_url:
    options.ldap_primary_host = options.ldap_url.split(":")[0]
    options.ldap_primary_port = options.ldap_url.split(":")[1]

  if options.ldap_secondary_url:
    options.ldap_secondary_host = options.ldap_secondary_url.split(":")[0]
    options.ldap_secondary_port = options.ldap_secondary_url.split(":")[1]

  ldap_property_list_reqd = init_ldap_properties_list_reqd(properties, options)
  ldap_bind_dn_template = LdapPropTemplate(
    properties,
    options.ldap_manager_dn,
    LDAP_MGR_USERNAME_PROPERTY,
    "Bind DN{0}: ",
    REGEX_ANYTHING,
    False,
    LdapDefaultMap(
      {
        LDAP_AD: "cn=ldapbind,dc=ambari,dc=apache,dc=org",
        LDAP_IPA: "uid=ldapbind,cn=users,cn=accounts,dc=ambari,dc=apache,dc=org",
        LDAP_GENERIC: "uid=ldapbind,cn=users,dc=ambari,dc=apache,dc=org",
      }
    ),
  )
  ldap_type = (
    query_ldap_type(options.ldap_type)
    if options.ldap_type or should_query_ldap_type(ldap_property_list_reqd)
    else LDAP_GENERIC
  )
  ldap_property_list_opt = [
    LDAP_MGR_USERNAME_PROPERTY,
    LDAP_MGR_PASSWORD_PROPERTY,
    LDAP_DISABLE_ENDPOINT_IDENTIFICATION,
    SSL_TRUSTSTORE_TYPE_PROPERTY,
    SSL_TRUSTSTORE_PATH_PROPERTY,
    SSL_TRUSTSTORE_PASSWORD_PROPERTY,
    LDAP_MANAGE_SERVICES,
    LDAP_ENABLED_SERVICES,
  ]

  ldap_property_list_passwords = [
    LDAP_MGR_PASSWORD_PROPERTY,
    SSL_TRUSTSTORE_PASSWORD_PROPERTY,
  ]

  ssl_truststore_type_default = get_value_from_properties(
    properties, SSL_TRUSTSTORE_TYPE_PROPERTY, "jks"
  )
  ssl_truststore_path_default = get_value_from_properties(
    properties, SSL_TRUSTSTORE_PATH_PROPERTY
  )
  disable_endpoint_identification_default = get_value_from_properties(
    properties, LDAP_DISABLE_ENDPOINT_IDENTIFICATION, "False"
  )

  ldap_property_value_map = {}
  ldap_property_values_in_ambari_properties = {}
  interactive_mode = is_interactive(ldap_property_list_reqd)
  for ldap_prop in ldap_property_list_reqd:
    input = ldap_prop.get_input(ldap_type, interactive_mode)

    if input is not None and input != "":
      ldap_property_value_map[ldap_prop.prop_name] = input

    if ldap_prop.prop_name == LDAP_ANONYMOUS_BIND:
      anonymous = input and input.lower() == "true"
      mgr_password = None
      # Ask for manager credentials only if bindAnonymously is false
      if not anonymous:
        username = ldap_bind_dn_template.get_input(ldap_type, interactive_mode)
        ldap_property_value_map[LDAP_MGR_USERNAME_PROPERTY] = username
        mgr_password = configure_ldap_password(
          options.ldap_manager_password, interactive_mode
        )
        ldap_property_value_map[LDAP_MGR_PASSWORD_PROPERTY] = mgr_password
    elif ldap_prop.prop_name == LDAP_USE_SSL:
      ldaps = input and input.lower() == "true"
      ts_password = None

      if ldaps:
        disable_endpoint_identification = (
          get_validated_string_input(
            f"Disable endpoint identification during SSL handshake [true/false] ({disable_endpoint_identification_default}): ",
            disable_endpoint_identification_default,
            REGEX_TRUE_FALSE,
            "Invalid characters in the input!",
            False,
            allowEmpty=True,
            answer=options.ldap_sync_disable_endpoint_identification,
          )
          if interactive_mode
          else options.ldap_sync_disable_endpoint_identification
        )
        if disable_endpoint_identification is not None:
          ldap_property_value_map[LDAP_DISABLE_ENDPOINT_IDENTIFICATION] = (
            disable_endpoint_identification
          )

        truststore_default = "n"
        truststore_set = bool(ssl_truststore_path_default)
        if truststore_set:
          truststore_default = "y"
        custom_trust_store = (
          True
          if options.trust_store_path is not None and options.trust_store_path
          else False
        )
        if not custom_trust_store:
          custom_trust_store = (
            get_YN_input(
              "Do you want to provide custom TrustStore for Ambari [y/n] ({0})?".format(
                truststore_default
              ),
              truststore_set,
            )
            if interactive_mode
            else None
          )
        if custom_trust_store:
          ts_type = (
            get_validated_string_input(
              f"TrustStore type [jks/jceks/pkcs12] {get_prompt_default(ssl_truststore_type_default)}:",
              ssl_truststore_type_default,
              "^(jks|jceks|pkcs12)?$",
              "Wrong type",
              False,
              answer=options.trust_store_type,
            )
            if interactive_mode
            else options.trust_store_type
          )
          ts_path = None
          while True:
            ts_path = (
              get_validated_string_input(
                format_prop_val_prompt(
                  "Path to TrustStore file{0}: ", ssl_truststore_path_default
                ),
                ssl_truststore_path_default,
                ".*",
                False,
                False,
                answer=options.trust_store_path,
              )
              if interactive_mode
              else options.trust_store_path
            )
            if os.path.exists(ts_path):
              break
            else:
              print("File not found.")
              hasAnswer = (
                options.trust_store_path is not None and options.trust_store_path
              )
              quit_if_has_answer(hasAnswer)

          ts_password = (
            read_password(
              "",
              ".*",
              "Password for TrustStore:",
              "Invalid characters in password",
              options.trust_store_password,
            )
            if interactive_mode
            else options.trust_store_password
          )

          ldap_property_values_in_ambari_properties[SSL_TRUSTSTORE_TYPE_PROPERTY] = (
            ts_type
          )
          ldap_property_values_in_ambari_properties[SSL_TRUSTSTORE_PATH_PROPERTY] = (
            ts_path
          )
          ldap_property_values_in_ambari_properties[
            SSL_TRUSTSTORE_PASSWORD_PROPERTY
          ] = ts_password
          pass
        elif properties.get_property(SSL_TRUSTSTORE_TYPE_PROPERTY):
          print("The TrustStore is already configured: ")
          print(
            "  "
            + SSL_TRUSTSTORE_TYPE_PROPERTY
            + " = "
            + properties.get_property(SSL_TRUSTSTORE_TYPE_PROPERTY)
          )
          print(
            "  "
            + SSL_TRUSTSTORE_PATH_PROPERTY
            + " = "
            + properties.get_property(SSL_TRUSTSTORE_PATH_PROPERTY)
          )
          print(
            "  "
            + SSL_TRUSTSTORE_PASSWORD_PROPERTY
            + " = "
            + properties.get_property(SSL_TRUSTSTORE_PASSWORD_PROPERTY)
          )
          if get_YN_input(
            "Do you want to remove these properties [y/n] (y)? ",
            True,
            options.trust_store_reconfigure,
          ):
            properties.removeOldProp(SSL_TRUSTSTORE_TYPE_PROPERTY)
            properties.removeOldProp(SSL_TRUSTSTORE_PATH_PROPERTY)
            properties.removeOldProp(SSL_TRUSTSTORE_PASSWORD_PROPERTY)
        pass
      pass

  populate_ambari_requires_ldap(options, ldap_property_value_map)
  populate_service_management(
    options, ldap_property_value_map, properties, admin_login, admin_password
  )

  print("=" * 20)
  print("Review Settings")
  print("=" * 20)
  for property in ldap_property_list_reqd:
    if property.prop_name in ldap_property_value_map:
      print(
        f"{property.get_prompt_text(ldap_type)} {ldap_property_value_map[property.prop_name]}"
      )

  for property in ldap_property_list_opt:
    if property in ldap_property_value_map:
      if property not in ldap_property_list_passwords:
        print(f"{property}: {ldap_property_value_map[property]}")
      else:
        print(f"{property}: {BLIND_PASSWORD}")

  for property in ldap_property_list_opt:
    if property in ldap_property_values_in_ambari_properties:
      if property not in ldap_property_list_passwords:
        print(f"{property}: {ldap_property_values_in_ambari_properties[property]}")
      else:
        print(f"{property}: {BLIND_PASSWORD}")

  save_settings = (
    True
    if options.ldap_save_settings is not None
    else get_YN_input("Save settings [y/n] (y)? ", True)
  )

  if save_settings:
    if isSecure:
      if ts_password:
        encrypted_passwd = encrypt_password(
          SSL_TRUSTSTORE_PASSWORD_ALIAS, ts_password, options
        )
        if ts_password != encrypted_passwd:
          ldap_property_values_in_ambari_properties[
            SSL_TRUSTSTORE_PASSWORD_PROPERTY
          ] = encrypted_passwd

    print("Saving LDAP properties...")

    # Saving LDAP configuration in Ambari DB using the REST API
    update_ldap_configuration(
      admin_login, admin_password, properties, ldap_property_value_map
    )

    # The only properties we want to write out in Ambari.properties are the client.security type being LDAP and the custom Truststore related properties (if any)
    ldap_property_values_in_ambari_properties[CLIENT_SECURITY] = "ldap"
    update_properties_2(properties, ldap_property_values_in_ambari_properties)

    print("Saving LDAP properties finished")

  return 0