-
Notifications
You must be signed in to change notification settings - Fork 132
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Active Directory LDAP Auth support #697
Conversation
|
||
# Get full name and group memberships | ||
try: | ||
res = self._ldap_conn.search_s(self._ldap_basedn, ldap.SCOPE_SUBTREE, '(sAMAccountName=' + self.username + ')',['cn','memberOf']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The value in self.username should be escaped (by calling ldap.filter.escape_filter_chars on it) before being included in the filter string passed to search_s.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great point and applies to the already existing LDAP module as well...
I'm not sure whether the username needs to be escaped when performing the bind using UPN, but if it does, it should be escaped using ldap.dn.escape_dn_chars. Aside from that and the line note, this looks good to me. |
Ok, so we had a lengthy discussion on IRC around this PR. To sum up, I'd like to not see an extra module for AD but that we integrate the functionality needed into the current LDAP module so that it also can be used for AD authentication. I think much of it is based on the search filter and by having something along the lines of a dn_filter variable we could use it for both scenarios;
The rwgroup / rogroup is new functionality (applause! :) and I would love to see the same support for "normal" LDAP, which is again a reason I don't want to have two modules. Also for the group support we should be able to handle a configuration where groups are not used, ie all users are granted RW or if we only define a rwgroup then all users get RO except for the users that are in the rwgroup who obviously gets RW access. It also has me thinking about more granular privileges but perhaps it's not really time for that quite yet... |
It would be possible to merge this into the LDAP module, however it's not possible to directly bind as the authenticating user in that case. When binding against AD0, you can either use the UPN (as in this PR), or you can use the CN (usually the user's real name). This means, that to authenticate the user using their sAMAccountName, you need to:
This extra user would need to be configured in AD and NIPAP, and have read access to the relevant trees. |
Escaping added |
return self._authenticated | ||
# if either ro_group or rw_group are configured and the search | ||
# fails, give readonly access | ||
elif self._ldap_rw_group or self._ldap_ro_group: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to https://github.com/SpriteLink/NIPAP/pull/697/files#diff-1ac79fd5b11080d64d2820829861e54eR143 one should get RW by default, so if ro_group is defined and search fails we should give read/write, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe, depends. If one is using the ro_group its probably for some security reason, if the search fail I would prefer giving normal users read only over giving untrusted users read/write. I guess this will most likely happen if there is a LDAP miss configuration. If your normal users don't get write access they will let you know and you can fix the problem, your untrusted users will probably not tell you that they got write access by accident, so you will never know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd agree with giving read only rather than read/write access here.
However, this except clause will only be reached if search_s fails, which should never happen, except when it's passed an invalid filter string (_ldap_search is misconfigured), or when there's a problem communicating with the LDAP server (e.g. connection has dropped since binding). The former is likely to be much more common.
Maybe it would be better to raise an exception instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry, I read this on a mobile device and didn't get the whole context when I initially commented.
If we only end up in here because of something like an invalid filter string, we should throw an exception instead and please try to refrain from using just except - try to match on the specific exception instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, do you happen to know what ldap exceptions I can get from a search_s? Or should I use LDAPError? We can also get KeyError if the memberOf attribute is missing at if self._ldap_ro_group in res[0][1]['memberOf']:
. At least from my tests the search_s succeeds when the attribute is missing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will also end up in the except if the username does not exist at all (but then the bind should fail) or if the basedn is wrong, or if the username is not found with the configured basedn.
Dunno if you are interested in the python3 compatibility effort going on over in #611. I don't mind keeping the two issues separate and convert the LDAP implementation to ldap3 once this PR is merged, but if you are interested in writing for py3 I would happily merge a PR that fixes both AD and py3 compatibility in one go. Regardless, before merging anything I want a squashed history - no need to see the rejected code in our history. |
I prefer keeping it separate, it will be to much work for me right now to test this code with py3. |
6f55e43
to
8f50f8f
Compare
Add Active Directory LDAP Auth support
The current LDAP Auth does not work with AD, and having the current one doing both I think would have been a bit messy, so created a new one for AD.
You use your samAccountName as username, it does UPN style LDAP bind with username@domain, where domain is from the config file.
It checks for group memberships, you have to be member of either the rogroup or rwgroup to be authenticated. If you are a member of both groups you will get rw access.
Fixes #607