{"record":{"id":"b7873e4caca7b9be","repo":"NationalSecurityAgency/ghidra","slug":"distinguished-name-required-dn","errorCode":null,"errorMessage":"Distinguished name required (dn=\"..\")","messagePattern":"Distinguished name required \\(dn=\"\\.\\.\"\\)","errorType":"exception","errorClass":"GeneralSecurityException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/BSimControlLaunchable.java","lineNumber":1144,"sourceCode":"\t\t\ttrue);\n\t\tFileUtilities.copyFile(copyFile, identFile, false, null);\n\t}\n\n\t/**\n\t * Add a new user to the currently running server on the local host.\n\t * A connection is established, using the local interface, and the \"CREATE ROLE\" command\n\t * is executed. If the server is configured to require certificate authentication on\n\t * remote connections, the user must have provided a distinguished name associated with\n\t * the certificate, which is then mapped to the new username. \n\t * @throws GeneralSecurityException if using PKI and no Distinguished Name is found\n\t * @throws Exception if there's a problem initializing the Application of discovering the Postgres installation\n\t */\n\tprivate void addUserCommand() throws GeneralSecurityException, Exception {\n\t\tdiscoverPostgresInstall();\n\t\tinitializeDataDirectory();\t\t\t// Needed to pick up authentication settings\n\t\tif (hostAuthentication == AUTHENTICATION_PKI) {\n\t\t\tif (distinguishedName == null || commonName == null) {\n\t\t\t\tthrow new GeneralSecurityException(\"Distinguished name required (dn=\\\"..\\\")\");\n\t\t\t}\n\t\t}\n\t\tStringBuilder resultMessage = new StringBuilder();\n\t\tresultMessage.append(\"Added user: \");\n\t\tresultMessage.append(specifiedUserName);\n\t\tboolean resetPassword = (hostAuthentication == AUTHENTICATION_PASSWORD);\n\n\t\tadminPasswordData = null;\n\n\t\tlocalConnection = getOrCreateLocalConnection();\n\n\t\tStringBuilder buffer = new StringBuilder();\n\t\tbuffer.append(\"CREATE ROLE \");\n\t\tUtils.escapeIdentifier(buffer, specifiedUserName);\n\t\tbuffer.append(\" WITH LOGIN\");\n\n\t\ttry (Statement st = localConnection.createStatement()) {\n\t\t\tst.executeUpdate(buffer.toString());","sourceCodeStart":1126,"sourceCodeEnd":1162,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/BSimControlLaunchable.java#L1126-L1162","documentation":"Thrown by addUserCommand() when host authentication is PKI but either distinguishedName or commonName is null. Adding a user to a PKI-secured server requires a DN (and its extracted CN) so the certificate identity can be mapped to the new role in pg_ident.conf.","triggerScenarios":"Running `bsim_ctl adduser <name> <priv>` against a server configured with `--auth cert`, without supplying `--dn \"CN=...\"`, or supplying a DN with no CN RDN so commonName extraction failed.","commonSituations":"Forgetting --dn on adduser; malformed DN string; CN component missing from the DN; assuming the DN from server init carries over to the adduser invocation (each invocation parses its own args).","solutions":["Pass `--dn \"CN=<common name>\"` on the adduser command.","Ensure the DN includes a CN RDN that matches the client certificate.","Confirm the CN maps to the new role via the mymap identity map.","If PKI is not in use, verify the server's actual auth mode with `bsim_ctl status`."],"exampleFix":"// before\nbsim_ctl adduser alice admin\n// after\nbsim_ctl adduser --dn \"CN=alice\" alice admin","handlingStrategy":"validation","validationCode":"if (hostAuthIsPki && (dn == null || !dn.contains(\"CN=\"))) {\n    throw new IllegalArgumentException(\n        \"--dn \\\"CN=...\\\" is required when adding a user to a PKI-secured server\");\n}","typeGuard":"public boolean dnReadyForPkiAdduser(String dn) {\n    if (dn == null) return false;\n    try { return new LdapName(dn).getRdns().stream()\n            .anyMatch(r -> \"CN\".equalsIgnoreCase(r.getType())); }\n    catch (Exception e) { return false; }\n}","tryCatchPattern":"try {\n    bsimControl.adduser(args);\n} catch (GeneralSecurityException e) {\n    if (\"Distinguished name required (dn=\\\"..\\\")\".equals(e.getMessage())) {\n        throw new UserFacingException(\"Add --dn \\\"CN=<name>\\\" for PKI adduser\", e);\n    }\n    throw e;\n}","preventionTips":["Each bsim_ctl invocation parses its own args; always pass --dn on PKI adduser.","Validate the DN has a CN before invoking.","Keep the CN aligned with the client certificate and the mymap identity map."],"tags":["pki","authentication","configuration","bsim","cli"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}