LDAP Authentication Approach

I recently made an adjustment in a branch of my fork to allow my authentication server to look for WoW passwords in my local LDAP directory (link). It was a fun enough exercise that allowed me to learn some new things about C and OpenLDAP, but now after the feature is in a working state I’m worried that I went with an approach that was much more complicated than it needed to be.

I extended my LDAP schema to have an additional field for a WoW password, and made some adjustments to the web app that I use to allow users to change their password. When a user changes their password, their WoW password property in the directory is updated to reflect their new password.

When the user attempts to log into WoW, the server attempts to pull user properties (UID, E-mail, WoW Password) via LDAP. If it gets the UID and password (e-mail is optional), it will create the the account if needed and return the appropriate information out of the database. The user’s new LDAP password is also saved to the database. If any part of this process fails, the server will fall back to attempting to use the database.

My concern is that a much less overkill solution would be to make some extra changes to my password-changer to do the password-changing and account creation if necessary without having to do a rebuild of the TC server.

Potential Pro’s of LDAP Implementation:

[ul][li]Possible TLS/SSL encryption of entire connection.[/li]
[li]Group-based validation (NYI).[/li]
[li]Would support multiple realmlist servers retroactively (i.e. a user could instantly sign into an authentication server set up after they set their last new password), possibly multiple cores/expansions (though each of these would need to be outfitted with a similar patch, meaning more work).[/li]
[/ul]
Cons of LDAP:

[ul][li]The LDAP server is contacted with every logon attempt, as opposed to only one database connection when the user changes their password. If the user is interested in making use of the server at all, I’d be very surprised if password changes outnumbered WoW connections.[/li]
[li]Introduces a new libary, which would probably need extra testing to be considered stable.[/li]
[/ul]

What is your opinion of this feature? If it is overkill as-is, are there any features that you can think of that would make it worthwhile as opposed to a utility that writes to the database? If you use some sort of shared authentication setup to link your server to your local network, which approach did you go with?

This is definitely interesting topic and I have quickly looked at your code - not a fan of updating password in database on every login but that is a tricky thing to solve given the use of SRP in 3.3.5 client

Not going to comment on the code itself at this point

Have you looked into integrating this into 6.x branch first? SRP is no longer used for authentication, meaning that you could possibly authenticate with any credential manager (you just need to hook here https://github.com/TrinityCore/TrinityCore/blob/6.x/src/server/bnetserver/REST/LoginRESTService.cpp#L200). Obviously account/battlenet_account data must exist as it has more than just login/password data (probably introducing more authentication methods would justify splitting these tables)

ps You can use a single shared auth database for both 3.3.5 and 6.x - given an existing 3.3.5 account ABC you could run these commands on 6.x to have access to all auth data too - .bnetaccount create [email protected] you_new_password false AND .bnetaccount link [email protected] ABC

With the PasswordInfo struct, the write to the database isn’t actually necessary. PasswordInfo was actually a last-minute addition because I wanted to quickly confirm the proof-of-concept without having to add in a synchronous version of the password update query and do a longer rebuild. Since the database-stored value is never actually read from with a successful LDAP connection, I could make it something setting controlled in case someone really wanted to do so.

I didn’t know that the 6.x authentication server was fully compatible with the 3.5.5 client, but in hindsight it makes sense. I tried to use my branch to connect to an instance of a TBC-era server with a TBC client (solely for jollies, the connection attempt flopped), but since the 3.x-era was when more Battle.net integration started happening in it makes sense that a 3.x era client would play ball with 6.x-era authserver where going from 2.x->3.x wouldn’t. I’ll take a stab at applying the changes to a branch off of 6.x at some point in the near future.

Perhaps you misunderstood me - you cannot use the same auth executable for both versions but you can share the database

As for write to database - sadly it is neccessary for gm commands that check password, see HandleAccountPasswordCommand in cs_account.cpp (and its worldserver that handles commands, not auth/bnet) and telnet RA/soap