{"action":"opened","issue":{"url":"https://api.github.com/repos/ngoduykhanh/PowerDNS-Admin/issues/344","repository_url":"https://api.github.com/repos/ngoduykhanh/PowerDNS-Admin","labels_url":"https://api.github.com/repos/ngoduykhanh/PowerDNS-Admin/issues/344/labels{/name}","comments_url":"https://api.github.com/repos/ngoduykhanh/PowerDNS-Admin/issues/344/comments","events_url":"https://api.github.com/repos/ngoduykhanh/PowerDNS-Admin/issues/344/events","html_url":"https://github.com/ngoduykhanh/PowerDNS-Admin/issues/344","id":355511330,"node_id":"MDU6SXNzdWUzNTU1MTEzMzA=","number":344,"title":"Authentication to AD gives bad filter error - Bug in the code(?)","user":{"login":"ptselios-inmarsat","id":39766556,"node_id":"MDQ6VXNlcjM5NzY2NTU2","avatar_url":"https://avatars1.githubusercontent.com/u/39766556?v=4","gravatar_id":"","url":"https://api.github.com/users/ptselios-inmarsat","html_url":"https://github.com/ptselios-inmarsat","followers_url":"https://api.github.com/users/ptselios-inmarsat/followers","following_url":"https://api.github.com/users/ptselios-inmarsat/following{/other_user}","gists_url":"https://api.github.com/users/ptselios-inmarsat/gists{/gist_id}","starred_url":"https://api.github.com/users/ptselios-inmarsat/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ptselios-inmarsat/subscriptions","organizations_url":"https://api.github.com/users/ptselios-inmarsat/orgs","repos_url":"https://api.github.com/users/ptselios-inmarsat/repos","events_url":"https://api.github.com/users/ptselios-inmarsat/events{/privacy}","received_events_url":"https://api.github.com/users/ptselios-inmarsat/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-08-30T09:55:32Z","updated_at":"2018-08-30T09:55:32Z","closed_at":null,"author_association":"NONE","body":"Hello, \r\nI need to authenticate my users against the AD of the company. We have created a specific AD Group for them. \r\nThe configuration I have is: \r\n```\r\nLDAP_ENABLED = True\r\n# with LDAP_BIND_TYPE you can specify 'direct' or 'search' to use user credentials\r\n# for binding or a predefined LDAP_USERNAME and LDAP_PASSWORD, binding with non-DN only works with AD\r\nLDAP_BIND_TYPE= 'direct' # direct or search\r\nLDAP_GROUP_SECURITY = False\r\nLDAP_TYPE = 'ad'\r\nLDAP_URI = 'ldaps://ldaps.domain.local:636'\r\nLDAP_SEARCH_BASE = 'dc=domain,dc=local'\r\n## You may prefer 'userPrincipalName' instead\r\nLDAP_USERNAMEFIELD = 'sAMAccountName'\r\n## AD Group that you would like to have accesss to web app\r\n#LDAP_FILTER = 'memberof=CN=PDNSAdmin,OU=PowerDNS,OU=Group,OU=DS,DC=domain,DC=local'\r\nLDAP_FILTER = ''\r\n```\r\nNow the problems.\r\nWhen I set anything in the LDAP_FILTER, I get an error:`\r\n\r\n` {'desc': 'Bad search filter'}`\r\n\r\nIf I keep the LDAP_FILTER empty, users can login and they are created in the local DB BUT:\r\n1. I give access to ALL AD users in the app (not acceptable)\r\n2. Users are not admins!\r\n\r\nI searched in the code (models.py) and found this:\r\n```\r\n\r\n           # user already exists in database, set their admin status based on group membership (if enabled)\r\n            if LDAP_GROUP_SECURITY:\r\n                self.set_admin(isadmin)\r\n            self.update_profile()\r\n            return True\r\n```\r\nNow, I am lost. My understanding of the LDAP_SECURITY is that **all** users will be admins if I don't use this variable, not the other way around. In my opinion, if you don't apply group \"policy\", then all users should be admins. \r\n\r\nNow to the point: \r\nThe first problem is the user filter. \r\nLooking at the code the search is constructed as:  \r\n```\r\nAD searchFilter:\r\n\"(&(objectcategory=person)(sAMAccountName=Username)memberof=CN=PDNSAdmin,OU=PowerDNS,OU=Group,OU=DS,DC=domain,DC=local)\"\r\n```\r\nIt is obvious that the search is wrong!  \r\nSo, I went into the code (models.py) and changed this:\r\n`searchFilter = \"(&(objectcategory=person)({0}={1}){2})\".format(LDAP_USERNAMEFIELD, self.username, LDAP_FILTER)\r\n`\r\nto this:\r\n`searchFilter = \"(&(objectcategory=person)({0}={1})({2}))\".format(LDAP_USERNAMEFIELD, self.username, LDAP_FILTER)`\r\n\r\nChecking the code it looks like the AD authentication is completely changed in the last couple of months, so I don't dare to update the software.\r\n\r\nThe second issue is with the admin users. In our AD, users belong to a number of different groups in different OUs etc. So, it's not easy to select one specific group. So, I have the admin group set but the users group is just ''. \r\nThis results to an exception error. The problem is in the code. \r\nSpecifically, the code is: \r\n(Line 253 in my version): \r\n\r\n```\r\n                   try:\r\n                        if LDAP_TYPE == 'ldap':\r\n                            ldap_user_dn = ldap.filter.escape_filter_chars(result[0][0][0])\r\n                            logging.info(result[0][0][0])\r\n                        if (self.ldap_search('(member={0})'.format(ldap_user_dn) ,LDAP_ADMIN_GROUP)):\r\n                            allowedlogin = True\r\n                            isadmin = True\r\n                            logging.info('User {0} is part of the \"{1}\" group that allows admin access to PowerDNS-Admin'.format(self.username,LDAP_ADMIN_GROUP))\r\n                        if (self.ldap_search('(member={0})'.format(ldap_user_dn) ,LDAP_USER_GROUP)):\r\n                            #if (group == LDAP_USER_GROUP):\r\n                            allowedlogin = True\r\n                            logging.info('User {0} is part of the \"{1}\" group that allows user access to PowerDNS-Admin'.format(self.username,LDAP_USER_GROUP))\r\n                        if allowedlogin == False:\r\n                            logging.error('User {0} is not part of the \"{1}\" or \"{2}\" groups that allow access to PowerDNS-Admin'.format(self.username,LDAP_ADMIN_GROUP,LDAP_USER_GROUP))\r\n                            return False\r\n                    except Exception as e:\r\n                        logging.error('LDAP group lookup for user \"{0}\" has failed. Authentication request from {1}'.format(self.username, src_ip))\r\n\r\n```\r\nAs you can clearly see, this works only for LDAP, no AD. Also, there is a single exception for 3 \"if\". \r\nAlso, using the logging.debug does not write the actual error in the logs (in which case was that the variable ldap_user_dn was used before defined.\r\nThat led me to the slight change in code:\r\nFrom \r\n`if LDAP_TYPE == 'ldap'`\r\nto:\r\n`if LDAP_TYPE == 'ldap' or LDAP_TYPE == 'ad':`\r\n\r\n"}}
{"actor":{"display_login":"ptselios-inmarsat"}}