diff options
Diffstat (limited to 'daemons/ipa-kdb')
-rw-r--r-- | daemons/ipa-kdb/ipa_kdb_mspac.c | 102 |
1 files changed, 101 insertions, 1 deletions
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c index 390111f7d..df19880d3 100644 --- a/daemons/ipa-kdb/ipa_kdb_mspac.c +++ b/daemons/ipa-kdb/ipa_kdb_mspac.c @@ -1317,6 +1317,22 @@ static void filter_logon_info_log_message(struct dom_sid *sid) } } +static void filter_logon_info_log_message_rid(struct dom_sid *sid, uint32_t rid) +{ + char *domstr = NULL; + + domstr = dom_sid_string(NULL, sid); + if (domstr) { + krb5_klog_syslog(LOG_ERR, "PAC filtering issue: SID [%s-%d] is not allowed " + "from a trusted source and will be excluded.", domstr, rid); + talloc_free(domstr); + } else { + krb5_klog_syslog(LOG_ERR, "PAC filtering issue: SID is not allowed " + "from a trusted source and will be excluded." + "Unable to allocate memory to display SID."); + } +} + static krb5_error_code filter_logon_info(krb5_context context, TALLOC_CTX *memctx, krb5_data realm, @@ -1328,9 +1344,21 @@ static krb5_error_code filter_logon_info(krb5_context context, * attempt at getting us to sign fake credentials with the help of a * compromised trusted realm */ + /* NOTE: there are two outcomes from filtering: + * REJECT TICKET -- ticket is rejected if domain SID of + * the principal with MS-PAC is filtered out or + * its primary group RID is filtered out + * + * REMOVE SID -- SIDs are removed from the list of SIDs associated + * with the principal if they are filtered out + * This applies also to secondary RIDs of the principal + * if domain_sid-<secondary RID> is filtered out + */ + struct ipadb_context *ipactx; struct ipadb_adtrusts *domain; - int i, j, k, count; + int i, j, k, l, count; + uint32_t rid; bool result; char *domstr = NULL; @@ -1377,6 +1405,78 @@ static krb5_error_code filter_logon_info(krb5_context context, } } + /* Check if this user's SIDs membership is filtered too */ + for(k = 0; k < domain->len_sid_blacklist_incoming; k++) { + /* Short-circuit if there are no RIDs. This may happen if we filtered everything already. + * In normal situation there would be at least primary gid as RID in the RIDs array + * but if we filtered out the primary RID, this MS-PAC is invalid */ + count = info->info->info3.base.groups.count; + if (count == 0) { + krb5_klog_syslog(LOG_ERR, "MS-PAC record of [%s] has no groups, including primary, rejecting.", + info->info->info3.base.account_name.string); + return KRB5KDC_ERR_POLICY; + } + result = dom_sid_is_prefix(info->info->info3.base.domain_sid, + &domain->sid_blacklist_incoming[k]); + if (result) { + i = 0; + j = 0; + if (domain->sid_blacklist_incoming[k].num_auths - info->info->info3.base.domain_sid->num_auths != 1) { + krb5_klog_syslog(LOG_ERR, "Incoming SID blacklist element matching domain [%s with SID %s] " + "has more than one RID component. Invalid check skipped.", + domain->domain_name, domain->domain_sid); + break; + } + rid = domain->sid_blacklist_incoming[k].sub_auths[domain->sid_blacklist_incoming[k].num_auths - 1]; + if (rid == info->info->info3.base.rid) { + filter_logon_info_log_message_rid(info->info->info3.base.domain_sid, rid); + /* Actual user's SID is filtered out */ + return KRB5KDC_ERR_POLICY; + } + do { + if (rid == info->info->info3.base.groups.rids[i].rid) { + filter_logon_info_log_message_rid(info->info->info3.base.domain_sid, rid); + if (rid == info->info->info3.base.primary_gid) { + /* User's primary group SID is filtered out */ + return KRB5KDC_ERR_POLICY; + } + /* If this is just a non-primary RID, we simply remove it from the array of RIDs */ + l = count - i - j - 1; + if (l != 0) { + memmove(info->info->info3.base.groups.rids+i, + info->info->info3.base.groups.rids+i+1, + sizeof(struct samr_RidWithAttribute)*l); + } + j++; + } else { + i++; + } + } while ((i + j) < count); + + if (j != 0) { + count = count-j; + if (count == 0) { + /* All RIDs were filtered out, including the primary one, bail out */ + info->info->info3.base.groups.count = 0; + talloc_free(info->info->info3.base.groups.rids); + info->info->info3.base.groups.rids = NULL; + krb5_klog_syslog(LOG_ERR, "All group membership in MS-PAC of [%s] is filtered. Rejecting.", + info->info->info3.base.account_name.string); + return KRB5KDC_ERR_POLICY; + } else { + info->info->info3.base.groups.rids = talloc_realloc(memctx, + info->info->info3.base.groups.rids, + struct samr_RidWithAttribute, count); + if (!info->info->info3.base.groups.rids) { + info->info->info3.base.groups.count = 0; + return ENOMEM; + } + info->info->info3.base.groups.count = count; + } + } + } + } + /* According to MS-KILE 25.0, info->info->info3.sids may be non zero, so check * should include different possibilities into account * */ |