mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Add Authentication Indicator Kerberos ticket policy options
For the authentication indicators 'otp', 'radius', 'pkinit', and 'hardened', allow specifying maximum ticket life and maximum renewable age in Kerberos ticket policy. The policy extensions are now loaded when a Kerberos principal data is requested by the KDC and evaluated in AS_REQ KDC policy check. If one of the authentication indicators mentioned above is present in the AS_REQ, corresponding policy is applied to the ticket. Related: https://pagure.io/freeipa/issue/8001 Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com> Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com> Reviewed-By: Rob Crittenden <rcritten@redhat.com> Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
This commit is contained in:
parent
9db6f65a85
commit
c5f32165d6
4
ACI.txt
4
ACI.txt
@ -185,9 +185,9 @@ aci: (targetattr = "cn || createtimestamp || entryusn || ipabaseid || ipabaserid
|
|||||||
dn: cn=views,cn=accounts,dc=ipa,dc=example
|
dn: cn=views,cn=accounts,dc=ipa,dc=example
|
||||||
aci: (targetattr = "cn || createtimestamp || description || entryusn || ipadomainresolutionorder || modifytimestamp || objectclass")(targetfilter = "(objectclass=nsContainer)")(version 3.0;acl "permission:System: Read ID Views";allow (compare,read,search) userdn = "ldap:///all";)
|
aci: (targetattr = "cn || createtimestamp || description || entryusn || ipadomainresolutionorder || modifytimestamp || objectclass")(targetfilter = "(objectclass=nsContainer)")(version 3.0;acl "permission:System: Read ID Views";allow (compare,read,search) userdn = "ldap:///all";)
|
||||||
dn: cn=IPA.EXAMPLE,cn=kerberos,dc=ipa,dc=example
|
dn: cn=IPA.EXAMPLE,cn=kerberos,dc=ipa,dc=example
|
||||||
aci: (targetattr = "createtimestamp || entryusn || krbdefaultencsalttypes || krbmaxrenewableage || krbmaxticketlife || krbsupportedencsalttypes || modifytimestamp || objectclass")(targetfilter = "(objectclass=krbticketpolicyaux)")(version 3.0;acl "permission:System: Read Default Kerberos Ticket Policy";allow (compare,read,search) groupdn = "ldap:///cn=System: Read Default Kerberos Ticket Policy,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
aci: (targetattr = "createtimestamp || entryusn || krbauthindmaxrenewableage || krbauthindmaxticketlife || krbdefaultencsalttypes || krbmaxrenewableage || krbmaxticketlife || krbsupportedencsalttypes || modifytimestamp || objectclass")(targetfilter = "(objectclass=krbticketpolicyaux)")(version 3.0;acl "permission:System: Read Default Kerberos Ticket Policy";allow (compare,read,search) groupdn = "ldap:///cn=System: Read Default Kerberos Ticket Policy,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||||
dn: cn=users,cn=accounts,dc=ipa,dc=example
|
dn: cn=users,cn=accounts,dc=ipa,dc=example
|
||||||
aci: (targetattr = "krbmaxrenewableage || krbmaxticketlife")(targetfilter = "(objectclass=krbticketpolicyaux)")(version 3.0;acl "permission:System: Read User Kerberos Ticket Policy";allow (compare,read,search) groupdn = "ldap:///cn=System: Read User Kerberos Ticket Policy,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
aci: (targetattr = "krbauthindmaxrenewableage || krbauthindmaxticketlife || krbmaxrenewableage || krbmaxticketlife")(targetfilter = "(objectclass=krbticketpolicyaux)")(version 3.0;acl "permission:System: Read User Kerberos Ticket Policy";allow (compare,read,search) groupdn = "ldap:///cn=System: Read User Kerberos Ticket Policy,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||||
dn: cn=locations,cn=etc,dc=ipa,dc=example
|
dn: cn=locations,cn=etc,dc=ipa,dc=example
|
||||||
aci: (targetfilter = "(objectclass=ipaLocationObject)")(version 3.0;acl "permission:System: Add IPA Locations";allow (add) groupdn = "ldap:///cn=System: Add IPA Locations,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
aci: (targetfilter = "(objectclass=ipaLocationObject)")(version 3.0;acl "permission:System: Add IPA Locations";allow (add) groupdn = "ldap:///cn=System: Add IPA Locations,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||||
dn: cn=locations,cn=etc,dc=ipa,dc=example
|
dn: cn=locations,cn=etc,dc=ipa,dc=example
|
||||||
|
10
API.txt
10
API.txt
@ -3219,11 +3219,19 @@ output: Output('result', type=[<type 'bool'>])
|
|||||||
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
|
||||||
output: PrimaryKey('value')
|
output: PrimaryKey('value')
|
||||||
command: krbtpolicy_mod/1
|
command: krbtpolicy_mod/1
|
||||||
args: 1,9,3
|
args: 1,17,3
|
||||||
arg: Str('uid?', cli_name='user')
|
arg: Str('uid?', cli_name='user')
|
||||||
option: Str('addattr*', cli_name='addattr')
|
option: Str('addattr*', cli_name='addattr')
|
||||||
option: Flag('all', autofill=True, cli_name='all', default=False)
|
option: Flag('all', autofill=True, cli_name='all', default=False)
|
||||||
option: Str('delattr*', cli_name='delattr')
|
option: Str('delattr*', cli_name='delattr')
|
||||||
|
option: Int('krbauthindmaxrenewableage_hardened?', autofill=False, cli_name='hardened_maxrenew')
|
||||||
|
option: Int('krbauthindmaxrenewableage_otp?', autofill=False, cli_name='otp_maxrenew')
|
||||||
|
option: Int('krbauthindmaxrenewableage_pkinit?', autofill=False, cli_name='pkinit_maxrenew')
|
||||||
|
option: Int('krbauthindmaxrenewableage_radius?', autofill=False, cli_name='radius_maxrenew')
|
||||||
|
option: Int('krbauthindmaxticketlife_hardened?', autofill=False, cli_name='hardened_maxlife')
|
||||||
|
option: Int('krbauthindmaxticketlife_otp?', autofill=False, cli_name='otp_maxlife')
|
||||||
|
option: Int('krbauthindmaxticketlife_pkinit?', autofill=False, cli_name='pkinit_maxlife')
|
||||||
|
option: Int('krbauthindmaxticketlife_radius?', autofill=False, cli_name='radius_maxlife')
|
||||||
option: Int('krbmaxrenewableage?', autofill=False, cli_name='maxrenew')
|
option: Int('krbmaxrenewableage?', autofill=False, cli_name='maxrenew')
|
||||||
option: Int('krbmaxticketlife?', autofill=False, cli_name='maxlife')
|
option: Int('krbmaxticketlife?', autofill=False, cli_name='maxlife')
|
||||||
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
option: Flag('raw', autofill=True, cli_name='raw', default=False)
|
||||||
|
@ -94,6 +94,14 @@ enum ipadb_user_auth {
|
|||||||
IPADB_USER_AUTH_HARDENED = 1 << 5,
|
IPADB_USER_AUTH_HARDENED = 1 << 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ipadb_user_auth_idx {
|
||||||
|
IPADB_USER_AUTH_IDX_OTP = 0,
|
||||||
|
IPADB_USER_AUTH_IDX_RADIUS,
|
||||||
|
IPADB_USER_AUTH_IDX_PKINIT,
|
||||||
|
IPADB_USER_AUTH_IDX_HARDENED,
|
||||||
|
IPADB_USER_AUTH_IDX_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
struct ipadb_global_config {
|
struct ipadb_global_config {
|
||||||
time_t last_update;
|
time_t last_update;
|
||||||
bool disable_last_success;
|
bool disable_last_success;
|
||||||
@ -128,6 +136,11 @@ struct ipadb_context {
|
|||||||
struct ipadb_global_config config;
|
struct ipadb_global_config config;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ipadb_e_pol_limits {
|
||||||
|
krb5_deltat max_life;
|
||||||
|
krb5_deltat max_renewable_life;
|
||||||
|
};
|
||||||
|
|
||||||
#define IPA_E_DATA_MAGIC 0x0eda7a
|
#define IPA_E_DATA_MAGIC 0x0eda7a
|
||||||
struct ipadb_e_data {
|
struct ipadb_e_data {
|
||||||
int magic;
|
int magic;
|
||||||
@ -142,6 +155,7 @@ struct ipadb_e_data {
|
|||||||
char **authz_data;
|
char **authz_data;
|
||||||
bool has_tktpolaux;
|
bool has_tktpolaux;
|
||||||
enum ipadb_user_auth user_auth;
|
enum ipadb_user_auth user_auth;
|
||||||
|
struct ipadb_e_pol_limits pol_limits[IPADB_USER_AUTH_IDX_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ipadb_context *ipadb_get_context(krb5_context kcontext);
|
struct ipadb_context *ipadb_get_context(krb5_context kcontext);
|
||||||
|
@ -21,14 +21,13 @@ ipa_kdcpolicy_check_as(krb5_context context, krb5_kdcpolicy_moddata moddata,
|
|||||||
krb5_error_code kerr;
|
krb5_error_code kerr;
|
||||||
enum ipadb_user_auth ua;
|
enum ipadb_user_auth ua;
|
||||||
struct ipadb_e_data *ied;
|
struct ipadb_e_data *ied;
|
||||||
|
struct ipadb_e_pol_limits *pol_limits = NULL;
|
||||||
int valid_auth_indicators = 0;
|
int valid_auth_indicators = 0;
|
||||||
|
|
||||||
*status = NULL;
|
*status = NULL;
|
||||||
*lifetime_out = 0;
|
*lifetime_out = 0;
|
||||||
*renew_lifetime_out = 0;
|
*renew_lifetime_out = 0;
|
||||||
|
|
||||||
krb5_klog_syslog(LOG_INFO, "IPA kdcpolicy: checking AS-REQ.");
|
|
||||||
|
|
||||||
ied = (struct ipadb_e_data *)client->e_data;
|
ied = (struct ipadb_e_data *)client->e_data;
|
||||||
if (ied == NULL || ied->magic != IPA_E_DATA_MAGIC) {
|
if (ied == NULL || ied->magic != IPA_E_DATA_MAGIC) {
|
||||||
/* e-data is not availble, getting user auth from LDAP */
|
/* e-data is not availble, getting user auth from LDAP */
|
||||||
@ -63,18 +62,21 @@ ipa_kdcpolicy_check_as(krb5_context context, krb5_kdcpolicy_moddata moddata,
|
|||||||
*status = "OTP pre-authentication not allowed for this user.";
|
*status = "OTP pre-authentication not allowed for this user.";
|
||||||
return KRB5KDC_ERR_POLICY;
|
return KRB5KDC_ERR_POLICY;
|
||||||
}
|
}
|
||||||
|
pol_limits = &(ied->pol_limits[IPADB_USER_AUTH_IDX_OTP]);
|
||||||
} else if (strcmp(auth_indicator, "radius") == 0) {
|
} else if (strcmp(auth_indicator, "radius") == 0) {
|
||||||
valid_auth_indicators++;
|
valid_auth_indicators++;
|
||||||
if (!(ua & IPADB_USER_AUTH_RADIUS)) {
|
if (!(ua & IPADB_USER_AUTH_RADIUS)) {
|
||||||
*status = "OTP pre-authentication not allowed for this user.";
|
*status = "OTP pre-authentication not allowed for this user.";
|
||||||
return KRB5KDC_ERR_POLICY;
|
return KRB5KDC_ERR_POLICY;
|
||||||
}
|
}
|
||||||
|
pol_limits = &(ied->pol_limits[IPADB_USER_AUTH_IDX_RADIUS]);
|
||||||
} else if (strcmp(auth_indicator, "pkinit") == 0) {
|
} else if (strcmp(auth_indicator, "pkinit") == 0) {
|
||||||
valid_auth_indicators++;
|
valid_auth_indicators++;
|
||||||
if (!(ua & IPADB_USER_AUTH_PKINIT)) {
|
if (!(ua & IPADB_USER_AUTH_PKINIT)) {
|
||||||
*status = "PKINIT pre-authentication not allowed for this user.";
|
*status = "PKINIT pre-authentication not allowed for this user.";
|
||||||
return KRB5KDC_ERR_POLICY;
|
return KRB5KDC_ERR_POLICY;
|
||||||
}
|
}
|
||||||
|
pol_limits = &(ied->pol_limits[IPADB_USER_AUTH_IDX_PKINIT]);
|
||||||
} else if (strcmp(auth_indicator, "hardened") == 0) {
|
} else if (strcmp(auth_indicator, "hardened") == 0) {
|
||||||
valid_auth_indicators++;
|
valid_auth_indicators++;
|
||||||
/* Allow hardened even if only password pre-auth is allowed */
|
/* Allow hardened even if only password pre-auth is allowed */
|
||||||
@ -82,6 +84,7 @@ ipa_kdcpolicy_check_as(krb5_context context, krb5_kdcpolicy_moddata moddata,
|
|||||||
*status = "Password pre-authentication not not allowed for this user.";
|
*status = "Password pre-authentication not not allowed for this user.";
|
||||||
return KRB5KDC_ERR_POLICY;
|
return KRB5KDC_ERR_POLICY;
|
||||||
}
|
}
|
||||||
|
pol_limits = &(ied->pol_limits[IPADB_USER_AUTH_IDX_HARDENED]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +97,18 @@ ipa_kdcpolicy_check_as(krb5_context context, krb5_kdcpolicy_moddata moddata,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If there were policy limits associated with the authentication indicators,
|
||||||
|
* apply them */
|
||||||
|
if (pol_limits != NULL) {
|
||||||
|
if (pol_limits->max_life != 0) {
|
||||||
|
*lifetime_out = pol_limits->max_life;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pol_limits->max_renewable_life != 0) {
|
||||||
|
*renew_lifetime_out = pol_limits->max_renewable_life;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,8 +125,6 @@ ipa_kdcpolicy_check_tgs(krb5_context context, krb5_kdcpolicy_moddata moddata,
|
|||||||
*lifetime_out = 0;
|
*lifetime_out = 0;
|
||||||
*renew_lifetime_out = 0;
|
*renew_lifetime_out = 0;
|
||||||
|
|
||||||
krb5_klog_syslog(LOG_INFO, "IPA kdcpolicy: checking TGS-REQ.");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +79,8 @@ 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",
|
||||||
|
"krbAuthIndMaxTicketLife",
|
||||||
|
"krbAuthIndMaxRenewableAge",
|
||||||
|
|
||||||
"objectClass",
|
"objectClass",
|
||||||
NULL
|
NULL
|
||||||
@ -88,6 +90,8 @@ static char *std_tktpolicy_attrs[] = {
|
|||||||
"krbmaxticketlife",
|
"krbmaxticketlife",
|
||||||
"krbmaxrenewableage",
|
"krbmaxrenewableage",
|
||||||
"krbticketflags",
|
"krbticketflags",
|
||||||
|
"krbauthindmaxticketlife",
|
||||||
|
"krbauthindmaxrenewableage",
|
||||||
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
@ -506,6 +510,66 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ipadb_parse_authind_policies(krb5_context kcontext,
|
||||||
|
LDAP *lcontext,
|
||||||
|
LDAPMessage *lentry,
|
||||||
|
krb5_db_entry *entry,
|
||||||
|
enum ipadb_user_auth ua)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
int ret;
|
||||||
|
struct ipadb_e_data *ied;
|
||||||
|
const struct {
|
||||||
|
char *attribute;
|
||||||
|
enum ipadb_user_auth flag;
|
||||||
|
enum ipadb_user_auth_idx idx;
|
||||||
|
} life_authind_map[] = {
|
||||||
|
{"krbAuthIndMaxTicketLife;otp",
|
||||||
|
IPADB_USER_AUTH_OTP, IPADB_USER_AUTH_IDX_OTP},
|
||||||
|
{"krbAuthIndMaxTicketLife;radius",
|
||||||
|
IPADB_USER_AUTH_RADIUS, IPADB_USER_AUTH_IDX_RADIUS},
|
||||||
|
{"krbAuthIndMaxTicketLife;pkinit",
|
||||||
|
IPADB_USER_AUTH_PKINIT, IPADB_USER_AUTH_IDX_PKINIT},
|
||||||
|
{"krbAuthIndMaxTicketLife;hardened",
|
||||||
|
IPADB_USER_AUTH_HARDENED, IPADB_USER_AUTH_IDX_HARDENED},
|
||||||
|
{NULL, IPADB_USER_AUTH_NONE, IPADB_USER_AUTH_IDX_MAX},
|
||||||
|
}, age_authind_map[] = {
|
||||||
|
{"krbAuthIndMaxRenewableAge;otp",
|
||||||
|
IPADB_USER_AUTH_OTP, IPADB_USER_AUTH_IDX_OTP},
|
||||||
|
{"krbAuthIndMaxRenewableAge;radius",
|
||||||
|
IPADB_USER_AUTH_RADIUS, IPADB_USER_AUTH_IDX_RADIUS},
|
||||||
|
{"krbAuthIndMaxRenewableAge;pkinit",
|
||||||
|
IPADB_USER_AUTH_PKINIT, IPADB_USER_AUTH_IDX_PKINIT},
|
||||||
|
{"krbAuthIndMaxRenewableAge;hardened",
|
||||||
|
IPADB_USER_AUTH_HARDENED, IPADB_USER_AUTH_IDX_HARDENED},
|
||||||
|
{NULL, IPADB_USER_AUTH_NONE, IPADB_USER_AUTH_IDX_MAX},
|
||||||
|
};
|
||||||
|
|
||||||
|
ied = (struct ipadb_e_data *)entry->e_data;
|
||||||
|
if (ied == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; life_authind_map[i].attribute != NULL; i++) {
|
||||||
|
if (ua & life_authind_map[i].flag) {
|
||||||
|
ret = ipadb_ldap_attr_to_int(lcontext, lentry,
|
||||||
|
life_authind_map[i].attribute,
|
||||||
|
&result);
|
||||||
|
if (ret == 0) {
|
||||||
|
ied->pol_limits[life_authind_map[i].idx].max_life = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ipadb_ldap_attr_to_int(lcontext, lentry,
|
||||||
|
age_authind_map[i].attribute,
|
||||||
|
&result);
|
||||||
|
if (ret == 0) {
|
||||||
|
ied->pol_limits[age_authind_map[i].idx].max_renewable_life = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
|
static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
|
||||||
char *principal,
|
char *principal,
|
||||||
LDAPMessage *lentry,
|
LDAPMessage *lentry,
|
||||||
@ -861,6 +925,10 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ua & ~IPADB_USER_AUTH_NONE) {
|
||||||
|
ipadb_parse_authind_policies(kcontext, lcontext, lentry, entry, ua);
|
||||||
|
}
|
||||||
|
|
||||||
kerr = 0;
|
kerr = 0;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -71,19 +71,17 @@ Tickets without an authentication indicator will have the default lifetime / ren
|
|||||||
|
|
||||||
Administrators can specify max life and renew for each auth indicator and global default via `ipa krbtpolicy-mod` command.
|
Administrators can specify max life and renew for each auth indicator and global default via `ipa krbtpolicy-mod` command.
|
||||||
|
|
||||||
e.g. `ipa krbtpolicy-mod --setattr otp-maxlife=604800 pkinit-maxtime=604800`
|
e.g. `ipa krbtpolicy-mod --otp-maxlife=604800 --pkinit-maxlife=604800`
|
||||||
|
|
||||||
Current `--maxlife` and `--maxrenew` options for `ipa krbtpolicy-mod` will set the default max life / renew respectively.
|
Current `--maxlife` and `--maxrenew` options for `ipa krbtpolicy-mod` will set the default max life / renew respectively.
|
||||||
|
|
||||||
After this, the output for `ipa krbtpolicy-show` will look like:
|
After this, the output for `ipa krbtpolicy-show` will look like:
|
||||||
|
|
||||||
```
|
```
|
||||||
Max life:
|
Max life: 86400
|
||||||
- default: 86400
|
OTP max life: 604800
|
||||||
- otp: 604800
|
PKINIT max life: 604800
|
||||||
- pkinit: 604800
|
Max renew: 604800
|
||||||
Max renew:
|
|
||||||
- default: 604800
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### WebUI Workflow:
|
#### WebUI Workflow:
|
||||||
@ -110,7 +108,14 @@ but ticket lifecycle policy will require LDAP to store relations between authent
|
|||||||
and lifetime information. We have global ticket lifetime and renew time setting stored as attribute
|
and lifetime information. We have global ticket lifetime and renew time setting stored as attribute
|
||||||
`krbmaxticketlife` and `krbmaxrenewableage` inside the `cn=$REALM,cn=kerberos,$SUFFIX` subtree,
|
`krbmaxticketlife` and `krbmaxrenewableage` inside the `cn=$REALM,cn=kerberos,$SUFFIX` subtree,
|
||||||
which represents the default lifetime policy.
|
which represents the default lifetime policy.
|
||||||
For each authentication indicator, there will be an attribute to store specific lifetime for that indicator,
|
|
||||||
such as `krbmaxticketlifetop`, `krbmaxrenewableagepkinit`
|
|
||||||
They are stored in the same location as default policy in LDAP.
|
|
||||||
|
|
||||||
|
Two new multi-valued attributes are added to store an authentication
|
||||||
|
indicator-specific maximum ticket life and ticket's maximum renewable age. The
|
||||||
|
type of authentication indicator is specified as LDAP attribute option:
|
||||||
|
|
||||||
|
```
|
||||||
|
krbAuthIndMaxTicketLife;otp: 604800
|
||||||
|
krbAuthIndMaxRenewableAge;pkinit: 604800
|
||||||
|
```
|
||||||
|
|
||||||
|
They are stored in the same policy object in LDAP.
|
||||||
|
@ -269,6 +269,10 @@ attributetypes: ( 1.3.6.1.4.1.5322.21.2.4 NAME 'krbAllowedToDelegateTo' EQUALITY
|
|||||||
##### A list of authentication indicator strings, one of which must be satisfied
|
##### A list of authentication indicator strings, one of which must be satisfied
|
||||||
##### to authenticate to the principal as a service.
|
##### to authenticate to the principal as a service.
|
||||||
attributetypes: ( 2.16.840.1.113730.3.8.15.2.1 NAME 'krbPrincipalAuthInd' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
|
attributetypes: ( 2.16.840.1.113730.3.8.15.2.1 NAME 'krbPrincipalAuthInd' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15)
|
||||||
|
##### The maximum ticket lifetime for a principal based on authentication indicator in seconds. Indicator is specified as an attribute option
|
||||||
|
attributetypes: ( 2.16.840.1.113730.3.8.15.2.2 NAME 'krbAuthIndMaxTicketLife' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27)
|
||||||
|
##### Maximum renewable lifetime for a principal's ticket based on authentication indicator in seconds. Indicator is specified as an attribute option
|
||||||
|
attributetypes: ( 2.16.840.1.113730.3.8.15.2.3 NAME 'krbAuthIndMaxRenewableAge' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27)
|
||||||
########################################################################
|
########################################################################
|
||||||
# Object Class Definitions #
|
# Object Class Definitions #
|
||||||
########################################################################
|
########################################################################
|
||||||
@ -312,6 +316,6 @@ objectClasses: ( 2.16.840.1.113719.1.301.6.13.1 NAME 'krbAdmService' SUP ( krbSe
|
|||||||
objectClasses: ( 2.16.840.1.113719.1.301.6.14.1 NAME 'krbPwdPolicy' SUP top MUST ( cn ) MAY ( krbMaxPwdLife $ krbMinPwdLife $ krbPwdMinDiffChars $ krbPwdMinLength $ krbPwdHistoryLength $ krbPwdMaxFailure $ krbPwdFailureCountInterval $ krbPwdLockoutDuration $ krbPwdAttributes $ krbPwdMaxLife $ krbPwdMaxRenewableLife $ krbPwdAllowedKeysalts ) )
|
objectClasses: ( 2.16.840.1.113719.1.301.6.14.1 NAME 'krbPwdPolicy' SUP top MUST ( cn ) MAY ( krbMaxPwdLife $ krbMinPwdLife $ krbPwdMinDiffChars $ krbPwdMinLength $ krbPwdHistoryLength $ krbPwdMaxFailure $ krbPwdFailureCountInterval $ krbPwdLockoutDuration $ krbPwdAttributes $ krbPwdMaxLife $ krbPwdMaxRenewableLife $ krbPwdAllowedKeysalts ) )
|
||||||
##### The krbTicketPolicyAux holds Kerberos ticket policy attributes.
|
##### The krbTicketPolicyAux holds Kerberos ticket policy attributes.
|
||||||
##### This class can be attached to a principal object or realm object.
|
##### This class can be attached to a principal object or realm object.
|
||||||
objectClasses: ( 2.16.840.1.113719.1.301.6.16.1 NAME 'krbTicketPolicyAux' AUXILIARY MAY ( krbTicketFlags $ krbMaxTicketLife $ krbMaxRenewableAge ) )
|
objectClasses: ( 2.16.840.1.113719.1.301.6.16.1 NAME 'krbTicketPolicyAux' AUXILIARY MAY ( krbTicketFlags $ krbMaxTicketLife $ krbMaxRenewableAge $ krbAuthIndMaxTicketLife $ krbAuthIndMaxRenewableAge ) )
|
||||||
##### The krbTicketPolicy object is an effective ticket policy that is associated with a realm or a principal
|
##### The krbTicketPolicy object is an effective ticket policy that is associated with a realm or a principal
|
||||||
objectClasses: ( 2.16.840.1.113719.1.301.6.17.1 NAME 'krbTicketPolicy' SUP top MUST ( cn ) )
|
objectClasses: ( 2.16.840.1.113719.1.301.6.17.1 NAME 'krbTicketPolicy' SUP top MUST ( cn ) )
|
||||||
|
@ -70,6 +70,10 @@ _default_values = {
|
|||||||
'krbmaxrenewableage': 604800,
|
'krbmaxrenewableage': 604800,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# These attributes never have non-optional values, so they should be
|
||||||
|
# ignored in post callbacks
|
||||||
|
_option_based_attrs = ('krbauthindmaxticketlife', 'krbauthindmaxrenewableage')
|
||||||
|
_supported_options = ('otp', 'radius', 'pkinit', 'hardened')
|
||||||
|
|
||||||
@register()
|
@register()
|
||||||
class krbtpolicy(baseldap.LDAPObject):
|
class krbtpolicy(baseldap.LDAPObject):
|
||||||
@ -78,7 +82,9 @@ class krbtpolicy(baseldap.LDAPObject):
|
|||||||
"""
|
"""
|
||||||
container_dn = DN(('cn', api.env.realm), ('cn', 'kerberos'))
|
container_dn = DN(('cn', api.env.realm), ('cn', 'kerberos'))
|
||||||
object_name = _('kerberos ticket policy settings')
|
object_name = _('kerberos ticket policy settings')
|
||||||
default_attributes = ['krbmaxticketlife', 'krbmaxrenewableage']
|
default_attributes = ['krbmaxticketlife', 'krbmaxrenewableage',
|
||||||
|
'krbauthindmaxticketlife',
|
||||||
|
'krbauthindmaxrenewableage']
|
||||||
limit_object_classes = ['krbticketpolicyaux']
|
limit_object_classes = ['krbticketpolicyaux']
|
||||||
# permission_filter_objectclasses is deliberately missing,
|
# permission_filter_objectclasses is deliberately missing,
|
||||||
# so it is not possible to create a permission of `--type krbtpolicy`.
|
# so it is not possible to create a permission of `--type krbtpolicy`.
|
||||||
@ -94,7 +100,8 @@ class krbtpolicy(baseldap.LDAPObject):
|
|||||||
'ipapermdefaultattr': {
|
'ipapermdefaultattr': {
|
||||||
'krbdefaultencsalttypes', 'krbmaxrenewableage',
|
'krbdefaultencsalttypes', 'krbmaxrenewableage',
|
||||||
'krbmaxticketlife', 'krbsupportedencsalttypes',
|
'krbmaxticketlife', 'krbsupportedencsalttypes',
|
||||||
'objectclass',
|
'objectclass', 'krbauthindmaxticketlife',
|
||||||
|
'krbauthindmaxrenewableage',
|
||||||
},
|
},
|
||||||
'default_privileges': {
|
'default_privileges': {
|
||||||
'Kerberos Ticket Policy Readers',
|
'Kerberos Ticket Policy Readers',
|
||||||
@ -108,6 +115,7 @@ class krbtpolicy(baseldap.LDAPObject):
|
|||||||
'ipapermright': {'read', 'search', 'compare'},
|
'ipapermright': {'read', 'search', 'compare'},
|
||||||
'ipapermdefaultattr': {
|
'ipapermdefaultattr': {
|
||||||
'krbmaxrenewableage', 'krbmaxticketlife',
|
'krbmaxrenewableage', 'krbmaxticketlife',
|
||||||
|
'krbauthindmaxticketlife', 'krbauthindmaxrenewableage',
|
||||||
},
|
},
|
||||||
'default_privileges': {
|
'default_privileges': {
|
||||||
'Kerberos Ticket Policy Readers',
|
'Kerberos Ticket Policy Readers',
|
||||||
@ -137,6 +145,46 @@ class krbtpolicy(baseldap.LDAPObject):
|
|||||||
doc=_('Maximum renewable age (seconds)'),
|
doc=_('Maximum renewable age (seconds)'),
|
||||||
minvalue=1,
|
minvalue=1,
|
||||||
),
|
),
|
||||||
|
Int('krbauthindmaxticketlife_otp?',
|
||||||
|
cli_name='otp_maxlife',
|
||||||
|
label=_('OTP max life'),
|
||||||
|
doc=_('OTP token maximum ticket life (seconds)'),
|
||||||
|
minvalue=1),
|
||||||
|
Int('krbauthindmaxrenewableage_otp?',
|
||||||
|
cli_name='otp_maxrenew',
|
||||||
|
label=_('OTP max renew'),
|
||||||
|
doc=_('OTP token ticket maximum renewable age (seconds)'),
|
||||||
|
minvalue=1),
|
||||||
|
Int('krbauthindmaxticketlife_radius?',
|
||||||
|
cli_name='radius_maxlife',
|
||||||
|
label=_('RADIUS max life'),
|
||||||
|
doc=_('RADIUS maximum ticket life (seconds)'),
|
||||||
|
minvalue=1),
|
||||||
|
Int('krbauthindmaxrenewableage_radius?',
|
||||||
|
cli_name='radius_maxrenew',
|
||||||
|
label=_('RADIUS max renew'),
|
||||||
|
doc=_('RADIUS ticket maximum renewable age (seconds)'),
|
||||||
|
minvalue=1),
|
||||||
|
Int('krbauthindmaxticketlife_pkinit?',
|
||||||
|
cli_name='pkinit_maxlife',
|
||||||
|
label=_('PKINIT max life'),
|
||||||
|
doc=_('PKINIT maximum ticket life (seconds)'),
|
||||||
|
minvalue=1),
|
||||||
|
Int('krbauthindmaxrenewableage_pkinit?',
|
||||||
|
cli_name='pkinit_maxrenew',
|
||||||
|
label=_('PKINIT max renew'),
|
||||||
|
doc=_('PKINIT ticket maximum renewable age (seconds)'),
|
||||||
|
minvalue=1),
|
||||||
|
Int('krbauthindmaxticketlife_hardened?',
|
||||||
|
cli_name='hardened_maxlife',
|
||||||
|
label=_('Hardened max life'),
|
||||||
|
doc=_('Hardened ticket maximum ticket life (seconds)'),
|
||||||
|
minvalue=1),
|
||||||
|
Int('krbauthindmaxrenewableage_hardened?',
|
||||||
|
cli_name='hardened_maxrenew',
|
||||||
|
label=_('Hardened max renew'),
|
||||||
|
doc=_('Hardened ticket maximum renewable age (seconds)'),
|
||||||
|
minvalue=1),
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_dn(self, *keys, **kwargs):
|
def get_dn(self, *keys, **kwargs):
|
||||||
@ -145,6 +193,27 @@ class krbtpolicy(baseldap.LDAPObject):
|
|||||||
return DN(self.container_dn, api.env.basedn)
|
return DN(self.container_dn, api.env.basedn)
|
||||||
|
|
||||||
|
|
||||||
|
def rename_authind_options_from_ldap(entry_attrs, options):
|
||||||
|
if options.get('raw', False):
|
||||||
|
return
|
||||||
|
|
||||||
|
for subtype in _supported_options:
|
||||||
|
for attr in _option_based_attrs:
|
||||||
|
name = '{};{}'.format(attr, subtype)
|
||||||
|
if name in entry_attrs:
|
||||||
|
new_name = '{}_{}'.format(attr, subtype)
|
||||||
|
entry_attrs[new_name] = entry_attrs.pop(name)
|
||||||
|
|
||||||
|
|
||||||
|
def rename_authind_options_to_ldap(entry_attrs):
|
||||||
|
for subtype in _supported_options:
|
||||||
|
for attr in _option_based_attrs:
|
||||||
|
name = '{}_{}'.format(attr, subtype)
|
||||||
|
if name in entry_attrs:
|
||||||
|
new_name = '{};{}'.format(attr, subtype)
|
||||||
|
entry_attrs[new_name] = entry_attrs.pop(name)
|
||||||
|
|
||||||
|
|
||||||
@register()
|
@register()
|
||||||
class krbtpolicy_mod(baseldap.LDAPUpdate):
|
class krbtpolicy_mod(baseldap.LDAPUpdate):
|
||||||
__doc__ = _('Modify Kerberos ticket policy.')
|
__doc__ = _('Modify Kerberos ticket policy.')
|
||||||
@ -158,6 +227,15 @@ class krbtpolicy_mod(baseldap.LDAPUpdate):
|
|||||||
# ticket policies are attached to objects with unrelated attributes
|
# ticket policies are attached to objects with unrelated attributes
|
||||||
if options.get('all'):
|
if options.get('all'):
|
||||||
options['all'] = False
|
options['all'] = False
|
||||||
|
|
||||||
|
# Rename authentication indicator-specific policy elements to LDAP
|
||||||
|
rename_authind_options_to_ldap(entry_attrs)
|
||||||
|
return dn
|
||||||
|
|
||||||
|
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||||
|
assert isinstance(dn, DN)
|
||||||
|
# Rename authentication indicator-specific policy elements from LDAP
|
||||||
|
rename_authind_options_from_ldap(entry_attrs, options)
|
||||||
return dn
|
return dn
|
||||||
|
|
||||||
|
|
||||||
@ -200,9 +278,18 @@ class krbtpolicy_show(baseldap.LDAPRetrieve):
|
|||||||
default_entry = {}
|
default_entry = {}
|
||||||
if attrname in default_entry:
|
if attrname in default_entry:
|
||||||
entry[attrname] = default_entry[attrname]
|
entry[attrname] = default_entry[attrname]
|
||||||
if attrname not in entry:
|
elif attrname in _option_based_attrs:
|
||||||
|
# If default entry contains option-based default attrs,
|
||||||
|
# copy the options explicitly
|
||||||
|
attrs = [(a, a.split(';')[0]) for a in default_entry]
|
||||||
|
for a in attrs:
|
||||||
|
if a[1] == attrname and a[0] not in entry:
|
||||||
|
entry[a[0]] = default_entry[a[0]]
|
||||||
|
if attrname not in entry and attrname not in _option_based_attrs:
|
||||||
raise errors.ACIError(
|
raise errors.ACIError(
|
||||||
info=_('Default ticket policy could not be read'))
|
info=_('Default ticket policy could not be read'))
|
||||||
|
# Rename authentication indicator-specific policy elements from LDAP
|
||||||
|
rename_authind_options_from_ldap(entry, options)
|
||||||
return dn
|
return dn
|
||||||
|
|
||||||
|
|
||||||
@ -239,5 +326,6 @@ class krbtpolicy_reset(baseldap.LDAPQuery):
|
|||||||
entry_attrs = ldap.get_entry(dn, self.obj.default_attributes)
|
entry_attrs = ldap.get_entry(dn, self.obj.default_attributes)
|
||||||
|
|
||||||
entry_attrs = entry_to_dict(entry_attrs, **options)
|
entry_attrs = entry_to_dict(entry_attrs, **options)
|
||||||
|
rename_authind_options_from_ldap(entry_attrs, options)
|
||||||
|
|
||||||
return dict(result=entry_attrs, value=pkey_to_value(uid, options))
|
return dict(result=entry_attrs, value=pkey_to_value(uid, options))
|
||||||
|
@ -117,6 +117,20 @@ class test_krbtpolicy(Declarative):
|
|||||||
),
|
),
|
||||||
|
|
||||||
|
|
||||||
|
dict(
|
||||||
|
desc='Update user ticket policy for auth indicator pkinit',
|
||||||
|
command=('krbtpolicy_mod', [user1],
|
||||||
|
dict(krbauthindmaxticketlife_pkinit=3600)),
|
||||||
|
expected=dict(
|
||||||
|
value=user1,
|
||||||
|
summary=None,
|
||||||
|
result=dict(
|
||||||
|
krbmaxticketlife=[u'3600'],
|
||||||
|
krbauthindmaxticketlife_pkinit=[u'3600'],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
dict(
|
dict(
|
||||||
desc='Try updating other user attribute',
|
desc='Try updating other user attribute',
|
||||||
command=(
|
command=(
|
||||||
|
Loading…
Reference in New Issue
Block a user