summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Bokovoy <abokovoy@redhat.com>2015-05-28 08:33:51 +0000
committerAlexander Bokovoy <abokovoy@redhat.com>2015-07-07 10:33:53 +0300
commita797874359544e431bdd96dd11e26f404c578db0 (patch)
tree40ec014adeefad323d316692bc7f056373507375
parent0e252fb1f8455daa87dccbc6dcba61b08570b444 (diff)
downloadfreeipa-a797874359544e431bdd96dd11e26f404c578db0.tar.gz
freeipa-a797874359544e431bdd96dd11e26f404c578db0.tar.xz
freeipa-a797874359544e431bdd96dd11e26f404c578db0.zip
ipa-kdb: filter out group membership from MS-PAC for exact SID matches too
When incoming SID blacklist contains exact SIDs of users and groups, attempt to filter them out as well, according to [MS-PAC] 4.1.1.2. Note that we treat user's SID and primary group RID filtering as violation of the KDC policy because the resulting MS-PAC will have no user SID or primary group and thus will be invalid. For group RIDs we filter them out and in unlikely event of empty list of groups treat that as violation of the KDC policy as well. Part of fix for https://bugzilla.redhat.com/show_bug.cgi?id=1222475
-rw-r--r--daemons/ipa-kdb/ipa_kdb_mspac.c102
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
* */