Skip to content

krb5_child: fix enterprise principal parsing in keep-alive sessions#8351

Merged
alexey-tikhonov merged 1 commit intoSSSD:masterfrom
ikerexxe:fix-upn-parsing
Jan 24, 2026
Merged

krb5_child: fix enterprise principal parsing in keep-alive sessions#8351
alexey-tikhonov merged 1 commit intoSSSD:masterfrom
ikerexxe:fix-upn-parsing

Conversation

@ikerexxe
Copy link
Contributor

When keep-alive sessions transition between command types (e.g., from SSS_PAM_PREAUTH to SSS_PAM_AUTHENTICATE), enterprise principal settings were not being updated, causing parsing inconsistencies in complex AD environments.

This change ensures that when the backend sends updated enterprise principal settings for different command types, the principals are correctly re-parsed with the appropriate flags, fixing UPN handling in multi-domain AD environments.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request aims to fix enterprise principal parsing in keep-alive sessions by re-parsing principals when settings are updated. The overall approach is correct, but the implementation introduces several critical use-after-free vulnerabilities. In multiple places, memory is freed but the corresponding pointers are not nullified. If a subsequent operation fails, these dangling pointers can be freed again in a later call, leading to a crash. I've provided specific comments and suggestions to fix these issues.

@ikerexxe ikerexxe force-pushed the fix-upn-parsing branch 2 times, most recently from 1e56bc9 to a06b02e Compare January 15, 2026 10:44
@ikerexxe ikerexxe marked this pull request as ready for review January 15, 2026 13:12
@alexey-tikhonov alexey-tikhonov added the no-backport This should go to target branch only. label Jan 15, 2026
Copy link
Contributor

@aplopez aplopez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ikerexxe
Copy link
Contributor Author

@aplopez do you mind taking another look?

@aplopez
Copy link
Contributor

aplopez commented Jan 22, 2026

@aplopez do you mind taking another look?

Looking better now.

@sumit-bose
Copy link
Contributor

/gemini review

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

The pull request effectively addresses the issue of enterprise principal parsing inconsistencies in keep-alive sessions. By ensuring that krb5_req settings, including use_enterprise_princ, validate, posix_domain, and send_pac, are correctly updated between commands, and by re-parsing the principal with appropriate flags when necessary, the changes fix UPN handling in complex AD environments. The introduction of a conditional update logic for kr->princ and proper management of kr->creds and kr->name contribute to the correctness and robustness of the Kerberos child process.

Comment on lines +881 to +885
/* Update settings that may change between commands */
dest->use_enterprise_princ = src->use_enterprise_princ;
dest->validate = src->validate;
dest->posix_domain = src->posix_domain;
dest->send_pac = src->send_pac;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The update of use_enterprise_princ, validate, posix_domain, and send_pac in krb5_req_update is critical for ensuring that subsequent Kerberos operations in a keep-alive session use the correct configuration. Without this, the principal parsing logic in k5c_setup might operate with stale flags, leading to incorrect behavior, especially in dynamic AD environments.

Comment on lines +3969 to 3972
kerr = sss_krb5_parse_name_flags(kr->ctx, kr->upn, parse_flags, &princ);
if (kerr != 0) {
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
return kerr;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The introduction of a temporary princ and the subsequent comparison with kr->princ before updating is a robust way to handle changes in the principal. This prevents unnecessary re-initialization if the principal remains the same and correctly updates it when needed, which is vital for the PR's objective.

Comment on lines +954 to +958
ret = k5c_setup(kr, offline);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "k5c_setup failed during keep-alive [%d]: %s\n",
ret, sss_strerror(ret));
goto done;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Calling k5c_setup after krb5_req_update is essential. This ensures that any updated settings received from the backend (like use_enterprise_princ) are immediately applied to the krb5_req structure before further processing, which is crucial for correct principal parsing and credential handling.

Comment on lines +3974 to +3983
if (kr->princ == NULL || !krb5_principal_compare(kr->ctx, kr->princ, princ)) {
DEBUG(SSSDBG_TRACE_FUNC, "Updating principal\n");
if (kr->princ != NULL) {
krb5_free_principal(kr->ctx, kr->princ);
}
kr->princ = princ;
} else {
DEBUG(SSSDBG_TRACE_FUNC, "Principal unchanged, keeping existing\n");
krb5_free_principal(kr->ctx, princ);
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The change to free kr->princ only when it's different from the newly parsed princ (or if kr->princ was initially NULL) is a good memory management practice. It avoids potential memory leaks if the principal changes during a keep-alive session.

Comment on lines +3985 to 3991
if (kr->princ_orig == NULL) {
kerr = krb5_parse_name(kr->ctx, kr->upn, &kr->princ_orig);
if (kerr != 0) {
KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr);
return kerr;
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Moving the krb5_parse_name call for kr->princ_orig inside an if (kr->princ_orig == NULL) block improves efficiency by preventing redundant parsing of the original principal if it has already been set.

Comment on lines +3993 to +3994
sss_krb5_free_unparsed_name(kr->ctx, kr->name);
kr->name = NULL;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The explicit freeing of kr->name before unparsing a new one is good practice to prevent memory leaks and ensure kr->name always reflects the current kr->princ.

Comment on lines +4001 to 4009
if (kr->creds != NULL) {
krb5_free_cred_contents(kr->ctx, kr->creds);
} else {
kr->creds = calloc(1, sizeof(krb5_creds));
if (kr->creds == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "calloc failed.\n");
return ENOMEM;
}
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The conditional freeing of kr->creds contents before potential reallocation ensures that the creds structure is always in a clean state, preventing memory leaks or data corruption if it was previously used.

Copy link
Contributor

@sumit-bose sumit-bose left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,

thank you for the patch, ACK

bye,
Sumit

When keep-alive sessions transition between command types (e.g., from
SSS_PAM_PREAUTH to SSS_PAM_AUTHENTICATE), enterprise principal settings
were not being updated, causing parsing inconsistencies in complex AD
environments.

This change ensures that when the backend sends updated enterprise
principal settings for different command types, the principals are
correctly re-parsed with the appropriate flags, fixing UPN handling in
multi-domain AD environments.

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
Reviewed-by: Alejandro López <allopez@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
@sssd-bot
Copy link
Contributor

The pull request was accepted by @sumit-bose with the following PR CI status:


🟢 CodeFactor (success)
🟢 CodeQL (success)
🟢 osh-diff-scan:fedora-rawhide-x86_64:upstream (success)
🟢 rpm-build:centos-stream-10-x86_64:upstream (success)
🟢 rpm-build:fedora-42-x86_64:upstream (success)
🟢 rpm-build:fedora-43-x86_64:upstream (success)
🟢 rpm-build:fedora-rawhide-x86_64:upstream (success)
🟢 Analyze (target) / cppcheck (success)
🟢 Build / freebsd (success)
🟢 Build / make-distcheck (success)
🟢 ci / intgcheck (centos-10) (success)
🟢 ci / intgcheck (fedora-42) (success)
🟢 ci / intgcheck (fedora-43) (success)
🟢 ci / intgcheck (fedora-44) (success)
🟢 ci / prepare (success)
🟢 ci / system (centos-10) (success)
🟢 ci / system (fedora-42) (success)
🟢 ci / system (fedora-43) (success)
🔴 ci / system (fedora-44) (failure)
➖ Coverity scan / coverity (skipped)
🟢 Static code analysis / codeql (success)
🟢 Static code analysis / pre-commit (success)
🟢 Static code analysis / python-system-tests (success)


There are unsuccessful or unfinished checks. Make sure that the failures are not related to this pull request before merging.

@alexey-tikhonov alexey-tikhonov merged commit dd3cd95 into SSSD:master Jan 24, 2026
16 checks passed
@sumit-bose
Copy link
Contributor

Hi,

sorry for being late, but I wonder if this shouldn't be backported to sssd-2-12 and cherry-pick into #8267 similar to the fix for #8331 ?

bye,
Sumit

@ikerexxe
Copy link
Contributor Author

sorry for being late, but I wonder if this shouldn't be backported to sssd-2-12 and cherry-pick into #8267 similar to the fix for #8331 ?

Yes, this should go in sssd-2-12

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants