Considering that ipauserauthtype field could be modified from multiple sources (i.e. LDAP, IPA commands, or WebUI), the values can contain unsupported null characters, making the corresponding element to not reflect the current state of the data.
ipauserauthtype
Showing a warning message to highlight values that are not allowed in the ipauserauthtype record could easily fix that problem. It could be something that displays the authentication values as greyed out with a message like: "Wrong authentication types present in the entry", thus providing to the user a more accurate result of the actual values.
If a user introduces a null character or space (e.g. otp or otp\0) from an LDAP command, the corresponding checkbox from ipauserauthtype is not checked, although the value is stored. But this change is not reflected in the webui.
otp
otp\0
The authentication values as greyed out with a message like: "Wrong authentication types present in the entry", thus providing to the user a more accurate result of the actual values.
IPA API exposes the attribute ipauserauthtype as StrEnum parameter. This parameter type also strips whitespace around the explicitly defined values and does not allow non-defined values. So the problem affects direct LDAP modification.
StrEnum
The fix is to add a warning to KDB driver code when we parse ipauserauthtype field. Right now it compares the values and does not warn that non-empty value did not match any of the defined ones. We should add the warning so that admins have something to act on.
\0
In ipadb_get_ldap_mod_str_list() (daemons/ipa-kdb/ipa_kdb_principals.c), bv_len was set to strlen(s) + 1, incorrectly including the C string null terminator as part of the LDAP BER value length. LDAP bv_len must be the exact byte count of the value content — the null terminator must not be counted.
ipadb_get_ldap_mod_str_list()
bv_len
strlen(s) + 1
LDAP BER
Both attributes written through ipadb_get_ldap_mod_str_list() were affected:
The in-KDC round-trip through ipadb_get_ldap_auth_ind() was accidentally resilient: strndup(bv_val, bv_len) gives a string with an embedded \0, but the subsequent snprintf(..., "%s ", ...) stops at that \0 and produces the correct space-separated require_auth string. The KDC therefore functioned correctly; the corruption was only visible at the LDAP protocol level.
strndup(bv_val, bv_len)
snprintf(..., "%s ", ...)
require_auth
krbPrincipalAuthInd values stored with a trailing \0 byte ("otp\0" instead of "otp") caused LDAP equality filter matching to silently fail. Concretely:
krbPrincipalAuthInd
"otp\0"
"otp"
The passwordHistory corruption was benign in practice: the ipa-pwd-extop plugin reads history via slapi_entry_attr_get_charray() and compares with C string functions (strchr, strlen, strcmp) that all stop at the first \0, so history enforcement continued to work correctly.
passwordHistory
ipa-pwd-extop
slapi_entry_attr_get_charray()
The same + 1 mistake existed in daemons/ipa-slapi-plugins/ipa-version/ipa_repl_version.c:85, which builds a berval for the replication session handshake (IPA version negotiation). That instance is functionally benign — the value is never stored in the DIT and is compared with strcmp on the receiver — but was incorrect for the same reason.
+ 1
daemons/ipa-slapi-plugins/ipa-version/ipa_repl_version.c:85
daemons/ipa-kdb/ipa_kdb_principals.c:2678 /* before */ bvs[i]->bv_len = strlen(strlist[i]) + 1; /* after */ bvs[i]->bv_len = strlen(strlist[i]);
and
daemons/ipa-slapi-plugins/ipa-version/ipa_repl_version.c:85 /* before */ (*data)->bv_len = strlen((*data)->bv_val) + 1; /* after */ (*data)->bv_len = strlen((*data)->bv_val);