NationalSecurityAgency/ghidra · error · GeneralSecurityException

Distinguished name option (--dn) required for {}

Error message

Distinguished name option (--dn) required for {}

What it means

Thrown during initializeDataDirectory() (the postgres `init` step) when host authentication is PKI but commonName is null, meaning no `--dn` was parsed or the DN lacked a CN component. PostgreSQL's cert auth maps the certificate's common name to a database role, so BSim needs a DN before initializing.

Source

Thrown at Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/BSimControlLaunchable.java:900

			System.out.println("Remote client authentication via password");
		}
		else {
			System.out.println("No client authentication");
		}
		System.out.println("Initializing data directory");
		List<String> command = new ArrayList<String>();
		command.add(postgresControl.getAbsolutePath());
		command.add("init");
		command.add("-o");
		command.add("'--username=" + connectingUserName + '\'');
		if (hostAuthentication == AUTHENTICATION_PASSWORD) {
			establishAdminPassword();
			command.add("-o");
			command.add("'--pwfile=" + passwordFile.getAbsolutePath() + '\'');
		}
		else if (hostAuthentication == AUTHENTICATION_PKI) {
			if (commonName == null) {
				throw new GeneralSecurityException(
					"Distinguished name option (--dn) required for " + connectingUserName);
			}
			checkCertAuthorityFile();
		}
		command.add("-D");
		command.add(dataDirectory.getAbsolutePath());
		int res = runCommand(null, command, loadLibraryVar, loadLibraryValue);
		if (res != 0) {
			throw new IOException("Error initializing postgres database");
		}
		File configCopy = new File(dataDirectory, POSTGRES_CONFIGFILE + ".orig");

		if (hostAuthentication == AUTHENTICATION_PKI || localAuthentication == AUTHENTICATION_PKI) {
			File rootCA = new File(dataDirectory, POSTGRES_ROOTCA);
			FileUtilities.copyFile(certAuthorityFile, rootCA, false, null);
			addCertificateName(connectingUserName);
		}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Add `--dn "CN=<common name>"` to the command line.
  2. Ensure the DN contains a CN RDN; BSim extracts commonName from the LDAP-format DN.
  3. Confirm the CN matches the user/role name PostgreSQL will map (mymap in pg_ident.conf).
  4. If PKI is not intended, switch to `--auth scram-sha-256`.

Example fix

// before
bsim_ctl start --auth cert --cafile root.crt
// after
bsim_ctl start --auth cert --cafile root.crt --dn "CN=bsim_admin" --cert client.crt
Defensive patterns

Strategy: validation

Validate before calling

if ("cert".equals(authMode) && (dn == null || !dn.contains("CN="))) {
    throw new IllegalArgumentException(
        "--dn \"CN=...\" is required when --auth cert is used for init/start");
}

Type guard

public boolean hasValidCommonName(String dn) {
    if (dn == null) return false;
    try { return new LdapName(dn).getRdns().stream()
            .anyMatch(r -> "CN".equalsIgnoreCase(r.getType())
                        && StringUtils.isNotBlank(r.getValue().toString())); }
    catch (Exception e) { return false; }
}

Try / catch

try {
    bsimControl.start(args);
} catch (GeneralSecurityException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Distinguished name option (--dn) required")) {
        throw new UserFacingException("Add --dn \"CN=<name>\" for PKI auth", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Running `bsim_ctl start` (or changeauth/adduser with init) using `--auth cert` with `--cafile` but no `--dn "CN=..."`. commonName stays null and the init command aborts before `pg_ctl init`.

Common situations: Operator provides the CA but forgets the DN; DN string malformed so commonName extraction failed silently upstream; reusing a command template that predates the --dn requirement.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/184d9d52ddeeae30. Report an issue: GitHub.