Keytab retrieval: allow requesting arcfour-hmac for SMB services

With system-wide crypto policy in use, arcfour-hmac encryption type
might be removed from the list of permitted encryption types in the MIT
Kerberos library. Applications aren't prevented to use the arcfour-hmac
enctype if they operate on it directly.

Since FreeIPA supported and default encryption types stored in LDAP, on
the server side we don't directly use a set of permitted encryption
types provided by the MIT Kerberos library. However, this set will be
trimmed to disallow arcfour-hmac and other weaker types by default.

While the arcfour-hmac key can be generated and retrieved, MIT Kerberos
library will still not allow its use in Kerberos protocol if it is not
on the list of permitted encryption types. We only need this workaround
to allow setting up arcfour-hmac key for SMB services where arcfour-hmac
key is used to validate communication between a domain member and its
domain controller. Without this fix it will not be possible to request
setting up a machine account credential from the domain member side. The
latter is needed for Samba running on IPA client.

Thus, extend filtering facilities in ipa-pwd-extop plugin to explicitly
allow arcfour-hmac encryption type for SMB services (Kerberos principal
name starts with cifs/).

Reviewed-By: Christian Heimes <cheimes@redhat.com>
This commit is contained in:
Alexander Bokovoy 2019-04-12 16:30:07 +03:00
parent 0f891c6a3f
commit b5fbbd1957
2 changed files with 37 additions and 4 deletions

View File

@ -97,7 +97,8 @@ void *ipapwd_get_plugin_id(void)
} }
static void filter_keys(struct ipapwd_krbcfg *krbcfg, static void filter_keys(struct ipapwd_krbcfg *krbcfg,
struct ipapwd_keyset *kset) struct ipapwd_keyset *kset,
bool allow_nthash)
{ {
int i, j; int i, j;
@ -108,6 +109,14 @@ static void filter_keys(struct ipapwd_krbcfg *krbcfg,
break; break;
} }
} }
/* if requested by the caller, allow arcfour-hmac even
* if it is missing in the list of supported enctypes. */
if (allow_nthash &&
(ENCTYPE_ARCFOUR_HMAC == kset->keys[i].key_data_type[0])) {
break;
}
if (j == krbcfg->num_supp_encsalts) { /* not valid */ if (j == krbcfg->num_supp_encsalts) { /* not valid */
/* free key */ /* free key */
@ -130,7 +139,8 @@ static void filter_keys(struct ipapwd_krbcfg *krbcfg,
static void filter_enctypes(struct ipapwd_krbcfg *krbcfg, static void filter_enctypes(struct ipapwd_krbcfg *krbcfg,
krb5_key_salt_tuple *kenctypes, krb5_key_salt_tuple *kenctypes,
int *num_kenctypes) int *num_kenctypes,
bool allow_nthash)
{ {
/* first filter for duplicates */ /* first filter for duplicates */
for (int i = 0; i + 1 < *num_kenctypes; i++) { for (int i = 0; i + 1 < *num_kenctypes; i++) {
@ -158,6 +168,12 @@ static void filter_enctypes(struct ipapwd_krbcfg *krbcfg,
break; break;
} }
} }
/* if requested by the caller, allow arcfour-hmac even
* if it is missing in the list of supported enctypes. */
if (allow_nthash &&
(ENCTYPE_ARCFOUR_HMAC == kenctypes[i].ks_enctype)) {
break;
}
if (j == krbcfg->num_supp_encsalts) { if (j == krbcfg->num_supp_encsalts) {
/* Unsupported, filter out */ /* Unsupported, filter out */
for (int k = i; k + 1 < *num_kenctypes; k++) { for (int k = i; k + 1 < *num_kenctypes; k++) {
@ -1198,6 +1214,7 @@ static int ipapwd_setkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
int kvno; int kvno;
char *svcname; char *svcname;
bool allowed_access = false; bool allowed_access = false;
bool is_nthash_allowed = false;
struct berval *bvp = NULL; struct berval *bvp = NULL;
LDAPControl new_ctrl; LDAPControl new_ctrl;
@ -1270,7 +1287,12 @@ static int ipapwd_setkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
for (int i = 0; i < kset->num_keys; i++) { for (int i = 0; i < kset->num_keys; i++) {
kset->keys[i].key_data_kvno = kvno; kset->keys[i].key_data_kvno = kvno;
} }
filter_keys(krbcfg, kset);
/* Only allow generating arcfour-hmac keys for cifs/.. services
* unless the enctype is allowed by the IPA configuration for use
* by the all principals */
is_nthash_allowed = (0 == strncmp("cifs/", serviceName, 5));
filter_keys(krbcfg, kset, is_nthash_allowed);
/* check if we have any left */ /* check if we have any left */
if (kset->num_keys == 0) { if (kset->num_keys == 0) {
@ -1579,6 +1601,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
struct berval *bvp = NULL; struct berval *bvp = NULL;
LDAPControl new_ctrl; LDAPControl new_ctrl;
bool wantold = false; bool wantold = false;
bool is_nthash_allowed = false;
/* Get Bind DN */ /* Get Bind DN */
slapi_pblock_get(pb, SLAPI_CONN_DN, &bind_dn); slapi_pblock_get(pb, SLAPI_CONN_DN, &bind_dn);
@ -1664,7 +1687,11 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
goto free_and_return; goto free_and_return;
} }
filter_enctypes(krbcfg, kenctypes, &num_kenctypes); /* Only allow generating arcfour-hmac keys for cifs/.. services
* unless the enctype is allowed by the IPA configuration for use
* by the all principals */
is_nthash_allowed = (0 == strncmp("cifs/", service_name, 5));
filter_enctypes(krbcfg, kenctypes, &num_kenctypes, is_nthash_allowed);
/* check if we have any left */ /* check if we have any left */
if (num_kenctypes == 0 && kenctypes != NULL) { if (num_kenctypes == 0 && kenctypes != NULL) {

View File

@ -41,6 +41,12 @@ dn: $SUFFIX
add:aci: (targetattr = "ipaNTHash")(version 3.0; acl "Samba system principals can read and write NT passwords"; allow (read,write) groupdn="ldap:///cn=adtrust agents,cn=sysaccounts,cn=etc,$SUFFIX";) add:aci: (targetattr = "ipaNTHash")(version 3.0; acl "Samba system principals can read and write NT passwords"; allow (read,write) groupdn="ldap:///cn=adtrust agents,cn=sysaccounts,cn=etc,$SUFFIX";)
remove:aci: (targetattr = "ipaNTHash")(version 3.0; acl "Samba system principals can read NT passwords"; allow (read) groupdn="ldap:///cn=adtrust agents,cn=sysaccounts,cn=etc,$SUFFIX";) remove:aci: (targetattr = "ipaNTHash")(version 3.0; acl "Samba system principals can read NT passwords"; allow (read) groupdn="ldap:///cn=adtrust agents,cn=sysaccounts,cn=etc,$SUFFIX";)
# For Samba as a domain member setup we need to allow synchronizing ipaNTHash value
dn: cn=services,cn=accounts,$SUFFIX
add:aci: (target="ldap:///krbprincipalname=cifs/($$dn),cn=services,cn=accounts,$SUFFIX")(targetattr="ipaNTHash")(version 3.0; acl "CIFS service can modify own ipaNTHash"; allow(write) userdn="ldap:///krbprincipalname=cifs/($$dn),cn=services,cn=accounts,$SUFFIX" or userattr="managedby#SELFDN";)
add:aci: (target="ldap:///krbprincipalname=cifs/($$dn),cn=services,cn=accounts,$SUFFIX")(targattrfilters="add=objectClass:(objectClass=ipaNTUserAttrs)")(version 3.0; acl "CIFS service can add ipaNTUserAttrs to itself"; allow(write) userdn="ldap:///krbprincipalname=cifs/($$dn),cn=services,cn=accounts,$SUFFIX" or userattr="managedby#SELFDN";)
# Add the default PAC type to configuration # Add the default PAC type to configuration
dn: cn=ipaConfig,cn=etc,$SUFFIX dn: cn=ipaConfig,cn=etc,$SUFFIX
addifnew: ipaKrbAuthzData: MS-PAC addifnew: ipaKrbAuthzData: MS-PAC