// Change the component section and save it to disk
  private void setSection(final String section, ODocument sectionDoc) {

    ODocument oldSection = getSection(section);
    try {
      if (configDoc != null) {

        configDoc.field(section, sectionDoc);
        String configFile =
            OSystemVariableResolver.resolveSystemVariables("${ORIENTDB_HOME}/config/security.json");

        // The default "security.json" file can be overridden in the server config file.
        String securityFile = getConfigProperty("server.security.file");
        if (securityFile != null) configFile = securityFile;

        String ssf = OGlobalConfiguration.SERVER_SECURITY_FILE.getValueAsString();
        if (ssf != null) configFile = ssf;

        File f = new File(configFile);
        OIOUtils.writeFile(f, configDoc.toJSON("prettyPrint"));
      }
    } catch (Exception ex) {
      configDoc.field(section, oldSection);
      OLogManager.instance()
          .error(
              this,
              "ODefaultServerSecurity.setSection(%s) Exception: %s",
              section,
              ex.getMessage());
    }
  }
  // Returns a section of the JSON document configuration as an ODocument if section is present.
  private ODocument getSection(final String section) {
    ODocument sectionDoc = null;

    try {
      if (configDoc != null) {
        if (configDoc.containsField(section)) {
          sectionDoc = configDoc.field(section);
        }
      } else {
        OLogManager.instance()
            .error(
                this,
                "ODefaultServerSecurity.getSection(%s) Configuration document is null",
                section);
      }
    } catch (Exception ex) {
      OLogManager.instance()
          .error(
              this,
              "ODefaultServerSecurity.getSection(%s) Exception: %s",
              section,
              ex.getMessage());
    }

    return sectionDoc;
  }
  // OSecuritySystem (via OServerSecurity)
  public String authenticate(final String username, final String password) {
    try {
      // It's possible for the username to be null or an empty string in the case of SPNEGO Kerberos
      // tickets.
      if (username != null && !username.isEmpty()) {
        if (debug)
          OLogManager.instance()
              .info(
                  this,
                  "ODefaultServerSecurity.authenticate() ** Authenticating username: %s",
                  username);

        // This means it originates from us (used by openDatabase).
        if (username.equals(superUser) && password.equals(superUserPassword)) return superUser;
      }

      synchronized (authenticatorsList) {
        // Walk through the list of OSecurityAuthenticators.
        for (OSecurityAuthenticator sa : authenticatorsList) {
          if (sa.isEnabled()) {
            String principal = sa.authenticate(username, password);

            if (principal != null) return principal;
          }
        }
      }
    } catch (Exception ex) {
      OLogManager.instance()
          .error(this, "ODefaultServerSecurity.authenticate() Exception: %s", ex.getMessage());
    }

    return null; // Indicates authentication failed.
  }
  private void reloadImportLDAP() {
    try {
      synchronized (importLDAPSynch) {
        if (importLDAP != null) {
          importLDAP.dispose();
          importLDAP = null;
        }

        if (ldapImportDoc != null && isEnabled(ldapImportDoc)) {
          Class<?> cls = getClass(ldapImportDoc);

          if (cls != null) {
            if (OSecurityComponent.class.isAssignableFrom(cls)) {
              importLDAP = (OSecurityComponent) cls.newInstance();
              importLDAP.config(server, serverConfig, ldapImportDoc);
              importLDAP.active();
            } else {
              OLogManager.instance()
                  .error(
                      this,
                      "ODefaultServerSecurity.reloadImportLDAP() class is not an OSecurityComponent");
            }
          } else {
            OLogManager.instance()
                .error(
                    this,
                    "ODefaultServerSecurity.reloadImportLDAP() ImportLDAP class property is missing");
          }
        }
      }
    } catch (Exception ex) {
      OLogManager.instance()
          .error(this, "ODefaultServerSecurity.reloadImportLDAP() Exception: %s", ex.getMessage());
    }
  }
  private boolean isEnabled(final ODocument sectionDoc) {
    boolean enabled = true;

    try {
      if (sectionDoc.containsField("enabled")) {
        enabled = sectionDoc.field("enabled");
      }
    } catch (Exception ex) {
      OLogManager.instance()
          .error(this, "ODefaultServerSecurity.isEnabled() Exception: %s", ex.getMessage());
    }

    return enabled;
  }
  private void reloadServer() {
    try {
      storePasswords = true;

      if (serverDoc != null) {
        if (serverDoc.containsField("createDefaultUsers")) {
          OGlobalConfiguration.CREATE_DEFAULT_USERS.setValue(serverDoc.field("createDefaultUsers"));
        }

        if (serverDoc.containsField("storePasswords")) {
          storePasswords = serverDoc.field("storePasswords");
        }
      }
    } catch (Exception ex) {
      OLogManager.instance()
          .error(this, "ODefaultServerSecurity.loadServer() Exception: %s", ex.getMessage());
    }
  }
  // "${ORIENTDB_HOME}/config/security.json"
  private ODocument loadConfig(final String cfgPath) {
    ODocument securityDoc = null;

    try {
      if (cfgPath != null) {
        // Default
        String jsonFile = OSystemVariableResolver.resolveSystemVariables(cfgPath);

        File file = new File(jsonFile);

        if (file.exists() && file.canRead()) {
          FileInputStream fis = null;

          try {
            fis = new FileInputStream(file);

            final byte[] buffer = new byte[(int) file.length()];
            fis.read(buffer);

            securityDoc = (ODocument) new ODocument().fromJSON(new String(buffer), "noMap");
          } finally {
            if (fis != null) fis.close();
          }
        } else {
          OLogManager.instance()
              .error(
                  this,
                  "ODefaultServerSecurity.loadConfig() Could not access the security JSON file: %s",
                  jsonFile);
        }
      } else {
        OLogManager.instance()
            .error(this, "ODefaultServerSecurity.loadConfig() Configuration file path is null");
      }
    } catch (Exception ex) {
      OLogManager.instance()
          .error(this, "ODefaultServerSecurity.loadConfig() Exception: %s", ex.getMessage());
    }

    return securityDoc;
  }
  private void loadSecurity() {
    try {
      enabled = false;

      if (configDoc != null) {
        if (configDoc.containsField("enabled")) {
          enabled = configDoc.field("enabled");
        }

        if (configDoc.containsField("debug")) {
          debug = configDoc.field("debug");
        }
      } else {
        OLogManager.instance()
            .error(this, "ODefaultServerSecurity.loadSecurity() jsonConfig is null");
      }
    } catch (Exception ex) {
      OLogManager.instance()
          .error(this, "ODefaultServerSecurity.loadSecurity() Exception: %s", ex.getMessage());
    }
  }
  private void reloadPasswordValidator() {
    try {
      synchronized (passwordValidatorSynch) {
        if (passwordValidator != null) {
          passwordValidator.dispose();
          passwordValidator = null;
        }

        if (passwdValDoc != null && isEnabled(passwdValDoc)) {
          Class<?> cls = getClass(passwdValDoc);

          if (cls != null) {
            if (OPasswordValidator.class.isAssignableFrom(cls)) {
              passwordValidator = (OPasswordValidator) cls.newInstance();
              passwordValidator.config(server, serverConfig, passwdValDoc);
              passwordValidator.active();
            } else {
              OLogManager.instance()
                  .error(
                      this,
                      "ODefaultServerSecurity.reloadPasswordValidator() class is not an OPasswordValidator");
            }
          } else {
            OLogManager.instance()
                .error(
                    this,
                    "ODefaultServerSecurity.reloadPasswordValidator() PasswordValidator class property is missing");
          }
        }
      }
    } catch (Exception ex) {
      OLogManager.instance()
          .error(
              this,
              "ODefaultServerSecurity.reloadPasswordValidator() Exception: %s",
              ex.getMessage());
    }
  }
  private void reloadAuditingService() {
    try {
      synchronized (auditingSynch) {
        if (auditingService != null) {
          auditingService.dispose();
          auditingService = null;
        }

        if (auditingDoc != null && isEnabled(auditingDoc)) {
          Class<?> cls = getClass(auditingDoc);

          if (cls != null) {
            if (OAuditingService.class.isAssignableFrom(cls)) {
              auditingService = (OAuditingService) cls.newInstance();
              auditingService.config(server, serverConfig, auditingDoc);
              auditingService.active();
            } else {
              OLogManager.instance()
                  .error(
                      this,
                      "ODefaultServerSecurity.reloadAuditingService() class is not an OAuditingService");
            }
          } else {
            OLogManager.instance()
                .error(
                    this,
                    "ODefaultServerSecurity.reloadAuditingService() Auditing class property is missing");
          }
        }
      }
    } catch (Exception ex) {
      OLogManager.instance()
          .error(
              this,
              "ODefaultServerSecurity.reloadAuditingService() Exception: %s",
              ex.getMessage());
    }
  }