summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--daemons/ipa-kdb/ipa_kdb_mspac.c108
1 files changed, 100 insertions, 8 deletions
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
index 2a48c4f8c..b5346fed1 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
@@ -977,7 +977,101 @@ static krb5_error_code save_logon_info(krb5_context context,
return 0;
}
+static struct ipadb_adtrusts *get_domain_from_realm(krb5_context context,
+ krb5_data realm)
+{
+ struct ipadb_context *ipactx;
+ struct ipadb_adtrusts *domain;
+ int i;
+
+ ipactx = ipadb_get_context(context);
+ if (!ipactx) {
+ return NULL;
+ }
+
+ if (ipactx->mspac == NULL) {
+ return NULL;
+ }
+
+ for (i = 0; i < ipactx->mspac->num_trusts; i++) {
+ domain = &ipactx->mspac->trusts[i];
+ if (strlen(domain->domain_name) != realm.length) {
+ continue;
+ }
+ if (strncasecmp(domain->domain_name, realm.data, realm.length) == 0) {
+ return domain;
+ }
+ }
+
+ return NULL;
+}
+
+static krb5_error_code filter_logon_info(krb5_context context,
+ TALLOC_CTX *memctx,
+ krb5_data realm,
+ struct PAC_LOGON_INFO_CTR *info)
+{
+
+ /* We must refuse a PAC that comes signed with a cross realm TGT
+ * where the client pretends to be from a different realm. It is an
+ * attempt at getting us to sign fake credentials with the help of a
+ * compromised trusted realm */
+
+ struct ipadb_adtrusts *domain;
+ char *domsid;
+
+ domain = get_domain_from_realm(context, realm);
+ if (!domain) {
+ return EINVAL;
+ }
+
+ /* check netbios/flat name */
+ if (strcasecmp(info->info->info3.base.logon_domain.string,
+ domain->flat_name) != 0) {
+ krb5_klog_syslog(LOG_ERR, "PAC Info mismatch: domain = %s, "
+ "expected flat name = %s, "
+ "found logon name = %s",
+ domain->domain_name, domain->flat_name,
+ info->info->info3.base.logon_domain.string);
+ return EINVAL;
+ }
+
+ /* check sid */
+ domsid = dom_sid_string(NULL, info->info->info3.base.domain_sid);
+ if (!domsid) {
+ return EINVAL;
+ }
+
+ if (strcmp(domsid, domain->domain_sid) != 0) {
+ krb5_klog_syslog(LOG_ERR, "PAC Info mismatch: domain = %s, "
+ "expected domain SID = %s, "
+ "found domain SID = %s",
+ domain->domain_name, domain->domain_sid,
+ domsid);
+ talloc_free(domsid);
+ return EINVAL;
+ }
+ talloc_free(domsid);
+
+ /* According to MS-KILE, info->info->info3.sids must be zero, so check
+ * that it is the case here */
+ if (info->info->info3.sidcount != 0) {
+ return EINVAL;
+ }
+
+ /* According to MS-KILE, ResourceGroups must be zero, so check
+ * that it is the case here */
+ if (info->info->res_group_dom_sid != NULL &&
+ info->info->res_groups.count != 0) {
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+
static krb5_error_code ipadb_check_logon_info(krb5_context context,
+ krb5_data origin_realm,
krb5_data *pac_blob)
{
struct PAC_LOGON_INFO_CTR info;
@@ -994,6 +1088,11 @@ static krb5_error_code ipadb_check_logon_info(krb5_context context,
goto done;
}
+ kerr = filter_logon_info(context, tmpctx, origin_realm, &info);
+ if (kerr) {
+ goto done;
+ }
+
kerr = add_local_groups(context, tmpctx, &info);
if (kerr) {
goto done;
@@ -1050,13 +1149,6 @@ static krb5_error_code ipadb_verify_pac(krb5_context context,
/* krbtgt from a trusted realm */
is_cross_realm = true;
- /* FIXME:
- * We must refuse a PAC that comes signed with a cross realm TGT
- * where the client pretends to be from our realm. It is an attempt
- * at getting us to sign fake credentials with the help of a
- * compromised trusted realm */
-
- /* TODO: Here is where we need to plug our PAC Filtering, later on */
srv_key = krbtgt_key;
} else {
@@ -1079,7 +1171,7 @@ static krb5_error_code ipadb_verify_pac(krb5_context context,
goto done;
}
- kerr = ipadb_check_logon_info(context, &pac_blob);
+ kerr = ipadb_check_logon_info(context, client_princ->realm, &pac_blob);
if (kerr != 0) {
goto done;
}