Bug 220325

Summary: databases/postgresql*-{client,server}: Poudriere build broken with GSSAPI option
Product: Ports & Packages Reporter: Christian Ullrich <chris>
Component: Individual Port(s)Assignee: Palle Girgensohn <girgen>
Status: New ---    
Severity: Affects Some People CC: cy, girgen, hrs, pgsql, pmc
Priority: ---    
Version: Latest   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
Sample patch
none
Patch updated against databases/postgresql10-server chris: maintainer-approval?

Description Christian Ullrich 2017-06-28 07:07:51 UTC
The PostgreSQL ports support building with the usual Kerberos variants: base, ports Heimdal, ports MIT. The way they do this, however, breaks badly when building within poudriere.

Poudriere builders have no packages installed initially, and prepare for each port build by installing the packages declared as dependencies by the port. Hence, any dependency undeclared by the port, e.g. as LIB_DEPENDS, will not be satisfied during build.

The PostgreSQL ports are affected by this because they:

- declare a dependency on security/krb5 only if it is already installed
- never declare a dependency on security/heimdal at all
Comment 1 Palle Girgensohn freebsd_committer freebsd_triage 2017-06-29 19:21:00 UTC
I'll check this out.
Comment 2 Palle Girgensohn freebsd_committer freebsd_triage 2017-06-29 20:04:39 UTC
I seem to remeber that Kerberos is either not supported, or at least gravely deprecated, in favour of GSSAPI. I has been on my list to chekt this out for some time.
Comment 3 Christian Ullrich 2017-06-29 20:13:07 UTC
The "krb5" authentication method was removed in 9.4, yes, and this results in a warning from configure in 9.[456] about "--with-krb5" being an unknown option. I thought about reporting that, too, but decided it wasn't important enough to require building different CONFIGURE_ARGS in different port versions.

For *this* bug that does not matter because the GSSAPI implementations come from the Kerberos suites. GSSAPI is an abstraction layer (similar to SASL and SSPI) after all, and one of the authentication mechanisms it supports happens to be Kerberos.
Comment 4 Palle Girgensohn freebsd_committer freebsd_triage 2017-06-29 21:42:25 UTC
(In reply to Christian Ullrich from comment #3)

Quite so. I just thought that since GSSAPI requires less dependencies on the kerberos installation, the base heimdal could suffice, and we would not have to bother about which Kerberos port that is installed.
Comment 5 Christian Ullrich 2017-06-30 05:55:25 UTC
(In reply to Palle Girgensohn from comment #4)

The problem is that having multiple Kerberoses in the same system is a steady source of trouble. I have had a lot of not-fun in the past with things like Samba and PostgreSQL picking up the wrong one even at run time, so these days I build my worlds WITHOUT_KERBEROS, i.e. omit the base Heimdal entirely.

Anyway, the ports collection has good support for selecting one's favorite Kerberos through USES=gssapi.

I'm not sure whether library selection through /etc/gss/mech is supposed to work cross-package, i.e. let you use ports MIT's implementation of something with your application linked against base Heimdal, but I rather doubt it. At API level, MIT and Heimdal are too different.

For example (from MIT's gssapi_krb5.h):

/* Alias for Heimdal compat. */
#define gsskrb5_register_acceptor_identity krb5_gss_register_acceptor_identity

OM_uint32 KRB5_CALLCONV krb5_gss_register_acceptor_identity(const char *);

This may let code that expects the Heimdal function name build against MIT, but it is no help at run time, where the dynamic linker clearly has no hope of matching up the symbols.
Comment 6 Christian Ullrich 2017-08-11 07:01:23 UTC
The recent update to, among other things, 9.6.4 and 9.2.22, now breaks the poudriere build (at least in my configuration; base WITHOUT_KERBEROS and with security/krb5 installed) entirely and with no feasible workaround.

Included in the update is a change to the clan elder of the family of PostgreSQL ports, databases/postgresql92-server, which removes the MIT_KRB5 and HEIMDAL_KRB5 port options from all ports from version 9.4 onwards. Instead, it falls back to simply adding -lgssapi to LDFLAGS.

No such library exists in MIT, and therefore the configure script fails right at the start:

configure:3884: checking whether the C compiler works
configure:3906: cc -O -pipe -march=haswell  -O3 -funroll-loops -fstack-protector
 -fno-strict-aliasing -I/usr/local/include  -L/usr/local/lib -lpthread -lgssapi
-L/usr/local/lib -Wl,-rpath,/usr/local/lib -fstack-protector conftest.c  >&5
/usr/bin/ld: cannot find -lgssapi
cc: error: linker command failed with exit code 1 (use -v to see invocation)
[...]
configure:3953: error: in `/wrkdirs/usr/ports/databases/postgresql96-client/work/postgresql-9.6.4':
configure:3956: error: C compiler cannot create executables

This worked before the update because the spurious -lgssapi option was not added in the presence of both the GSSAPI and MIT_KRB5 port options.

I will also point out, again, that relying on base Heimdal's libgssapi does not work because a) it may not be there at all, and b) even if it is, the "active" Kerberos on any given system may be from ports.

I'm not sure how to fix this properly, but my best guess is:

- Reinstate the MIT_KRB5 and HEIMDAL_KRB5 options for all versions.
- To avoid the configure warning I mentioned earlier (though I could care
  less) only leave out --with-krb5 from CONFIGURE_ARGS in 9.4+.
- Use the *_KRB5 and GSSAPI options to build a correct USES option, and 
  leave the details to that machinery.
Comment 7 Christian Ullrich 2017-08-11 14:37:07 UTC
Also, I just read your comment in #215950 as well as comment no. 4 here, and I think we are simply talking about different things here.

You seem to think that – any, but particularly the one in base – GSSAPI is an interface layer that can use any Kerberos implementation on the "backend".

This is not correct. The well-standardized GSSAPI is the interface to the consumer only, that is, the C API used by services to support GSSAPI authentication, and the ASN.1 data structures used by (network) clients.

There is not a whole second interoperability layer between GSSAPI and the underlying Kerberos. Each Kerberos has its own GSSAPI, but each of the various GSSAPIs looks the same to the consumer as any other.

Applied to PostgreSQL, this means that the GSSAPI port option controls whether the "gss" authentication method is supported, and the *_KRB5 options control where the GSSAPI comes from. Before 9.4, they also control which Kerberos is used for the "krb5" authentication method.

Considering only the 9.4 and later ports, what the port options are supposed to mean is this:

- GSSAPI: Build with base Heimdal, enable "gss" auth
- GSSAPI && MIT_KRB5: Build with security/krb5, enable "gss" auth
- GSSAPI && HEIMDAL_KRB5: Build with security/heimdal, enable "gss" auth
- MIT_KRB5: Build without GSSAPI support
- HEIMDAL_KRB5: Build without GSSAPI support
- (none): Build without GSSAPI support

That is, if GSSAPI is on, then the *_KRB5 options control which of the Kerberos distributions provides its GSSAPI implementation, and if GSSAPI is off, there is no Kerberos support at all.
Comment 8 Palle Girgensohn freebsd_committer freebsd_triage 2017-08-12 11:25:21 UTC
Hello,

I have apparently misunderstood the GSSAPI part on the server side, thanks for clarifying that.

I need to setup a poudriere jail WITHOUT_KERBEROS. Do you have a suggestion how to quickly do that? Just build from source and install to a DESTDIR, and the poudriere jail -m null -M /destdir ?

Palle
Comment 9 Christian Ullrich 2017-08-12 14:04:18 UTC
(In reply to Palle Girgensohn from comment #8)

I would do this, to let poudriere itself build the jail:

# echo WITHOUT_KERBEROS=yes > /usr/local/etc/poudriere.d/nokerberos-src.conf
# poudriere jail -c -j nokerberos -m svn -v stable/11

Adjust -v to taste, of course.
Comment 10 Christian Ullrich 2017-08-17 15:18:19 UTC
Created attachment 185529 [details]
Sample patch

This is what I have been able to come up with. It looks quite ugly because many options are essentially repeated. Unfortunately the port options support is not able to model "radio"-type option groups where each option has a specific effect, but selecting _any_ one has another.

It builds successfully with all combinations of BASE/MIT/HEIMDAL and GSSAPI/!GSSAPI (in 9.[23]), for client and server of all versions. Since it builds, I must assume (but have not tested) that it will also run.

The duplicated *_KRB5/GSSAPI_* options are to keep the options' names consistent for each version. They could probably be combined into the *_KRB5 names.

I removed the block that excludes building with MIT if base Heimdal exists because it looks like a NOP to me; the variable it's conditional on is never defined anywhere.
Comment 11 Cy Schubert freebsd_committer freebsd_triage 2017-09-11 03:17:28 UTC
If you wish you can new projects/krb5. Heimdal in base is private and won't interfere with Heimdal or MIT in base. It's probably best to try this on a sandbox VM or non-production machine as it's probably best not to deviate from head or stable in those instances.
Comment 12 Cy Schubert freebsd_committer freebsd_triage 2017-09-11 03:23:40 UTC
(In reply to Christian Ullrich from comment #10)
This patch makes some sense regardless of how we do Kerberos in base.
Comment 13 Christian Ullrich 2018-02-19 15:43:58 UTC
Created attachment 190807 [details]
Patch updated against databases/postgresql10-server
Comment 14 Peter Much 2022-01-19 21:49:48 UTC
It does not only break with poudriere, it breaks with other build&deploy schemes also.

I agree with Palle Girgenson (#4) that the Heimdal in base does suffice for all that postgres would need. But now we have pgadmin4, and it requires Gssapi credstore extensions in order to copy the creds (as received from the browser via spnego) over to postgres - and that extension is currently only available in MIT kerberos.

And this gets runtime-linked together with the libpq.so into the same image, and also the webserver used (apache, uwsgi, whatever) gets linked into the same image, and a webserver might do other things with spnego, which may also need certain extensions.

A proper instance to *run* such a zoo can certainly be created, but then we do not want to extra adjust/hack/fix our deploy system (poudriere or elsewise) in order to build and link the packages as required.

The port options to choose the kerberos implementation are only present for postgresql <= 9.3. There is no means to choose for newer versions; these will always link with the Heimdal in base (and, according to bug #225801, the build just fails if that has been removed).

What I am currently doing: I switch *OFF* the GSSAPI option (because it always produces a LDFLAGS+=-lgssapi linker feature, which will make configure to always use  the Heimdal. (I didn't understand the comment in the Makefile about DT_NEEDED - maybe something will bite me there and I don't know it yet).
And then, individually for the specific instance that the images are built for, that should get MIT instead of base gssapi, I prepend the make from /etc/make.conf with this snippet:

.if ${.CURDIR:C/.*\/databases\/postgresql[0-9]+-(client|server)//} == ""
GSSAPI_CONFIGURE_OFF=--with-gssapi
GSSAPI_VARS_OFF=USES+=gssapi:mit
.endif

This appears to produce something working, i.e it creates the necessary prereq and it seems to link how it should, to use MIT kerberos.

But I would much appreciate to get the radio buttons, like many other ports have them - that would make things simpler.