Fix for LDAP authentication with LDAP servers that don't allow anonymous searches

When authenticating a user for login, the current code does an anonymous search
to find the user, and then attempts to bind as that user when the search
results contain that user. This is a problem since some LDAP servers do not
allow anonymous searches. Fix is to do the anonymous search still, but if the
search results in no entries, attempt to bind as that user anyways by
constructing DN from the username plus configured base DN. If the search does
contain the user, use the DN in the returned result.

Testing done:
Tested in-house with LDAP server that doesn't respond to anonymous searches.

Reviewed at https://reviews.reviewboard.org/r/4953/
Switch over to django.contrib.auth.views.login

Once upon a time, django.contrib.auth didn't have a built-in login view. As of
about half a decade ago, it does. This means we can kill the one in djblets,
which isn't nearly as well maintained.

This change switches us over to the new view and form, which works pretty
similarly to the old one. The major differences are in the naming of the error
fields, 'next' vs. 'next_page' (which I'll deal with once I stop using
djblets.auth.util.login_required), and CSRF protection.

Testing done:
* Tried to login with an invalid username and password and saw the right error.
* Tried to login after fiddling with the CSRF token and saw a 403.
* Logged in with a valid username and password and was redirected to
  /dashboard/
* Checked that when I accessed a page when logged out I was redirected to log
  in, and then once I logged in, I was redirected back to that page.

Reviewed at https://reviews.reviewboard.org/r/4931/

This change has been cherry-picked from the master branch.
Merge branch 'release-1.7.x'