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
Teach pgBouncer to do auth_query for users defined without a password. #1039
Conversation
As described in pgbouncer#484, if a user is defined in the [users] section of the config file (perhaps to take advantage of per-user overrides) but then that user is *not* defined in auth_file, pgBouncer currently gets confused when trying to check their password. It sees the user exists, but fails to notice a password was never defined, resulting in no running of auth_query.
As described in pgbouncer#484, if a user is defined in the [users] section of the config file (perhaps to take advantage of per-user overrides) but then that user is *not* defined in auth_file, pgBouncer currently gets confused when trying to check their password. It sees the user exists, but fails to notice a password was never defined, resulting in no running of auth_query. Add a test case to catch this. The case successfully fails before this patchset and succeeds after it.
As described in pgbouncer#484, if a user is defined in the [users] section of the config file (perhaps to take advantage of per-user overrides) but then that user is *not* defined in auth_file, pgBouncer currently gets confused when trying to check their password. It sees the user exists, but fails to notice a password was never defined, resulting in no running of auth_query. Add a test case to catch this. The case successfully fails before this patchset and succeeds after it.
As described in pgbouncer#484, if a user is defined in the [users] section of the config file (perhaps to take advantage of per-user overrides) but then that user is *not* defined in auth_file, pgBouncer currently gets confused when trying to check their password. It sees the user exists, but fails to notice a password was never defined, resulting in no running of auth_query.t Add a test case to catch this. The case successfully fails before this patchset and succeeds after it.
I'm not really sure what's going on with these tests, and I think it's clear I'm flailing around more than enough on github. However, this really does seem to address an outstanding bug with auth_query and configured users. |
While reviewing pgbouncer#1039 I had a hard time max_user_connections seeing if max_user_connections was applied correctly because `SHOW USERS` didn't list it. This addresses that by adding a `max_user_connections` and `current_connections` column to the output of `SHOW USERS`.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your work on this! This is indeed quite an annoying bug. I think overall direction is good, but I think we should go a bit further with the change because I dislike the cf_user checks that now proliferate the codebase.
Also, I just created while reviewing this PR #1040 I'd appreciate it if you could take a look at that and let me know if you think that change makes sense.
While reviewing pgbouncer#1039 I had a hard time max_user_connections seeing if max_user_connections was applied correctly because `SHOW USERS` didn't list it. This addresses that by adding a `max_user_connections` and `current_connections` column to the output of `SHOW USERS`.
This reduces checks that must be made throughout the code, though it does not reduce the need to know which record is the proper one (user or user->cf_user) to use. Also, pre-emptively make uncrustify happy *before* github has a go at it.
OK @JelteF, I think I addressed all your points. Let me know what you think. |
While reviewing #1039 I had a hard time seeing if max_user_connections was applied correctly because `SHOW USERS` didn't list it. This addresses that by adding a `max_user_connections` and `current_connections` column to the output of `SHOW USERS`.
The comments are more accurate, and the unit test now runs against freebsd as well as other OSs.
The current logic that adds those users to the I believe the following would be a better approach: The users in the [user] section are not added to the same list with auth_file users. A new structure is used to maintain them, e.g:
If a user is not found in auth_file users
|
Sorry @emelsimsek, I'm afraid I'm not seeing what we gain by having two different user trees? My understanding of user_tree is that it is used as the collection of users that pgBouncer knows about. What do we gain by having one set for users whose password comes from auth_query and another set where the password comes from auth_file? Wouldn't we need to check both trees in every place where we are currently checking just one? |
@benchub My thinking goes like this: The Users section is for overriding user configurations for users that comes from various sources. The users and their authentication tokens could be defined in either auth_file or remote user directories such as LDAP. Therefore for flexibility reasons, the user configurations should be maintained in a different list then auth_file's list. |
OK @emelsimsek, I've spent some time trying to understand more of the pgBouncer codebase and I'm afraid I don't understand how to implement what you're suggesting, or even understand enough to see how it would help. I assume when you say, "remote user directories such as LDAP" you are talking about PAM authentication and using LDAP as a PAM provider. I can appreciate that having user credentials being possibly defined in 3 places (pam, auth_file, or auth_query) could get messy, but the documentation is clear that pam is incompatible with the other two options. And indeed, when I look at the code base, there are multiple times that pgBouncer says "Oh, in the case of PAM, do this all differently" - for example, client.c:set_pool(), admin.c:show_one_fd(), or objects.c:use_server_socket(). It's a fair question to ask if pgBouncer should do it all differently, or if it should, as you seem to be suggesting, be able to use auth_query, auth_file, and pam all at the same time. I would suggest that such a change in behavior is beyond the scope of this bug fix. More importantly, I don't know how to test pgBouncer using PAM. I don't see any unit tests doing so to work from, I don't have PAM set up in any of my environments, and frankly, while I remember PAM coming to linux almost 30 years ago, I've never set it up in all that time. I'm sure somebody is using it, but it's not me. I'm uncomfortable proposing code I don't have the ability to test. Less importantly, in many of the places that the (currently only) user_tree is queried, it looks like having additional trees would seem to complicate the code for little gain. For example, objects.c:user_client_socket(), admin.c:admin_setup(), or admin.c:show_one_fd(). |
Yes, the users may be defined in an LDAP directory and this is integrated into pgbouncer using PAM libraries.
auth_file and LDAP are alternatives to each other. users section in the configuration file on the other hand looks like intended to overrride user configurations for particular users.
I agree that for getting this functionality work in its simplest form, the code change can be kept limited as you had done.
|
Yeah. FWIW I did modify add_pam_user in the same way I modified add_db_user, and the unit test I added does make sure that add_db_user (for auth_query users) does work correctly, so I don't think it's unreasonable to assume pam users also work with this change. But again, I don't know how to test that. So @JelteF, anything else needed to let this be merged? |
@JelteF are you waiting on me for anything? |
I feel like As a side note, adding self referencing pointer and additional boolean to make this work feels hacky to me. But that is of course up to @JelteF and @emelsimsek to decide. Edit: some grammar improvements. Edit-2: If we were to separate them into different structures, I guess it would be a breaking change, deserving a major version bump? Though this would require some compatibility tests when implemented. |
The more I look into this the more I realize how big of a mess our user management currently is. I definitely think we need some distinction between different types of users. It's super confusing to reason about. I'm trying out a few options for this at the moment. |
I created a PR for the user management refactor here: #1052 |
Based upon #1039, but changed a lot by splitting the PgUser type into two different types. One type for storing global user configuration, auth info, and connection count tracking and a second type for dynamically created users (which always references a global user). This makes user configuration work for dynamically created users and will also list dynamically created users in the output of `SHOW USERS`. Fixes #484 Fixes #706 Resolves #1039 Co-authored-by: Ben Chobot <bench@instructure.com> Co-authored-by: benchub <bench@silentmedia.com>
As described in #484, if a user is defined in the [users] section of
the config file (perhaps to take advantage of per-user overrides)
but then that user is not defined in auth_file, pgBouncer currently
gets confused when trying to check their password. It sees the user
exists, but fails to notice a password was never defined, resulting
in no running of auth_query.
Add a test case to catch this. The case successfully fails before
this patchset and succeeds after it.
Fixes #484
Fixes #706