Closed weightyfoe closed 11 years ago
This is very odd.
I threw a quick test together which looks like this:
ldap_user = Adauth.authenticate("administrator", "")
ldap_user.should be_false
which passed no problem. then after adding a few more cases to to the test that first example failed giving me a successful authentication as administrator with no code change or anything...
Something very odd is going on here its almost as if AD is allowing password less bindings which as far as I'm aware it shouldn't.
More research is needed
Is there anything I can do over here to provide some more data? AD config variables, run some ruby code?
You'll have to be be precise about what you want me to do though - I don't really know much at all about AD & it's configuration. Glad to help though, especially if it is something our AD is doing wrong (passwordless logins! Sounds bad...)
Here's the log of a single login attempt, using username "james" and no password:
# Logfile created on 2013-08-16 11:58:31 +0100 by logger.rb/36483
Loading new config
Attempting to authenticate as james
Searching for all "(objectClass=user)" where sAMAccountName = james
Connecting to AD as "low_priv_user"
Searching for all "(objectClass=group)" where name = SSL VPN Users
Searching for all "(objectClass=user)" where sAMAccountName =
Searching for all "(objectClass=group)" where sAMAccountName =
Searching for all "(objectClass=user)" where sAMAccountName = ITIPAD
Searching for all "(objectClass=group)" where sAMAccountName = ITIPAD
Searching for all "(objectClass=group)" where name = App_Sharepoint_KnowledgeUpdaters
Searching for all "(objectClass=user)" where sAMAccountName =
Searching for all "(objectClass=group)" where sAMAccountName =
Searching for all "(objectClass=user)" where sAMAccountName = James Bhatt
Searching for all "(objectClass=group)" where sAMAccountName = James Bhatt
Searching for all "(objectClass=group)" where name = Dept_IT
Searching for all "(objectClass=user)" where sAMAccountName =
Searching for all "(objectClass=group)" where sAMAccountName =
Searching for all "(objectClass=user)" where sAMAccountName = User1
Searching for all "(objectClass=group)" where sAMAccountName = User1
Searching for all "(objectClass=group)" where name = Everyone Outlook
Searching for all "(objectClass=user)" where sAMAccountName =
Searching for all "(objectClass=group)" where sAMAccountName =
Searching for all "(objectClass=user)" where sAMAccountName = User1
Searching for all "(objectClass=group)" where sAMAccountName = User1
Searching for all "(objectClass=group)" where name = Domain Admins
Searching for all "(objectClass=user)" where sAMAccountName =
Searching for all "(objectClass=group)" where sAMAccountName =
Searching for all "(objectClass=user)" where sAMAccountName = SQLEngine Original
Searching for all "(objectClass=group)" where sAMAccountName = SQLEngine Original
Searching for all "(objectClass=group)" where name = Enterprise Admins
Searching for all "(objectClass=user)" where sAMAccountName =
Searching for all "(objectClass=group)" where sAMAccountName =
Searching for all "(objectClass=user)" where sAMAccountName = User2
Searching for all "(objectClass=group)" where sAMAccountName = User2
Authentication succesful
I've left my name in, but bodged out the others & replaced them with generic peeps.
Just a question.
Is the binding bit done by this user (set in adauth.rb)?
c.query_user = "<a low privilege account>"
c.query_password = "****"
Because this user is a real user on our AD, ie I would be able to log in as this user & be authenticated. Or, does it use the username & password provided on the login page?
Because in the sessions controller I use (as per the doc):
ldap_user = Adauth.authenticate(params[:username], params[:password])
Which would be the username & password that are typed into the login form correct? So what is the user defined in adauth.rb for?
Ok,
So I create a brand new AD account (called special). The account is bog standard: primary group is Active Directory/users
I can still "Authenticate" a user without using a password, if I connect using the above account as the query user.
I'm unsure of the internals of how AD/LDAP queries actually work, but could this possibly be something like:
1) Connect as a given user (a query user used to make all queries against AD) to create a "connection" to AD 2) Using that connection, ask AD: "Does a user with user name 'foo' and password '' exist?" 3) AD seems to allow an authenticated user to query the directory, so it says yes, there is a user whose username = 'foo' (and because no password is specified, AD doesn't check it) 3a) Same query, but this time using a bad password: Ad says no, because although the user 'foo' exists, the password hashes (which it now uses because it is specified) do not match.
So, is it a case the because we're already connected to AD using the query_user, we're not "authenticating" the user who is trying to log in, we're just trying to see whether they exist or not?
And, could this be fixed by running the query using the supplied username & password rather than using a defined query_user?
Query User us used to let Adauth query for information e.g. find the groups user X is in.
Authenticate creates a new connection to AD using the supplied credentials to make sure that the details are valid. As far as I'm aware the only way Adauth would do this is if Net/LDAP returned a valid connection and again that should only happen if it gets a successful connection
I've got some time today to test this so hopefully a solution will exist soon (Now that I've managed to replicate the issue my boss is happy for me to spend time looking at instead of doing other work)
I've written up the case here:
http://arcath.github.io/blog/2013/08/28/issue-37/
Basically the LDAPv3 Specification states that you need to make the rootDSE accessible anonymously which because we bind against it meant that Adauth would get a false positive.
We've noticed that it's possible to login using adauth by supplying a correct username & a blank password. We've seen the following:
correct username & correct password -> login correct username & incorrect password -> fail correct username, & blank password -> login (as username) incorrect username & [correct|incorrect|blank] password -> fail
This is even for users who are NOT currently in the users table (ie have never previously logged in).
Currently using the latest git master branch (pulled from git today using bundle update): https://github.com/Arcath/Adauth.git
Setup is like this (boring bits omitted):
We added the begin/rescue/end in the create session because we encountered an error when giving incorrect usernames/passwords (ldap_user was true even for bad usernames - like logging in as asdf/crap_pass)
Removing the rescue still lets you log in without a password, and errors if the username or password is incorrect (but not blank), ie it being there has no effect on this issue, but it does prevent an error.
What's going on?
Oh, an excerpt from the users table:
Not sure whats going on with group_strings(!) or ou_strings, but I don't currently use them for anything. This user logged on by providing username "james" and no password