{"record":{"id":"184d9d52ddeeae30","repo":"NationalSecurityAgency/ghidra","slug":"distinguished-name-option-dn-required-for","errorCode":null,"errorMessage":"Distinguished name option (--dn) required for {}","messagePattern":"Distinguished name option \\(--dn\\) required for (.+?)","errorType":"exception","errorClass":"GeneralSecurityException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/BSimControlLaunchable.java","lineNumber":900,"sourceCode":"\t\t\tSystem.out.println(\"Remote client authentication via password\");\n\t\t}\n\t\telse {\n\t\t\tSystem.out.println(\"No client authentication\");\n\t\t}\n\t\tSystem.out.println(\"Initializing data directory\");\n\t\tList<String> command = new ArrayList<String>();\n\t\tcommand.add(postgresControl.getAbsolutePath());\n\t\tcommand.add(\"init\");\n\t\tcommand.add(\"-o\");\n\t\tcommand.add(\"'--username=\" + connectingUserName + '\\'');\n\t\tif (hostAuthentication == AUTHENTICATION_PASSWORD) {\n\t\t\testablishAdminPassword();\n\t\t\tcommand.add(\"-o\");\n\t\t\tcommand.add(\"'--pwfile=\" + passwordFile.getAbsolutePath() + '\\'');\n\t\t}\n\t\telse if (hostAuthentication == AUTHENTICATION_PKI) {\n\t\t\tif (commonName == null) {\n\t\t\t\tthrow new GeneralSecurityException(\n\t\t\t\t\t\"Distinguished name option (--dn) required for \" + connectingUserName);\n\t\t\t}\n\t\t\tcheckCertAuthorityFile();\n\t\t}\n\t\tcommand.add(\"-D\");\n\t\tcommand.add(dataDirectory.getAbsolutePath());\n\t\tint res = runCommand(null, command, loadLibraryVar, loadLibraryValue);\n\t\tif (res != 0) {\n\t\t\tthrow new IOException(\"Error initializing postgres database\");\n\t\t}\n\t\tFile configCopy = new File(dataDirectory, POSTGRES_CONFIGFILE + \".orig\");\n\n\t\tif (hostAuthentication == AUTHENTICATION_PKI || localAuthentication == AUTHENTICATION_PKI) {\n\t\t\tFile rootCA = new File(dataDirectory, POSTGRES_ROOTCA);\n\t\t\tFileUtilities.copyFile(certAuthorityFile, rootCA, false, null);\n\t\t\taddCertificateName(connectingUserName);\n\t\t}\n","sourceCodeStart":882,"sourceCodeEnd":918,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/BSimControlLaunchable.java#L882-L918","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","solutions":["Add `--dn \"CN=<common name>\"` to the command line.","Ensure the DN contains a CN RDN; BSim extracts commonName from the LDAP-format DN.","Confirm the CN matches the user/role name PostgreSQL will map (mymap in pg_ident.conf).","If PKI is not intended, switch to `--auth scram-sha-256`."],"exampleFix":"// before\nbsim_ctl start --auth cert --cafile root.crt\n// after\nbsim_ctl start --auth cert --cafile root.crt --dn \"CN=bsim_admin\" --cert client.crt","handlingStrategy":"validation","validationCode":"if (\"cert\".equals(authMode) && (dn == null || !dn.contains(\"CN=\"))) {\n    throw new IllegalArgumentException(\n        \"--dn \\\"CN=...\\\" is required when --auth cert is used for init/start\");\n}","typeGuard":"public boolean hasValidCommonName(String dn) {\n    if (dn == null) return false;\n    try { return new LdapName(dn).getRdns().stream()\n            .anyMatch(r -> \"CN\".equalsIgnoreCase(r.getType())\n                        && StringUtils.isNotBlank(r.getValue().toString())); }\n    catch (Exception e) { return false; }\n}","tryCatchPattern":"try {\n    bsimControl.start(args);\n} catch (GeneralSecurityException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Distinguished name option (--dn) required\")) {\n        throw new UserFacingException(\"Add --dn \\\"CN=<name>\\\" for PKI auth\", e);\n    }\n    throw e;\n}","preventionTips":["Always pair --auth cert with a --dn containing a CN.","Pre-parse the DN with javax.naming.ldap.LdapName to catch malformed strings early.","Keep the CN consistent with the role name for the mymap identity map."],"tags":["pki","authentication","configuration","bsim","cli","postgresql"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}