mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
KDB: support external IdP configuration
When IdP configuration is provided, take it into account: - idp-specific Kerberos ticket policy would be applied - Presence of IdP link in a Kerberos principal entry would cause KDB to enable `idp` pre-authentication method on KDC side. The latter requires additional pre-authentication method supplied with SSSD 2.7.0. Fixes: https://pagure.io/freeipa/issue/8804 Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com> Signed-off-by: Pavel Březina <pbrezina@redhat.com> Reviewed-By: Francisco Trivino <ftrivino@redhat.com> Reviewed-By: Sumit Bose <sbose@redhat.com>
This commit is contained in:
parent
3f6656e09a
commit
a1be4fc863
@ -199,6 +199,7 @@ static const struct {
|
|||||||
{ "otp", IPADB_USER_AUTH_OTP },
|
{ "otp", IPADB_USER_AUTH_OTP },
|
||||||
{ "pkinit", IPADB_USER_AUTH_PKINIT },
|
{ "pkinit", IPADB_USER_AUTH_PKINIT },
|
||||||
{ "hardened", IPADB_USER_AUTH_HARDENED },
|
{ "hardened", IPADB_USER_AUTH_HARDENED },
|
||||||
|
{ "idp", IPADB_USER_AUTH_IDP },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -89,6 +89,7 @@ enum ipadb_user_auth {
|
|||||||
IPADB_USER_AUTH_OTP = 1 << 3,
|
IPADB_USER_AUTH_OTP = 1 << 3,
|
||||||
IPADB_USER_AUTH_PKINIT = 1 << 4,
|
IPADB_USER_AUTH_PKINIT = 1 << 4,
|
||||||
IPADB_USER_AUTH_HARDENED = 1 << 5,
|
IPADB_USER_AUTH_HARDENED = 1 << 5,
|
||||||
|
IPADB_USER_AUTH_IDP = 1 << 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ipadb_user_auth_idx {
|
enum ipadb_user_auth_idx {
|
||||||
@ -96,6 +97,7 @@ enum ipadb_user_auth_idx {
|
|||||||
IPADB_USER_AUTH_IDX_RADIUS,
|
IPADB_USER_AUTH_IDX_RADIUS,
|
||||||
IPADB_USER_AUTH_IDX_PKINIT,
|
IPADB_USER_AUTH_IDX_PKINIT,
|
||||||
IPADB_USER_AUTH_IDX_HARDENED,
|
IPADB_USER_AUTH_IDX_HARDENED,
|
||||||
|
IPADB_USER_AUTH_IDX_IDP,
|
||||||
IPADB_USER_AUTH_IDX_MAX,
|
IPADB_USER_AUTH_IDX_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -133,6 +133,15 @@ ipa_kdcpolicy_check_as(krb5_context context, krb5_kdcpolicy_moddata moddata,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
pol_limits = &(ied->pol_limits[IPADB_USER_AUTH_IDX_HARDENED]);
|
pol_limits = &(ied->pol_limits[IPADB_USER_AUTH_IDX_HARDENED]);
|
||||||
|
} else if (strcmp(auth_indicator, "idp") == 0) {
|
||||||
|
valid_auth_indicators++;
|
||||||
|
/* Allow hardened even if only password pre-auth is allowed */
|
||||||
|
if (!(ua & IPADB_USER_AUTH_IDP)) {
|
||||||
|
*status = "IdP pre-authentication not allowed for this user.";
|
||||||
|
kerr = KRB5KDC_ERR_POLICY;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
pol_limits = &(ied->pol_limits[IPADB_USER_AUTH_IDX_IDP]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@ static char *std_principal_attrs[] = {
|
|||||||
IPA_KRB_AUTHZ_DATA_ATTR,
|
IPA_KRB_AUTHZ_DATA_ATTR,
|
||||||
IPA_USER_AUTH_TYPE,
|
IPA_USER_AUTH_TYPE,
|
||||||
"ipatokenRadiusConfigLink",
|
"ipatokenRadiusConfigLink",
|
||||||
|
"ipaIdpConfigLink",
|
||||||
"krbAuthIndMaxTicketLife",
|
"krbAuthIndMaxTicketLife",
|
||||||
"krbAuthIndMaxRenewableAge",
|
"krbAuthIndMaxRenewableAge",
|
||||||
"ipaNTSecurityIdentifier",
|
"ipaNTSecurityIdentifier",
|
||||||
@ -316,8 +317,31 @@ static void ipadb_validate_radius(struct ipadb_context *ipactx,
|
|||||||
"ipatokenRadiusConfigLink");
|
"ipatokenRadiusConfigLink");
|
||||||
if (vals == NULL || vals[0] == NULL)
|
if (vals == NULL || vals[0] == NULL)
|
||||||
*ua &= ~IPADB_USER_AUTH_RADIUS;
|
*ua &= ~IPADB_USER_AUTH_RADIUS;
|
||||||
else
|
else {
|
||||||
*ua = IPADB_USER_AUTH_RADIUS;
|
/* OTP use implies presence of password in IPA LDAP,
|
||||||
|
* this is incompatible with RADIUS proxy case where
|
||||||
|
* a password in LDAP is not used anymore. */
|
||||||
|
*ua &= ~IPADB_USER_AUTH_OTP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vals != NULL)
|
||||||
|
ldap_value_free_len(vals);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ipadb_validate_idp(struct ipadb_context *ipactx,
|
||||||
|
LDAPMessage *lentry,
|
||||||
|
enum ipadb_user_auth *ua)
|
||||||
|
{
|
||||||
|
struct berval **vals;
|
||||||
|
|
||||||
|
if (!(*ua & IPADB_USER_AUTH_IDP))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Ensure that the user has a link to an IdP config. */
|
||||||
|
vals = ldap_get_values_len(ipactx->lcontext, lentry,
|
||||||
|
"ipaIdpConfigLink");
|
||||||
|
if (vals == NULL || vals[0] == NULL)
|
||||||
|
*ua &= ~IPADB_USER_AUTH_IDP;
|
||||||
|
|
||||||
if (vals != NULL)
|
if (vals != NULL)
|
||||||
ldap_value_free_len(vals);
|
ldap_value_free_len(vals);
|
||||||
@ -355,6 +379,7 @@ static enum ipadb_user_auth ipadb_get_user_auth(struct ipadb_context *ipactx,
|
|||||||
/* Perform flag validation. */
|
/* Perform flag validation. */
|
||||||
ipadb_validate_otp(ipactx, lentry, &ua);
|
ipadb_validate_otp(ipactx, lentry, &ua);
|
||||||
ipadb_validate_radius(ipactx, lentry, &ua);
|
ipadb_validate_radius(ipactx, lentry, &ua);
|
||||||
|
ipadb_validate_idp(ipactx, lentry, &ua);
|
||||||
|
|
||||||
return ua;
|
return ua;
|
||||||
}
|
}
|
||||||
@ -537,6 +562,8 @@ static void ipadb_parse_authind_policies(krb5_context kcontext,
|
|||||||
IPADB_USER_AUTH_PKINIT, IPADB_USER_AUTH_IDX_PKINIT},
|
IPADB_USER_AUTH_PKINIT, IPADB_USER_AUTH_IDX_PKINIT},
|
||||||
{"krbAuthIndMaxTicketLife;hardened",
|
{"krbAuthIndMaxTicketLife;hardened",
|
||||||
IPADB_USER_AUTH_HARDENED, IPADB_USER_AUTH_IDX_HARDENED},
|
IPADB_USER_AUTH_HARDENED, IPADB_USER_AUTH_IDX_HARDENED},
|
||||||
|
{"krbAuthIndMaxTicketLife;idp",
|
||||||
|
IPADB_USER_AUTH_IDP, IPADB_USER_AUTH_IDX_IDP},
|
||||||
{NULL, IPADB_USER_AUTH_NONE, IPADB_USER_AUTH_IDX_MAX},
|
{NULL, IPADB_USER_AUTH_NONE, IPADB_USER_AUTH_IDX_MAX},
|
||||||
}, age_authind_map[] = {
|
}, age_authind_map[] = {
|
||||||
{"krbAuthIndMaxRenewableAge;otp",
|
{"krbAuthIndMaxRenewableAge;otp",
|
||||||
@ -547,6 +574,8 @@ static void ipadb_parse_authind_policies(krb5_context kcontext,
|
|||||||
IPADB_USER_AUTH_PKINIT, IPADB_USER_AUTH_IDX_PKINIT},
|
IPADB_USER_AUTH_PKINIT, IPADB_USER_AUTH_IDX_PKINIT},
|
||||||
{"krbAuthIndMaxRenewableAge;hardened",
|
{"krbAuthIndMaxRenewableAge;hardened",
|
||||||
IPADB_USER_AUTH_HARDENED, IPADB_USER_AUTH_IDX_HARDENED},
|
IPADB_USER_AUTH_HARDENED, IPADB_USER_AUTH_IDX_HARDENED},
|
||||||
|
{"krbAuthIndMaxRenewableAge;idp",
|
||||||
|
IPADB_USER_AUTH_IDP, IPADB_USER_AUTH_IDX_IDP},
|
||||||
{NULL, IPADB_USER_AUTH_NONE, IPADB_USER_AUTH_IDX_MAX},
|
{NULL, IPADB_USER_AUTH_NONE, IPADB_USER_AUTH_IDX_MAX},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -583,6 +612,7 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
|
|||||||
{
|
{
|
||||||
const krb5_octet rad_string[] = "otp\0[{\"indicators\": [\"radius\"]}]";
|
const krb5_octet rad_string[] = "otp\0[{\"indicators\": [\"radius\"]}]";
|
||||||
const krb5_octet otp_string[] = "otp\0[{\"indicators\": [\"otp\"]}]";
|
const krb5_octet otp_string[] = "otp\0[{\"indicators\": [\"otp\"]}]";
|
||||||
|
const krb5_octet idp_string[] = "idp\0[{\"type\":\"oauth2\",\"indicators\": [\"idp\"]}]";
|
||||||
struct ipadb_context *ipactx;
|
struct ipadb_context *ipactx;
|
||||||
enum ipadb_user_auth ua;
|
enum ipadb_user_auth ua;
|
||||||
LDAP *lcontext;
|
LDAP *lcontext;
|
||||||
@ -961,6 +991,11 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
|
|||||||
sizeof(rad_string), rad_string);
|
sizeof(rad_string), rad_string);
|
||||||
if (kerr)
|
if (kerr)
|
||||||
goto done;
|
goto done;
|
||||||
|
} else if (ua & IPADB_USER_AUTH_IDP) {
|
||||||
|
kerr = ipadb_set_tl_data(entry, KRB5_TL_STRING_ATTRS,
|
||||||
|
sizeof(idp_string), idp_string);
|
||||||
|
if (kerr)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ua & ~IPADB_USER_AUTH_NONE) {
|
if (ua & ~IPADB_USER_AUTH_NONE) {
|
||||||
|
Loading…
Reference in New Issue
Block a user