Problem joining ldap/FreeIPA domain

First, I’m very happy TrueNAS has native FreeIPA support now. I was really waiting for that. But I’m having trouble joining an FreeIPA based domain through the ldap interface.

Depending on how I try to join I get different errors.

Using a bind-dn and password I get the following error:

Error: Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/middlewared/job.py", line 509, in run
    await self.future
  File "/usr/lib/python3/dist-packages/middlewared/job.py", line 554, in __run_body
    rv = await self.method(*args)
         ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/schema/processor.py", line 49, in nf
    res = await f(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/schema/processor.py", line 179, in nf
    return await func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/plugins/ldap.py", line 673, in do_update
    verrors.check()
  File "/usr/lib/python3/dist-packages/middlewared/service_exception.py", line 72, in check
    raise self
middlewared.service_exception.ValidationErrors: [EINVAL] ldap_update: [UNWILLING_TO_PERFORM]: Server is unwilling to perform: Unauthenticated binds are not allowed

Using a bind-dn + password + creating and selecting the REALM for the domain I get the following error:

 Error: Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/middlewared/plugins/kerberos.py", line 417, in do_kinit
    gss_acquire_cred_principal(
  File "/usr/lib/python3/dist-packages/middlewared/utils/directoryservices/krb5.py", line 251, in gss_acquire_cred_principal
    cr = gssapi.Credentials(
         ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/gssapi/creds.py", line 77, in __new__
    res = cls.acquire(name, lifetime, mechs, usage,
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/gssapi/creds.py", line 173, in acquire
    res = rcred_cred_store.acquire_cred_from(b_store, name,
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "gssapi/raw/ext_cred_store.pyx", line 161, in gssapi.raw.ext_cred_store.acquire_cred_from
gssapi.raw.exceptions.MissingCredentialsError: Major (458752): No credentials were supplied, or the credentials were unavailable or inaccessible, Minor (2529639107): No credentials cache found

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/middlewared/job.py", line 509, in run
    await self.future
  File "/usr/lib/python3/dist-packages/middlewared/job.py", line 554, in __run_body
    rv = await self.method(*args)
         ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/schema/processor.py", line 49, in nf
    res = await f(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/schema/processor.py", line 179, in nf
    return await func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/plugins/ldap.py", line 672, in do_update
    await self.ldap_validate(old, new, verrors)
  File "/usr/lib/python3/dist-packages/middlewared/plugins/ldap.py", line 500, in ldap_validate
    await self.validate_credentials(data)
  File "/usr/lib/python3/dist-packages/middlewared/plugins/ldap.py", line 757, in validate_credentials
    await self.kinit(ldap_config)
  File "/usr/lib/python3/dist-packages/middlewared/plugins/ldap.py", line 746, in kinit
    await self.middleware.call('kerberos.do_kinit', {'krb5_cred': cred})
  File "/usr/lib/python3/dist-packages/middlewared/main.py", line 1629, in call
    return await self._call(
           ^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/main.py", line 1471, in _call
    return await self.run_in_executor(prepared_call.executor, methodobj, *prepared_call.args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/main.py", line 1364, in run_in_executor
    return await loop.run_in_executor(pool, functools.partial(method, *args, **kwargs))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/schema/processor.py", line 183, in nf
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/middlewared/plugins/kerberos.py", line 430, in do_kinit
    raise KRB5Error(
middlewared.utils.directoryservices.krb5_error.KRB5Error: [KRB5_FCC_NOFILE] Major (458752): No credentials were supplied, or the credentials were unavailable or inaccessible, Minor (2529639107): No credentials cache found

With keytab

I can join the domain by importing a keytab but this gives an incomplete join…

I’m using the (redacted) bind-dn with a correct password: uid=admin,cn=users,cn=accounts,dc=department,dc=example,dc=com

I’ve tried sifting through open/closed issues, pull requests and the code but haven’t found any obvious errors, but I’m not really familiar with the codebase. Is this a bug or am I doing something wrong?

This has similarity to another reported issue (post 26438 that I’m not allowed to link) but it has a different error in the backtrace.

Forgot to mention; this is on an up-to-date TrueNAS version ElectricEel-24.10.1 .

I found the issue in the middleware that I ran into. More details on the bugtracker, see:

@Invariant how did you comment out lines 408 and 409 on a production machine? I am running into this issue now.

Well, I figured out this specific bug but it led to SSSD not working/loading (for new bug: Forum topic, Jira ticket).

Here is my workaround to get it to bind a second time (also noted in the original Jira issue):

I manually removed the keytab with ipa-rmkeytab -d -r MY.NAME.NAME.TLD -k /etc/krb5.keytab and that causes it not to be listed in the dropdown. However, there is still an issue in SQL.

Curiously, directoryservice_ldap.ldap_kerberos_principal is NULL in row 1 in factory-v1.db, but this column has a NOT NULL constraint which I think is causing this bug. When I look at directoryservice_ldap.ldap_kerberos_principal in freenas-v1.db , I see the old Kerberos principal. Removing this row from freenas-v1.db causes the middleware to fail to recreate it due to the NOT NULL constraint. I reset freenas-v1.db by copying the table from factory-v1.db.

Full workaround:

  1. Remove the old keytab from ipa and krb5 with: ipa-rmkeytab -d -r MY.NAME.NAME.TLD -k /etc/krb5.keytab
  2. Reset all of the directory services tables:
    sqlite3 /data/factory-v1.db ".dump directoryservice_activedirectory" | sqlite3 -cmd "DROP TABLE IF EXISTS directoryservice_activedirectory" /data/freenas-v1.db
    sqlite3 /data/factory-v1.db ".dump directoryservice_idmap_domain" | sqlite3 -cmd "DROP TABLE IF EXISTS directoryservice_idmap_domain" /data/freenas-v1.db
    sqlite3 /data/factory-v1.db ".dump directoryservice_kerberoskeytab" | sqlite3 -cmd "DROP TABLE IF EXISTS directoryservice_kerberoskeytab" /data/freenas-v1.db
    sqlite3 /data/factory-v1.db ".dump directoryservice_kerberosrealm" | sqlite3 -cmd "DROP TABLE IF EXISTS directoryservice_kerberosrealm" /data/freenas-v1.db
    sqlite3 /data/factory-v1.db ".dump directoryservice_kerberossettings" | sqlite3 -cmd "DROP TABLE IF EXISTS directoryservice_kerberossettings" /data/freenas-v1.db
    sqlite3 /data/factory-v1.db ".dump directoryservice_ldap" | sqlite3 -cmd "DROP TABLE IF EXISTS directoryservice_ldap" /data/freenas-v1.db
    
  3. Try binding again!