diff options
author | Stephen Gallagher <sgallagh@redhat.com> | 2010-10-28 12:12:12 -0400 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2010-11-15 09:52:34 -0500 |
commit | ca92350db6ad6ac344181f7b8ec695eda29da675 (patch) | |
tree | a13639292904be7def057dd21127c768153669f5 | |
parent | a476bf85436d8a8195df1693db5b806a9c8f56bd (diff) | |
download | sssd-ca92350db6ad6ac344181f7b8ec695eda29da675.tar.gz sssd-ca92350db6ad6ac344181f7b8ec695eda29da675.tar.bz2 sssd-ca92350db6ad6ac344181f7b8ec695eda29da675.zip |
Add utility function to sanitize LDAP/LDB filters
Also adds a unit test.
-rw-r--r-- | src/tests/util-tests.c | 68 | ||||
-rw-r--r-- | src/util/util.c | 52 | ||||
-rw-r--r-- | src/util/util.h | 11 |
3 files changed, 131 insertions, 0 deletions
diff --git a/src/tests/util-tests.c b/src/tests/util-tests.c index bfc48bba..cf96f0e3 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 06eea283..772a8b73 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 e93f6f86..53a6b1c9 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__ */ |