The NpgsqlPasswordPacket class assumes that it needs to null-terminate all
passwords that come through, but GSSAPI and SSPI send binary data. I move
the null-termination logic up to the state class, where it can decide
whether a password needs to be null-terminated.
For a Windows client to connect to a Linux-hosted PostgreSQL, it needs to
support GSSAPI. Fortunately, that just requires two changes:
* Use the hostname in the SPN
* Ask for the "kerberos" package instead of "negotiate"
When PostgreSQL receives our username, it will expect the case to match
Active Directory. For us to guess it correctly requires an LDAP lookup.
While I'm here, I'm also adding an "IncludeRealm" option to the connection
string to add the realm to the username if the include_realm option is
being used on the server side.
One real nasty thing about having the username set upon reading the
property is that it freezes the username at possibly bad times, such as
when you're examining the connection builder in the debugger. I'd fix that
now, but I'm worried about breaking too much.
WARNING: There's a serious bug here where one user could get access to
another user's cached connection if connection pooling is on and integrated
security is being used. This is because the user ID is not in the
connection string until the connection is opened, which is after any
pooling logic. I'll address this in the next patch.
When connection pooling is turned on, connections are cached by connection
string. But when integrated security is turned on, the user's identity
isn't part of the connection string, so two users can get each other's
connections back from the connection pool.
This patch forces the username to appear in the connection string if
integrated security is on, before any pooling takes place.