I'm trying to extend a windows service I've written to accept a kerberos ticket from a client and then delegate that ticket to an ODBC driver so it can connect to another server with it.
The ODBC driver works with kerberos authentication fine in a standalone scenario. That is, it can request and forward on a ticket for the current user just fine. But in my service, I may be dealing with multiple users at once. How do I accept a ticket so that when I connect to the ODBC driver it discovers and uses the correct user's ticket?
One possibility I can think of is to create a new process as the desired user by using the ticket. However, I would really like to avoid this if possible as it does not fit well within the current architecture of my service.
(Note: My service is written in C/C++ with the Win32 api)
I found the answer to my own question.
After authenticating a security context, I can use the ImpersonateSecurityContext function. This will cause the current thread to run as client who initiated the security context. From that thread I can call the connection functions for the ODBC driver and it will authenticate as the correct user.
http://msdn.microsoft.com/en-us/library/aa375497%28v=vs.85%29.aspx
Related
In Azure DevOps services, when you connect an agent to the server, you have different types of ways to authenticate to the server. You can see here for example, about connecting a Linux agent, that you have these 4 types:
Alternate (Basic authentication)
PAT
Negotiate - Connect as a user other than the signed-in user via a scheme such as Kerberos or NTLM.
Integrated - Not supported in Linux
The integrated type is mentioned in the page about connecting a Windows agent as "Windows default credentials"
Bare with me please.
In my organization, we have a Active Directory domain with a Single-Sign-On, I suppose it uses Kerberos as the authentication protocol. Sometimes I use Powershell scripts to access the API of our internal Azure DevOps Server, and I use the -UseDefaultCredentials flag so the user won't have to enter username and password - it will just authenticate based on the logged-in user.
That got me thinking that the -UseDefaultCredentials flag is using Kerberos to authenticate.
But from the above, it seems that Integrated is using "Default credentials", which is something else than "Negotiate" which uses Kerberos.
Can someone help me understand this?
The UseDefaultCredentials flag tells the underlying system to try and use the caller's SSO credentials, which in most cases is the credential used to log into the system interactively or otherwise.
Strictly speaking it does not indicate which protocol to use. What it's actually saying is "dear system internals: please figure it out for me". The way this works is by selecting the negotiate protocol, which as it's name suggests negotiates the use of specific authentication protocols based on the client credentials as well as information from the server. This is called the SPNEGO protocol. It is transparent to the caller.
SPNEGO is fairly simple in nature. The client has a list of known authentication protocols (Kerberos, NTLM, etc.) and will send that list to the server saying 'pick one please'. The server can select any of them and respond telling them what to use, and the client then goes and uses it. Fin.
SPNEGO is also relatively smart because it can reasonably predict what it thinks the server will accept and will attempt to optimistically provide a token up front using the first protocol in the list. So if it thinks it needs Kerberos it'll go and get a Kerberos ticket up front and send it first. The server might think that's fine, or it might fail and return a response saying
"no, I really need NTLM", and so the client tries again with NTLM.
We are in the planning phase of configuring our soon-to-be-upgraded databases (19c) to authenticate directly against AD (no oracle proxy). I have read a handful of documents from Oracle on how to do this. Most of the documentation focuses around using passwords (password filter/verifier). The only problem is that our AD administrators are dead-set against implementing Oracle's password filter into our existing AD infrastructure. That being said, one of the security guys said we could implement the oracle authentication using Kerberos instead. From what I have read, and the documents are scattered all over the place, and nothing that detailed, to use Kerberos:
1) The client no longer uses a username/password - they connect using a wallet-style connection (e.g. /#dbname)
2) Not only does the Oracle DB need some configuration changes, but so does every client that plans on using Kerberos
I don't know anything about Kerberos, how it works, and what goes on when you implement this, but I was hoping for, at the end of this is:
1) No client changes/installs (only the oracle DB would have config changes)
The user will continue to provide credentials as before - completely transparent
2) No need for the password filter as our admins have a "beef" against it
So my question is:
If using Kerberos directly against AD on >=18c:
1) Does the client user still provide a username and password to authenticate against AD, or does the client simply get "accepted" due to the tickets/tokens/configuration that occurs on the client (i.e. the client is simply trusted)?
2) Is there client config changes that need to occur, or does the client reach out to the DB and the DB, with its config changes, does all the legwork to authenticate against AD based off of client info being passed
3) Does any additional manual component need to occur on occasion (periodically retrieving a ticket/token/something) (because, say, it expires)
So in the end, we want to have complete transparency with every client and using something other than the password verifier with AD.
Thanks in advance.
-Jim
It sounds like you want to authenticate Windows clients against an Oracle database over a network using Active Directory without making any client changes.
This is pretty open-ended and complex StackOverflow question.
Probably you've been reading the docs about Third Party Network Authentication using Oracle Advanced Security. You can use Kerberos, SSL, RADIUS, PKI, etc. For most of these options, you need to do some setup on the client, because both the Oracle client and server need to authenticate or verify with the third-party system.
I think you need Enterprise User Security (using Oracle Internet Directory). Assuming you go with password-based authentication, you don't need client changes. In this scenario, Oracle Internet Directory can synchronize its user directory with AD, so your users can use their same username/password. However, when they change their AD password, they'll need to change their Oracle password separately.
On a different note, you may be able to alleviate your AD admins' fears about Oracle password complexity requirements, since you can change or remove those to fit your AD requirements.
I am working on enabling Kerberos authentication/delegation in my application.
My setup: The client is any web browser. The server runs on Windows and hosts some of my services, with Apache/Tomcat as the front end. The server can delegate work to one or more of my services on one or more machines. My services run in Java, but invoke C++ code via JNI and the C++ code makes the connection to the data sources (via ODBC for most relational data sources). Currently I am working on connecting to SQL Server via its ODBC driver.
I have mod_auth_kerb set up in Apache, and that is able to authenticate the user using Kerberos. My question: How do I use the established security context to impersonate the thread which will invoke the ODBC driver's SQLDriverConnect call? I have a working prototype that uses LogonUser and ImpersonateLoggedonUser API's to login a particular user (using her username and password) and impersonate her on the thread that invokes the SQLDriverConnect call on the SQL Server ODBC driver. But I don't know how to use GSSAPI's established security context/delegated context (gss_ctx_id_t/gss_cred_id_t) to impersonate my thread. In other words, how do I convert the GSSAPI's handles into SSPI handles so that I can invoke ImpersonateSecurityContext or ImpersonateLoggedonUser or similar Win32 API's.
Any help would be appreciated. Thanks!
Ed
Given a windows domain, and two win7 systems, how can I establish a user verified connection from the first computer to the second without prompting for the user to re-enter credentials.
A good summary of this is: A TCP connection, server-side, has no idea what user is originating the connection. How can implementing a TCP based program permit user validation.
Work around ideas:
- I could write a WMI provider and use the underlying WMI infrastructure to verify the user.
I'd prefer not to get a work-around, as I've been working around not really understanding how to authenticate over the network using Windows for many years. Please help me to understand how Windows is actually performing this step so that I can implement the technique. If the answer is kerberos some example code on how to generate/send something from the client (without prompting for credentials, just use the logged in user) that the server can process/validate.
I think this may have already been answered here: Windows authentication token C++
(Will need some time to implement/test before I will be sure.)
The magic answer I was looking for back then was SSPI (Kerberos). A similar solution exists with OpenSSL. For others looking for this you will also be interested in SSL, TLS (the new SSL), and SASL (a mechanism for deciding on the fly which identification algorithm to use) and it's Microsoft counterpart SSPI.
We are trying to shape up an old, 2 tier, Delphi based application. It originally uses database authentication, we'd like to transform the db user accounts to global users, so an OID server could perform the authentication instead of the database.
The Delphi program can no longer log into the database if the account is a global user. I'm trying to understand the login protocol, so far without results.
Similar thing happens with SQLDeveloper, I can't connect as a global user. SQLPlus however works with both kinds of users. We checked the information flow with Wireshark. When the dbserver asks back for a password, the SQLPlus sends it, while the SQLDeveloper doesn't send a password when attempting to connect as a global user.
The client sends the application name too in the login request. Is it possible that we have to store the client app name in the LDAP itself?
To connect to Oracle using OID, application must properly configure OCI (Oracle Call Interface). The data access components (which one ?), you are using, must set OCI_ATTR_DISTINGUISHED_NAME session attribute. If that is not done, then you will be not able to connect to Oracle server using ODI and OCI.
You should check your components documentation for this feature. And if it is not implemented, then discuss this issue with the components vendor. Actually, there is not much work to implement, but some work to setup testing environment is required ...