{"record":{"id":"9c26ea1139909286","repo":"rancher/rancher","slug":"permission-denied","errorCode":null,"errorMessage":"permission denied","messagePattern":"permission denied","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/auth/providers/activedirectory/activedirectory_client.go","lineNumber":170,"sourceCode":"\treturn groupPrincipals, err\n}\n\nfunc (p *adProvider) UsesUserSecrets() bool      { return false }\nfunc (p *adProvider) CanRefreshPrincipals() bool { return true }\n\nfunc (p *adProvider) getPrincipalsFromSearchResult(lConn ldapv3.Client, config *v3.ActiveDirectoryConfig, result *ldapv3.SearchResult) (v3.Principal, []v3.Principal, error) {\n\tvar (\n\t\tgroupPrincipals       []v3.Principal\n\t\tuserPrincipal         v3.Principal\n\t\tnonDupGroupPrincipals []v3.Principal\n\t\tnestedGroupPrincipals []v3.Principal\n\t)\n\n\tgroupMap := make(map[string]bool)\n\tentry := result.Entries[0]\n\n\tif !p.permissionCheck(entry.Attributes, config) {\n\t\treturn v3.Principal{}, nil, fmt.Errorf(\"permission denied\")\n\t}\n\n\tmemberOf := entry.GetAttributeValues(MemberOfAttribute)\n\n\tlogrus.Debugf(\"ADConstants userMemberAttribute() {%v}\", MemberOfAttribute)\n\tlogrus.Debugf(\"SearchResult memberOf attribute {%s}\", memberOf)\n\n\tisType := false\n\tobjectClass := entry.GetAttributeValues(ObjectClass)\n\tfor _, obj := range objectClass {\n\t\tif strings.EqualFold(string(obj), config.UserObjectClass) {\n\t\t\tisType = true\n\t\t}\n\t}\n\tif !isType {\n\t\treturn v3.Principal{}, nil, nil\n\t}\n","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/rancher/rancher/blob/932558d4e68565aff2d2f36e89ec4a391b06e7c5/pkg/auth/providers/activedirectory/activedirectory_client.go#L152-L188","documentation":"Before accepting a login, Rancher runs permissionCheck → ldap.HasPermission: for entries matching UserObjectClass it parses the UserEnabledAttribute (default userAccountControl) as an integer and treats the account as disabled when (value & UserDisabledBitMask) == UserDisabledBitMask (default 2 = AD ACCOUNTDISABLE). A non-integer attribute value also fails the check. So 'permission denied' here means the AD account is disabled, or the enabled-attribute configuration is wrong.","triggerScenarios":"Login or principal fetch for a disabled AD account (userAccountControl has bit 0x2, e.g. 514); or UserEnabledAttribute pointing at a non-numeric attribute; or a wrong UserDisabledBitMask marking healthy accounts disabled.","commonSituations":"Departed/disabled employees or disabled service accounts still attempting login; admins remapping UserEnabledAttribute to a custom attribute (e.g. msDS-UserDontExpirePassword) that is not an integer bitmask.","solutions":["Check the account in AD: userAccountControl 514 (or 66050 etc.) means disabled — re-enable it (512 = enabled) or use another account","If UserEnabledAttribute is customized, make sure it is an integer-valued attribute and the bitmask matches its bit layout","Clearing the attribute name makes HasPermission return true (check skipped) — use only if you have another enforcement point"],"exampleFix":"# before: disabled account\nuserAccountControl: 514\n# after: enabled\nuserAccountControl: 512","handlingStrategy":"try-catch","validationCode":"// Before wiring automation to an AD account, check its enabled flag\n// ldapsearch ... '<userDN>' userAccountControl\n// disabled if value & 0x2","typeGuard":null,"tryCatchPattern":"_, _, err := adProvider.Login(ctx, creds)\nif err != nil && strings.Contains(err.Error(), \"permission denied\") {\n    // account disabled (or enabled-attribute misconfigured):\n    // surface 'account is disabled' and verify userAccountControl / UserEnabledAttribute config\n}","preventionTips":["Exclude disabled accounts from automated login flows","If customizing UserEnabledAttribute, pick an integer-valued attribute and matching bitmask","Remember: non-integer attribute values also fail the check"],"tags":["rancher","go","ldap","active-directory","authorization","account-disabled"],"backgroundTag":null,"analyzedSha":"932558d4e68565aff2d2f36e89ec4a391b06e7c5","analyzedAt":"2026-08-16T04:37:02.125Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}