public inbox for [email protected]
help / color / mirror / Atom feed[PATCH] Remove duplicate code in brin_memtuple_initialize
9+ messages / 3 participants
[nested] [flat]
* [PATCH] Remove duplicate code in brin_memtuple_initialize
@ 2020-11-08 01:11 Tomas Vondra <[email protected]>
0 siblings, 0 replies; 9+ messages in thread
From: Tomas Vondra @ 2020-11-08 01:11 UTC (permalink / raw)
Commit 8bf74967dab moved some of the code from brin_new_memtuple to
brin_memtuple_initialize, but this resulted in some of the code being
duplicate. Fix by removing the duplicate lines and backpatch to 10.
Author: Tomas Vondra
Backpatch-through: 10
Discussion: TBD
---
src/backend/access/brin/brin_tuple.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/backend/access/brin/brin_tuple.c b/src/backend/access/brin/brin_tuple.c
index 6774f597a4..17e50de530 100644
--- a/src/backend/access/brin/brin_tuple.c
+++ b/src/backend/access/brin/brin_tuple.c
@@ -491,9 +491,6 @@ brin_memtuple_initialize(BrinMemTuple *dtuple, BrinDesc *brdesc)
sizeof(BrinValues) * brdesc->bd_tupdesc->natts);
for (i = 0; i < brdesc->bd_tupdesc->natts; i++)
{
- dtuple->bt_columns[i].bv_allnulls = true;
- dtuple->bt_columns[i].bv_hasnulls = false;
-
dtuple->bt_columns[i].bv_attno = i + 1;
dtuple->bt_columns[i].bv_allnulls = true;
dtuple->bt_columns[i].bv_hasnulls = false;
--
2.26.2
--------------1A9CDC5F16256E331D56D2AE--
^ permalink raw reply [nested|flat] 9+ messages in thread
* Re: [PoC] Federated Authn/z with OAUTHBEARER
@ 2025-04-11 16:21 Wolfgang Walther <[email protected]>
2025-04-14 16:12 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
0 siblings, 1 reply; 9+ messages in thread
From: Wolfgang Walther @ 2025-04-11 16:21 UTC (permalink / raw)
To: Jacob Champion <[email protected]>; Jelte Fennema-Nio <[email protected]>; +Cc: Christoph Berg <[email protected]>; Peter Eisentraut <[email protected]>; Andres Freund <[email protected]>; Tom Lane <[email protected]>; Bruce Momjian <[email protected]>; pgsql-hackers; Daniel Gustafsson <[email protected]>; Thomas Munro <[email protected]>; Nazir Bilal Yavuz <[email protected]>; Antonin Houska <[email protected]>
Jacob Champion:
> On Wed, Apr 9, 2025 at 4:42 PM Jelte Fennema-Nio <[email protected]> wrote:
>> I think your suggestion of not using any .so files would best there (from w user perspective). I'd be quite surprised if a static build still resulted in me having to manage shared library files anyway.
> Done this way in v5. I had planned to separate the implementations by
> a #define, but I ran into issues with Makefile.shlib, so I split the
> shared and dynamic versions into separate files. I just now realized
> that we do something about this exact problem in src/common, so I'll
> see if I can copy its technique for the next go round.
I tried to apply this patch to nixpkgs' libpq build [1]. First, I pinned
a recent commit from master (one where the v5 patch will apply cleanly
later) and enabled --with-libcurl [2].
At this stage, without the patch applied, I observe the following:
1. The default, dynamically linked, build succeeds and libpq.so is
linked to libcurl.so as expected!
2. The statically linked build fails during configure:
checking for curl_multi_init in -lcurl... no
configure: error: library 'curl' does not provide curl_multi_init
config.log tells me that it can't link to libcurl, because of undefined
references, for example:
undefined reference to `psl_is_cookie_domain_acceptable'
undefined reference to `nghttp2_session_check_request_allowed'
I assume the many libs listed in Libs.private in libcurl.pc are not
added automatically for this check?
Next, I applied the v5 patch and:
3. Running the same build as in step 1 above (dynamically linked), I can
see that libpq.so does have some reference to dlopen / libpq-oauth in it
- good. But libpq-oauth.so itself is not built. The commands I am using
to build just the libpq package are essentially like this:
make submake-libpgport
make submake-libpq
make -C src/bin/pg_config install
make -C src/common install
make -C src/include install
make -C src/interfaces/libpq install
make -C src/port install
I tried adding "make submake-libpq-oauth", but that doesn't exist.
When I do "make -C src/interfaces/libpq-oauth", I get this error:
make: *** No rule to make target 'oauth-curl.o', needed by
'libpq-oauth-18.so'. Stop.
Not sure how to proceed to build libpq-oauth.so.
4. The statically linked build fails with the same configure error as above.
I can only test autoconf right now, not meson - don't have a working
setup for that, yet.
Best,
Wolfgang
[1]:
https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/sql/postgresql/libpq.nix
^ permalink raw reply [nested|flat] 9+ messages in thread
* Re: [PoC] Federated Authn/z with OAUTHBEARER
2025-04-11 16:21 Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
@ 2025-04-14 16:12 ` Jacob Champion <[email protected]>
2025-04-14 17:09 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
0 siblings, 1 reply; 9+ messages in thread
From: Jacob Champion @ 2025-04-14 16:12 UTC (permalink / raw)
To: Wolfgang Walther <[email protected]>; +Cc: Jelte Fennema-Nio <[email protected]>; Christoph Berg <[email protected]>; Peter Eisentraut <[email protected]>; Andres Freund <[email protected]>; Tom Lane <[email protected]>; Bruce Momjian <[email protected]>; pgsql-hackers; Daniel Gustafsson <[email protected]>; Thomas Munro <[email protected]>; Nazir Bilal Yavuz <[email protected]>; Antonin Houska <[email protected]>
On Fri, Apr 11, 2025 at 9:21 AM Wolfgang Walther
<[email protected]> wrote:
> I tried to apply this patch to nixpkgs' libpq build [1]. First, I pinned
> a recent commit from master (one where the v5 patch will apply cleanly
> later) and enabled --with-libcurl [2].
(The [2] link is missing, I think.)
> 2. The statically linked build fails during configure:
I'm confused by this -- the build produces staticlibs alongside the
dynamically linked ones, so that's what I've been testing against.
What different options do you pass to configure for a "statically
linked build"?
> undefined reference to `psl_is_cookie_domain_acceptable'
> undefined reference to `nghttp2_session_check_request_allowed'
>
> I assume the many libs listed in Libs.private in libcurl.pc are not
> added automatically for this check?
Not unless there is some magic in PKG_CHECK_MODULES I've never heard
of (which is entirely possible!). Furthermore I imagine that the
transitive dependencies of all its dependencies are not added either.
Does your build method currently work for dependency forests like
libgssapi_krb5 and libldap? (I want to make sure I'm not accidentally
doing less work than we currently support for those other deps, but
I'm also not planning to add more feature work as part of this
particular open item.)
> I tried adding "make submake-libpq-oauth", but that doesn't exist.
There is no submake for this because no other targets depend on it.
Currently I don't have any plans to add one (but -C should work).
> When I do "make -C src/interfaces/libpq-oauth", I get this error:
>
> make: *** No rule to make target 'oauth-curl.o', needed by
> 'libpq-oauth-18.so'. Stop.
I cannot reproduce this. The CI seems happy, too. Is this patch the
only modification you've made to our build system, or are there more
changes?
I'm about to rewrite this part somewhat, so a deep dive may not be very helpful.
Thanks,
--Jacob
^ permalink raw reply [nested|flat] 9+ messages in thread
* Re: [PoC] Federated Authn/z with OAUTHBEARER
2025-04-11 16:21 Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 16:12 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
@ 2025-04-14 17:09 ` Wolfgang Walther <[email protected]>
2025-04-14 18:27 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
0 siblings, 1 reply; 9+ messages in thread
From: Wolfgang Walther @ 2025-04-14 17:09 UTC (permalink / raw)
To: Jacob Champion <[email protected]>; +Cc: Jelte Fennema-Nio <[email protected]>; Christoph Berg <[email protected]>; Peter Eisentraut <[email protected]>; Andres Freund <[email protected]>; Tom Lane <[email protected]>; Bruce Momjian <[email protected]>; pgsql-hackers; Daniel Gustafsson <[email protected]>; Thomas Munro <[email protected]>; Nazir Bilal Yavuz <[email protected]>; Antonin Houska <[email protected]>
Jacob Champion:
> (The [2] link is missing, I think.)
Ah, sry. This is the link:
https://github.com/wolfgangwalther/nixpkgs/commits/postgresql-libpq-curl/
It's the last two commits on that branch.
> I'm confused by this -- the build produces staticlibs alongside the
> dynamically linked ones, so that's what I've been testing against.
> What different options do you pass to configure for a "statically
> linked build"?
It's not so much the options, but more that for this build there are no
shared libs available at buildtime at all. You can consider it a "fully
static system". So in your case, you'd always do the configure test with
shared libs, but I can't.
The build system passes --enable-static and --disable-shared to
configure, but both of those are ignored by configure, as indicated by a
WARNING immediately.
>> Not unless there is some magic in PKG_CHECK_MODULES I've never heard
>> of (which is entirely possible!). Furthermore I imagine that the
>> transitive dependencies of all its dependencies are not added either.
IIUC, the transitive dependencies would be part of libcurl's
Libs.private / Requires.private (assuming that file is correctly
created). So that would be taken care of, I guess.
> Does your build method currently work for dependency forests like
> libgssapi_krb5 and libldap? (I want to make sure I'm not accidentally
> doing less work than we currently support for those other deps, but
> I'm also not planning to add more feature work as part of this
> particular open item.)
We currently build libpq with neither libldap, nor libkrb5, at least for
the static case. But I just tried on the bigger postgresql package and
force-enabled libldap there for the static build - it fails in exactly
the same way.
So yes, not related to your patch. I do understand that PostgreSQL's
autoconf build system is not designed for "static only", I am certainly
not expecting you to fix that.
I think meson will do better here, but I was not able to make that work,
yet.
>> When I do "make -C src/interfaces/libpq-oauth", I get this error:
>>
>> make: *** No rule to make target 'oauth-curl.o', needed by
>> 'libpq-oauth-18.so'. Stop.
> I cannot reproduce this. The CI seems happy, too. Is this patch the
> only modification you've made to our build system, or are there more
> changes?
We apply another patch to change the default socket directory to /run,
but that's certainly unrelated. All the other custom stuff only kicks in
afterwards, in the installPhase, so unrelated as well.
I just tried the same thing on the bigger postgresql package, where the
full build is run and not only libpq / libpq-oauth. It fails with the
same error. No rule for oauth-curl.o.
> I'm about to rewrite this part somewhat, so a deep dive may not be very helpful.
OK. I will try to get meson running, at least enough to try this patch
again. Maybe that gives better results.
Thanks,
Wolfgang
^ permalink raw reply [nested|flat] 9+ messages in thread
* Re: [PoC] Federated Authn/z with OAUTHBEARER
2025-04-11 16:21 Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 16:12 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
2025-04-14 17:09 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
@ 2025-04-14 18:27 ` Wolfgang Walther <[email protected]>
2025-04-14 19:14 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
0 siblings, 1 reply; 9+ messages in thread
From: Wolfgang Walther @ 2025-04-14 18:27 UTC (permalink / raw)
To: Jacob Champion <[email protected]>; +Cc: Jelte Fennema-Nio <[email protected]>; Christoph Berg <[email protected]>; Peter Eisentraut <[email protected]>; Andres Freund <[email protected]>; Tom Lane <[email protected]>; Bruce Momjian <[email protected]>; pgsql-hackers; Daniel Gustafsson <[email protected]>; Thomas Munro <[email protected]>; Nazir Bilal Yavuz <[email protected]>; Antonin Houska <[email protected]>
Wolfgang Walther:
> So yes, not related to your patch. I do understand that PostgreSQL's
> autoconf build system is not designed for "static only", I am certainly
> not expecting you to fix that.
>
> I think meson will do better here, but I was not able to make that work,
> yet.
I did a basic meson build. Full postgresql package, not libpq-only.
The static-only build just works. On master that is. Same as the regular
build.
So yes, meson will handle the static stuff much better.
> I just tried the same thing on the bigger postgresql package, where the
> full build is run and not only libpq / libpq-oauth. It fails with the
> same error. No rule for oauth-curl.o.
Applying the v5 patch to the above meson build, will give me a different
error. This time for both the static-only and the regular build:
src/interfaces/libpq-oauth/meson.build:18:22: ERROR: File
oauth-curl.c does not exist.
This.. clears it up, because that file is indeed missing for me on disk.
I assume that's because this file is tracked as a rename in the v5
patch. I can apply this with git, but not directly in the nix build
system. TIL, I need to use "fetchpatch2" instead of "fetchpatch" for
that. Sure thing.
So, with the patch applied correctly, I get the following:
1. Meson regular build:
libpq-oauth-18.so
libpq.so
libpq.so.5
libpq.so.5.18
The libpq.so file has references to dlopen and libpq-auth-18.so, cool.
2. Meson static-only build:
libpq.a
libpq-oauth-18.a
The libpq.a file has no references to dlopen, but plenty of references
to curl stuff.
I'm not sure what the libpq-oauth-18.a file is for.
3. Back to the lipq-only build with autoconf, from where I started. I
only need to add the following line:
make -C src/interfaces/libpq-oauth install
and get this:
libpq-oauth-18.so
libpq.so
libpq.so.5
libpq.so.5.18
Sweet!
4. Of course the static-only build does not work with autoconf, but
that's expected.
So, sorry for the noise before. Now, that I know how to apply patches
with renames, I will try your next patch as well.
Best,
Wolfgang
^ permalink raw reply [nested|flat] 9+ messages in thread
* Re: [PoC] Federated Authn/z with OAUTHBEARER
2025-04-11 16:21 Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 16:12 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
2025-04-14 17:09 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 18:27 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
@ 2025-04-14 19:14 ` Jacob Champion <[email protected]>
2025-04-14 19:46 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
0 siblings, 1 reply; 9+ messages in thread
From: Jacob Champion @ 2025-04-14 19:14 UTC (permalink / raw)
To: Wolfgang Walther <[email protected]>; +Cc: Jelte Fennema-Nio <[email protected]>; Christoph Berg <[email protected]>; Peter Eisentraut <[email protected]>; Andres Freund <[email protected]>; Tom Lane <[email protected]>; Bruce Momjian <[email protected]>; pgsql-hackers; Daniel Gustafsson <[email protected]>; Thomas Munro <[email protected]>; Nazir Bilal Yavuz <[email protected]>; Antonin Houska <[email protected]>
On Mon, Apr 14, 2025 at 11:27 AM Wolfgang Walther
<[email protected]> wrote:
> src/interfaces/libpq-oauth/meson.build:18:22: ERROR: File
> oauth-curl.c does not exist.
>
> This.. clears it up, because that file is indeed missing for me on disk.
Aha! Okay, glad I don't need to track that down.
> libpq.a
> libpq-oauth-18.a
>
> The libpq.a file has no references to dlopen, but plenty of references
> to curl stuff.
Which references? libpq-oauth should be the only thing using Curl symbols:
$ nm src/interfaces/libpq/libpq.a | grep --count curl
0
$ nm src/interfaces/libpq-oauth/libpq-oauth-18.a | grep --count curl
116
> I'm not sure what the libpq-oauth-18.a file is for.
That implements the flow. You'll need to link that into your
application or it will complain about missing flow symbols. (I don't
think there's an easy way to combine the two libraries in our Autoconf
setup; the only ways I can think of right now would introduce a
circular dependency between libpq and libpq-oauth...)
Thanks!
--Jacob
^ permalink raw reply [nested|flat] 9+ messages in thread
* Re: [PoC] Federated Authn/z with OAUTHBEARER
2025-04-11 16:21 Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 16:12 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
2025-04-14 17:09 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 18:27 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 19:14 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
@ 2025-04-14 19:46 ` Wolfgang Walther <[email protected]>
2025-04-14 20:17 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
0 siblings, 1 reply; 9+ messages in thread
From: Wolfgang Walther @ 2025-04-14 19:46 UTC (permalink / raw)
To: Jacob Champion <[email protected]>; +Cc: Jelte Fennema-Nio <[email protected]>; Christoph Berg <[email protected]>; Peter Eisentraut <[email protected]>; Andres Freund <[email protected]>; Tom Lane <[email protected]>; Bruce Momjian <[email protected]>; pgsql-hackers; Daniel Gustafsson <[email protected]>; Thomas Munro <[email protected]>; Nazir Bilal Yavuz <[email protected]>; Antonin Houska <[email protected]>
Jacob Champion:
>> libpq.a
>> libpq-oauth-18.a
>>
>> The libpq.a file has no references to dlopen, but plenty of references
>> to curl stuff.
>
> Which references? libpq-oauth should be the only thing using Curl symbols:
>
> $ nm src/interfaces/libpq/libpq.a | grep --count curl
> 0
> $ nm src/interfaces/libpq-oauth/libpq-oauth-18.a | grep --count curl
> 116
Not sure what I was looking at earlier, probably too many different
builds at the same time. Now I can't find the curl symbols in libpq.a
either...
>> I'm not sure what the libpq-oauth-18.a file is for.
>
> That implements the flow. You'll need to link that into your
> application or it will complain about missing flow symbols. (I don't
> think there's an easy way to combine the two libraries in our Autoconf
> setup; the only ways I can think of right now would introduce a
> circular dependency between libpq and libpq-oauth...)
... which immediately explains what the libpq-oauth-18.a file is for, yes.
But that means we'd need a -lpq-oauth-18 or something like that in
Libs.private in libpq.pc, right?
This seems to be missing, I checked both the autoconf and meson builds.
Best,
Wolfgang
^ permalink raw reply [nested|flat] 9+ messages in thread
* Re: [PoC] Federated Authn/z with OAUTHBEARER
2025-04-11 16:21 Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 16:12 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
2025-04-14 17:09 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 18:27 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 19:14 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
2025-04-14 19:46 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
@ 2025-04-14 20:17 ` Jacob Champion <[email protected]>
2025-04-15 00:13 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
0 siblings, 1 reply; 9+ messages in thread
From: Jacob Champion @ 2025-04-14 20:17 UTC (permalink / raw)
To: Wolfgang Walther <[email protected]>; +Cc: Jelte Fennema-Nio <[email protected]>; Christoph Berg <[email protected]>; Peter Eisentraut <[email protected]>; Andres Freund <[email protected]>; Tom Lane <[email protected]>; Bruce Momjian <[email protected]>; pgsql-hackers; Daniel Gustafsson <[email protected]>; Thomas Munro <[email protected]>; Nazir Bilal Yavuz <[email protected]>; Antonin Houska <[email protected]>
On Mon, Apr 14, 2025 at 12:46 PM Wolfgang Walther
<[email protected]> wrote:
> But that means we'd need a -lpq-oauth-18 or something like that in
> Libs.private in libpq.pc, right?
I believe so. I'm in the middle of the .pc stuff right now; v6 should
have the fixes as long as I don't get stuck.
Thanks,
--Jacob
^ permalink raw reply [nested|flat] 9+ messages in thread
* Re: [PoC] Federated Authn/z with OAUTHBEARER
2025-04-11 16:21 Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 16:12 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
2025-04-14 17:09 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 18:27 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 19:14 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
2025-04-14 19:46 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 20:17 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
@ 2025-04-15 00:13 ` Jacob Champion <[email protected]>
0 siblings, 0 replies; 9+ messages in thread
From: Jacob Champion @ 2025-04-15 00:13 UTC (permalink / raw)
To: Wolfgang Walther <[email protected]>; +Cc: Jelte Fennema-Nio <[email protected]>; Christoph Berg <[email protected]>; Peter Eisentraut <[email protected]>; Andres Freund <[email protected]>; Tom Lane <[email protected]>; Bruce Momjian <[email protected]>; pgsql-hackers; Daniel Gustafsson <[email protected]>; Thomas Munro <[email protected]>; Nazir Bilal Yavuz <[email protected]>; Antonin Houska <[email protected]>
On Mon, Apr 14, 2025 at 1:17 PM Jacob Champion
<[email protected]> wrote:
> I believe so. I'm in the middle of the .pc stuff right now; v6 should
> have the fixes as long as I don't get stuck.
Done in v6-0001. I think this is now architecturally complete, so if
reviewers are happy I can work on docs and the commit message. As a
summary:
- We provide a libpq-oauth-18.so module for shared builds, and a
corresponding .a for static builds, when OAuth is enabled.
- Platforms which cannot support the builtin flow now error out if you
request OAuth at configure time.
- When OAuth is enabled and there's no custom client flow, libpq.so
loads the module via dlopen(), which respects RPATH/LD_LIBRARY_PATH et
al. If it's not installed, OAuth doesn't continue.
- Static builds must link libpq-oauth-18.a explicitly. libpq.pc now
puts -lpq-oauth-18 in Libs.private, and libcurl in Requires.private.
- Internally, we compile separate versions of fe-auth-oauth.c to
handle the different cases (disabled, dynamic, static). This is
borrowed from src/common.
- The only new export from libpq is appendPQExpBufferVA. Other
internal symbols are shared with libpq-oauth via dependency injection.
v6-0002 is a WIP rename of the --with-libcurl option to
--with-oauth-client. I'm not sure I have all of the Meson corner cases
with auto_features figured out, but maybe it doesn't matter since it's
temporary (it targets a total of seven buildfarm animals, and once
they've switched we can remove the old name). I have added a separate
open item for this.
Thanks,
--Jacob
Attachments:
[application/octet-stream] v6-0002-oauth-rename-with-libcurl-to-with-oauth-client.patch (15.5K, ../../CAOYmi+=pFfkDFpRMXE87x73ee-viTgn6ztE_VkxnYE7owr_SbQ@mail.gmail.com/2-v6-0002-oauth-rename-with-libcurl-to-with-oauth-client.patch)
download | inline diff:
From 6ba708e512f18b6d0cada3f6657a4d7fd8b1058f Mon Sep 17 00:00:00 2001
From: Jacob Champion <[email protected]>
Date: Mon, 14 Apr 2025 16:34:09 -0700
Subject: [PATCH v6 2/2] oauth: rename --with-libcurl to --with-oauth-client
WIP, see mailing list.
Discussion: https://postgr.es/m/CAOYmi%2Bn9DHS_xUatuuspdC8tjtaMzY8P11Y9y5Fz%2B2pjikkL9g%40mail.gmail.com
---
.cirrus.tasks.yml | 2 +-
config/programs.m4 | 2 +-
configure | 56 +++++++++++++++----
configure.ac | 22 +++++---
meson.build | 16 ++++--
meson_options.txt | 6 +-
src/Makefile.global.in | 2 +-
src/include/pg_config.h.in | 7 ++-
src/interfaces/Makefile | 4 +-
src/interfaces/libpq/Makefile | 2 +-
src/interfaces/libpq/fe-auth-oauth.c | 4 +-
src/makefiles/meson.build | 3 +-
src/test/modules/oauth_validator/Makefile | 2 +-
src/test/modules/oauth_validator/meson.build | 2 +-
.../modules/oauth_validator/t/001_server.pl | 2 +-
.../modules/oauth_validator/t/002_client.pl | 2 +-
16 files changed, 94 insertions(+), 40 deletions(-)
diff --git a/.cirrus.tasks.yml b/.cirrus.tasks.yml
index 86a1fa9bbdb..30bdeb96738 100644
--- a/.cirrus.tasks.yml
+++ b/.cirrus.tasks.yml
@@ -350,11 +350,11 @@ LINUX_CONFIGURE_FEATURES: &LINUX_CONFIGURE_FEATURES >-
--with-gssapi
--with-icu
--with-ldap
- --with-libcurl
--with-libxml
--with-libxslt
--with-llvm
--with-lz4
+ --with-oauth-client
--with-pam
--with-perl
--with-python
diff --git a/config/programs.m4 b/config/programs.m4
index 0ad1e58b48d..328a4701cee 100644
--- a/config/programs.m4
+++ b/config/programs.m4
@@ -285,7 +285,7 @@ AC_DEFUN([PGAC_CHECK_STRIP],
AC_DEFUN([PGAC_CHECK_LIBCURL],
[
AC_CHECK_HEADER(curl/curl.h, [],
- [AC_MSG_ERROR([header file <curl/curl.h> is required for --with-libcurl])])
+ [AC_MSG_ERROR([header file <curl/curl.h> is required for --with-oauth-client])])
AC_CHECK_LIB(curl, curl_multi_init, [
AC_DEFINE([HAVE_LIBCURL], [1], [Define to 1 if you have the `curl' library (-lcurl).])
AC_SUBST(LIBCURL_LDLIBS, -lcurl)
diff --git a/configure b/configure
index df1da549c4c..a99b97006f2 100755
--- a/configure
+++ b/configure
@@ -713,7 +713,7 @@ LIBCURL_LDFLAGS
LIBCURL_CPPFLAGS
LIBCURL_LIBS
LIBCURL_CFLAGS
-with_libcurl
+with_oauth_client
with_uuid
LIBURING_LIBS
LIBURING_CFLAGS
@@ -874,6 +874,7 @@ with_libedit_preferred
with_liburing
with_uuid
with_ossp_uuid
+with_oauth_client
with_libcurl
with_libxml
with_libxslt
@@ -1590,7 +1591,8 @@ Optional Packages:
--with-liburing build with io_uring support, for asynchronous I/O
--with-uuid=LIB build contrib/uuid-ossp using LIB (bsd,e2fs,ossp)
--with-ossp-uuid obsolete spelling of --with-uuid=ossp
- --with-libcurl build with libcurl support
+ --with-oauth-client build OAuth Device Authorization support
+ --with-libcurl Deprecated. Use --with-oauth-client instead
--with-libxml build with XML support
--with-libxslt use XSLT support when building contrib/xml2
--with-system-tzdata=DIR
@@ -8918,8 +8920,36 @@ fi
#
# libcurl
#
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with libcurl support" >&5
-$as_echo_n "checking whether to build with libcurl support... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build OAuth Device Authorization support" >&5
+$as_echo_n "checking whether to build OAuth Device Authorization support... " >&6; }
+
+
+
+# Check whether --with-oauth-client was given.
+if test "${with_oauth_client+set}" = set; then :
+ withval=$with_oauth_client;
+ case $withval in
+ yes)
+
+$as_echo "#define USE_BUILTIN_OAUTH 1" >>confdefs.h
+
+ ;;
+ no)
+ :
+ ;;
+ *)
+ as_fn_error $? "no argument expected for --with-oauth-client option" "$LINENO" 5
+ ;;
+ esac
+
+else
+ with_oauth_client=no
+
+fi
+
+
+
+# --with-libcurl is a deprecated equivalent. TODO: remove
@@ -8929,7 +8959,7 @@ if test "${with_libcurl+set}" = set; then :
case $withval in
yes)
-$as_echo "#define USE_LIBCURL 1" >>confdefs.h
+$as_echo "#define USE_BUILTIN_OAUTH 1" >>confdefs.h
;;
no)
@@ -8946,11 +8976,15 @@ else
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_libcurl" >&5
-$as_echo "$with_libcurl" >&6; }
+if test "$with_libcurl" = yes ; then
+ with_oauth_client=yes
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_oauth_client" >&5
+$as_echo "$with_oauth_client" >&6; }
-if test "$with_libcurl" = yes ; then
+
+if test "$with_oauth_client" = yes ; then
# Check for libcurl 7.61.0 or higher (corresponding to RHEL8 and the ability
# to explicitly set TLS 1.3 ciphersuites).
@@ -12528,13 +12562,13 @@ fi
fi
-if test "$with_libcurl" = yes ; then
+if test "$with_oauth_client" = yes ; then
ac_fn_c_check_header_mongrel "$LINENO" "curl/curl.h" "ac_cv_header_curl_curl_h" "$ac_includes_default"
if test "x$ac_cv_header_curl_curl_h" = xyes; then :
else
- as_fn_error $? "header file <curl/curl.h> is required for --with-libcurl" "$LINENO" 5
+ as_fn_error $? "header file <curl/curl.h> is required for --with-oauth-client" "$LINENO" 5
fi
@@ -14350,7 +14384,7 @@ done
fi
-if test "$with_libcurl" = yes ; then
+if test "$with_oauth_client" = yes ; then
# Error out early if this platform can't support libpq-oauth.
if test "$ac_cv_header_sys_event_h" != yes -a "$ac_cv_header_sys_epoll_h" != yes; then
as_fn_error $? "client OAuth is not supported on this platform" "$LINENO" 5
diff --git a/configure.ac b/configure.ac
index 218aeea1b3b..7ffe8901250 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1022,13 +1022,21 @@ AC_SUBST(with_uuid)
#
# libcurl
#
-AC_MSG_CHECKING([whether to build with libcurl support])
-PGAC_ARG_BOOL(with, libcurl, no, [build with libcurl support],
- [AC_DEFINE([USE_LIBCURL], 1, [Define to 1 to build with libcurl support. (--with-libcurl)])])
-AC_MSG_RESULT([$with_libcurl])
-AC_SUBST(with_libcurl)
+AC_MSG_CHECKING([whether to build OAuth Device Authorization support])
+PGAC_ARG_BOOL(with, oauth-client, no, [build OAuth Device Authorization support],
+ [AC_DEFINE([USE_BUILTIN_OAUTH], 1, [Define to 1 to build with OAuth Device Authorization support. (--with-oauth-client)])])
+# --with-libcurl is a deprecated equivalent. TODO: remove
+PGAC_ARG_BOOL(with, libcurl, no, [Deprecated. Use --with-oauth-client instead],
+ [AC_DEFINE([USE_BUILTIN_OAUTH], 1, [Define to 1 to build with OAuth Device Authorization support. (--with-oauth-client)])])
if test "$with_libcurl" = yes ; then
+ with_oauth_client=yes
+fi
+
+AC_MSG_RESULT([$with_oauth_client])
+AC_SUBST(with_oauth_client)
+
+if test "$with_oauth_client" = yes ; then
# Check for libcurl 7.61.0 or higher (corresponding to RHEL8 and the ability
# to explicitly set TLS 1.3 ciphersuites).
PKG_CHECK_MODULES(LIBCURL, [libcurl >= 7.61.0])
@@ -1348,7 +1356,7 @@ failure. It is possible the compiler isn't looking in the proper directory.
Use --without-zlib to disable zlib support.])])
fi
-if test "$with_libcurl" = yes ; then
+if test "$with_oauth_client" = yes ; then
PGAC_CHECK_LIBCURL
fi
@@ -1645,7 +1653,7 @@ if test "$PORTNAME" = "win32" ; then
AC_CHECK_HEADERS(crtdefs.h)
fi
-if test "$with_libcurl" = yes ; then
+if test "$with_oauth_client" = yes ; then
# Error out early if this platform can't support libpq-oauth.
if test "$ac_cv_header_sys_event_h" != yes -a "$ac_cv_header_sys_epoll_h" != yes; then
AC_MSG_ERROR([client OAuth is not supported on this platform])
diff --git a/meson.build b/meson.build
index b436c362147..ab34d69dd1a 100644
--- a/meson.build
+++ b/meson.build
@@ -860,13 +860,19 @@ endif
# Library: libcurl
###############################################################
-libcurlopt = get_option('libcurl')
+oauthopt = get_option('oauth-client')
oauth_flow_supported = false
-if not libcurlopt.disabled()
+# -Dlibcurl is a deprecated equivalent. TODO: remove
+libcurlopt = get_option('libcurl')
+if oauthopt.auto() or libcurlopt.enabled()
+ oauthopt = libcurlopt
+endif
+
+if not oauthopt.disabled()
# Check for libcurl 7.61.0 or higher (corresponding to RHEL8 and the ability
# to explicitly set TLS 1.3 ciphersuites).
- libcurl = dependency('libcurl', version: '>= 7.61.0', required: libcurlopt)
+ libcurl = dependency('libcurl', version: '>= 7.61.0', required: oauthopt)
if libcurl.found()
# Check to see whether the current platform supports thread-safe Curl
# initialization.
@@ -950,8 +956,8 @@ if not libcurlopt.disabled()
)
if oauth_flow_supported
- cdata.set('USE_LIBCURL', 1)
- elif libcurlopt.enabled()
+ cdata.set('USE_BUILTIN_OAUTH', 1)
+ elif oauthopt.enabled()
error('client OAuth is not supported on this platform')
endif
diff --git a/meson_options.txt b/meson_options.txt
index dd7126da3a7..5d828b491a9 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -100,8 +100,9 @@ option('icu', type: 'feature', value: 'auto',
option('ldap', type: 'feature', value: 'auto',
description: 'LDAP support')
+# Deprecated. TODO: remove
option('libcurl', type : 'feature', value: 'auto',
- description: 'libcurl support')
+ description: 'Deprecated. Use -Doauth-client instead')
option('libedit_preferred', type: 'boolean', value: false,
description: 'Prefer BSD Libedit over GNU Readline')
@@ -121,6 +122,9 @@ option('llvm', type: 'feature', value: 'disabled',
option('lz4', type: 'feature', value: 'auto',
description: 'LZ4 support')
+option('oauth-client', type : 'feature', value: 'auto',
+ description: 'OAuth Device Authorization support')
+
option('nls', type: 'feature', value: 'auto',
description: 'Native language support')
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index eb9b5de75b4..0c0822c314b 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -195,11 +195,11 @@ with_systemd = @with_systemd@
with_gssapi = @with_gssapi@
with_krb_srvnam = @with_krb_srvnam@
with_ldap = @with_ldap@
-with_libcurl = @with_libcurl@
with_liburing = @with_liburing@
with_libxml = @with_libxml@
with_libxslt = @with_libxslt@
with_llvm = @with_llvm@
+with_oauth_client = @with_oauth_client@
with_system_tzdata = @with_system_tzdata@
with_uuid = @with_uuid@
with_zlib = @with_zlib@
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 9891b9b05c3..1e189581896 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -677,6 +677,10 @@
/* Define to 1 to build with BSD Authentication support. (--with-bsd-auth) */
#undef USE_BSD_AUTH
+/* Define to 1 to build with OAuth Device Authorization support.
+ (--with-oauth-client) */
+#undef USE_BUILTIN_OAUTH
+
/* Define to build with ICU support. (--with-icu) */
#undef USE_ICU
@@ -686,9 +690,6 @@
/* Define to 1 to build with LDAP support. (--with-ldap) */
#undef USE_LDAP
-/* Define to 1 to build with libcurl support. (--with-libcurl) */
-#undef USE_LIBCURL
-
/* Define to build with io_uring support. (--with-liburing) */
#undef USE_LIBURING
diff --git a/src/interfaces/Makefile b/src/interfaces/Makefile
index e6822caa206..ccb4a9b6e69 100644
--- a/src/interfaces/Makefile
+++ b/src/interfaces/Makefile
@@ -14,7 +14,7 @@ include $(top_builddir)/src/Makefile.global
SUBDIRS = libpq ecpg
-ifeq ($(with_libcurl), yes)
+ifeq ($(with_oauth_client), yes)
SUBDIRS += libpq-oauth
else
ALWAYS_SUBDIRS += libpq-oauth
@@ -26,7 +26,7 @@ $(recurse_always)
all-ecpg-recurse: all-libpq-recurse
install-ecpg-recurse: install-libpq-recurse
-ifeq ($(with_libcurl), yes)
+ifeq ($(with_oauth_client), yes)
all-libpq-oauth-recurse: all-libpq-recurse
install-libpq-oauth-recurse: install-libpq-recurse
endif
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index d4c20066ce4..a835d94a142 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -102,7 +102,7 @@ ifeq ($(with_ssl),openssl)
PKG_CONFIG_REQUIRES_PRIVATE = libssl, libcrypto
endif
-ifeq ($(with_libcurl),yes)
+ifeq ($(with_oauth_client),yes)
# libpq.so doesn't link against libcurl, but libpq.a needs libpq-oauth, and
# libpq-oauth needs libcurl. Put both into *.private.
PKG_CONFIG_REQUIRES_PRIVATE += libcurl
diff --git a/src/interfaces/libpq/fe-auth-oauth.c b/src/interfaces/libpq/fe-auth-oauth.c
index 5c285adccbd..af6db2eec28 100644
--- a/src/interfaces/libpq/fe-auth-oauth.c
+++ b/src/interfaces/libpq/fe-auth-oauth.c
@@ -738,7 +738,7 @@ cleanup_user_oauth_flow(PGconn *conn)
* executable.
*/
-#if !defined(USE_LIBCURL)
+#if !defined(USE_BUILTIN_OAUTH)
/*
* This configuration doesn't support the builtin flow.
@@ -859,7 +859,7 @@ use_builtin_flow(PGconn *conn, fe_oauth_state *state)
return true;
}
-#endif /* USE_LIBCURL */
+#endif /* USE_BUILTIN_OAUTH */
/*
diff --git a/src/makefiles/meson.build b/src/makefiles/meson.build
index f2ba5b38124..6160c172d75 100644
--- a/src/makefiles/meson.build
+++ b/src/makefiles/meson.build
@@ -75,6 +75,8 @@ pgxs_kv = {
'with_krb_srvnam': get_option('krb_srvnam'),
'krb_srvtab': krb_srvtab,
+ 'with_oauth_client': oauth_flow_supported ? 'yes' : 'no',
+
'STRIP': ' '.join(strip_cmd),
'STRIP_STATIC_LIB': ' '.join(strip_static_cmd),
'STRIP_SHARED_LIB': ' '.join(strip_shared_cmd),
@@ -233,7 +235,6 @@ pgxs_deps = {
'gssapi': gssapi,
'icu': icu,
'ldap': ldap,
- 'libcurl': libcurl,
'liburing': liburing,
'libxml': libxml,
'libxslt': libxslt,
diff --git a/src/test/modules/oauth_validator/Makefile b/src/test/modules/oauth_validator/Makefile
index 05b9f06ed73..57733dc533f 100644
--- a/src/test/modules/oauth_validator/Makefile
+++ b/src/test/modules/oauth_validator/Makefile
@@ -34,7 +34,7 @@ include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
export PYTHON
-export with_libcurl
+export with_oauth_client
export with_python
endif
diff --git a/src/test/modules/oauth_validator/meson.build b/src/test/modules/oauth_validator/meson.build
index 36d1b26369f..84d169cb8e1 100644
--- a/src/test/modules/oauth_validator/meson.build
+++ b/src/test/modules/oauth_validator/meson.build
@@ -78,7 +78,7 @@ tests += {
],
'env': {
'PYTHON': python.path(),
- 'with_libcurl': libcurl.found() ? 'yes' : 'no',
+ 'with_oauth_client': oauth_flow_supported ? 'yes' : 'no',
'with_python': 'yes',
},
},
diff --git a/src/test/modules/oauth_validator/t/001_server.pl b/src/test/modules/oauth_validator/t/001_server.pl
index d88994abc24..01b5e1c3c43 100644
--- a/src/test/modules/oauth_validator/t/001_server.pl
+++ b/src/test/modules/oauth_validator/t/001_server.pl
@@ -33,7 +33,7 @@ unless (check_pg_config("#define HAVE_SYS_EVENT_H 1")
'OAuth server-side tests are not supported on this platform';
}
-if ($ENV{with_libcurl} ne 'yes')
+if ($ENV{with_oauth_client} ne 'yes')
{
plan skip_all => 'client-side OAuth not supported by this build';
}
diff --git a/src/test/modules/oauth_validator/t/002_client.pl b/src/test/modules/oauth_validator/t/002_client.pl
index 54769f12f57..1e329b328a6 100644
--- a/src/test/modules/oauth_validator/t/002_client.pl
+++ b/src/test/modules/oauth_validator/t/002_client.pl
@@ -104,7 +104,7 @@ $node->log_check("validator receives correct token",
$log_start,
log_like => [ qr/oauth_validator: token="my-token", role="$user"/, ]);
-if ($ENV{with_libcurl} ne 'yes')
+if ($ENV{with_oauth_client} ne 'yes')
{
# libpq should help users out if no OAuth support is built in.
test(
--
2.34.1
[application/octet-stream] v6-0001-WIP-split-Device-Authorization-flow-into-dlopen-d.patch (44.8K, ../../CAOYmi+=pFfkDFpRMXE87x73ee-viTgn6ztE_VkxnYE7owr_SbQ@mail.gmail.com/3-v6-0001-WIP-split-Device-Authorization-flow-into-dlopen-d.patch)
download | inline diff:
From a202bd932ea390c97df10fcbb0cc3b60419453be Mon Sep 17 00:00:00 2001
From: Jacob Champion <[email protected]>
Date: Wed, 26 Mar 2025 10:55:28 -0700
Subject: [PATCH v6 1/2] WIP: split Device Authorization flow into dlopen'd
module
See notes on mailing list.
Co-authored-by: Daniel Gustafsson <[email protected]>
---
config/programs.m4 | 17 +-
configure | 50 ++++-
configure.ac | 26 ++-
meson.build | 32 ++-
src/Makefile.global.in | 3 +
src/interfaces/Makefile | 12 ++
src/interfaces/libpq-oauth/Makefile | 65 ++++++
src/interfaces/libpq-oauth/README | 43 ++++
src/interfaces/libpq-oauth/exports.txt | 4 +
src/interfaces/libpq-oauth/meson.build | 43 ++++
.../oauth-curl.c} | 60 +++---
src/interfaces/libpq-oauth/oauth-curl.h | 24 +++
src/interfaces/libpq-oauth/oauth-utils.c | 202 ++++++++++++++++++
src/interfaces/libpq-oauth/oauth-utils.h | 35 +++
src/interfaces/libpq/Makefile | 36 +++-
src/interfaces/libpq/exports.txt | 1 +
src/interfaces/libpq/fe-auth-oauth.c | 151 ++++++++++++-
src/interfaces/libpq/fe-auth-oauth.h | 5 +-
src/interfaces/libpq/meson.build | 28 ++-
src/interfaces/libpq/nls.mk | 12 +-
src/makefiles/meson.build | 2 +
21 files changed, 763 insertions(+), 88 deletions(-)
create mode 100644 src/interfaces/libpq-oauth/Makefile
create mode 100644 src/interfaces/libpq-oauth/README
create mode 100644 src/interfaces/libpq-oauth/exports.txt
create mode 100644 src/interfaces/libpq-oauth/meson.build
rename src/interfaces/{libpq/fe-auth-oauth-curl.c => libpq-oauth/oauth-curl.c} (98%)
create mode 100644 src/interfaces/libpq-oauth/oauth-curl.h
create mode 100644 src/interfaces/libpq-oauth/oauth-utils.c
create mode 100644 src/interfaces/libpq-oauth/oauth-utils.h
diff --git a/config/programs.m4 b/config/programs.m4
index 0a07feb37cc..0ad1e58b48d 100644
--- a/config/programs.m4
+++ b/config/programs.m4
@@ -286,9 +286,20 @@ AC_DEFUN([PGAC_CHECK_LIBCURL],
[
AC_CHECK_HEADER(curl/curl.h, [],
[AC_MSG_ERROR([header file <curl/curl.h> is required for --with-libcurl])])
- AC_CHECK_LIB(curl, curl_multi_init, [],
+ AC_CHECK_LIB(curl, curl_multi_init, [
+ AC_DEFINE([HAVE_LIBCURL], [1], [Define to 1 if you have the `curl' library (-lcurl).])
+ AC_SUBST(LIBCURL_LDLIBS, -lcurl)
+ ],
[AC_MSG_ERROR([library 'curl' does not provide curl_multi_init])])
+ pgac_save_CPPFLAGS=$CPPFLAGS
+ pgac_save_LDFLAGS=$LDFLAGS
+ pgac_save_LIBS=$LIBS
+
+ CPPFLAGS="$LIBCURL_CPPFLAGS $CPPFLAGS"
+ LDFLAGS="$LIBCURL_LDFLAGS $LDFLAGS"
+ LIBS="$LIBCURL_LDLIBS $LIBS"
+
# Check to see whether the current platform supports threadsafe Curl
# initialization.
AC_CACHE_CHECK([for curl_global_init thread safety], [pgac_cv__libcurl_threadsafe_init],
@@ -338,4 +349,8 @@ AC_DEFUN([PGAC_CHECK_LIBCURL],
*** lookups. Rebuild libcurl with the AsynchDNS feature enabled in order
*** to use it with libpq.])
fi
+
+ CPPFLAGS=$pgac_save_CPPFLAGS
+ LDFLAGS=$pgac_save_LDFLAGS
+ LIBS=$pgac_save_LIBS
])# PGAC_CHECK_LIBCURL
diff --git a/configure b/configure
index 8f4a5ab28ec..df1da549c4c 100755
--- a/configure
+++ b/configure
@@ -655,6 +655,7 @@ UUID_LIBS
LDAP_LIBS_BE
LDAP_LIBS_FE
with_ssl
+LIBCURL_LDLIBS
PTHREAD_CFLAGS
PTHREAD_LIBS
PTHREAD_CC
@@ -708,6 +709,8 @@ XML2_LIBS
XML2_CFLAGS
XML2_CONFIG
with_libxml
+LIBCURL_LDFLAGS
+LIBCURL_CPPFLAGS
LIBCURL_LIBS
LIBCURL_CFLAGS
with_libcurl
@@ -9042,19 +9045,27 @@ $as_echo "yes" >&6; }
fi
- # We only care about -I, -D, and -L switches;
- # note that -lcurl will be added by PGAC_CHECK_LIBCURL below.
+ # Curl's flags are kept separate from the standard CPPFLAGS/LDFLAGS. We use
+ # them only for libpq-oauth.
+ LIBCURL_CPPFLAGS=
+ LIBCURL_LDFLAGS=
+
+ # We only care about -I, -D, and -L switches. Note that -lcurl will be added
+ # to LIBCURL_LDLIBS by PGAC_CHECK_LIBCURL, below.
for pgac_option in $LIBCURL_CFLAGS; do
case $pgac_option in
- -I*|-D*) CPPFLAGS="$CPPFLAGS $pgac_option";;
+ -I*|-D*) LIBCURL_CPPFLAGS="$LIBCURL_CPPFLAGS $pgac_option";;
esac
done
for pgac_option in $LIBCURL_LIBS; do
case $pgac_option in
- -L*) LDFLAGS="$LDFLAGS $pgac_option";;
+ -L*) LIBCURL_LDFLAGS="$LIBCURL_LDFLAGS $pgac_option";;
esac
done
+
+
+
# OAuth requires python for testing
if test "$with_python" != yes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** OAuth support tests require --with-python to run" >&5
@@ -12517,9 +12528,6 @@ fi
fi
-# XXX libcurl must link after libgssapi_krb5 on FreeBSD to avoid segfaults
-# during gss_acquire_cred(). This is possibly related to Curl's Heimdal
-# dependency on that platform?
if test "$with_libcurl" = yes ; then
ac_fn_c_check_header_mongrel "$LINENO" "curl/curl.h" "ac_cv_header_curl_curl_h" "$ac_includes_default"
@@ -12567,17 +12575,26 @@ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curl_curl_multi_init" >&5
$as_echo "$ac_cv_lib_curl_curl_multi_init" >&6; }
if test "x$ac_cv_lib_curl_curl_multi_init" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBCURL 1
-_ACEOF
- LIBS="-lcurl $LIBS"
+
+$as_echo "#define HAVE_LIBCURL 1" >>confdefs.h
+
+ LIBCURL_LDLIBS=-lcurl
+
else
as_fn_error $? "library 'curl' does not provide curl_multi_init" "$LINENO" 5
fi
+ pgac_save_CPPFLAGS=$CPPFLAGS
+ pgac_save_LDFLAGS=$LDFLAGS
+ pgac_save_LIBS=$LIBS
+
+ CPPFLAGS="$LIBCURL_CPPFLAGS $CPPFLAGS"
+ LDFLAGS="$LIBCURL_LDFLAGS $LDFLAGS"
+ LIBS="$LIBCURL_LDLIBS $LIBS"
+
# Check to see whether the current platform supports threadsafe Curl
# initialization.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for curl_global_init thread safety" >&5
@@ -12681,6 +12698,10 @@ $as_echo "$pgac_cv__libcurl_async_dns" >&6; }
*** to use it with libpq." "$LINENO" 5
fi
+ CPPFLAGS=$pgac_save_CPPFLAGS
+ LDFLAGS=$pgac_save_LDFLAGS
+ LIBS=$pgac_save_LIBS
+
fi
if test "$with_gssapi" = yes ; then
@@ -14329,6 +14350,13 @@ done
fi
+if test "$with_libcurl" = yes ; then
+ # Error out early if this platform can't support libpq-oauth.
+ if test "$ac_cv_header_sys_event_h" != yes -a "$ac_cv_header_sys_epoll_h" != yes; then
+ as_fn_error $? "client OAuth is not supported on this platform" "$LINENO" 5
+ fi
+fi
+
##
## Types, structures, compiler characteristics
##
diff --git a/configure.ac b/configure.ac
index fc5f7475d07..218aeea1b3b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1033,19 +1033,27 @@ if test "$with_libcurl" = yes ; then
# to explicitly set TLS 1.3 ciphersuites).
PKG_CHECK_MODULES(LIBCURL, [libcurl >= 7.61.0])
- # We only care about -I, -D, and -L switches;
- # note that -lcurl will be added by PGAC_CHECK_LIBCURL below.
+ # Curl's flags are kept separate from the standard CPPFLAGS/LDFLAGS. We use
+ # them only for libpq-oauth.
+ LIBCURL_CPPFLAGS=
+ LIBCURL_LDFLAGS=
+
+ # We only care about -I, -D, and -L switches. Note that -lcurl will be added
+ # to LIBCURL_LDLIBS by PGAC_CHECK_LIBCURL, below.
for pgac_option in $LIBCURL_CFLAGS; do
case $pgac_option in
- -I*|-D*) CPPFLAGS="$CPPFLAGS $pgac_option";;
+ -I*|-D*) LIBCURL_CPPFLAGS="$LIBCURL_CPPFLAGS $pgac_option";;
esac
done
for pgac_option in $LIBCURL_LIBS; do
case $pgac_option in
- -L*) LDFLAGS="$LDFLAGS $pgac_option";;
+ -L*) LIBCURL_LDFLAGS="$LIBCURL_LDFLAGS $pgac_option";;
esac
done
+ AC_SUBST(LIBCURL_CPPFLAGS)
+ AC_SUBST(LIBCURL_LDFLAGS)
+
# OAuth requires python for testing
if test "$with_python" != yes; then
AC_MSG_WARN([*** OAuth support tests require --with-python to run])
@@ -1340,9 +1348,6 @@ failure. It is possible the compiler isn't looking in the proper directory.
Use --without-zlib to disable zlib support.])])
fi
-# XXX libcurl must link after libgssapi_krb5 on FreeBSD to avoid segfaults
-# during gss_acquire_cred(). This is possibly related to Curl's Heimdal
-# dependency on that platform?
if test "$with_libcurl" = yes ; then
PGAC_CHECK_LIBCURL
fi
@@ -1640,6 +1645,13 @@ if test "$PORTNAME" = "win32" ; then
AC_CHECK_HEADERS(crtdefs.h)
fi
+if test "$with_libcurl" = yes ; then
+ # Error out early if this platform can't support libpq-oauth.
+ if test "$ac_cv_header_sys_event_h" != yes -a "$ac_cv_header_sys_epoll_h" != yes; then
+ AC_MSG_ERROR([client OAuth is not supported on this platform])
+ fi
+fi
+
##
## Types, structures, compiler characteristics
##
diff --git a/meson.build b/meson.build
index 27717ad8976..b436c362147 100644
--- a/meson.build
+++ b/meson.build
@@ -107,6 +107,7 @@ os_deps = []
backend_both_deps = []
backend_deps = []
libpq_deps = []
+libpq_oauth_deps = []
pg_sysroot = ''
@@ -860,13 +861,13 @@ endif
###############################################################
libcurlopt = get_option('libcurl')
+oauth_flow_supported = false
+
if not libcurlopt.disabled()
# Check for libcurl 7.61.0 or higher (corresponding to RHEL8 and the ability
# to explicitly set TLS 1.3 ciphersuites).
libcurl = dependency('libcurl', version: '>= 7.61.0', required: libcurlopt)
if libcurl.found()
- cdata.set('USE_LIBCURL', 1)
-
# Check to see whether the current platform supports thread-safe Curl
# initialization.
libcurl_threadsafe_init = false
@@ -938,6 +939,22 @@ if not libcurlopt.disabled()
endif
endif
+ # Check that the current platform supports our builtin flow. This requires
+ # libcurl and one of either epoll or kqueue.
+ oauth_flow_supported = (
+ libcurl.found()
+ and (cc.check_header('sys/event.h', required: false,
+ args: test_c_args, include_directories: postgres_inc)
+ or cc.check_header('sys/epoll.h', required: false,
+ args: test_c_args, include_directories: postgres_inc))
+ )
+
+ if oauth_flow_supported
+ cdata.set('USE_LIBCURL', 1)
+ elif libcurlopt.enabled()
+ error('client OAuth is not supported on this platform')
+ endif
+
else
libcurl = not_found_dep
endif
@@ -3251,17 +3268,18 @@ libpq_deps += [
gssapi,
ldap_r,
- # XXX libcurl must link after libgssapi_krb5 on FreeBSD to avoid segfaults
- # during gss_acquire_cred(). This is possibly related to Curl's Heimdal
- # dependency on that platform?
- libcurl,
libintl,
ssl,
]
+libpq_oauth_deps += [
+ libcurl,
+]
+
subdir('src/interfaces/libpq')
-# fe_utils depends on libpq
+# fe_utils and libpq-oauth depends on libpq
subdir('src/fe_utils')
+subdir('src/interfaces/libpq-oauth')
# for frontend binaries
frontend_code = declare_dependency(
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 737b2dd1869..eb9b5de75b4 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -343,6 +343,9 @@ perl_embed_ldflags = @perl_embed_ldflags@
AWK = @AWK@
LN_S = @LN_S@
+LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@
+LIBCURL_LDFLAGS = @LIBCURL_LDFLAGS@
+LIBCURL_LDLIBS = @LIBCURL_LDLIBS@
MSGFMT = @MSGFMT@
MSGFMT_FLAGS = @MSGFMT_FLAGS@
MSGMERGE = @MSGMERGE@
diff --git a/src/interfaces/Makefile b/src/interfaces/Makefile
index 7d56b29d28f..e6822caa206 100644
--- a/src/interfaces/Makefile
+++ b/src/interfaces/Makefile
@@ -14,7 +14,19 @@ include $(top_builddir)/src/Makefile.global
SUBDIRS = libpq ecpg
+ifeq ($(with_libcurl), yes)
+SUBDIRS += libpq-oauth
+else
+ALWAYS_SUBDIRS += libpq-oauth
+endif
+
$(recurse)
+$(recurse_always)
all-ecpg-recurse: all-libpq-recurse
install-ecpg-recurse: install-libpq-recurse
+
+ifeq ($(with_libcurl), yes)
+all-libpq-oauth-recurse: all-libpq-recurse
+install-libpq-oauth-recurse: install-libpq-recurse
+endif
diff --git a/src/interfaces/libpq-oauth/Makefile b/src/interfaces/libpq-oauth/Makefile
new file mode 100644
index 00000000000..5fd251a1d27
--- /dev/null
+++ b/src/interfaces/libpq-oauth/Makefile
@@ -0,0 +1,65 @@
+#-------------------------------------------------------------------------
+#
+# Makefile for libpq-oauth
+#
+# Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+# Portions Copyright (c) 1994, Regents of the University of California
+#
+# src/interfaces/libpq-oauth/Makefile
+#
+#-------------------------------------------------------------------------
+
+subdir = src/interfaces/libpq-oauth
+top_builddir = ../../..
+include $(top_builddir)/src/Makefile.global
+
+PGFILEDESC = "libpq-oauth - device authorization OAuth support"
+
+# This is an internal module; we don't want an SONAME and therefore do not set
+# SO_MAJOR_VERSION.
+NAME = pq-oauth-$(MAJORVERSION)
+
+# Force the name "libpq-oauth" for both the static and shared libraries.
+override shlib := lib$(NAME)$(DLSUFFIX)
+override stlib := lib$(NAME).a
+
+override CPPFLAGS := -I$(libpq_srcdir) -I$(top_builddir)/src/port $(LIBCURL_CPPFLAGS) $(CPPFLAGS)
+
+OBJS = \
+ $(WIN32RES) \
+ oauth-curl.o
+
+# The shared library needs additional glue symbols.
+$(shlib): OBJS += oauth-utils.o
+$(shlib): oauth-utils.o
+
+SHLIB_LINK_INTERNAL = $(libpq_pgport_shlib)
+SHLIB_LINK = $(LIBCURL_LDFLAGS) $(LIBCURL_LDLIBS)
+SHLIB_PREREQS = submake-libpq
+SHLIB_EXPORTS = exports.txt
+
+# Disable -bundle_loader on macOS.
+BE_DLLLIBS =
+
+# By default, a library without an SONAME doesn't get a static library, so we
+# add it to the build explicitly.
+all: all-lib all-static-lib
+
+# Shared library stuff
+include $(top_srcdir)/src/Makefile.shlib
+
+# Ignore the standard rules for SONAME-less installation; we want both the
+# static and shared libraries to go into libdir.
+install: all installdirs $(stlib) $(shlib)
+ $(INSTALL_SHLIB) $(shlib) '$(DESTDIR)$(libdir)/$(shlib)'
+ $(INSTALL_STLIB) $(stlib) '$(DESTDIR)$(libdir)/$(stlib)'
+
+installdirs:
+ $(MKDIR_P) '$(DESTDIR)$(libdir)'
+
+uninstall:
+ rm -f '$(DESTDIR)$(libdir)/$(stlib)'
+ rm -f '$(DESTDIR)$(libdir)/$(shlib)'
+
+clean distclean: clean-lib
+ rm -f $(OBJS) oauth-utils.o
diff --git a/src/interfaces/libpq-oauth/README b/src/interfaces/libpq-oauth/README
new file mode 100644
index 00000000000..45def6c1ab6
--- /dev/null
+++ b/src/interfaces/libpq-oauth/README
@@ -0,0 +1,43 @@
+libpq-oauth is an optional module implementing the Device Authorization flow for
+OAuth clients (RFC 8628). It was originally developed as part of libpq core and
+later split out as its own shared library in order to isolate its dependency on
+libcurl. (End users who don't want the Curl dependency can simply choose not to
+install this module.)
+
+If a connection string allows the use of OAuth, and the server asks for it, and
+a libpq client has not installed its own custom OAuth flow, libpq will attempt
+to delay-load this module using dlopen() and the following ABI. Failure to load
+results in a failed connection.
+
+= Load-Time ABI =
+
+This module ABI is an internal implementation detail, so it's subject to change
+across major releases; the name of the module (libpq-oauth-MAJOR) reflects this.
+The module exports the following symbols:
+
+- PostgresPollingStatusType pg_fe_run_oauth_flow(PGconn *conn);
+- void pg_fe_cleanup_oauth_flow(PGconn *conn);
+
+pg_fe_run_oauth_flow and pg_fe_cleanup_oauth_flow are implementations of
+conn->async_auth and conn->cleanup_async_auth, respectively.
+
+- void libpq_oauth_init(pgthreadlock_t threadlock,
+ libpq_gettext_func gettext_impl,
+ conn_errorMessage_func errmsg_impl);
+
+At the moment, pg_fe_run_oauth_flow() relies on libpq's pg_g_threadlock and
+libpq_gettext(), which must be injected by libpq using this initialization
+function before the flow is run. It also relies on libpq to expose
+conn->errorMessage, via the errmsg_impl.
+
+This dependency injection is done to ensure that the module ABI is decoupled
+from the internals of `struct pg_conn`. This way we can safely search the
+standard dlopen() paths (e.g. RPATH, LD_LIBRARY_PATH, the SO cache) for an
+implementation module to use, even if that module wasn't compiled at the same
+time as libpq.
+
+= Static Build =
+
+The static library libpq.a does not perform any dynamic loading. If the builtin
+flow is enabled, the application is expected to link against libpq-oauth-*.a
+directly to provide the necessary symbols.
diff --git a/src/interfaces/libpq-oauth/exports.txt b/src/interfaces/libpq-oauth/exports.txt
new file mode 100644
index 00000000000..6891a83dbf9
--- /dev/null
+++ b/src/interfaces/libpq-oauth/exports.txt
@@ -0,0 +1,4 @@
+# src/interfaces/libpq-oauth/exports.txt
+libpq_oauth_init 1
+pg_fe_run_oauth_flow 2
+pg_fe_cleanup_oauth_flow 3
diff --git a/src/interfaces/libpq-oauth/meson.build b/src/interfaces/libpq-oauth/meson.build
new file mode 100644
index 00000000000..cf597e1da1e
--- /dev/null
+++ b/src/interfaces/libpq-oauth/meson.build
@@ -0,0 +1,43 @@
+# Copyright (c) 2022-2025, PostgreSQL Global Development Group
+
+if not oauth_flow_supported
+ subdir_done()
+endif
+
+libpq_oauth_sources = files(
+ 'oauth-curl.c',
+)
+
+# The shared library needs additional glue symbols.
+libpq_oauth_so_sources = files(
+ 'oauth-utils.c',
+)
+
+export_file = custom_target('libpq-oauth.exports',
+ kwargs: gen_export_kwargs,
+)
+
+# port needs to be in include path due to pthread-win32.h
+libpq_oauth_inc = include_directories('.', '../libpq', '../../port')
+
+# This is an internal module; we don't want an SONAME and therefore do not set
+# SO_MAJOR_VERSION.
+libpq_oauth_name = 'libpq-oauth-@0@'.format(pg_version_major)
+
+libpq_oauth_st = static_library(libpq_oauth_name,
+ libpq_oauth_sources,
+ include_directories: [libpq_oauth_inc, postgres_inc],
+ c_pch: pch_postgres_fe_h,
+ dependencies: [frontend_stlib_code, libpq_oauth_deps],
+ kwargs: default_lib_args,
+)
+
+libpq_oauth_so = shared_module(libpq_oauth_name,
+ libpq_oauth_sources + libpq_oauth_so_sources,
+ include_directories: [libpq_oauth_inc, postgres_inc],
+ c_pch: pch_postgres_fe_h,
+ dependencies: [frontend_shlib_code, libpq, libpq_oauth_deps],
+ link_depends: export_file,
+ link_args: export_fmt.format(export_file.full_path()),
+ kwargs: default_lib_args,
+)
diff --git a/src/interfaces/libpq/fe-auth-oauth-curl.c b/src/interfaces/libpq-oauth/oauth-curl.c
similarity index 98%
rename from src/interfaces/libpq/fe-auth-oauth-curl.c
rename to src/interfaces/libpq-oauth/oauth-curl.c
index cd9c0323bb6..d52125415bc 100644
--- a/src/interfaces/libpq/fe-auth-oauth-curl.c
+++ b/src/interfaces/libpq-oauth/oauth-curl.c
@@ -1,6 +1,6 @@
/*-------------------------------------------------------------------------
*
- * fe-auth-oauth-curl.c
+ * oauth-curl.c
* The libcurl implementation of OAuth/OIDC authentication, using the
* OAuth Device Authorization Grant (RFC 8628).
*
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * src/interfaces/libpq/fe-auth-oauth-curl.c
+ * src/interfaces/libpq-oauth/oauth-curl.c
*
*-------------------------------------------------------------------------
*/
@@ -17,20 +17,23 @@
#include <curl/curl.h>
#include <math.h>
-#ifdef HAVE_SYS_EPOLL_H
+#include <unistd.h>
+
+#if defined(HAVE_SYS_EPOLL_H)
#include <sys/epoll.h>
#include <sys/timerfd.h>
-#endif
-#ifdef HAVE_SYS_EVENT_H
+#elif defined(HAVE_SYS_EVENT_H)
#include <sys/event.h>
+#else
+#error libpq-oauth is not supported on this platform
#endif
-#include <unistd.h>
#include "common/jsonapi.h"
#include "fe-auth.h"
#include "fe-auth-oauth.h"
-#include "libpq-int.h"
#include "mb/pg_wchar.h"
+#include "oauth-curl.h"
+#include "oauth-utils.h"
/*
* It's generally prudent to set a maximum response size to buffer in memory,
@@ -1110,7 +1113,7 @@ parse_access_token(struct async_ctx *actx, struct token *tok)
static bool
setup_multiplexer(struct async_ctx *actx)
{
-#ifdef HAVE_SYS_EPOLL_H
+#if defined(HAVE_SYS_EPOLL_H)
struct epoll_event ev = {.events = EPOLLIN};
actx->mux = epoll_create1(EPOLL_CLOEXEC);
@@ -1134,8 +1137,7 @@ setup_multiplexer(struct async_ctx *actx)
}
return true;
-#endif
-#ifdef HAVE_SYS_EVENT_H
+#elif defined(HAVE_SYS_EVENT_H)
actx->mux = kqueue();
if (actx->mux < 0)
{
@@ -1158,10 +1160,9 @@ setup_multiplexer(struct async_ctx *actx)
}
return true;
+#else
+#error setup_multiplexer is not implemented on this platform
#endif
-
- actx_error(actx, "libpq does not support the Device Authorization flow on this platform");
- return false;
}
/*
@@ -1174,7 +1175,7 @@ register_socket(CURL *curl, curl_socket_t socket, int what, void *ctx,
{
struct async_ctx *actx = ctx;
-#ifdef HAVE_SYS_EPOLL_H
+#if defined(HAVE_SYS_EPOLL_H)
struct epoll_event ev = {0};
int res;
int op = EPOLL_CTL_ADD;
@@ -1230,8 +1231,7 @@ register_socket(CURL *curl, curl_socket_t socket, int what, void *ctx,
}
return 0;
-#endif
-#ifdef HAVE_SYS_EVENT_H
+#elif defined(HAVE_SYS_EVENT_H)
struct kevent ev[2] = {0};
struct kevent ev_out[2];
struct timespec timeout = {0};
@@ -1312,10 +1312,9 @@ register_socket(CURL *curl, curl_socket_t socket, int what, void *ctx,
}
return 0;
+#else
+#error register_socket is not implemented on this platform
#endif
-
- actx_error(actx, "libpq does not support multiplexer sockets on this platform");
- return -1;
}
/*
@@ -1334,7 +1333,7 @@ register_socket(CURL *curl, curl_socket_t socket, int what, void *ctx,
static bool
set_timer(struct async_ctx *actx, long timeout)
{
-#if HAVE_SYS_EPOLL_H
+#if defined(HAVE_SYS_EPOLL_H)
struct itimerspec spec = {0};
if (timeout < 0)
@@ -1363,8 +1362,7 @@ set_timer(struct async_ctx *actx, long timeout)
}
return true;
-#endif
-#ifdef HAVE_SYS_EVENT_H
+#elif defined(HAVE_SYS_EVENT_H)
struct kevent ev;
#ifdef __NetBSD__
@@ -1419,10 +1417,9 @@ set_timer(struct async_ctx *actx, long timeout)
}
return true;
+#else
+#error set_timer is not implemented on this platform
#endif
-
- actx_error(actx, "libpq does not support timers on this platform");
- return false;
}
/*
@@ -1433,7 +1430,7 @@ set_timer(struct async_ctx *actx, long timeout)
static int
timer_expired(struct async_ctx *actx)
{
-#if HAVE_SYS_EPOLL_H
+#if defined(HAVE_SYS_EPOLL_H)
struct itimerspec spec = {0};
if (timerfd_gettime(actx->timerfd, &spec) < 0)
@@ -1453,8 +1450,7 @@ timer_expired(struct async_ctx *actx)
/* If the remaining time to expiration is zero, we're done. */
return (spec.it_value.tv_sec == 0
&& spec.it_value.tv_nsec == 0);
-#endif
-#ifdef HAVE_SYS_EVENT_H
+#elif defined(HAVE_SYS_EVENT_H)
int res;
/* Is the timer queue ready? */
@@ -1466,10 +1462,9 @@ timer_expired(struct async_ctx *actx)
}
return (res > 0);
+#else
+#error timer_expired is not implemented on this platform
#endif
-
- actx_error(actx, "libpq does not support timers on this platform");
- return -1;
}
/*
@@ -2487,8 +2482,9 @@ prompt_user(struct async_ctx *actx, PGconn *conn)
.verification_uri_complete = actx->authz.verification_uri_complete,
.expires_in = actx->authz.expires_in,
};
+ PQauthDataHook_type hook = PQgetAuthDataHook();
- res = PQauthDataHook(PQAUTHDATA_PROMPT_OAUTH_DEVICE, conn, &prompt);
+ res = hook(PQAUTHDATA_PROMPT_OAUTH_DEVICE, conn, &prompt);
if (!res)
{
diff --git a/src/interfaces/libpq-oauth/oauth-curl.h b/src/interfaces/libpq-oauth/oauth-curl.h
new file mode 100644
index 00000000000..248d0424ad0
--- /dev/null
+++ b/src/interfaces/libpq-oauth/oauth-curl.h
@@ -0,0 +1,24 @@
+/*-------------------------------------------------------------------------
+ *
+ * oauth-curl.h
+ *
+ * Definitions for OAuth Device Authorization module
+ *
+ * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/interfaces/libpq-oauth/oauth-curl.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef OAUTH_CURL_H
+#define OAUTH_CURL_H
+
+#include "libpq-fe.h"
+
+/* Exported async-auth callbacks. */
+extern PGDLLEXPORT PostgresPollingStatusType pg_fe_run_oauth_flow(PGconn *conn);
+extern PGDLLEXPORT void pg_fe_cleanup_oauth_flow(PGconn *conn);
+
+#endif /* OAUTH_CURL_H */
diff --git a/src/interfaces/libpq-oauth/oauth-utils.c b/src/interfaces/libpq-oauth/oauth-utils.c
new file mode 100644
index 00000000000..2bdbf904743
--- /dev/null
+++ b/src/interfaces/libpq-oauth/oauth-utils.c
@@ -0,0 +1,202 @@
+/*-------------------------------------------------------------------------
+ *
+ * oauth-utils.c
+ *
+ * "Glue" helpers providing a copy of some internal APIs from libpq. At
+ * some point in the future, we might be able to deduplicate.
+ *
+ * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ * src/interfaces/libpq-oauth/oauth-utils.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+
+#include <signal.h>
+
+#include "libpq-int.h"
+#include "oauth-utils.h"
+
+static libpq_gettext_func libpq_gettext_impl;
+static conn_errorMessage_func conn_errorMessage;
+
+pgthreadlock_t pg_g_threadlock;
+
+/*-
+ * Initializes libpq-oauth by setting necessary callbacks.
+ *
+ * The current implementation relies on the following private implementation
+ * details of libpq:
+ *
+ * - pg_g_threadlock: protects libcurl initialization if the underlying Curl
+ * installation is not threadsafe
+ *
+ * - libpq_gettext: translates error messages using libpq's message domain
+ *
+ * - conn->errorMessage: holds translated errors for the connection. This is
+ * handled through a translation shim, which avoids either depending on the
+ * offset of the errorMessage in PGconn, or needing to export the variadic
+ * libpq_append_conn_error().
+ */
+void
+libpq_oauth_init(pgthreadlock_t threadlock_impl,
+ libpq_gettext_func gettext_impl,
+ conn_errorMessage_func errmsg_impl)
+{
+ pg_g_threadlock = threadlock_impl;
+ libpq_gettext_impl = gettext_impl;
+ conn_errorMessage = errmsg_impl;
+}
+
+/*
+ * Append a formatted string to the error message buffer of the given
+ * connection, after translating it. This is a copy of libpq's internal API.
+ */
+void
+libpq_append_conn_error(PGconn *conn, const char *fmt,...)
+{
+ int save_errno = errno;
+ bool done;
+ va_list args;
+ PQExpBuffer errorMessage = conn_errorMessage(conn);
+
+ Assert(fmt[strlen(fmt) - 1] != '\n');
+
+ if (PQExpBufferBroken(errorMessage))
+ return; /* already failed */
+
+ /* Loop in case we have to retry after enlarging the buffer. */
+ do
+ {
+ errno = save_errno;
+ va_start(args, fmt);
+ done = appendPQExpBufferVA(errorMessage, libpq_gettext(fmt), args);
+ va_end(args);
+ } while (!done);
+
+ appendPQExpBufferChar(errorMessage, '\n');
+}
+
+#ifdef ENABLE_NLS
+
+/*
+ * A shim that defers to the actual libpq_gettext().
+ */
+char *
+libpq_gettext(const char *msgid)
+{
+ if (!libpq_gettext_impl)
+ {
+ /*
+ * Possible if the libpq build doesn't enable NLS. That's a concerning
+ * mismatch, but in this particular case we can handle it. Try to warn
+ * a developer with an assertion, though.
+ */
+ Assert(false);
+
+ /*
+ * Note that callers of libpq_gettext() have to treat the return value
+ * as if it were const, because builds without NLS simply pass through
+ * their argument.
+ */
+ return unconstify(char *, msgid);
+ }
+
+ return libpq_gettext_impl(msgid);
+}
+
+#endif /* ENABLE_NLS */
+
+/*
+ * Returns true if the PGOAUTHDEBUG=UNSAFE flag is set in the environment.
+ */
+bool
+oauth_unsafe_debugging_enabled(void)
+{
+ const char *env = getenv("PGOAUTHDEBUG");
+
+ return (env && strcmp(env, "UNSAFE") == 0);
+}
+
+/*
+ * Duplicate SOCK_ERRNO* definitions from libpq-int.h, for use by
+ * pq_block/reset_sigpipe().
+ */
+#ifdef WIN32
+#define SOCK_ERRNO (WSAGetLastError())
+#define SOCK_ERRNO_SET(e) WSASetLastError(e)
+#else
+#define SOCK_ERRNO errno
+#define SOCK_ERRNO_SET(e) (errno = (e))
+#endif
+
+/*
+ * Block SIGPIPE for this thread. This is a copy of libpq's internal API.
+ */
+int
+pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
+{
+ sigset_t sigpipe_sigset;
+ sigset_t sigset;
+
+ sigemptyset(&sigpipe_sigset);
+ sigaddset(&sigpipe_sigset, SIGPIPE);
+
+ /* Block SIGPIPE and save previous mask for later reset */
+ SOCK_ERRNO_SET(pthread_sigmask(SIG_BLOCK, &sigpipe_sigset, osigset));
+ if (SOCK_ERRNO)
+ return -1;
+
+ /* We can have a pending SIGPIPE only if it was blocked before */
+ if (sigismember(osigset, SIGPIPE))
+ {
+ /* Is there a pending SIGPIPE? */
+ if (sigpending(&sigset) != 0)
+ return -1;
+
+ if (sigismember(&sigset, SIGPIPE))
+ *sigpipe_pending = true;
+ else
+ *sigpipe_pending = false;
+ }
+ else
+ *sigpipe_pending = false;
+
+ return 0;
+}
+
+/*
+ * Discard any pending SIGPIPE and reset the signal mask. This is a copy of
+ * libpq's internal API.
+ */
+void
+pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
+{
+ int save_errno = SOCK_ERRNO;
+ int signo;
+ sigset_t sigset;
+
+ /* Clear SIGPIPE only if none was pending */
+ if (got_epipe && !sigpipe_pending)
+ {
+ if (sigpending(&sigset) == 0 &&
+ sigismember(&sigset, SIGPIPE))
+ {
+ sigset_t sigpipe_sigset;
+
+ sigemptyset(&sigpipe_sigset);
+ sigaddset(&sigpipe_sigset, SIGPIPE);
+
+ sigwait(&sigpipe_sigset, &signo);
+ }
+ }
+
+ /* Restore saved block mask */
+ pthread_sigmask(SIG_SETMASK, osigset, NULL);
+
+ SOCK_ERRNO_SET(save_errno);
+}
diff --git a/src/interfaces/libpq-oauth/oauth-utils.h b/src/interfaces/libpq-oauth/oauth-utils.h
new file mode 100644
index 00000000000..279fc113248
--- /dev/null
+++ b/src/interfaces/libpq-oauth/oauth-utils.h
@@ -0,0 +1,35 @@
+/*-------------------------------------------------------------------------
+ *
+ * oauth-utils.h
+ *
+ * Definitions providing missing libpq internal APIs
+ *
+ * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/interfaces/libpq-oauth/oauth-utils.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef OAUTH_UTILS_H
+#define OAUTH_UTILS_H
+
+#include "libpq-fe.h"
+#include "pqexpbuffer.h"
+
+typedef char *(*libpq_gettext_func) (const char *msgid);
+typedef PQExpBuffer (*conn_errorMessage_func) (PGconn *conn);
+
+/* Initializes libpq-oauth. */
+extern PGDLLEXPORT void libpq_oauth_init(pgthreadlock_t threadlock,
+ libpq_gettext_func gettext_impl,
+ conn_errorMessage_func errmsg_impl);
+
+/* Duplicated APIs, copied from libpq. */
+extern void libpq_append_conn_error(PGconn *conn, const char *fmt,...) pg_attribute_printf(2, 3);
+extern bool oauth_unsafe_debugging_enabled(void);
+extern int pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending);
+extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe);
+
+#endif /* OAUTH_UTILS_H */
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index 90b0b65db6f..d4c20066ce4 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -31,7 +31,6 @@ endif
OBJS = \
$(WIN32RES) \
- fe-auth-oauth.o \
fe-auth-scram.o \
fe-cancel.o \
fe-connect.o \
@@ -64,9 +63,11 @@ OBJS += \
fe-secure-gssapi.o
endif
-ifeq ($(with_libcurl),yes)
-OBJS += fe-auth-oauth-curl.o
-endif
+# The OAuth implementation differs depending on the type of library being built.
+OBJS_STATIC = fe-auth-oauth.o
+
+fe-auth-oauth_shlib.o: override CPPFLAGS_SHLIB += -DUSE_DYNAMIC_OAUTH
+OBJS_SHLIB = fe-auth-oauth_shlib.o
ifeq ($(PORTNAME), cygwin)
override shlib = cyg$(NAME)$(DLSUFFIX)
@@ -86,7 +87,7 @@ endif
# that are built correctly for use in a shlib.
SHLIB_LINK_INTERNAL = -lpgcommon_shlib -lpgport_shlib
ifneq ($(PORTNAME), win32)
-SHLIB_LINK += $(filter -lcrypt -ldes -lcom_err -lcrypto -lk5crypto -lkrb5 -lgssapi_krb5 -lgss -lgssapi -lssl -lcurl -lsocket -lnsl -lresolv -lintl -lm, $(LIBS)) $(LDAP_LIBS_FE) $(PTHREAD_LIBS)
+SHLIB_LINK += $(filter -lcrypt -ldes -lcom_err -lcrypto -lk5crypto -lkrb5 -lgssapi_krb5 -lgss -lgssapi -lssl -lsocket -lnsl -lresolv -lintl -lm, $(LIBS)) $(LDAP_LIBS_FE) $(PTHREAD_LIBS)
else
SHLIB_LINK += $(filter -lcrypt -ldes -lcom_err -lcrypto -lk5crypto -lkrb5 -lgssapi32 -lssl -lsocket -lnsl -lresolv -lintl -lm $(PTHREAD_LIBS), $(LIBS)) $(LDAP_LIBS_FE)
endif
@@ -101,12 +102,26 @@ ifeq ($(with_ssl),openssl)
PKG_CONFIG_REQUIRES_PRIVATE = libssl, libcrypto
endif
+ifeq ($(with_libcurl),yes)
+# libpq.so doesn't link against libcurl, but libpq.a needs libpq-oauth, and
+# libpq-oauth needs libcurl. Put both into *.private.
+PKG_CONFIG_REQUIRES_PRIVATE += libcurl
+%.pc: override SHLIB_LINK_INTERNAL += -lpq-oauth-$(MAJORVERSION)
+endif
+
all: all-lib libpq-refs-stamp
# Shared library stuff
include $(top_srcdir)/src/Makefile.shlib
backend_src = $(top_srcdir)/src/backend
+# Add shlib-/stlib-specific objects.
+$(shlib): override OBJS += $(OBJS_SHLIB)
+$(shlib): $(OBJS_SHLIB)
+
+$(stlib): override OBJS += $(OBJS_STATIC)
+$(stlib): $(OBJS_STATIC)
+
# Check for functions that libpq must not call, currently just exit().
# (Ideally we'd reject abort() too, but there are various scenarios where
# build toolchains insert abort() calls, e.g. to implement assert().)
@@ -115,8 +130,6 @@ backend_src = $(top_srcdir)/src/backend
# which seems to insert references to that even in pure C code. Excluding
# __tsan_func_exit is necessary when using ThreadSanitizer data race detector
# which use this function for instrumentation of function exit.
-# libcurl registers an exit handler in the memory debugging code when running
-# with LeakSanitizer.
# Skip the test when profiling, as gcc may insert exit() calls for that.
# Also skip the test on platforms where libpq infrastructure may be provided
# by statically-linked libraries, as we can't expect them to honor this
@@ -124,7 +137,7 @@ backend_src = $(top_srcdir)/src/backend
libpq-refs-stamp: $(shlib)
ifneq ($(enable_coverage), yes)
ifeq (,$(filter solaris,$(PORTNAME)))
- @if nm -A -u $< 2>/dev/null | grep -v -e __cxa_atexit -e __tsan_func_exit -e _atexit | grep exit; then \
+ @if nm -A -u $< 2>/dev/null | grep -v -e __cxa_atexit -e __tsan_func_exit | grep exit; then \
echo 'libpq must not be calling any function which invokes exit'; exit 1; \
fi
endif
@@ -138,6 +151,11 @@ fe-misc.o: fe-misc.c $(top_builddir)/src/port/pg_config_paths.h
$(top_builddir)/src/port/pg_config_paths.h:
$(MAKE) -C $(top_builddir)/src/port pg_config_paths.h
+# Use src/common/Makefile's trick for tracking dependencies of shlib-specific
+# objects.
+%_shlib.o: %.c %.o
+ $(CC) $(CFLAGS) $(CFLAGS_SL) $(CPPFLAGS) $(CPPFLAGS_SHLIB) -c $< -o $@
+
install: all installdirs install-lib
$(INSTALL_DATA) $(srcdir)/libpq-fe.h '$(DESTDIR)$(includedir)'
$(INSTALL_DATA) $(srcdir)/libpq-events.h '$(DESTDIR)$(includedir)'
@@ -171,6 +189,6 @@ uninstall: uninstall-lib
clean distclean: clean-lib
$(MAKE) -C test $@
rm -rf tmp_check
- rm -f $(OBJS) pthread.h libpq-refs-stamp
+ rm -f $(OBJS) $(OBJS_SHLIB) $(OBJS_STATIC) pthread.h libpq-refs-stamp
# Might be left over from a Win32 client-only build
rm -f pg_config_paths.h
diff --git a/src/interfaces/libpq/exports.txt b/src/interfaces/libpq/exports.txt
index d5143766858..0625cf39e9a 100644
--- a/src/interfaces/libpq/exports.txt
+++ b/src/interfaces/libpq/exports.txt
@@ -210,3 +210,4 @@ PQsetAuthDataHook 207
PQgetAuthDataHook 208
PQdefaultAuthDataHook 209
PQfullProtocolVersion 210
+appendPQExpBufferVA 211
diff --git a/src/interfaces/libpq/fe-auth-oauth.c b/src/interfaces/libpq/fe-auth-oauth.c
index cf1a25e2ccc..5c285adccbd 100644
--- a/src/interfaces/libpq/fe-auth-oauth.c
+++ b/src/interfaces/libpq/fe-auth-oauth.c
@@ -15,6 +15,10 @@
#include "postgres_fe.h"
+#ifdef USE_DYNAMIC_OAUTH
+#include <dlfcn.h>
+#endif
+
#include "common/base64.h"
#include "common/hmac.h"
#include "common/jsonapi.h"
@@ -721,6 +725,143 @@ cleanup_user_oauth_flow(PGconn *conn)
state->async_ctx = NULL;
}
+/*-------------
+ * Builtin Flow
+ *
+ * There are three potential implementations of use_builtin_flow:
+ *
+ * 1) If the OAuth client is disabled at configuration time, return false.
+ * Dependent clients must provide their own flow.
+ * 2) If the OAuth client is enabled and USE_DYNAMIC_OAUTH is defined, dlopen()
+ * the libpq-oauth plugin and use its implementation.
+ * 3) Otherwise, use flow callbacks that are statically linked into the
+ * executable.
+ */
+
+#if !defined(USE_LIBCURL)
+
+/*
+ * This configuration doesn't support the builtin flow.
+ */
+
+bool
+use_builtin_flow(PGconn *conn, fe_oauth_state *state)
+{
+ return false;
+}
+
+#elif defined(USE_DYNAMIC_OAUTH)
+
+/*
+ * Use the builtin flow in the libpq-oauth plugin, which is loaded at runtime.
+ */
+
+typedef char *(*libpq_gettext_func) (const char *msgid);
+typedef PQExpBuffer (*conn_errorMessage_func) (PGconn *conn);
+
+/*
+ * This shim is injected into libpq-oauth so that it doesn't depend on the
+ * offset of conn->errorMessage.
+ *
+ * TODO: look into exporting libpq_append_conn_error or a comparable API from
+ * libpq, instead.
+ */
+static PQExpBuffer
+conn_errorMessage(PGconn *conn)
+{
+ return &conn->errorMessage;
+}
+
+/*
+ * Loads the libpq-oauth plugin via dlopen(), initializes it, and plugs its
+ * callbacks into the connection's async auth handlers.
+ *
+ * Failure to load here results in a relatively quiet connection error, to
+ * handle the use case where the build supports loading a flow but a user does
+ * not want to install it. Troubleshooting of linker/loader failures can be done
+ * via PGOAUTHDEBUG.
+ */
+bool
+use_builtin_flow(PGconn *conn, fe_oauth_state *state)
+{
+ void (*init) (pgthreadlock_t threadlock,
+ libpq_gettext_func gettext_impl,
+ conn_errorMessage_func errmsg_impl);
+ PostgresPollingStatusType (*flow) (PGconn *conn);
+ void (*cleanup) (PGconn *conn);
+
+ state->builtin_flow = dlopen("libpq-oauth-" PG_MAJORVERSION DLSUFFIX,
+ RTLD_NOW | RTLD_LOCAL);
+ if (!state->builtin_flow)
+ {
+ /*
+ * For end users, this probably isn't an error condition, it just
+ * means the flow isn't installed. Developers and package maintainers
+ * may want to debug this via the PGOAUTHDEBUG envvar, though.
+ *
+ * Note that POSIX dlerror() isn't guaranteed to be threadsafe.
+ */
+ if (oauth_unsafe_debugging_enabled())
+ fprintf(stderr, "failed dlopen for libpq-oauth: %s\n", dlerror());
+
+ return false;
+ }
+
+ if ((init = dlsym(state->builtin_flow, "libpq_oauth_init")) == NULL
+ || (flow = dlsym(state->builtin_flow, "pg_fe_run_oauth_flow")) == NULL
+ || (cleanup = dlsym(state->builtin_flow, "pg_fe_cleanup_oauth_flow")) == NULL)
+ {
+ /*
+ * This is more of an error condition than the one above, but due to
+ * the dlerror() threadsafety issue, lock it behind PGOAUTHDEBUG too.
+ */
+ if (oauth_unsafe_debugging_enabled())
+ fprintf(stderr, "failed dlsym for libpq-oauth: %s\n", dlerror());
+
+ dlclose(state->builtin_flow);
+ return false;
+ }
+
+ /*
+ * Inject necessary function pointers into the module.
+ */
+ init(pg_g_threadlock,
+#ifdef ENABLE_NLS
+ libpq_gettext,
+#else
+ NULL,
+#endif
+ conn_errorMessage);
+
+ /* Set our asynchronous callbacks. */
+ conn->async_auth = flow;
+ conn->cleanup_async_auth = cleanup;
+
+ return true;
+}
+
+#else
+
+/*
+ * Use the builtin flow in libpq-oauth.a (see libpq-oauth/oauth-curl.h).
+ */
+
+extern PostgresPollingStatusType pg_fe_run_oauth_flow(PGconn *conn);
+extern void pg_fe_cleanup_oauth_flow(PGconn *conn);
+
+bool
+use_builtin_flow(PGconn *conn, fe_oauth_state *state)
+{
+ /* Set our asynchronous callbacks. */
+ conn->async_auth = pg_fe_run_oauth_flow;
+ conn->cleanup_async_auth = pg_fe_cleanup_oauth_flow;
+
+ return true;
+}
+
+#endif /* USE_LIBCURL */
+
+
/*
* Chooses an OAuth client flow for the connection, which will retrieve a Bearer
* token for presentation to the server.
@@ -792,18 +933,10 @@ setup_token_request(PGconn *conn, fe_oauth_state *state)
libpq_append_conn_error(conn, "user-defined OAuth flow failed");
goto fail;
}
- else
+ else if (!use_builtin_flow(conn, state))
{
-#if USE_LIBCURL
- /* Hand off to our built-in OAuth flow. */
- conn->async_auth = pg_fe_run_oauth_flow;
- conn->cleanup_async_auth = pg_fe_cleanup_oauth_flow;
-
-#else
libpq_append_conn_error(conn, "no custom OAuth flows are available, and libpq was not built with libcurl support");
goto fail;
-
-#endif
}
return true;
diff --git a/src/interfaces/libpq/fe-auth-oauth.h b/src/interfaces/libpq/fe-auth-oauth.h
index 3f1a7503a01..687e664475f 100644
--- a/src/interfaces/libpq/fe-auth-oauth.h
+++ b/src/interfaces/libpq/fe-auth-oauth.h
@@ -33,12 +33,13 @@ typedef struct
PGconn *conn;
void *async_ctx;
+
+ void *builtin_flow;
} fe_oauth_state;
-extern PostgresPollingStatusType pg_fe_run_oauth_flow(PGconn *conn);
-extern void pg_fe_cleanup_oauth_flow(PGconn *conn);
extern void pqClearOAuthToken(PGconn *conn);
extern bool oauth_unsafe_debugging_enabled(void);
+extern bool use_builtin_flow(PGconn *conn, fe_oauth_state *state);
/* Mechanisms in fe-auth-oauth.c */
extern const pg_fe_sasl_mech pg_oauth_mech;
diff --git a/src/interfaces/libpq/meson.build b/src/interfaces/libpq/meson.build
index 292fecf3320..63e48d9fcfb 100644
--- a/src/interfaces/libpq/meson.build
+++ b/src/interfaces/libpq/meson.build
@@ -18,6 +18,7 @@ libpq_sources = files(
'pqexpbuffer.c',
)
libpq_so_sources = [] # for shared lib, in addition to the above
+libpq_st_sources = [] # for static lib, in addition to the above
if host_system == 'windows'
libpq_sources += files('pthread-win32.c', 'win32.c')
@@ -38,10 +39,6 @@ if gssapi.found()
)
endif
-if libcurl.found()
- libpq_sources += files('fe-auth-oauth-curl.c')
-endif
-
export_file = custom_target('libpq.exports',
kwargs: gen_export_kwargs,
)
@@ -50,6 +47,9 @@ export_file = custom_target('libpq.exports',
libpq_inc = include_directories('.', '../../port')
libpq_c_args = ['-DSO_MAJOR_VERSION=5']
+# The OAuth implementation differs depending on the type of library being built.
+libpq_so_c_args = ['-DUSE_DYNAMIC_OAUTH']
+
# Not using both_libraries() here as
# 1) resource files should only be in the shared library
# 2) we want the .pc file to include a dependency to {pgport,common}_static for
@@ -59,7 +59,7 @@ libpq_c_args = ['-DSO_MAJOR_VERSION=5']
# more complexity than its worth (reusing object files requires also linking
# to the library on windows or breaks precompiled headers).
libpq_st = static_library('libpq',
- libpq_sources,
+ libpq_sources + libpq_st_sources,
include_directories: [libpq_inc],
c_args: libpq_c_args,
c_pch: pch_postgres_fe_h,
@@ -70,7 +70,7 @@ libpq_st = static_library('libpq',
libpq_so = shared_library('libpq',
libpq_sources + libpq_so_sources,
include_directories: [libpq_inc, postgres_inc],
- c_args: libpq_c_args,
+ c_args: libpq_c_args + libpq_so_c_args,
c_pch: pch_postgres_fe_h,
version: '5.' + pg_version_major.to_string(),
soversion: host_system != 'windows' ? '5' : '',
@@ -86,12 +86,26 @@ libpq = declare_dependency(
include_directories: [include_directories('.')]
)
+private_deps = [
+ frontend_stlib_code,
+ libpq_deps,
+]
+
+if oauth_flow_supported
+ # libpq.so doesn't link against libcurl, but libpq.a needs libpq-oauth, and
+ # libpq-oauth needs libcurl. Put both into *.private.
+ private_deps += [
+ libpq_oauth_deps,
+ '-lpq-oauth-@0@'.format(pg_version_major),
+ ]
+endif
+
pkgconfig.generate(
name: 'libpq',
description: 'PostgreSQL libpq library',
url: pg_url,
libraries: libpq,
- libraries_private: [frontend_stlib_code, libpq_deps],
+ libraries_private: private_deps,
)
install_headers(
diff --git a/src/interfaces/libpq/nls.mk b/src/interfaces/libpq/nls.mk
index ae761265852..b87df277d93 100644
--- a/src/interfaces/libpq/nls.mk
+++ b/src/interfaces/libpq/nls.mk
@@ -13,15 +13,21 @@ GETTEXT_FILES = fe-auth.c \
fe-secure-common.c \
fe-secure-gssapi.c \
fe-secure-openssl.c \
- win32.c
-GETTEXT_TRIGGERS = libpq_append_conn_error:2 \
+ win32.c \
+ ../libpq-oauth/oauth-curl.c \
+ ../libpq-oauth/oauth-utils.c
+GETTEXT_TRIGGERS = actx_error:2 \
+ libpq_append_conn_error:2 \
libpq_append_error:2 \
libpq_gettext \
libpq_ngettext:1,2 \
+ oauth_parse_set_error:2 \
pqInternalNotice:2
-GETTEXT_FLAGS = libpq_append_conn_error:2:c-format \
+GETTEXT_FLAGS = actx_error:2:c-format \
+ libpq_append_conn_error:2:c-format \
libpq_append_error:2:c-format \
libpq_gettext:1:pass-c-format \
libpq_ngettext:1:pass-c-format \
libpq_ngettext:2:pass-c-format \
+ oauth_parse_set_error:2:c-format \
pqInternalNotice:2:c-format
diff --git a/src/makefiles/meson.build b/src/makefiles/meson.build
index 46d8da070e8..f2ba5b38124 100644
--- a/src/makefiles/meson.build
+++ b/src/makefiles/meson.build
@@ -201,6 +201,8 @@ pgxs_empty = [
'ICU_LIBS',
'LIBURING_CFLAGS', 'LIBURING_LIBS',
+
+ 'LIBCURL_CPPFLAGS', 'LIBCURL_LDFLAGS', 'LIBCURL_LDLIBS',
]
if host_system == 'windows' and cc.get_argument_syntax() != 'msvc'
--
2.34.1
^ permalink raw reply [nested|flat] 9+ messages in thread
end of thread, other threads:[~2025-04-15 00:13 UTC | newest]
Thread overview: 9+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2020-11-08 01:11 [PATCH] Remove duplicate code in brin_memtuple_initialize Tomas Vondra <[email protected]>
2025-04-11 16:21 Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 16:12 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
2025-04-14 17:09 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 18:27 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 19:14 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
2025-04-14 19:46 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Wolfgang Walther <[email protected]>
2025-04-14 20:17 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
2025-04-15 00:13 ` Re: [PoC] Federated Authn/z with OAUTHBEARER Jacob Champion <[email protected]>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox