portainer: LDAP password can't be made empty after setting it once

Bug description When Portainer is freshly installed, the LDAP reader DN and password are both empty and anonymous access to an LDAP server works as expected. However, if you set a reader password in the settings, there is no way to set it back to empty and thus no way for anonymous access to the LDAP server to work again unless you wipe the settings storage.

This happens both, using the Portainer UI and the Portainer API. The problem seems to be that when sending an empty password "Password":"" inside LDAPSettings, the backend API considers this as do not change the password instead of set the password to empty and therefore retains any previously set password in the settings storage. The LDAP password is then impossible to be set back to empty, which is required for anonymous LDAP access.

Setting the reader DN to empty "ReaderDN":"" after having a value works as expected.

Related issue: #1118

Expected behavior When sending an empty "Password":"" inside LDAPSettings, it should be set as empty in the settings storage. This should work from both the Portainer UI and API.

Currently, if you don’t send a Password attribute in LDAPSettings or is null, the API does not change the password in the settings storage. Perhaps this behaviour could be made exclusive for do not change the password and make empty strings regular settable values. In other words:

  • If "Password"=null or is absent, do not change the password in the Settings storage (this is existing current behaviour in the Portainer API).
  • If "Password"="" or any value, update the password in the Settings storage (the Portainer API should consider an empty string "" as a settable value).

For the Portainer UI side, this can become a bit tricky because there is no way to distinguish a user wanting to set an empty password from a user wanting to leave the current password unchanged. Both cases would be an empty input field in the UI. Maybe there could be an explicit clear password button.

In addition, if you don’t provide a reader DN and password, you can’t test the LDAP configuration in the Portainer UI because it is expecting these settings to be set. However using the checkLDAP API endpoint does work if you don’t send a Password attribute.

Steps to reproduce the issue:

  1. Install a fresh copy of Portainer.
  2. Configure LDAP settings without setting a reader DN nor password.
  3. Verify that you can authenticate to an LDAP server using anonymous access. Notice that you can’t use the check LDAP configuration here without a reader DN/password. Instead you must add a valid LDAP user to Portainer and re-login to Portainer using it.
  4. Go back to LDAP settings and use a valid reader DN and password.
  5. Verify that you can still authenticate using LDAP.
  6. Go back to LDAP settings and set the reader DN and password back to empty.
  7. Verify that you can’t authenticate anymore using LDAP when it should. The reason is that the previous reader password is not set back to empty and thus Portainer is trying to connect to LDAP using an empty reader DN and the previous reader password.
  8. From now on, there is no way to set the reader password back to empty and go back to using anonymous LDAP access. The only way is to wipe the settings storage (and loose all settings).

Technical details:

  • Portainer version: 1.23.0 (not exclusive to this version)

  • Docker version (managed by Portainer): 19.03.5 (Docker is not related to this bug)

  • Platform (windows/linux): linux

  • Command used to start Portainer (docker run -p 9000:9000 portainer/portainer): Official instructions to deploy as a stack:

     $ curl -L https://downloads.portainer.io/portainer-agent-stack.yml -o portainer-agent-stack.yml
     $ docker stack deploy --compose-file=portainer-agent-stack.yml portainer
    
  • Browser: Google Chrome Version 78.0.3904.108 (Official Build) (64-bit)

Additional context Portainer using LDAP authentication against and LDAP server with anonymous access.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 18 (10 by maintainers)

Commits related to this issue

Most upvoted comments

@hhromic your API PR is now under review by our go developer 🎉

@hhromic I have pushed the code suggestions you made on my previous commit, thanks.

One thing I was thinking; if settings were previously saved in anonymous mode, it would make for a better user experience to load the settings in anonymous mode when the user browses back to the view.

As for where I got on this; I thought to check whether ReaderDN is set and decide by that, but by default it is returned as "", as such it was defaulting to Anonymous on a fresh install. One way to solve this I think will be to pass around a bool for AnonymousMode

We are glad to hear that Portainer has helped you and your team 👍

FYI if you are interested in keeping your team up to date with the latest in containerization; Kubernetes is the other big player, which we will support very soon 😃

@deviantony is our go developer who I believe can give you an answer on this. Unfortunately he is on his holiday break until mid-January. If you would like to get started on this then feel free to open a PR.

In regards to the logic for this I agree with what you have stated;

  • If Anonymous mode always send both ReaderDN & Password as ""
  • If Non-anonymous mode and no password is entered, do not send a password field.

@hhromic I have opened a PR with some frontend changes for this.

  • My boolean logics skills are rusty so you may be able to improve the logic used for enabling/disabling the Test connectivity and Save settings buttons.

  • I am also not sure if we want to be setting the credentials to "" or not sending them at all, so this may need to be amended.

  • The API will probably still need to be changed to accept null or "" as reset credentials.

Yup that works for me

Rgds

@hhromic Glad to hear you are keen to help! After discussing this with my colleagues, we thought a good UI would be to have Anonymous mode checkbox that will hide the credential fields if enabled. Something like this:

image

image

@ncresswell what do you think of this UI?