summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/providers/krb5/krb5_auth.c7
-rw-r--r--src/providers/krb5/krb5_auth.h1
-rw-r--r--src/providers/krb5/krb5_common.c31
-rw-r--r--src/providers/krb5/krb5_common.h4
-rw-r--r--src/tests/krb5_utils-tests.c45
5 files changed, 88 insertions, 0 deletions
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
index c98535b1..72f0711e 100644
--- a/src/providers/krb5/krb5_auth.c
+++ b/src/providers/krb5/krb5_auth.c
@@ -427,6 +427,13 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx,
DEBUG(1, ("krb5_get_simple_upn failed.\n"));
goto done;
}
+ } else {
+ ret = compare_principal_realm(kr->upn, realm,
+ &kr->upn_from_different_realm);
+ if (ret != 0) {
+ DEBUG(SSSDBG_OP_FAILURE, ("compare_principal_realm failed.\n"));
+ goto done;
+ }
}
kr->homedir = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_HOMEDIR,
diff --git a/src/providers/krb5/krb5_auth.h b/src/providers/krb5/krb5_auth.h
index cc079ba9..a23b8b47 100644
--- a/src/providers/krb5/krb5_auth.h
+++ b/src/providers/krb5/krb5_auth.h
@@ -54,6 +54,7 @@ struct krb5child_req {
bool active_ccache_present;
bool valid_tgt_present;
bool run_as_user;
+ bool upn_from_different_realm;
};
errno_t krb5_setup(TALLOC_CTX *mem_ctx, struct pam_data *pd,
diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c
index 006dac1c..45f126f7 100644
--- a/src/providers/krb5/krb5_common.c
+++ b/src/providers/krb5/krb5_common.c
@@ -881,3 +881,34 @@ errno_t krb5_get_simple_upn(TALLOC_CTX *mem_ctx, struct krb5_ctx *krb5_ctx,
*_upn = upn;
return EOK;
}
+
+errno_t compare_principal_realm(const char *upn, const char *realm,
+ bool *different_realm)
+{
+ size_t upn_len;
+ size_t realm_len;
+ char *at_sign;
+
+ if (upn == NULL || realm == NULL || different_realm == NULL) {
+ return EINVAL;
+ }
+
+ upn_len = strlen(upn);
+ realm_len = strlen(realm);
+ at_sign = strchr(upn, '@');
+
+ /* if coming from the same realm the upn must be at least the size of the
+ * realm plus 1 for the '@' char. */
+ if (upn_len == 0 || realm_len == 0 || upn_len <= realm_len + 1 ||
+ at_sign == NULL) {
+ return EINVAL;
+ }
+
+ if (strcmp(realm, at_sign + 1) == 0) {
+ *different_realm = false;
+ } else {
+ *different_realm = true;
+ }
+
+ return EOK;
+}
diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h
index 51bd2677..bc63bf98 100644
--- a/src/providers/krb5/krb5_common.h
+++ b/src/providers/krb5/krb5_common.h
@@ -177,6 +177,10 @@ errno_t remove_krb5_info_files(TALLOC_CTX *mem_ctx, const char *realm);
errno_t krb5_get_simple_upn(TALLOC_CTX *mem_ctx, struct krb5_ctx *krb5_ctx,
const char *username, const char **_upn);
+errno_t compare_principal_realm(const char *upn, const char *realm,
+ bool *different_realm);
+
+
int sssm_krb5_auth_init(struct be_ctx *bectx,
struct bet_ops **ops,
void **pvt_auth_data);
diff --git a/src/tests/krb5_utils-tests.c b/src/tests/krb5_utils-tests.c
index 5fee4544..636bcd40 100644
--- a/src/tests/krb5_utils-tests.c
+++ b/src/tests/krb5_utils-tests.c
@@ -673,6 +673,47 @@ START_TEST(test_no_substitution)
}
END_TEST
+START_TEST(test_compare_principal_realm)
+{
+ int ret;
+ bool different_realm;
+
+ ret = compare_principal_realm(NULL, "a", &different_realm);
+ fail_unless(ret == EINVAL, "NULL upn does not cause EINVAL.");
+
+ ret = compare_principal_realm("a", NULL, &different_realm);
+ fail_unless(ret == EINVAL, "NULL realm does not cause EINVAL.");
+
+ ret = compare_principal_realm("a", "b", NULL);
+ fail_unless(ret == EINVAL, "NULL different_realmbool " \
+ "does not cause EINVAL.");
+
+ ret = compare_principal_realm("", "a", &different_realm);
+ fail_unless(ret == EINVAL, "Empty upn does not cause EINVAL.");
+
+ ret = compare_principal_realm("a", "", &different_realm);
+ fail_unless(ret == EINVAL, "Empty realm does not cause EINVAL.");
+
+ ret = compare_principal_realm("ABC", "ABC", &different_realm);
+ fail_unless(ret == EINVAL, "Short UPN does not cause EINVAL.");
+
+ ret = compare_principal_realm("userABC", "ABC", &different_realm);
+ fail_unless(ret == EINVAL, "Missing '@' does not cause EINVAL.");
+
+ fail_unless(different_realm == false, "Same realm but " \
+ "different_realm is not false.");
+ ret = compare_principal_realm("user@ABC", "ABC", &different_realm);
+ fail_unless(ret == EOK, "Failure with same realm");
+ fail_unless(different_realm == false, "Same realm but " \
+ "different_realm is not false.");
+
+ ret = compare_principal_realm("user@ABC", "DEF", &different_realm);
+ fail_unless(ret == EOK, "Failure with different realm");
+ fail_unless(different_realm == true, "Different realm but " \
+ "different_realm is not true.");
+}
+END_TEST
+
Suite *krb5_utils_suite (void)
{
Suite *s = suite_create ("krb5_utils");
@@ -713,6 +754,10 @@ Suite *krb5_utils_suite (void)
}
suite_add_tcase (s, tc_create_dir);
+ TCase *tc_krb5_helpers = tcase_create("Helper functions");
+ tcase_add_test(tc_krb5_helpers, test_compare_principal_realm);
+ suite_add_tcase(s, tc_krb5_helpers);
+
return s;
}