Eldap and unicode

Hi,

I’m trying to use the eldap module to set a password for a new user in Active Directory. In AD, the default attribute for setting the password is unicodePwd, and uses a UTF-16. When I try to set the attribute using eldap I get an {:error, :unwillingToPerofrm} back. I know I need to encode the password, but I’m not quite sure how.

:application.ensure_all_started(:ssl)

{:ok, handle} = :eldap.open(['example.local'], [{:port,636}, {:ssl, true}])

authenticated = 
  :ok == :eldap.simple_bind(handle, 
    'CN=Administrator Account,CN=Users,DC=example,DC=local', 
    'password')

:eldap.add(handle, 'cn=John K Doe,cn=Users,dc=example,dc=local',
[{'objectclass', ['user']},
 {'displayName', ['John K. Doe']},
 {'givenName', ['John']},
 {'initials', ['K']},
 {'sn', ['Doe']},
 {'sAMAccountName', ['john.k.doe']},
 {'userPrincipalName', ['john.k.doe@example.local]},
 {'cn', ['John K Doe']},
 {'unicodePwd', ['abc@123!']}, # => { :error, :unwillingToPerform }
])

:eldap.close(handle)

I was able to get similar code to work in golang:

	// Encoding password
	utf16 := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
	encoded, err := utf16.NewEncoder().String("\"abc@123!\"")

	// Building Add Request for User Object
	addReq := ldap.AddRequest{
		DN: "CN=John W Doe,CN=Users,DC=example,DC=local",
		Attributes: []ldap.Attribute{
			ldap.Attribute{"objectClass", []string{"user"}},
			ldap.Attribute{"displayName", []string{"John W. Doe"}},
			ldap.Attribute{"givenName", []string{"John"}},
			ldap.Attribute{"sn", []string{"Doe"}},
			ldap.Attribute{"initials", []string{"W"}},
			ldap.Attribute{"sAMAccountName", []string{"john.w.doe"}},
			ldap.Attribute{"userPrincipalName", []string{"john.w.doe@example.local"}},
			ldap.Attribute{"unicodePwd", []string{encoded}},
			ldap.Attribute{"userAccountControl", []string{"512"}},
		},
	}

Any help would be most appreciated.

1 Like

It looks like the :unicode module in Erlang should be able to help converting the data, just like your golang example does:

http://erlang.org/doc/man/unicode.html

On my phone now, so I can’t experiment with it unfortunately… :sunglasses:

1 Like

Also, I made a binary based LDAP module for Elixir, it is read-only currently but I left it open for future development to be expanded if you want to make a PR for it. The interface is quite a bit nicer. :slight_smile:

1 Like

Thanks, the :unicode module fixed my problem. Below is what I changed:

encode = :unicode.characters_to_binary(~s("abc@123!"), :utf8, {:utf16, :little})
:eldap.add(handle, 'cn=John K Doe,cn=Users,dc=example,dc=local',
[{'objectclass', ['user']},
 {'displayName', ['John K. Doe']},
 {'givenName', ['John']},
 {'initials', ['K']},
 {'sn', ['Doe']},
 {'sAMAccountName', ['john.k.doe']},
 {'userPrincipalName', ['john.k.doe@example.local']},
 {'cn', ['John K Doe']},
 {'unicodePwd', [encode]},
 {'userAccountControl', ['512']}
])

This creates an account with the password abc@123!, and enables it. I was able to log in using the password. It took me a little longer than I want to admit due to using a simpler password that wasn’t meeting the password policy which also gives you the :unwillingToPerform error.

@OvermindDL1 your module looks awesome. I’ll definitely keep it in mind. I’m very new to Elixir/Erlang and programming in general. This was basically a proof of concept for me, in order to see if I could get Elixir to do what I need. It took me quite a while to figure out how to parse the search results from :eldap. Once I get a few more books on Elixir under my belt, I plan to come back to it.

Thank you both for your help.

3 Likes