I'm new with LDAP, and I'm having some problems binding/searching using a gMSA. I also can't find anything useful online about how to do this. We have some customers that want to change the account used for running services to a gMSA, so I have tried to create a connection only using the DN of the group managed service account. I've tried using LDAPConnectionOptions with setBindWithDNRequiresPassword=true, and then using a SimpleBindRequest with the gMSA DN and an empty password. The binding seems to go ok, as I receive a result code='0 (success)', but when I try to do a search, I get the following exception:
Exception in thread "main" LDAPException(resultCode=1 (operations error), numEntries=0, numReferences=0, diagnosticMessage='000004DC: LdapErr: DSID-0C090A5C, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v4563 ', ldapSDKVersion=6.0.1, revision=ca9bd061ccfdbf76247f8d6e011f1bc7f53eb520')
I've tried all sorts of stuff, but I can't seem to figure out how to do this.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Using the "gMSA DN and an empty password" will make a
successful "Unauthenticated Bind". For Microsoft Active Directory in most
cases the operation is not usable to perform most LDAP Operations.
AFIK, Microsoft Active Directory does not distinguish between
Unauthenticated and anonymous operations.
The operations for gMSA accounts as used within Microsoft Active Directory
use API operations which are outside of LDAP.
Although Microsoft Active Directory supports LDAP it also has many other
non-LDAP APIs.
You could, retrieve the password and then make the bind, however, the
password is managed by Microsoft Active Directory and could be changed
at any time.
The details for Password are stored in the msDS-ManagedPassword and
msDS-ManagedPasswordId attributes of the object, these could be returned in
LDAP Search, however, it does require a specific permissions and a "Secure
connection" for LDAP Search to return the details as they are protected
attributes.
I'm new with LDAP, and I'm having some problems binding/searching using a
gMSA. I also can't find anything useful online about how to do this. We
have some customers that want to change the account used for running
services to a gMSA, so I have tried to create a connection only using the
DN of the group managed service account. I've tried using
LDAPConnectionOptions with setBindWithDNRequiresPassword=true, and then
using a SimpleBindRequest with the gMSA DN and an empty password. The
binding seems to go ok, as I receive a result code='0 (success)', but
when I try to do a search, I get the following exception:
Exception in thread "main" LDAPException(resultCode=1 (operations error),
numEntries=0, numReferences=0, diagnosticMessage='000004DC: LdapErr:
DSID-0C090A5C, comment: In order to perform this operation a successful
bind must be completed on the connection., data 0, v4563 ',
ldapSDKVersion=6.0.1, revision=ca9bd061ccfdbf76247f8d6e011f1bc7f53eb520')
I've tried all sorts of stuff, but I can't seem to figure out how to do
this.
Thx for your reply Jim. I've tried going down this path, using a C# console application to retrieve the contents of the msDS-ManagedPassword attribute, and then extract the password from the byte blob. I then call this C# console application from a Java application using Runtime.exec(). I can verify that the password is correct, as I am able to authenticate using the sAMAccountName and a copy/paste of the password directly in the MS Ldap application on the server. I am however not able to make a bind using UnboundId LDAP SDK. I've tried various things without success. I'm using a SimpleBindRequest with the DN of the gMSA and the password either as a String or a byte array, but the result is the same:
I initially thought that it had to be some kind of encoding problem, but I'm not convinced this is the problem anymore, since I can authenticate using copy/paste. I am aware that placing the text into the clipboard might affect the encoding, but it still works this way for some reason. I have tried everything I can think off, so any advice would be much appreciated!
Last edit: Martin Jacobsen 2021-09-23
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thx for your reply Jim. I've tried going down this path, using a C#
console application to retrieve the contents of the msDS-ManagedPassword
attribute, and then extract the password from the byte blob. I can verify
that the password is correct, as I am able to authenticate using the
sAMAccountName and a copy/paste of the password directly in the MS Ldap
application on the server. I am however not able to make a bind using
UnboundId LDAP SDK. I've tried various things without success. I'm using a
SimpleBindRequest with the DN of the gMSA and the password either as a
String or a byte array, but the result is the same:
I initially thought that it had to be some kind of encoding problem, but
I'm not convinced this is the problem anymore, since I can authenticate
using copy/paste. I am aware that placing the text into the clipboard might
affect the encoding, but it still works this way for some reason. I have
tried everything I can think off, so any advice would be much appreciated!
This is only the java side of the project. It reads the B64 encoded password from the output stream from a C# console application, decodes the password and tries to bind. Everything starts in the main method of the RuntimeExecPOC.java.
Please let me know if you have any problems getting access to the code, or similar.
/Martin
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Did you get a chance to look at the code yet Jim? I did an experiment the other day, setting the same password as the gMSA on a normal user, and then tried binding to the user using my RuntimeExecPOC application, and it worked just fine. I'm beginning to think that it might just be a problem when using a gMSA. That you simply can't bind to it the normal way. It would be nice to find a solution for Java applications though. It doesn't feel right that this is something that you simply can't do in Java through LDAP.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Did you get a chance to look at the code yet Jim? I did an experiment the
other day, setting the same password as the gMSA on a normal user, and then
tried binding to the user using my RuntimeExecPOC application, and it
worked just fine. I'm beginning to think that it might just be a problem
when using a gMSA. That you simply can't bind to it the normal way. It
would be nice to find a solution for Java applications though. It doesn't
feel right that this is something that you simply can't do in Java through
LDAP.
Did you get a chance to look at the code yet Jim? I did an experiment the
other day, setting the same password as the gMSA on a normal user, and then
tried binding to the user using my RuntimeExecPOC application, and it
worked just fine. I'm beginning to think that it might just be a problem
when using a gMSA. That you simply can't bind to it the normal way. It
would be nice to find a solution for Java applications though. It doesn't
feel right that this is something that you simply can't do in Java through
LDAP.
Bind/search using Group Managed Service Account (gMSA)
I've tried to bind with the gMSA for several weeks now, but without success. Even though I'm able to get a hold of the password of the gMSA, I just can't get the bind to work through UnboundID LDAP SDK or even JNDI for that matter. It works fine in C# both with or without password. It's like there's something denying access when it's not a MS technology trying to make contact with AD through a gMSA. At the same time, I don't quite understand why this isn't something that is easily supported through the UnboundID LDAP SDK.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The problem is this: I have retrieved the password of the gMSA that I'm trying to bind to, but every time I do a simple bind using the DN of the gMSA and the retrieved password, I get a error 49 - invalid credentials. I can verify that the password is correct, since I can c/p it and do a bind in MS LDP.
The reason for base64 encoding the password was just to wrap it up in something when writing it to the std output stream from the C# application, and then of course I decode it after reading it from the std output stream in my java application.
EDIT: I might have misunderstood what you meant when I wrote the above, but this pretty much wraps up what my problem is :)
Last edit: Martin Jacobsen 2021-09-27
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Unfortunately, I can’t be of much direct help in this issue, since it’s specific to Active Directory, and I don’t have a lot of experience with or access to an Active Directory Instance for testing. However, I might be able to provide a couple of tips to help point you in the right direction.
First, I did look at the DSInternals article you posted above, and at the Microsoft MSDS-MANAGEDPASSWORD_BLOB article that it references. Even though that blob packs a lot of information into it, it should be a fairly straightforward process to get the clear-text password out of it. It looks like you should just need to start reading from the 17th byte (array offset 16) of the msDS-ManagedPassword value and keep going until you find a null terminator (a byte of 0x00).
According to the DSInternals article, you should end up with a raw password that is 256 bytes long, which represents 128 UTF-16 characters (and I’m guessing that it’s UTF-16LE, since I know that Microsoft really likes that encoding for some reason). My guess is that so far, you’ve tried using those 256 bytes directly as the password, and that might be the problem. That’s because while Microsoft provides the password as a UTF-16 string, LDAP generally uses UTF-8 for its strings, and that’s definitely the case for the password in a bind request. RFC 4511 section 4.2 specifically states: “Textual passwords (consisting of a character sequence with a known character set and encoding) transferred to the server using the simple AuthenticationChoice SHALL be transferred as UTF-8 [RFC3629] encoded [Unicode].” So my guess is that you need to convert the UTF-16 password into UTF-8 before using it in the bind request. You can do that with the following code:
String passwordString = new String(utf16LEPasswordBytes, StandardCharsets.UTF_16LE);
byte[] utf8PasswordBytes = passwordString.getBytes(StandardCharsets.UTF_8);
When creating the bind request, it should be sufficient to either use the password string obtained from the first step because the LDAP SDK will automatically encode the string to UTF-8 when creating the bind request, but you could also try creating the bind request directly from the UTF-8 bytes obtained from the second step.
If that doesn’t work, and if you’re able to get it working with a C# application, then the best option would probably be to capture the traffic generated by the C# application and examine it to see how the bytes it’s sending to Active Directory might be different from the bytes that the LDAP SDK is sending. If you can send the C# bind request over an unencrypted connection, then a network packet capture tool like Wireshark might be sufficient, but my guess is that may not be an option in this case. So instead, you can use the ldap-debugger tool that we provide with the LDAP SDK (in the tools directory). It’s a very simple LDAP proxy server that you can put between the client and an LDAP server and it will dump the details of the requests and responses that pass through it to standard output or to a file. So if you run it and point it at the Active Directory server, and then if you point your C# application at the ldap-debugger tool rather than directly at AD, then that should allow us to see the requests that the C# application is sending.
To do that, you can use a command like the following:
When you run it, it will automatically pick a free port on the system (or you can explicitly specify a port using the --listenPort argument). Then, point your C# application at the ldap-debugger tool (you might need to do something to convince it to trust the self-signed certificate that the tool generates for TLS-encrypted connections) and send the bind request as you normally would. When you do that, the decoded content of the bind request (and any other requests and responses passing through the tool) should be written to the ldap-debugger.txt file. If you can provide the captured details from that bind request, then it should let us see what the difference is and hopefully figure out how to do the same thing from an LDAP SDK request.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you for the answer and ideas Neil. I have also thought about using a program to capture the traffic, but I actually didn't know there was these tools in the SDK. That's nice to know.
I have tried the ldap-debugger a bit today, and while I did manage to capture some test traffic, using the admin login from a Java app on my dev machine, I'm still not there yet where I can use the C# application and capture the traffic. I had some problems with the auth mechanism used in the C# application (Microsoft Negotiate Authentication). I'm not really sure if it's a standard auth mechanism or not, but it's not supported in the ldap-debugger as far as I can tell.
We decided to try it directly on the server and get it working using ldp.exe, a tool where we have had success binding as the gMSA, but we never quite got it working. Even though we tried using the admin account to bind we couldn't get it to work.
We were also quite puzzled by the fact that you have to supply the ldap-debugger tool with distinguished name and password during setup when just running it. Is this another mode of operation for the tool than the one you supplied with the command arguments?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You don’t actually need to invoke the ldap-debugger tool with authentication information. By default, it will just create an unauthenticated connection to the target server and will directly forward any requests from the client to the server, and responses from the server to the client, including those that authenticate the client. The fact that those arguments are provided is primarily because it’s using a more general-purpose command-line framework that the LDAP SDK provides for creating command-line tools that can interact with LDAP servers, and you don’t need to use them if you don’t need the tool to authenticate the connections it creates.
I’m not familiar with the Microsoft Negotiate Authentication mechanism. I’m guessing that it’s not LDAP simple authentication, so I assume that it’s some type of SASL mechanism. But even if that’s the case, then ldap-debugger shouldn’t need to have direct knowledge of that mechanism because it will still be able to parse it as a generic SASL request to see the mechanism name and any credentials that are included in it, and it should at least be able to dump that much. It will then just forward that request on to the target server exactly as it was provided by the client. If it’s using a Microsoft-proprietary SASL mechanism, then the LDAP SDK won’t support it out of the box, but if it’s documented somewhere, then you could potentially write your own support for it by extending SASLBindRequest and handling all of the mechanism-specific logic in your class.
If for some reason it’s actually using something other than LDAP simple or SASL authentication, then it wouldn’t actually be using the LDAP protocol, because those are the only two types of authentication defined in LDAP, and the LDAP SDK will not support it. In that case, the ldap-debugger tool would fail to parse the request, and it wouldn’t be able to forward it to the target server.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It's been a while since I wrote about my gMSA adventure, so I thought it was time for an update. I have finally managed to get this to work. A lot of time has been spent trying to figure out why we couldn't get the login to work as the gMSA, but at least some of the issue seemed to be related to using a SimpleBind. Now we are using a Digest-MD5 bind instead and it works! Here's a quick rundown of the solution:
Since there's to my knowledge no easy way to retrieve the gMSA password from Java, we are using some C# code residing in a console application. Namely the DSInternals common module, which can be installed as a nuget package, and some code for decoding the gMSA byte blob. Both links can be found below.
A big thanks to Jim and Neil for helping out with this!
Hi.
I'm new with LDAP, and I'm having some problems binding/searching using a gMSA. I also can't find anything useful online about how to do this. We have some customers that want to change the account used for running services to a gMSA, so I have tried to create a connection only using the DN of the group managed service account. I've tried using LDAPConnectionOptions with setBindWithDNRequiresPassword=true, and then using a SimpleBindRequest with the gMSA DN and an empty password. The binding seems to go ok, as I receive a result code='0 (success)', but when I try to do a search, I get the following exception:
Exception in thread "main" LDAPException(resultCode=1 (operations error), numEntries=0, numReferences=0, diagnosticMessage='000004DC: LdapErr: DSID-0C090A5C, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v4563 ', ldapSDKVersion=6.0.1, revision=ca9bd061ccfdbf76247f8d6e011f1bc7f53eb520')
I've tried all sorts of stuff, but I can't seem to figure out how to do this.
Using the "gMSA DN and an empty password" will make a
successful "Unauthenticated Bind". For Microsoft Active Directory in most
cases the operation is not usable to perform most LDAP Operations.
AFIK, Microsoft Active Directory does not distinguish between
Unauthenticated and anonymous operations.
By default, anonymous Lightweight Directory Access Protocol (LDAP)
operations to Active Directory, other than rootDSE searches and binds, are
not permitted in Microsoft Windows Server 2003 and later.
https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/anonymous-ldap-operations-active-directory-disabled
The operations for gMSA accounts as used within Microsoft Active Directory
use API operations which are outside of LDAP.
Although Microsoft Active Directory supports LDAP it also has many other
non-LDAP APIs.
You could, retrieve the password and then make the bind, however, the
password is managed by Microsoft Active Directory and could be changed
at any time.
The details for Password are stored in the msDS-ManagedPassword and
msDS-ManagedPasswordId attributes of the object, these could be returned in
LDAP Search, however, it does require a specific permissions and a "Secure
connection" for LDAP Search to return the details as they are protected
attributes.
--
-jim
Jim Willeke
On Mon, Sep 13, 2021 at 5:14 AM Martin Jacobsen martin-jacobsen@users.sourceforge.net wrote:
Thx for your reply Jim. I've tried going down this path, using a C# console application to retrieve the contents of the msDS-ManagedPassword attribute, and then extract the password from the byte blob. I then call this C# console application from a Java application using Runtime.exec(). I can verify that the password is correct, as I am able to authenticate using the sAMAccountName and a copy/paste of the password directly in the MS Ldap application on the server. I am however not able to make a bind using UnboundId LDAP SDK. I've tried various things without success. I'm using a SimpleBindRequest with the DN of the gMSA and the password either as a String or a byte array, but the result is the same:
BindResult: BindResult(resultCode=49 (invalid credentials), messageID=1, diagnosticMessage='80090308: LdapErr: DSID-0C090439, comment: AcceptSecurityContext error, data 52e, v4563 ', hasServerSASLCredentials=false)
I initially thought that it had to be some kind of encoding problem, but I'm not convinced this is the problem anymore, since I can authenticate using copy/paste. I am aware that placing the text into the clipboard might affect the encoding, but it still works this way for some reason. I have tried everything I can think off, so any advice would be much appreciated!
Last edit: Martin Jacobsen 2021-09-23
You should post your code.
In Microsoft Active Directory the default password attribute is unicodePwd
and I this requires special encoding as shown in this example:
https://github.com/jwilleke/Examples-JNDI/blob/master/src/com/willeke/samples/ldap/jndi/ADConnection.java
See (updateUserPassword(String username, String password))
--
-jim
Jim Willeke
On Thu, Sep 23, 2021 at 5:40 AM Martin Jacobsen martin-jacobsen@users.sourceforge.net wrote:
Thx for your fast reply Jim! I have posted two classes here: https://github.com/nsismartin/gMSA_bind_java/tree/main
This is only the java side of the project. It reads the B64 encoded password from the output stream from a C# console application, decodes the password and tries to bind. Everything starts in the main method of the RuntimeExecPOC.java.
Please let me know if you have any problems getting access to the code, or similar.
/Martin
Did you get a chance to look at the code yet Jim? I did an experiment the other day, setting the same password as the gMSA on a normal user, and then tried binding to the user using my RuntimeExecPOC application, and it worked just fine. I'm beginning to think that it might just be a problem when using a gMSA. That you simply can't bind to it the normal way. It would be nice to find a solution for Java applications though. It doesn't feel right that this is something that you simply can't do in Java through LDAP.
I have but:
I am not sure what the problem is and
I do not know what the "B64 encoded password" would be. Would you even be
able to bind with that?
Unfortunately, I also have no test environment for this and have not done
Java stuff in a while.
--
-jim
Jim Willeke
On Sun, Sep 26, 2021 at 10:02 AM Martin Jacobsen martin-jacobsen@users.sourceforge.net wrote:
Well, I just could not leave it alone.
This is just from some searching, no word on the real hoto.
The return value of msDS-ManagedPassword is a msaBlob of a lot of items.
(sort of described here https://markgamache.blogspot.com/p/gmsa-magic.html)
Looks like this guy got it to work but using signing and sealing in a .NET
project.
https://markgamache.blogspot.com/2016/12/any-sufficiently-advanced-active.html
Good Luck.
-jim
Jim Willeke
On Sun, Sep 26, 2021 at 3:56 PM Jim Willeke jwilleke@users.sourceforge.net
wrote:
That is exactly the code I'm using in my C# application to get a hold of the msDS-ManagedPassword blob. I then run it into some other code to extract the password in clear text. It just looks like gibberish, but it's the password. I use the DSInternals module mentioned in this blog post: https://www.dsinternals.com/en/retrieving-cleartext-gmsa-passwords-from-active-directory/#comment-119852
Even though I have the actual password, I've not been able to perform a successful bind from a java application yet.
I've tried to bind with the gMSA for several weeks now, but without success. Even though I'm able to get a hold of the password of the gMSA, I just can't get the bind to work through UnboundID LDAP SDK or even JNDI for that matter. It works fine in C# both with or without password. It's like there's something denying access when it's not a MS technology trying to make contact with AD through a gMSA. At the same time, I don't quite understand why this isn't something that is easily supported through the UnboundID LDAP SDK.
The problem is this: I have retrieved the password of the gMSA that I'm trying to bind to, but every time I do a simple bind using the DN of the gMSA and the retrieved password, I get a error 49 - invalid credentials. I can verify that the password is correct, since I can c/p it and do a bind in MS LDP.
The reason for base64 encoding the password was just to wrap it up in something when writing it to the std output stream from the C# application, and then of course I decode it after reading it from the std output stream in my java application.
EDIT: I might have misunderstood what you meant when I wrote the above, but this pretty much wraps up what my problem is :)
Last edit: Martin Jacobsen 2021-09-27
Unfortunately, I can’t be of much direct help in this issue, since it’s specific to Active Directory, and I don’t have a lot of experience with or access to an Active Directory Instance for testing. However, I might be able to provide a couple of tips to help point you in the right direction.
First, I did look at the DSInternals article you posted above, and at the Microsoft MSDS-MANAGEDPASSWORD_BLOB article that it references. Even though that blob packs a lot of information into it, it should be a fairly straightforward process to get the clear-text password out of it. It looks like you should just need to start reading from the 17th byte (array offset 16) of the msDS-ManagedPassword value and keep going until you find a null terminator (a byte of 0x00).
According to the DSInternals article, you should end up with a raw password that is 256 bytes long, which represents 128 UTF-16 characters (and I’m guessing that it’s UTF-16LE, since I know that Microsoft really likes that encoding for some reason). My guess is that so far, you’ve tried using those 256 bytes directly as the password, and that might be the problem. That’s because while Microsoft provides the password as a UTF-16 string, LDAP generally uses UTF-8 for its strings, and that’s definitely the case for the password in a bind request. RFC 4511 section 4.2 specifically states: “Textual passwords (consisting of a character sequence with a known character set and encoding) transferred to the server using the simple AuthenticationChoice SHALL be transferred as UTF-8 [RFC3629] encoded [Unicode].” So my guess is that you need to convert the UTF-16 password into UTF-8 before using it in the bind request. You can do that with the following code:
When creating the bind request, it should be sufficient to either use the password string obtained from the first step because the LDAP SDK will automatically encode the string to UTF-8 when creating the bind request, but you could also try creating the bind request directly from the UTF-8 bytes obtained from the second step.
If that doesn’t work, and if you’re able to get it working with a C# application, then the best option would probably be to capture the traffic generated by the C# application and examine it to see how the bytes it’s sending to Active Directory might be different from the bytes that the LDAP SDK is sending. If you can send the C# bind request over an unencrypted connection, then a network packet capture tool like Wireshark might be sufficient, but my guess is that may not be an option in this case. So instead, you can use the ldap-debugger tool that we provide with the LDAP SDK (in the tools directory). It’s a very simple LDAP proxy server that you can put between the client and an LDAP server and it will dump the details of the requests and responses that pass through it to standard output or to a file. So if you run it and point it at the Active Directory server, and then if you point your C# application at the ldap-debugger tool rather than directly at AD, then that should allow us to see the requests that the C# application is sending.
To do that, you can use a command like the following:
When you run it, it will automatically pick a free port on the system (or you can explicitly specify a port using the --listenPort argument). Then, point your C# application at the ldap-debugger tool (you might need to do something to convince it to trust the self-signed certificate that the tool generates for TLS-encrypted connections) and send the bind request as you normally would. When you do that, the decoded content of the bind request (and any other requests and responses passing through the tool) should be written to the ldap-debugger.txt file. If you can provide the captured details from that bind request, then it should let us see what the difference is and hopefully figure out how to do the same thing from an LDAP SDK request.
Thank you for the answer and ideas Neil. I have also thought about using a program to capture the traffic, but I actually didn't know there was these tools in the SDK. That's nice to know.
I have tried the ldap-debugger a bit today, and while I did manage to capture some test traffic, using the admin login from a Java app on my dev machine, I'm still not there yet where I can use the C# application and capture the traffic. I had some problems with the auth mechanism used in the C# application (Microsoft Negotiate Authentication). I'm not really sure if it's a standard auth mechanism or not, but it's not supported in the ldap-debugger as far as I can tell.
We decided to try it directly on the server and get it working using ldp.exe, a tool where we have had success binding as the gMSA, but we never quite got it working. Even though we tried using the admin account to bind we couldn't get it to work.
We were also quite puzzled by the fact that you have to supply the ldap-debugger tool with distinguished name and password during setup when just running it. Is this another mode of operation for the tool than the one you supplied with the command arguments?
You don’t actually need to invoke the ldap-debugger tool with authentication information. By default, it will just create an unauthenticated connection to the target server and will directly forward any requests from the client to the server, and responses from the server to the client, including those that authenticate the client. The fact that those arguments are provided is primarily because it’s using a more general-purpose command-line framework that the LDAP SDK provides for creating command-line tools that can interact with LDAP servers, and you don’t need to use them if you don’t need the tool to authenticate the connections it creates.
I’m not familiar with the Microsoft Negotiate Authentication mechanism. I’m guessing that it’s not LDAP simple authentication, so I assume that it’s some type of SASL mechanism. But even if that’s the case, then ldap-debugger shouldn’t need to have direct knowledge of that mechanism because it will still be able to parse it as a generic SASL request to see the mechanism name and any credentials that are included in it, and it should at least be able to dump that much. It will then just forward that request on to the target server exactly as it was provided by the client. If it’s using a Microsoft-proprietary SASL mechanism, then the LDAP SDK won’t support it out of the box, but if it’s documented somewhere, then you could potentially write your own support for it by extending SASLBindRequest and handling all of the mechanism-specific logic in your class.
If for some reason it’s actually using something other than LDAP simple or SASL authentication, then it wouldn’t actually be using the LDAP protocol, because those are the only two types of authentication defined in LDAP, and the LDAP SDK will not support it. In that case, the ldap-debugger tool would fail to parse the request, and it wouldn’t be able to forward it to the target server.
It's been a while since I wrote about my gMSA adventure, so I thought it was time for an update. I have finally managed to get this to work. A lot of time has been spent trying to figure out why we couldn't get the login to work as the gMSA, but at least some of the issue seemed to be related to using a SimpleBind. Now we are using a Digest-MD5 bind instead and it works! Here's a quick rundown of the solution:
Since there's to my knowledge no easy way to retrieve the gMSA password from Java, we are using some C# code residing in a console application. Namely the DSInternals common module, which can be installed as a nuget package, and some code for decoding the gMSA byte blob. Both links can be found below.
A big thanks to Jim and Neil for helping out with this!
https://github.com/MichaelGrafnetter/DSInternals
https://markgamache.blogspot.com/p/gmsa-magic.html