summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2010-10-28 12:12:12 -0400
committerStephen Gallagher <sgallagh@redhat.com>2010-11-15 09:52:34 -0500
commitca92350db6ad6ac344181f7b8ec695eda29da675 (patch)
treea13639292904be7def057dd21127c768153669f5
parenta476bf85436d8a8195df1693db5b806a9c8f56bd (diff)
downloadsssd-ca92350db6ad6ac344181f7b8ec695eda29da675.tar.gz
sssd-ca92350db6ad6ac344181f7b8ec695eda29da675.tar.xz
sssd-ca92350db6ad6ac344181f7b8ec695eda29da675.zip
Add utility function to sanitize LDAP/LDB filters
Also adds a unit test.
-rw-r--r--src/tests/util-tests.c68
-rw-r--r--src/util/util.c52
-rw-r--r--src/util/util.h11
3 files changed, 131 insertions, 0 deletions
diff --git a/src/tests/util-tests.c b/src/tests/util-tests.c
index bfc48bbac..cf96f0e35 100644
--- a/src/tests/util-tests.c
+++ b/src/tests/util-tests.c
@@ -175,6 +175,73 @@ START_TEST(test_diff_string_lists)
}
END_TEST
+
+START_TEST(test_sss_filter_sanitize)
+{
+ errno_t ret;
+ char *sanitized = NULL;
+
+ TALLOC_CTX *test_ctx = talloc_new(NULL);
+ fail_if (test_ctx == NULL, "Out of memory");
+
+ const char no_specials[] = "username";
+ ret = sss_filter_sanitize(test_ctx, no_specials, &sanitized);
+ fail_unless(ret == EOK, "no_specials error [%d][%s]",
+ ret, strerror(ret));
+ fail_unless(strcmp(no_specials, sanitized)==0,
+ "Expected [%s], got [%s]",
+ no_specials, sanitized);
+
+ const char has_asterisk[] = "*username";
+ const char has_asterisk_expected[] = "\\2ausername";
+ ret = sss_filter_sanitize(test_ctx, has_asterisk, &sanitized);
+ fail_unless(ret == EOK, "has_asterisk error [%d][%s]",
+ ret, strerror(ret));
+ fail_unless(strcmp(has_asterisk_expected, sanitized)==0,
+ "Expected [%s], got [%s]",
+ has_asterisk_expected, sanitized);
+
+ const char has_lparen[] = "user(name";
+ const char has_lparen_expected[] = "user\\28name";
+ ret = sss_filter_sanitize(test_ctx, has_lparen, &sanitized);
+ fail_unless(ret == EOK, "has_lparen error [%d][%s]",
+ ret, strerror(ret));
+ fail_unless(strcmp(has_lparen_expected, sanitized)==0,
+ "Expected [%s], got [%s]",
+ has_lparen_expected, sanitized);
+
+ const char has_rparen[] = "user)name";
+ const char has_rparen_expected[] = "user\\29name";
+ ret = sss_filter_sanitize(test_ctx, has_rparen, &sanitized);
+ fail_unless(ret == EOK, "has_rparen error [%d][%s]",
+ ret, strerror(ret));
+ fail_unless(strcmp(has_rparen_expected, sanitized)==0,
+ "Expected [%s], got [%s]",
+ has_rparen_expected, sanitized);
+
+ const char has_backslash[] = "username\\";
+ const char has_backslash_expected[] = "username\\5c";
+ ret = sss_filter_sanitize(test_ctx, has_backslash, &sanitized);
+ fail_unless(ret == EOK, "has_backslash error [%d][%s]",
+ ret, strerror(ret));
+ fail_unless(strcmp(has_backslash_expected, sanitized)==0,
+ "Expected [%s], got [%s]",
+ has_backslash_expected, sanitized);
+
+ const char has_all[] = "\\(user)*name";
+ const char has_all_expected[] = "\\5c\\28user\\29\\2aname";
+ ret = sss_filter_sanitize(test_ctx, has_all, &sanitized);
+ fail_unless(ret == EOK, "has_all error [%d][%s]",
+ ret, strerror(ret));
+ fail_unless(strcmp(has_all_expected, sanitized)==0,
+ "Expected [%s], got [%s]",
+ has_all_expected, sanitized);
+
+ talloc_free(test_ctx);
+}
+END_TEST
+
+
Suite *util_suite(void)
{
Suite *s = suite_create("util");
@@ -182,6 +249,7 @@ Suite *util_suite(void)
TCase *tc_util = tcase_create("util");
tcase_add_test (tc_util, test_diff_string_lists);
+ tcase_add_test (tc_util, test_sss_filter_sanitize);
tcase_set_timeout(tc_util, 60);
suite_add_tcase (s, tc_util);
diff --git a/src/util/util.c b/src/util/util.c
index 06eea2837..772a8b73f 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -515,3 +515,55 @@ errno_t sss_hash_create(TALLOC_CTX *mem_ctx,
talloc_free(internal_ctx);
return ret;
}
+
+errno_t sss_filter_sanitize(TALLOC_CTX *mem_ctx,
+ const char *input,
+ char **sanitized)
+{
+ char *output;
+ size_t i = 0;
+ size_t j = 0;
+
+ /* Assume the worst-case. We'll resize it later, once */
+ output = talloc_array(mem_ctx, char, strlen(input) * 3 + 1);
+ if (!output) {
+ return ENOMEM;
+ }
+
+ while (input[i]) {
+ switch(input[i]) {
+ case '*':
+ output[j++] = '\\';
+ output[j++] = '2';
+ output[j++] = 'a';
+ break;
+ case '(':
+ output[j++] = '\\';
+ output[j++] = '2';
+ output[j++] = '8';
+ break;
+ case ')':
+ output[j++] = '\\';
+ output[j++] = '2';
+ output[j++] = '9';
+ break;
+ case '\\':
+ output[j++] = '\\';
+ output[j++] = '5';
+ output[j++] = 'c';
+ break;
+ default:
+ output[j++] = input[i];
+ }
+
+ i++;
+ }
+ output[j] = '\0';
+ *sanitized = talloc_realloc(mem_ctx, output, char, j+1);
+ if (!*sanitized) {
+ talloc_free(output);
+ return ENOMEM;
+ }
+
+ return EOK;
+}
diff --git a/src/util/util.h b/src/util/util.h
index e93f6f863..53a6b1c97 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -366,4 +366,15 @@ errno_t diff_string_lists(TALLOC_CTX *memctx,
char ***string1_only,
char ***string2_only,
char ***both_strings);
+
+/* Sanitize an input string (e.g. a username) for use in
+ * an LDAP/LDB filter
+ * Returns a newly-constructed string attached to mem_ctx
+ * It will fail only on an out of memory condition, where it
+ * will return ENOMEM.
+ */
+errno_t sss_filter_sanitize(TALLOC_CTX *mem_ctx,
+ const char *input,
+ char **sanitized);
+
#endif /* __SSSD_UTIL_H__ */