Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Active Directory LDAP Issues #348

Closed
mechanysm opened this issue Oct 5, 2017 · 38 comments
Closed

Active Directory LDAP Issues #348

mechanysm opened this issue Oct 5, 2017 · 38 comments
Assignees
Milestone

Comments

@mechanysm
Copy link

mechanysm commented Oct 5, 2017

Maybe its just me but at the moment I feel like I have tried everything.

Is it possible to get 4minitz working with active directory ldap? at the moment all I receieve is "Login error Invalid credentials [403]"

the logs say something along the lines of:
{"dn":"","code":49,"name":"InvalidCredentialsError","message":"80090308: LdapErr: DSID-0C0903D3, comment: AcceptSecurityContext error, data 52e, v3839\u0000"}

Current cut down ldap settings.

"ldap": {
        "enabled": true,
        "propertyMap": {
            "username": "sAMAccountName",
            "longname": "cn",
            "email": "mail"
        },
        "searchFilter": "",
        "serverDn": "DC=workplace,DC=local",
        "serverUrl": "ldap://servername.workplace.local:389",
        "allowSelfSignedTLS": true,
        "whiteListedFields": [ "sAMAccountName", "cn", "mail" ],
        "inactiveUsers": {"strategy": "none"},
        "autopublishFields": [ "sAMAccountName", "cn" ],
        "importCronTab": "* 14 5 * * *"
@derwok
Copy link
Member

derwok commented Oct 5, 2017

Yes, we've seen errors like this in MS AD environments. Some AD servers need a bind() with valid credentials before they allow queries of the AD DB.

Please try settings like this:

"ldap": {
     "enabled": true,
      [... your stuff...]
      "authentication": {
            "userDn": "YOURDC\\username",
            "password": "XXX"
        }
}

Sometimes this syntax works for authentication: "userDn": "cn=admin, ou=Admins, dc=example, dc=com",

Please report back if this works for you.
And don't foget to "star" us on github if you like 4Minitz. ;-)

@derwok
Copy link
Member

derwok commented Oct 5, 2017

One more thing: I see you have not set an "inactive user" setting... Please ask your LDAP admin and consider something like:
"inactiveUsers": {"strategy": "userAccountControl"},

Otherwise users switched to inactive in LDAP will be able to login to 4Minitz.

@mechanysm
Copy link
Author

mechanysm commented Oct 5, 2017

Nope this didn't seem to do anything, does it matter what the format is?

Based on the sample config it looks different than you have described (neither has worked)

        "authentication": {
            "userDn": "CN=ldapuser,CN=Users,DC=workplace,DC=local",
            "password": "somepassword"
        },

Am happy to star you guys am really excited to get this going.

@mechanysm
Copy link
Author

I have been doing a bit of wiresharking and it looks like active directory accepts a bind like this:
bindRequest(1) "username@workplace.local" simple

But depending on your setup what is being sent by 4minitz is:
bindRequest(1) "uid=username,DC=workplace,DC=local" simple
or
bindRequest(1) "sAMAccountName=username,DC=workplace,DC=local" simple

without being able to specify that the suffix is @workplace.local I think AD will not work till something is changed

I am happy to do testing, currently I am using the docker version so not sure how I would make code changes though.

@migerh
Copy link
Contributor

migerh commented Oct 6, 2017

Thanks for checking @derwok 's suggestion. Let me take a look and I'll get back to you when I find something.

@migerh
Copy link
Contributor

migerh commented Oct 8, 2017

@terryb8s I just pushed a potential fix for this issue (19792c8). @derwok will build a new docker image with a specific tag for you to check out. This fix introduces a new ldap setting, that enables the use of a user's email address. This assumes that username@workplace.local is indeed the users email address as stored in the AD. If not, I assume it is the users uid plus the AD's baseDN? Please let me know and I'll extend the patch.

The new setting is called bindWith:

"ldap": {
        "enabled": true,
        "bindWith": "mail",
…

@mechanysm
Copy link
Author

@migerh I had a look as its not the mail attribute its using, it appears to be userPrincipalName.

For example:
If our company name was Acme.
External domain = acme.com
Internal local domain = acme.local
Emails = firstname.lastname@acme.com
userPrincipalName = username@acme.local

Thanks for the quick response to all this.

@derwok
Copy link
Member

derwok commented Oct 8, 2017

Hi,
please try the docker image with the tag ldap-email-348 (long line! keep scrolling!):

docker run -it --rm -v $(pwd)/4minitz_storage:/4minitz_storage -p 3100:3333 4minitz/4minitz:ldap-email-348

Then inside the settings.json ldapsection use Michaels new setting:

ldap: {
     // ... blabla
     "bindWith": "mail"
      "authentication": {
            "userDn": "username@workplace.local",
            "password": "XXX"
        }
}

See his branch commit for details: 19792c8

Please report back if this goes into the right direction?
It seems LDAP leaves quite some room for interpretation - we see different behaviour all over the place...

@migerh
Copy link
Contributor

migerh commented Oct 8, 2017 via email

@migerh migerh self-assigned this Oct 18, 2017
@migerh
Copy link
Contributor

migerh commented Oct 18, 2017

I'm sorry for the delay @terryb8s

We now have a new docker image available, you can pull it with the ldap-email-348 label: 4minitz/4minitz:ldap-email-348

The ldap bindWith setting now allows you to set any LDAP attribute and that attribute will be used for the bind operation. In your case you may try it with the value userPrincipalName. Then import your users and then try to log in.

@mechanysm
Copy link
Author

I must be missing something here but I have no idea how to run importUsers.js there is no ./private so note sure where its supposed to run from.

@mechanysm
Copy link
Author

Yeah i'm really confused sorry, it doesn't seem to work, the authentication method has the username and password and my wireshark doesn't show any form of authentication happening.

Exception while invoking method 'login' TypeError: Cannot read property 'profile' of undefined
at Object.LDAP.bindValue (server/ldap.js:63:20)
at Object.LDAP._bind (packages/babrahams_accounts-ldap.js:231:33)
at [object Object]. (packages/babrahams_accounts-ldap.js:410:10)
at packages/accounts-base/accounts_server.js:468:32
at tryLoginMethod (packages/accounts-base/accounts_server.js:245:14)
at AccountsServer.Ap._runLoginHandlers (packages/accounts-base/accounts_server.js:465:18)
at [object Object].methods.login (packages/accounts-base/accounts_server.js:528:27)
at maybeAuditArgumentChecks (packages/ddp-server/livedata_server.js:1768:12)
at packages/ddp-server/livedata_server.js:719:19
at [object Object].EVp.withValue (packages/meteor.js:1135:15)

bindWith is set to userPrincipalName like you suggest.

@mechanysm
Copy link
Author

Is it possible to just have it so I can set the userDn to ldap@workplace.local and have it send that somehow?

Would it then use that to auth users or try and construct the userPrincipalName itself? e.g. user@workplace.local?

@derwok
Copy link
Member

derwok commented Oct 20, 2017

I can clarify on the importUsers.js:

1.) Good news: to just check LDAP config it is not necessary to import LDAP users. Simply try to login with a valid LDAP account. If the bind succeeds, then 4minitz will create an internal user account (only name & long name, no password - this will be checked against ldap). we need this local 4minitz account to store - e.g. user roles/access rights and settings.

2.) The importUsers script has the purpose to import all(!) LDAP users (at least those that survive your configured LDAP search filter in settings.json) into 4minitz. The advantage of doing so on a production server is that 4minitz users can assign action item responsibles and invite other users to meetings very easy with a "TypeAhead" / "Name Completion" user interface once 4minitz knows all users.
=> So for the time being you can skip this step while you stil have problems logging in.

3.) Unfortunately we never tested how/if importUsers works in a docker deployment (we run some instances without docker). And the sad news is: currently it does not work. I have opened a second issue for that and will take care for this: #359 - but this is currently not your problem

So, basically you are still stuck with step#1. And I would hope that @migerh can further help you there.
Sorry for this hazzle. LDAP is a complicated topic. And we are no LDAP experts. We really appreciate your patience and are happy to learn and improve on other scenarios!

@migerh
Copy link
Contributor

migerh commented Oct 20, 2017

1.) This is not correct. With bindWith set it tries to read the relevant property from the user's profile which has to be imported first. This is exactly the stack trace we see here. Of course this is not ideal. It should be possible to change this but then every user will have to login with ldap@workplace.local instead of a username or his email address.

@derwok
Copy link
Member

derwok commented Oct 20, 2017

Oh! I see. Then I have to fix #359 first.
It's on the way... stay tuned! ;-)

@migerh
Copy link
Contributor

migerh commented Nov 3, 2017

@derwok I see that #359 is closed now. Is a new docker image available?

@terryb8s Once the image is available, please set the ldap setting "importOnLaunch": true and try again.

@derwok
Copy link
Member

derwok commented Nov 4, 2017

Hi, yes -the docker image is available. Sorry. I forgot to comment here.

So, @terryb8s please perform

docker run -it --rm -v $(pwd)/4minitz_storage:/4minitz_storage -p 3100:3333 4minitz/4minitz:ldap-email-348

And make sure the new image is downloaded from docker hub. If not (or in doubt), this image label should work also: 4minitz/4minitz:gitcommit-b52bb852

The new image will not overwrite, but use your existing settings.json. Make sure you insert the new setting "importOnLaunch": true, as @migerh mentioned, into your settings.json. You can also see the new setting here in our sample settings:

"importOnLaunch": true,

Some "back ground info" for the new setting:
We support two LDAP scenarios:

  1. If LDAP works in a way that the login username also serves as LDAP bind name, it is possible that users are auto-imported one-by-one into 4Minitz on first successful login. This does not work on your server.
  2. If the above does not work, 4Minitz needs all users imported once by the admin. Then we store the bind path for every user. From then on users should be able to log in. The "importUsers" script for this job unfortunately was not reachable for docker deployment. Our fault!

So, to support scenario#2 for docker deployment, we introduced the above new setting. So, when LDAP is "enabled" and "importOnLaunch": true is set, then 4Minitz will try to import all users that match the current LDAP filter into the 4Minitz user database at every launch of 4Minitz server backend. Athentication is still done via LDAP, for sure!

So, please give the new image a try.
And thanks again for your patience.

@mechanysm
Copy link
Author

@derwok I should be thanking you for working on this problem I appreciate it.

So this is the result good and bad.

Success with the importOnLaunch setting but only when setup like this, users are imported.

        "bindWith": "dn",
        "authentication": {
            "userDn": "ldapbind@workplace.local",
            "password": "somepassword"
        },

Which results in this in wireshark

LDAPMessage bindRequest(1) "ldapbind@stgeorges.local" simple
LDAPMessage bindResponse(1) success

The problem with this is that neither sAMAccountName or userPrincipalName work in the bindWith setting and the user DN I am using is the only workaround I could think of as otherwise the result is like this in wireshark.

With sAMAccountName:
LDAPMessage bindRequest(1) "sAMAccountName=username,DC=workplace,DC=local" simple

With userPrincipalName:
Nothing readable
This in the 4minitz logs:
An error occurred: InvalidCredentialsError: 80090308: LdapErr: DSID-0C090400, comment: AcceptSecurityContext error, data 52e, v1db1

sAMAccountName is incorrect I think as it should be more like this which is an attempt from a bug tracker project called Mantis

bindRequest(3) "CN=someuser,OU=plebs,OU=staff,OU=department,DC=workplace,DC=local" simple .

Which I think works as opposed to userPrincipalName because its the full path to the user in AD. Mantis appears to do a search for the user first using the bindwith user then when it finds a matching result it uses it to do a bind.

I get the feeling that in the end if you had a setting like "domainSufix": "workplace.local", then you could create the bind string required using sAMAccountName@domainSufix which Active directory appears to accept.

Hope this all makes sense its late here,

@bmachek
Copy link

bmachek commented Nov 10, 2017

I don't get past the "Exception while invoking method 'login' TypeError: Cannot read property 'profile' of undefined error". What did I miss?

@migerh
Copy link
Contributor

migerh commented Nov 12, 2017

@terryb8s

Which I think works as opposed to userPrincipalName because its the full path to the user in AD. Mantis appears to do a search for the user first using the bindwith user then when it finds a matching result it uses it to do a bind.

This is what bindWith: "dn" does. On user import it stores the user's full dn in the database and uses that to bind that user with LDAP. Based on your input above it looked like your LDAP server only accepts binding with a specific user attribute (here: userPrincipalName) and without the whole dn. It also looks like we're getting closer. What do you mean when you say "Nothing readable"? Maybe there's an encoding problem somewhere?

@bmachek Can you please elaborate? E.g. with your (redacted if necessary) ldap settings? But please do so in a separate issue? It gets hard quickly if we try to discuss two possibly independent problems in the same issue. Thanks!

@bmachek
Copy link

bmachek commented Nov 12, 2017

sorry for the confusion, it's working now... helps to edit the configuration file not the backup copy :)

@migerh
Copy link
Contributor

migerh commented Nov 12, 2017

Success with the importOnLaunch setting but only when setup like this, users are imported.

    "bindWith": "dn",
    "authentication": {
        "userDn": "ldapbind@workplace.local",
        "password": "somepassword"
    },

Ok, now I'm confused. I just tried to set this up, knowing that I won't be authenticated by the test ldap server. But I already get an exception on the client side with ldapjs complaining about "InvalidDnSyntax". Apparently, ldapjs does not support using e.g. ldapbind@workplace.local to bind to LDAP. It has to be a valid DN. Can you please verify that this syntax really works?

@mechanysm
Copy link
Author

Hi @migerh have done some more work on this and have got it going thank you so much!

These are the settings I used for Active Directory, "username": "sAMAccountName" and the "userDn": "..." are the important parts that made it work.

    "ldap": {
        "enabled": true,
        "propertyMap": {
            "username": "sAMAccountName",
            "longname": "cn",
            "email": "mail"
        },
        "authentication": {
            "userDn": "cn=ldapbind, cn=users, dc=workplace, dc=local",
            "password": "MyPassword"
        },
        "bindWith": "dn",
        "searchFilter": "(objectCategory=person)",
        "serverDn": "DC=workplace,DC=local",
        "serverUrl": "ldap://server.workplace.local:389",
        "allowSelfSignedTLS": false,
        "whiteListedFields": [ "uid", "cn", "department", "employeeNumber", "mail", "mailEnabled" ],
        "inactiveUsers": {"strategy": "userAccountControl"},
        "autopublishFields": [ "cn" ],
        "importOnLaunch": true,
        "importCronTab": false

I notice you can't have importcrontab along with a importonlaunch? Is there a reason for this? would be good to have it update as users are added rather then having restart to populate every time, or is importonlaunch intended for initial population then change to importcrontab from there?

Also it appears I can't add more than one searchfilter otherwise it complains about to incorrect use of parentheses, maybe I just don't understand the syntax for this?

@mechanysm
Copy link
Author

Do you need anything more from me? I think I am happy for this to be closed otherwise?

@migerh
Copy link
Contributor

migerh commented Dec 5, 2017

No, I think we're done here. Thanks again for checking this and being persistent.

I'll open up separate issues about the importCronTab vs importOnLaunch issue and the searchFilter issue.

@migerh
Copy link
Contributor

migerh commented Dec 14, 2017

Reopened because a merge was requested in #385. We first need to check if a merge is necessary or if the config above works with what is already present on our develop branch.

@migerh
Copy link
Contributor

migerh commented Jan 7, 2018

I finally had the time to check if there is anything we need on our feature branch for this issue.

@derwok Can you please create a new docker image of that branch? Then @terryb8s can check if it still works, even without the bindWith setting. If so we can merge the branch and close this issue.

@migerh migerh added this to the v1.1.0 milestone Jan 7, 2018
@derwok
Copy link
Member

derwok commented Jan 7, 2018

The docker image is published as 4minitz/4minitz:gitcommit-5d6fd3f4 on dockerhub.
Terry, could you please check, if with this image still everythin runs fine on your side?
The branch still has the "ldap.importOnLaunch" setting per default enabled, so initial user import happens on every launch.

If everything OK on your end, then we can merge the branch to develop. We are currently in collecting the stuff that goes to the next master release 1.1.
Thankx in advance.

@mechanysm
Copy link
Author

Hi Guys, I moved to the dev version when @migerh mentioned that we need to check if a merge is necessary and he was correct in thinking this as everything seems to be working, .

I have tested the 4minitz/4minitz:gitcommit-5d6fd3f4 image though and this doesn't work.
`------------------------------- New 4Minitz!
/4minitz_bin/bundle/programs/server/boot.js:50
const { pause } = require("./debug.js");
^

SyntaxError: Unexpected token {
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:373:25)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at Object. (/4minitz_bin/bundle/main.js:4:1)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
`

@migerh
Copy link
Contributor

migerh commented Jan 15, 2018

Ah, alright. The only difference between develop and this branch is the "importOnLaunch" LDAP setting. So if you already moved to the develop branch it should be fine. I'll take a look at the image @derwok created of this branch but my guess is something unrelated went wrong during build or image creation.

Thanks again for your help and your patience!

@felixmw
Copy link

felixmw commented Feb 15, 2018

Hi there,

I am also trying to hook up 4minitz with our corporate Active Directory. But so far I am stuck with the following error messages in the log

{"dn":"","code":49,"name":"InvalidCredentialsError","message":"80090308: LdapErr: DSID-0C09042F, comment: AcceptSecurityContext error, data 52e, v2580\u0000"}
LDAP bind failed with error
{"dn":"","code":49,"name":"InvalidCredentialsError","message":"80090308: LdapErr: DSID-0C09042F, comment: AcceptSecurityContext error, data 52e, v2580\u0000"}

I am using the docker image from the development branch (4minitz/4minitz:develop) and have the ldap section of the config json set up as follows:

"ldap": {
    "enabled": true,
    "propertyMap": {
        "username": "sAMAccountName",
        "longname": "cn",
        "email": "mail"
    },
    "//1": "Optional, will perform bind with these credentials before searching for users",
    "authentication": {
        "userDn": " CN=[ldapbind],OU=BENUTZER,DC=[mycompany],DC=de",
        "password": "[mypassword]"
    },
    "searchFilter": "(objectClass=user)",
    "serverDn": "DC=[mycompany],DC=de",
    "serverUrl": "ldap://srvdc.[mycompany].de:389",
    "allowSelfSignedTLS": true,
    "whiteListedFields": [ "uid", "cn", "department", "employeeNumber", "mail", "mailEnabled" ],
    "inactiveUsers": {"strategy": "userAccountControl"},
    "autopublishFields": [ "cn" ],
    "importOnLaunch": true,
    "importCronTab": false

I also tried to set the userDn to [ldapbind]@[mycompany].de. But this also did not work.

I am sure that the bind credentials are correct since I tested it with JXplorer.

Any idea what is going wrong or what I have to do differently?

Thanx for your support,
Best
Felix

@derwok
Copy link
Member

derwok commented Feb 16, 2018

Hi Felix,
too bad you also have problems. As we have seen quite a few LDAP settings in "work mode" now, and looking at your error message, Ithink this is not a 4Minitz problme. I would expect we simply have not yet found the format that your specific LDAP/AD server accepts.

First thing I see: there is a leading space in your userDn config. Should not make problems - but maybe your server is picky?

Then some quick suggestions:

  • On an "official" Microsoft AD domain controller I have seen working 4Minitz binds with
    • "authentication": { "userDn": "USERNAME", ...
      Where USERNAME simply is the User account name. Also known as the logon name.
    • "authentication": { "userDn": "DOMAIN\\USERNAME", ...
      Where DOMAIN is the NetBIOS domain name. (Double backslash needed in JSON!)

So maybe you give this a shot? If this does not work - is there a possibility to talk to an admin (if you are not the admin) and get access to some AD/LDAP server logs to gather more information what goes wrong - so e.g. bind with your JXplorer then with 4Minitz and find differences?

Last, could you state what exact AD/LDAP server (brand name, incl. version) you are using in your company?

@felixmw
Copy link

felixmw commented Feb 28, 2018

Hi Wolfram,

thanks for your feedback. I tried all the different options that you mentioned but so far none of them solved the problem. I also got access to the log files of our Active Directory but this did not really helped a lot. The binds from 4Minitz do not generate any events in here. This is a pattern that I observe from other systems if the try to bind with an unknown user. In these cases the logs do not record any events. This is different for bind attempt with an existing user but a wrong password. In this case two events are logged (4776, 4625).

So I guess it really is a problem with specifying the binding user in a format that works for our Active Directory.

We us a Microsoft Windows Server 2012.

Any further suggestions?

Thanks a lot for your support,
best
Felix

@felixmw
Copy link

felixmw commented Mar 2, 2018

...or is there a way to get more detailed logs from 4minitz.
The 4minitz.log only gives the following information:

{"dn":"","code":49,"name":"InvalidCredentialsError","message":"80090308: LdapErr: DSID-0C09042F, comment: AcceptSecurityContext error, data 52e, v2580\u0000"}
LDAP bind failed with error
{"dn":"","code":49,"name":"InvalidCredentialsError","message":"80090308: LdapErr: DSID-0C09042F, comment: AcceptSecurityContext error, data 52e, v2580\u0000"}
ldapjs client reported an error: 

Thanx
Felix

@migerh
Copy link
Contributor

migerh commented Mar 6, 2018

According to this wiki, data 52e means that the username is correct, but the password is invalid. Is there, by any chance, a backslash \in the password which is unescaped?

@migerh
Copy link
Contributor

migerh commented Mar 9, 2018

I just realized I forgot the link to the wiki:

https://docs.servicenow.com/bundle/jakarta-platform-administration/page/administer/reference-pages/reference/r_LDAPErrorCodes.html?title=LDAP_Error_Codes

If you search for 52e on that site you find this info:

Indicates an Active Directory (AD) AcceptSecurityContext error, which is returned when the username is valid but the combination of password and user credential is invalid. This is the AD equivalent of LDAP error code 49: LDAP_INVALID_CREDENTIALS.

@migerh
Copy link
Contributor

migerh commented Mar 16, 2018

I'm closing this issue because we already have two issues that are discussed in here.

@felixmw if you still have problems connecting 4minitz to LDAP please open a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants