summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/responder/common/responder.h2
-rw-r--r--src/responder/common/responder_utils.c151
-rw-r--r--src/responder/ifp/ifp_private.h3
-rw-r--r--src/responder/ifp/ifpsrv_util.c117
-rw-r--r--src/tests/cmocka/test_ifp.c51
5 files changed, 208 insertions, 116 deletions
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index e3c0f2267..02a215ced 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -329,4 +329,6 @@ sss_parse_inp_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx,
errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
char **_name, char **_domname);
+const char **parse_attr_list_ex(TALLOC_CTX *mem_ctx, const char *conf_str,
+ const char **defaults);
#endif /* __SSS_RESPONDER_H__ */
diff --git a/src/responder/common/responder_utils.c b/src/responder/common/responder_utils.c
new file mode 100644
index 000000000..815b61b39
--- /dev/null
+++ b/src/responder/common/responder_utils.c
@@ -0,0 +1,151 @@
+
+/*
+ SSSD
+
+ Common Responder utility functions
+
+ Copyright (C) Sumit Bose <sbose@redhat.com> 2014
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <talloc.h>
+
+#include "util/util.h"
+
+static inline bool
+attr_in_list(const char **list, size_t nlist, const char *str)
+{
+ size_t i;
+
+ for (i = 0; i < nlist; i++) {
+ if (strcasecmp(list[i], str) == 0) {
+ break;
+ }
+ }
+
+ return (i < nlist) ? true : false;
+}
+
+const char **parse_attr_list_ex(TALLOC_CTX *mem_ctx, const char *conf_str,
+ const char **defaults)
+{
+ TALLOC_CTX *tmp_ctx;
+ errno_t ret;
+ const char **list = NULL;
+ const char **res = NULL;
+ int list_size;
+ char **conf_list = NULL;
+ int conf_list_size = 0;
+ const char **allow = NULL;
+ const char **deny = NULL;
+ int ai = 0, di = 0, li = 0;
+ int i;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return NULL;
+ }
+
+ if (conf_str) {
+ ret = split_on_separator(tmp_ctx, conf_str, ',', true, true,
+ &conf_list, &conf_list_size);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Cannot parse attribute ACL list %s: %d\n", conf_str, ret);
+ goto done;
+ }
+
+ allow = talloc_zero_array(tmp_ctx, const char *, conf_list_size);
+ deny = talloc_zero_array(tmp_ctx, const char *, conf_list_size);
+ if (allow == NULL || deny == NULL) {
+ goto done;
+ }
+ }
+
+ for (i = 0; i < conf_list_size; i++) {
+ switch (conf_list[i][0]) {
+ case '+':
+ allow[ai] = conf_list[i] + 1;
+ ai++;
+ continue;
+ case '-':
+ deny[di] = conf_list[i] + 1;
+ di++;
+ continue;
+ default:
+ DEBUG(SSSDBG_CRIT_FAILURE, "ACL values must start with "
+ "either '+' (allow) or '-' (deny), got '%s'\n",
+ conf_list[i]);
+ goto done;
+ }
+ }
+
+ /* Assume the output will have to hold defaults and all the configured,
+ * values, resize later
+ */
+ list_size = 0;
+ if (defaults != NULL) {
+ while (defaults[list_size]) {
+ list_size++;
+ }
+ }
+ list_size += conf_list_size;
+
+ list = talloc_zero_array(tmp_ctx, const char *, list_size + 1);
+ if (list == NULL) {
+ goto done;
+ }
+
+ /* Start by copying explicitly allowed attributes */
+ for (i = 0; i < ai; i++) {
+ /* if the attribute is explicitly denied, skip it */
+ if (attr_in_list(deny, di, allow[i])) {
+ continue;
+ }
+
+ list[li] = talloc_strdup(list, allow[i]);
+ if (list[li] == NULL) {
+ goto done;
+ }
+ li++;
+
+ DEBUG(SSSDBG_TRACE_INTERNAL,
+ "Added allowed attr %s to whitelist\n", allow[i]);
+ }
+
+ /* Add defaults */
+ if (defaults != NULL) {
+ for (i = 0; defaults[i]; i++) {
+ /* if the attribute is explicitly denied, skip it */
+ if (attr_in_list(deny, di, defaults[i])) {
+ continue;
+ }
+
+ list[li] = talloc_strdup(list, defaults[i]);
+ if (list[li] == NULL) {
+ goto done;
+ }
+ li++;
+
+ DEBUG(SSSDBG_TRACE_INTERNAL,
+ "Added default attr %s to whitelist\n", defaults[i]);
+ }
+ }
+
+ res = talloc_steal(mem_ctx, list);
+done:
+ talloc_free(tmp_ctx);
+ return res;
+}
diff --git a/src/responder/ifp/ifp_private.h b/src/responder/ifp/ifp_private.h
index bf2015a97..fb1639c8d 100644
--- a/src/responder/ifp/ifp_private.h
+++ b/src/responder/ifp/ifp_private.h
@@ -82,5 +82,8 @@ char *_ifp_reply_objpath(TALLOC_CTX *mem_ctx, const char *base,
errno_t ifp_add_ldb_el_to_dict(DBusMessageIter *iter_dict,
struct ldb_message_element *el);
const char **ifp_parse_attr_list(TALLOC_CTX *mem_ctx, const char *conf_str);
+const char **
+ifp_parse_attr_list_ex(TALLOC_CTX *mem_ctx, const char *conf_str,
+ const char **defaults);
bool ifp_attr_allowed(const char *whitelist[], const char *attr);
#endif /* _IFPSRV_PRIVATE_H_ */
diff --git a/src/responder/ifp/ifpsrv_util.c b/src/responder/ifp/ifpsrv_util.c
index c0ab686e4..909bc5487 100644
--- a/src/responder/ifp/ifpsrv_util.c
+++ b/src/responder/ifp/ifpsrv_util.c
@@ -356,127 +356,12 @@ errno_t ifp_add_ldb_el_to_dict(DBusMessageIter *iter_dict,
return EOK;
}
-static inline bool
-attr_in_list(const char **list, size_t nlist, const char *str)
-{
- size_t i;
-
- for (i = 0; i < nlist; i++) {
- if (strcasecmp(list[i], str) == 0) {
- break;
- }
- }
-
- return (i < nlist) ? true : false;
-}
-
const char **
ifp_parse_attr_list(TALLOC_CTX *mem_ctx, const char *conf_str)
{
- TALLOC_CTX *tmp_ctx;
- errno_t ret;
- const char **list = NULL;
- const char **res = NULL;
- int list_size;
- char **conf_list = NULL;
- int conf_list_size = 0;
- const char **allow = NULL;
- const char **deny = NULL;
- int ai = 0, di = 0, li = 0;
- int i;
const char *defaults[] = IFP_DEFAULT_ATTRS;
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
- return NULL;
- }
-
- if (conf_str) {
- ret = split_on_separator(tmp_ctx, conf_str, ',', true, true,
- &conf_list, &conf_list_size);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Cannot parse attribute ACL list %s: %d\n", conf_str, ret);
- goto done;
- }
-
- allow = talloc_zero_array(tmp_ctx, const char *, conf_list_size);
- deny = talloc_zero_array(tmp_ctx, const char *, conf_list_size);
- if (allow == NULL || deny == NULL) {
- goto done;
- }
- }
-
- for (i = 0; i < conf_list_size; i++) {
- switch (conf_list[i][0]) {
- case '+':
- allow[ai] = conf_list[i] + 1;
- ai++;
- continue;
- case '-':
- deny[di] = conf_list[i] + 1;
- di++;
- continue;
- default:
- DEBUG(SSSDBG_CRIT_FAILURE, "ACL values must start with "
- "either '+' (allow) or '-' (deny), got '%s'\n",
- conf_list[i]);
- goto done;
- }
- }
-
- /* Assume the output will have to hold defauls and all the configured,
- * values, resize later
- */
- list_size = 0;
- while (defaults[list_size]) {
- list_size++;
- }
- list_size += conf_list_size;
-
- list = talloc_zero_array(tmp_ctx, const char *, list_size + 1);
- if (list == NULL) {
- goto done;
- }
-
- /* Start by copying explicitly allowed attributes */
- for (i = 0; i < ai; i++) {
- /* if the attribute is explicitly denied, skip it */
- if (attr_in_list(deny, di, allow[i])) {
- continue;
- }
-
- list[li] = talloc_strdup(list, allow[i]);
- if (list[li] == NULL) {
- goto done;
- }
- li++;
-
- DEBUG(SSSDBG_TRACE_INTERNAL,
- "Added allowed attr %s to whitelist\n", allow[i]);
- }
-
- /* Add defaults */
- for (i = 0; defaults[i]; i++) {
- /* if the attribute is explicitly denied, skip it */
- if (attr_in_list(deny, di, defaults[i])) {
- continue;
- }
-
- list[li] = talloc_strdup(list, defaults[i]);
- if (list[li] == NULL) {
- goto done;
- }
- li++;
-
- DEBUG(SSSDBG_TRACE_INTERNAL,
- "Added default attr %s to whitelist\n", defaults[i]);
- }
-
- res = talloc_steal(mem_ctx, list);
-done:
- talloc_free(tmp_ctx);
- return res;
+ return parse_attr_list_ex(mem_ctx, conf_str, defaults);
}
bool
diff --git a/src/tests/cmocka/test_ifp.c b/src/tests/cmocka/test_ifp.c
index b0f6e0990..d6e41706d 100644
--- a/src/tests/cmocka/test_ifp.c
+++ b/src/tests/cmocka/test_ifp.c
@@ -246,6 +246,29 @@ static void attr_parse_test(const char *expected[], const char *input)
talloc_free(test_ctx);
}
+static void attr_parse_test_ex(const char *expected[], const char *input,
+ const char **defaults)
+{
+ const char **res;
+ TALLOC_CTX *test_ctx;
+
+ test_ctx = talloc_new(NULL);
+ assert_non_null(test_ctx);
+
+ res = parse_attr_list_ex(test_ctx, input, defaults);
+
+ if (expected) {
+ /* Positive test */
+ assert_non_null(res);
+ assert_string_list_equal(res, expected);
+ } else {
+ /* Negative test */
+ assert_null(res);
+ }
+
+ talloc_free(test_ctx);
+}
+
void test_attr_acl(void **state)
{
/* Test defaults */
@@ -296,6 +319,33 @@ void test_attr_acl(void **state)
attr_parse_test(NULL, "missing_plus_or_minus");
}
+void test_attr_acl_ex(void **state)
+{
+ /* Test defaults */
+ const char *exp_defaults[] = { "abc", "123", "xyz", NULL };
+ attr_parse_test_ex(exp_defaults, NULL, exp_defaults);
+
+ /* Test adding some attributes to the defaults */
+ const char *exp_add[] = { "telephoneNumber", "streetAddress",
+ "abc", "123", "xyz",
+ NULL };
+ attr_parse_test_ex(exp_add, "+telephoneNumber, +streetAddress",
+ exp_defaults);
+
+ /* Test removing some attributes to the defaults */
+ const char *exp_rm[] = { "123", NULL };
+ attr_parse_test_ex(exp_rm, "-abc, -xyz", exp_defaults);
+
+ /* Test adding with empty defaults */
+ const char *exp_add_empty[] = { "telephoneNumber", "streetAddress",
+ NULL };
+ attr_parse_test_ex(exp_add_empty, "+telephoneNumber, +streetAddress", NULL);
+
+ /* Test removing with empty defaults */
+ const char *rm_all[] = { NULL };
+ attr_parse_test_ex(rm_all, "-telephoneNumber, -streetAddress", NULL);
+}
+
void test_attr_allowed(void **state)
{
const char *whitelist[] = { "name", "gecos", NULL };
@@ -452,6 +502,7 @@ int main(int argc, const char *argv[])
unit_test(test_path_prefix),
unit_test(test_el_to_dict),
unit_test(test_attr_acl),
+ unit_test(test_attr_acl_ex),
unit_test(test_attr_allowed),
unit_test(test_path_escape_unescape),
unit_test_setup_teardown(test_reply_path,