{"record":{"id":"e89204ae4c875509","repo":"shadow1ng/fscan","slug":"ldap-dial-w","errorCode":null,"errorMessage":"LDAP dial: %w","messagePattern":"LDAP dial: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/local/systeminfo_dc_windows.go","lineNumber":91,"sourceCode":"func (p *SystemInfoPlugin) connectToDomain(domain string) (*domainInfo, error) {\n\tdcHost, err := p.findDC(domain)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tclient, err := gssapi.NewSSPIClient()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"SSPI: %w\", err)\n\t}\n\tdefer func() { _ = client.Close() }()\n\n\tconn, err := ldap.DialURL(ldapURL(dcHost, 389))\n\tif err != nil {\n\t\tif ipv4, resolveErr := resolveIPv4(dcHost); resolveErr == nil {\n\t\t\tconn, err = ldap.DialURL(ldapURL(ipv4, 389))\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"LDAP dial: %w\", err)\n\t\t}\n\t}\n\n\tif err := conn.GSSAPIBind(client, fmt.Sprintf(\"ldap/%s\", dcHost), \"\"); err != nil {\n\t\t_ = conn.Close()\n\t\treturn nil, fmt.Errorf(\"GSSAPI bind: %w\", err)\n\t}\n\n\tbaseDN, err := p.getBaseDN(conn, domain)\n\tif err != nil {\n\t\t_ = conn.Close()\n\t\treturn nil, err\n\t}\n\n\treturn &domainInfo{Domain: domain, BaseDN: baseDN, LDAPConn: conn}, nil\n}\n\nfunc (p *SystemInfoPlugin) findDC(domain string) (string, error) {","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/local/systeminfo_dc_windows.go#L73-L109","documentation":"connectToDomain in the Windows systeminfo plugin fails to open an LDAP connection (port 389) to the domain controller. It first tries ldap.DialURL with the DC hostname, and on failure retries once with the host's resolved IPv4; if both attempts fail, the underlying dial error is wrapped as \"LDAP dial: %w\". This means TCP to port 389 could not be established or the URL/handle was invalid.","triggerScenarios":"ldap.DialURL(ldapURL(dcHost, 389)) fails AND the fallback ldap.DialURL(ldapURL(ipv4, 389)) after resolveIPv4 also fails. Typical underlying causes: connection refused, timeout, DNS failure (also making resolveIPv4 fail), unreachable host, or malformed DC host value.","commonSituations":"Running the scanner from a machine that cannot reach the DC (firewall blocking LDAP 389), wrong or stale dcHost value, DNS not resolving the domain controller, DC offline, or scanning across a VPN/network segment where port 389 is filtered.","solutions":["Verify network reachability: from the scanning host run a TCP connect test to <dcHost>:389 (e.g. Test-NetConnection <dcHost> -Port 389 on Windows).","Confirm DNS resolves dcHost; if not, add the DC's IP to hosts or fix DNS, since the resolveIPv4 fallback also depends on resolution.","Check firewalls/ACLs between scanner and DC allow LDAP (TCP 389).","Verify the DC host value passed into collectDomainInfo is correct and the DC is online (ping -n 1 <domain> is used later in findDC as a sanity check)."],"exampleFix":"// before (host unreachable)\nconn, err := ldap.DialURL(ldapURL(dcHost, 389)) // fails: dial tcp 10.0.0.5:389: connectex: No connection could be made\n// after (verify reachability first in caller or use correct host)\nif !ldapReachable(dcHost, 389) {\n    return nil, fmt.Errorf(\"skipping: DC %s not reachable on 389\", dcHost)\n}\nconn, err := ldap.DialURL(ldapURL(dcHost, 389))","handlingStrategy":"retry","validationCode":"// Pre-check LDAP reachability before invoking the plugin\ntestConn, err := net.DialTimeout(\"tcp\", net.JoinHostPort(dcHost, \"389\"), 5*time.Second)\nif err != nil {\n    return fmt.Errorf(\"DC %s:389 unreachable: %w\", dcHost, err)\n}\ntestConn.Close()","typeGuard":null,"tryCatchPattern":"result := plugin.Scan(ctx, host, session)\nif result != nil && !result.Success {\n    var dnsErr *net.DNSError\n    if errors.As(result.Error, &dnsErr) {\n        // fix DNS or resolve IPv4 manually, then retry once\n    } else if isTimeout(result.Error) {\n        // retry with backoff\n    }\n}","preventionTips":["Run a TCP/389 reachability check (Test-NetConnection) before scanning a DC.","Use DC FQDNs and keep DNS healthy so both hostname and IPv4 fallback can resolve.","Document firewall rules allowing LDAP 389 from scanner subnets."],"tags":["network","ldap","windows","active-directory"],"backgroundTag":"connection-refused","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}