summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--daemons/ipa-kdb/ipa_kdb.h2
-rw-r--r--daemons/ipa-kdb/ipa_kdb_common.c43
-rw-r--r--daemons/ipa-kdb/ipa_kdb_principals.c3
-rw-r--r--daemons/ipa-kdb/ipa_kdb_pwdpolicy.c2
-rw-r--r--daemons/ipa-kdb/tests/ipa_kdb_tests.c55
5 files changed, 101 insertions, 4 deletions
diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h
index 4abb7335d..a9d36fe25 100644
--- a/daemons/ipa-kdb/ipa_kdb.h
+++ b/daemons/ipa-kdb/ipa_kdb.h
@@ -133,7 +133,7 @@ struct ipadb_context *ipadb_get_context(krb5_context kcontext);
int ipadb_get_connection(struct ipadb_context *ipactx);
/* COMMON LDAP FUNCTIONS */
-char *ipadb_filter_escape(const char *input, bool star);
+char *ipadb_filter_escape(const char *input, bool star, bool unify);
krb5_error_code ipadb_simple_search(struct ipadb_context *ipactx,
char *basedn, int scope,
char *filter, char **attrs,
diff --git a/daemons/ipa-kdb/ipa_kdb_common.c b/daemons/ipa-kdb/ipa_kdb_common.c
index 112086b57..80afa23f0 100644
--- a/daemons/ipa-kdb/ipa_kdb_common.c
+++ b/daemons/ipa-kdb/ipa_kdb_common.c
@@ -25,9 +25,41 @@
static struct timeval std_timeout = {300, 0};
-char *ipadb_filter_escape(const char *input, bool star)
+#define PRINC_BUF_SIZE 512
+
+static char *canon_princ(const char *princ)
+{
+ int ret;
+ char *p;
+ uint8_t *uc_realm;
+ char *canon_princ;
+ uint8_t buf[PRINC_BUF_SIZE] = { 0 };
+ size_t size = PRINC_BUF_SIZE;
+
+ p = strrchr(princ, '@');
+ if (p == NULL) {
+ return NULL;
+ }
+
+ /* Assume the worst-case. */
+ uc_realm = u8_toupper((const uint8_t *)( p + 1), size, NULL, NULL, buf,
+ &size);
+ if (uc_realm == NULL) {
+ return NULL;
+ }
+
+ ret = asprintf(&canon_princ, "%.*s@%s", (p - princ), princ, uc_realm);
+ if (ret == -1) {
+ return NULL;
+ }
+
+ return canon_princ;
+}
+
+char *ipadb_filter_escape(const char *input, bool star, bool canon)
{
char *output;
+ char *canonicalized;
size_t i = 0;
size_t j = 0;
@@ -75,6 +107,15 @@ char *ipadb_filter_escape(const char *input, bool star)
}
output[j] = '\0';
+ if (canon) {
+ canonicalized = canon_princ(output);
+ /* return output in case of an error */
+ if (canonicalized != NULL) {
+ free(output);
+ output = canonicalized;
+ }
+ }
+
return output;
}
diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c
index b3f8b1ad7..5fb280d62 100644
--- a/daemons/ipa-kdb/ipa_kdb_principals.c
+++ b/daemons/ipa-kdb/ipa_kdb_principals.c
@@ -788,7 +788,8 @@ static krb5_error_code ipadb_fetch_principals(struct ipadb_context *ipactx,
/* escape filter but do not touch '*' as this function accepts
* wildcards in names */
- esc_original_princ = ipadb_filter_escape(principal, false);
+ esc_original_princ = ipadb_filter_escape(principal, false,
+ (flags & KRB5_KDB_FLAG_ALIAS_OK));
if (!esc_original_princ) {
kerr = KRB5_KDB_INTERNAL_ERROR;
goto done;
diff --git a/daemons/ipa-kdb/ipa_kdb_pwdpolicy.c b/daemons/ipa-kdb/ipa_kdb_pwdpolicy.c
index 076314a12..875960c5d 100644
--- a/daemons/ipa-kdb/ipa_kdb_pwdpolicy.c
+++ b/daemons/ipa-kdb/ipa_kdb_pwdpolicy.c
@@ -151,7 +151,7 @@ krb5_error_code ipadb_get_pwd_policy(krb5_context kcontext, char *name,
return KRB5_KDB_DBNOTINITED;
}
- esc_name = ipadb_filter_escape(name, true);
+ esc_name = ipadb_filter_escape(name, true, false);
if (!esc_name) {
return ENOMEM;
}
diff --git a/daemons/ipa-kdb/tests/ipa_kdb_tests.c b/daemons/ipa-kdb/tests/ipa_kdb_tests.c
index edd4ae097..ac541ad91 100644
--- a/daemons/ipa-kdb/tests/ipa_kdb_tests.c
+++ b/daemons/ipa-kdb/tests/ipa_kdb_tests.c
@@ -465,6 +465,60 @@ void test_dom_sid_string(void **state)
str_sid = dom_sid_string(test_ctx, &test_sid);
}
+void test_ipadb_filter_escape(void **state)
+{
+ char *out;
+ size_t c;
+
+ struct test_data {
+ const char *in;
+ bool star;
+ bool canon;
+ const char *exp_out;
+ } test_data[] = {
+ {"abc", false, false, "abc"},
+ {"abc", false, true, "abc"},
+ {"abc", true, true, "abc"},
+ {"abc", true, false, "abc"},
+ {"abc@def", false, false, "abc@def"},
+ {"abc@def", false, true, "abc@DEF"},
+ {"abc@def", true, true, "abc@DEF"},
+ {"abc@def", true, false, "abc@def"},
+ {"abc@DEF", false, false, "abc@DEF"},
+ {"abc@DEF", false, true, "abc@DEF"},
+ {"abc@DEF", true, true, "abc@DEF"},
+ {"abc@DEF", true, false, "abc@DEF"},
+ {"ab*c@def", false, false, "ab*c@def"},
+ {"ab*c@def", false, true, "ab*c@DEF"},
+ {"ab*c@def", true, true, "ab\\2ac@DEF"},
+ {"ab*c@def", true, false, "ab\\2ac@def"},
+ {"\\a(b)c@def", false, false, "\\5ca\\28b\\29c@def"},
+ {"\\a(b)c@def", false, true, "\\5ca\\28b\\29c@DEF"},
+ {"\\a(b)c@def", true, true, "\\5ca\\28b\\29c@DEF"},
+ {"\\a(b)c@def", true, false, "\\5ca\\28b\\29c@def"},
+ {"abc@de*f", false, false, "abc@de*f"},
+ {"abc@de*f", false, true, "abc@DE*F"},
+ {"abc@de*f", true, true, "abc@DE\\2AF"},
+ {"abc@de*f", true, false, "abc@de\\2af"},
+ /* Special characters must be UTF-8 encoded, don't change encoding */
+ {"abc@öäü", false, false, "abc@öäü"},
+ {"abc@öäü", false, true, "abc@ÖÄÜ"},
+ {"abc@öäü", true, true, "abc@ÖÄÜ"},
+ {"abc@öäü", true, false, "abc@öäü"},
+ {NULL, false, false, NULL}
+ };
+
+ out = ipadb_filter_escape(NULL, false, false);
+ assert_null(out);
+
+ for (c = 0; test_data[c]. in != NULL; c++) {
+ out = ipadb_filter_escape(test_data[c].in, test_data[c].star,
+ test_data[c].canon);
+ assert_string_equal(out, test_data[c].exp_out);
+ free(out);
+ }
+}
+
int main(int argc, const char *argv[])
{
@@ -473,6 +527,7 @@ int main(int argc, const char *argv[])
unit_test_setup_teardown(test_filter_logon_info, setup, teardown),
unit_test(test_string_to_sid),
unit_test_setup_teardown(test_dom_sid_string, setup, teardown),
+ unit_test(test_ipadb_filter_escape),
};
return run_tests(tests);