Blame SOURCES/0057-Add-parse_attr_list_ex-helper-function.patch

905b4d
From b86a642a321d3763d997f07c47ec515acbe72cf0 Mon Sep 17 00:00:00 2001
905b4d
From: Sumit Bose <sbose@redhat.com>
905b4d
Date: Tue, 28 Oct 2014 19:40:02 +0100
905b4d
Subject: [PATCH 57/64] Add parse_attr_list_ex() helper function
905b4d
905b4d
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
905b4d
---
905b4d
 Makefile.am                            |   5 +-
905b4d
 src/responder/common/responder.h       |   2 +
905b4d
 src/responder/common/responder_utils.c | 151 +++++++++++++++++++++++++++++++++
905b4d
 src/responder/ifp/ifp_private.h        |   3 +
905b4d
 src/responder/ifp/ifpsrv_util.c        | 117 +------------------------
905b4d
 src/tests/cmocka/test_ifp.c            |  51 +++++++++++
905b4d
 6 files changed, 212 insertions(+), 117 deletions(-)
905b4d
 create mode 100644 src/responder/common/responder_utils.c
905b4d
905b4d
diff --git a/Makefile.am b/Makefile.am
905b4d
index 61bf5cf957d4024b67f48cf42f5735b5fa368945..ac8ad1566a5c931bf43526e2d29a57a5f8ade1cf 100644
905b4d
--- a/Makefile.am
905b4d
+++ b/Makefile.am
905b4d
@@ -409,6 +409,7 @@ SSSD_RESPONDER_OBJ = \
905b4d
     src/responder/common/responder_dp.c \
905b4d
     src/responder/common/responder_packet.c \
905b4d
     src/responder/common/responder_get_domains.c \
905b4d
+    src/responder/common/responder_utils.c \
905b4d
     src/monitor/monitor_iface_generated.c \
905b4d
     src/monitor/monitor_iface_generated.h \
905b4d
     src/providers/data_provider_iface_generated.c \
905b4d
@@ -2025,7 +2026,9 @@ ifp_tests_SOURCES = \
905b4d
     src/tests/cmocka/test_ifp.c \
905b4d
     src/responder/ifp/ifpsrv_cmd.c \
905b4d
     src/responder/ifp/ifp_iface_generated.c \
905b4d
-    src/responder/ifp/ifpsrv_util.c
905b4d
+    src/responder/ifp/ifpsrv_util.c \
905b4d
+    src/responder/common/responder_utils.c \
905b4d
+    $(NULL)
905b4d
 ifp_tests_CFLAGS = \
905b4d
     $(AM_CFLAGS)
905b4d
 ifp_tests_LDADD = \
905b4d
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
905b4d
index e3c0f226775d279ea8c0f300cc2de54d2f7f9b72..02a215ced435c87ec0439807ab5e575de0d0fe04 100644
905b4d
--- a/src/responder/common/responder.h
905b4d
+++ b/src/responder/common/responder.h
905b4d
@@ -329,4 +329,6 @@ sss_parse_inp_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx,
905b4d
 errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
905b4d
                            char **_name, char **_domname);
905b4d
 
905b4d
+const char **parse_attr_list_ex(TALLOC_CTX *mem_ctx, const char *conf_str,
905b4d
+                                const char **defaults);
905b4d
 #endif /* __SSS_RESPONDER_H__ */
905b4d
diff --git a/src/responder/common/responder_utils.c b/src/responder/common/responder_utils.c
905b4d
new file mode 100644
905b4d
index 0000000000000000000000000000000000000000..815b61b3971cfda2eda4efc643ea21c3b035b36d
905b4d
--- /dev/null
905b4d
+++ b/src/responder/common/responder_utils.c
905b4d
@@ -0,0 +1,151 @@
905b4d
+
905b4d
+/*
905b4d
+   SSSD
905b4d
+
905b4d
+   Common Responder utility functions
905b4d
+
905b4d
+   Copyright (C) Sumit Bose <sbose@redhat.com> 2014
905b4d
+
905b4d
+   This program is free software; you can redistribute it and/or modify
905b4d
+   it under the terms of the GNU General Public License as published by
905b4d
+   the Free Software Foundation; either version 3 of the License, or
905b4d
+   (at your option) any later version.
905b4d
+
905b4d
+   This program is distributed in the hope that it will be useful,
905b4d
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
905b4d
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
905b4d
+   GNU General Public License for more details.
905b4d
+
905b4d
+   You should have received a copy of the GNU General Public License
905b4d
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
905b4d
+*/
905b4d
+
905b4d
+#include <talloc.h>
905b4d
+
905b4d
+#include "util/util.h"
905b4d
+
905b4d
+static inline bool
905b4d
+attr_in_list(const char **list, size_t nlist, const char *str)
905b4d
+{
905b4d
+    size_t i;
905b4d
+
905b4d
+    for (i = 0; i < nlist; i++) {
905b4d
+        if (strcasecmp(list[i], str) == 0) {
905b4d
+            break;
905b4d
+        }
905b4d
+    }
905b4d
+
905b4d
+    return (i < nlist) ? true : false;
905b4d
+}
905b4d
+
905b4d
+const char **parse_attr_list_ex(TALLOC_CTX *mem_ctx, const char *conf_str,
905b4d
+                                const char **defaults)
905b4d
+{
905b4d
+    TALLOC_CTX *tmp_ctx;
905b4d
+    errno_t ret;
905b4d
+    const char **list = NULL;
905b4d
+    const char **res = NULL;
905b4d
+    int list_size;
905b4d
+    char **conf_list = NULL;
905b4d
+    int conf_list_size = 0;
905b4d
+    const char **allow = NULL;
905b4d
+    const char **deny = NULL;
905b4d
+    int ai = 0, di = 0, li = 0;
905b4d
+    int i;
905b4d
+
905b4d
+    tmp_ctx = talloc_new(NULL);
905b4d
+    if (tmp_ctx == NULL) {
905b4d
+        return NULL;
905b4d
+    }
905b4d
+
905b4d
+    if (conf_str) {
905b4d
+        ret = split_on_separator(tmp_ctx, conf_str, ',', true, true,
905b4d
+                                 &conf_list, &conf_list_size);
905b4d
+        if (ret != EOK) {
905b4d
+            DEBUG(SSSDBG_OP_FAILURE,
905b4d
+                  "Cannot parse attribute ACL list  %s: %d\n", conf_str, ret);
905b4d
+            goto done;
905b4d
+        }
905b4d
+
905b4d
+        allow = talloc_zero_array(tmp_ctx, const char *, conf_list_size);
905b4d
+        deny = talloc_zero_array(tmp_ctx, const char *, conf_list_size);
905b4d
+        if (allow == NULL || deny == NULL) {
905b4d
+            goto done;
905b4d
+        }
905b4d
+    }
905b4d
+
905b4d
+    for (i = 0; i < conf_list_size; i++) {
905b4d
+        switch (conf_list[i][0]) {
905b4d
+            case '+':
905b4d
+                allow[ai] = conf_list[i] + 1;
905b4d
+                ai++;
905b4d
+                continue;
905b4d
+            case '-':
905b4d
+                deny[di] = conf_list[i] + 1;
905b4d
+                di++;
905b4d
+                continue;
905b4d
+            default:
905b4d
+                DEBUG(SSSDBG_CRIT_FAILURE, "ACL values must start with "
905b4d
+                      "either '+' (allow) or '-' (deny), got '%s'\n",
905b4d
+                      conf_list[i]);
905b4d
+                goto done;
905b4d
+        }
905b4d
+    }
905b4d
+
905b4d
+    /* Assume the output will have to hold defaults and all the configured,
905b4d
+     * values, resize later
905b4d
+     */
905b4d
+    list_size = 0;
905b4d
+    if (defaults != NULL) {
905b4d
+        while (defaults[list_size]) {
905b4d
+            list_size++;
905b4d
+        }
905b4d
+    }
905b4d
+    list_size += conf_list_size;
905b4d
+
905b4d
+    list = talloc_zero_array(tmp_ctx, const char *, list_size + 1);
905b4d
+    if (list == NULL) {
905b4d
+        goto done;
905b4d
+    }
905b4d
+
905b4d
+    /* Start by copying explicitly allowed attributes */
905b4d
+    for (i = 0; i < ai; i++) {
905b4d
+        /* if the attribute is explicitly denied, skip it */
905b4d
+        if (attr_in_list(deny, di, allow[i])) {
905b4d
+            continue;
905b4d
+        }
905b4d
+
905b4d
+        list[li] = talloc_strdup(list, allow[i]);
905b4d
+        if (list[li] == NULL) {
905b4d
+            goto done;
905b4d
+        }
905b4d
+        li++;
905b4d
+
905b4d
+        DEBUG(SSSDBG_TRACE_INTERNAL,
905b4d
+              "Added allowed attr %s to whitelist\n", allow[i]);
905b4d
+    }
905b4d
+
905b4d
+    /* Add defaults */
905b4d
+    if (defaults != NULL) {
905b4d
+        for (i = 0; defaults[i]; i++) {
905b4d
+            /* if the attribute is explicitly denied, skip it */
905b4d
+            if (attr_in_list(deny, di, defaults[i])) {
905b4d
+                continue;
905b4d
+            }
905b4d
+
905b4d
+            list[li] = talloc_strdup(list, defaults[i]);
905b4d
+            if (list[li] == NULL) {
905b4d
+                goto done;
905b4d
+            }
905b4d
+            li++;
905b4d
+
905b4d
+            DEBUG(SSSDBG_TRACE_INTERNAL,
905b4d
+                  "Added default attr %s to whitelist\n", defaults[i]);
905b4d
+        }
905b4d
+    }
905b4d
+
905b4d
+    res = talloc_steal(mem_ctx, list);
905b4d
+done:
905b4d
+    talloc_free(tmp_ctx);
905b4d
+    return res;
905b4d
+}
905b4d
diff --git a/src/responder/ifp/ifp_private.h b/src/responder/ifp/ifp_private.h
905b4d
index bf2015a9722ff4b4f831cb63cd528881f0f259a8..fb1639c8dfd00f547a666dce67ee7a94c3143618 100644
905b4d
--- a/src/responder/ifp/ifp_private.h
905b4d
+++ b/src/responder/ifp/ifp_private.h
905b4d
@@ -82,5 +82,8 @@ char *_ifp_reply_objpath(TALLOC_CTX *mem_ctx, const char *base,
905b4d
 errno_t ifp_add_ldb_el_to_dict(DBusMessageIter *iter_dict,
905b4d
                                struct ldb_message_element *el);
905b4d
 const char **ifp_parse_attr_list(TALLOC_CTX *mem_ctx, const char *conf_str);
905b4d
+const char **
905b4d
+ifp_parse_attr_list_ex(TALLOC_CTX *mem_ctx, const char *conf_str,
905b4d
+                       const char **defaults);
905b4d
 bool ifp_attr_allowed(const char *whitelist[], const char *attr);
905b4d
 #endif /* _IFPSRV_PRIVATE_H_ */
905b4d
diff --git a/src/responder/ifp/ifpsrv_util.c b/src/responder/ifp/ifpsrv_util.c
905b4d
index c0ab686e4527a2508f67b789151365dfdbb89f25..909bc54870d6442ea9daf8e86d2dc97acfe4b93d 100644
905b4d
--- a/src/responder/ifp/ifpsrv_util.c
905b4d
+++ b/src/responder/ifp/ifpsrv_util.c
905b4d
@@ -356,127 +356,12 @@ errno_t ifp_add_ldb_el_to_dict(DBusMessageIter *iter_dict,
905b4d
     return EOK;
905b4d
 }
905b4d
 
905b4d
-static inline bool
905b4d
-attr_in_list(const char **list, size_t nlist, const char *str)
905b4d
-{
905b4d
-    size_t i;
905b4d
-
905b4d
-    for (i = 0; i < nlist; i++) {
905b4d
-        if (strcasecmp(list[i], str) == 0) {
905b4d
-            break;
905b4d
-        }
905b4d
-    }
905b4d
-
905b4d
-    return (i < nlist) ? true : false;
905b4d
-}
905b4d
-
905b4d
 const char **
905b4d
 ifp_parse_attr_list(TALLOC_CTX *mem_ctx, const char *conf_str)
905b4d
 {
905b4d
-    TALLOC_CTX *tmp_ctx;
905b4d
-    errno_t ret;
905b4d
-    const char **list = NULL;
905b4d
-    const char **res = NULL;
905b4d
-    int list_size;
905b4d
-    char **conf_list = NULL;
905b4d
-    int conf_list_size = 0;
905b4d
-    const char **allow = NULL;
905b4d
-    const char **deny = NULL;
905b4d
-    int ai = 0, di = 0, li = 0;
905b4d
-    int i;
905b4d
     const char *defaults[] = IFP_DEFAULT_ATTRS;
905b4d
 
905b4d
-    tmp_ctx = talloc_new(NULL);
905b4d
-    if (tmp_ctx == NULL) {
905b4d
-        return NULL;
905b4d
-    }
905b4d
-
905b4d
-    if (conf_str) {
905b4d
-        ret = split_on_separator(tmp_ctx, conf_str, ',', true, true,
905b4d
-                                 &conf_list, &conf_list_size);
905b4d
-        if (ret != EOK) {
905b4d
-            DEBUG(SSSDBG_OP_FAILURE,
905b4d
-                  "Cannot parse attribute ACL list  %s: %d\n", conf_str, ret);
905b4d
-            goto done;
905b4d
-        }
905b4d
-
905b4d
-        allow = talloc_zero_array(tmp_ctx, const char *, conf_list_size);
905b4d
-        deny = talloc_zero_array(tmp_ctx, const char *, conf_list_size);
905b4d
-        if (allow == NULL || deny == NULL) {
905b4d
-            goto done;
905b4d
-        }
905b4d
-    }
905b4d
-
905b4d
-    for (i = 0; i < conf_list_size; i++) {
905b4d
-        switch (conf_list[i][0]) {
905b4d
-            case '+':
905b4d
-                allow[ai] = conf_list[i] + 1;
905b4d
-                ai++;
905b4d
-                continue;
905b4d
-            case '-':
905b4d
-                deny[di] = conf_list[i] + 1;
905b4d
-                di++;
905b4d
-                continue;
905b4d
-            default:
905b4d
-                DEBUG(SSSDBG_CRIT_FAILURE, "ACL values must start with "
905b4d
-                      "either '+' (allow) or '-' (deny), got '%s'\n",
905b4d
-                      conf_list[i]);
905b4d
-                goto done;
905b4d
-        }
905b4d
-    }
905b4d
-
905b4d
-    /* Assume the output will have to hold defauls and all the configured,
905b4d
-     * values, resize later
905b4d
-     */
905b4d
-    list_size = 0;
905b4d
-    while (defaults[list_size]) {
905b4d
-        list_size++;
905b4d
-    }
905b4d
-    list_size += conf_list_size;
905b4d
-
905b4d
-    list = talloc_zero_array(tmp_ctx, const char *, list_size + 1);
905b4d
-    if (list == NULL) {
905b4d
-        goto done;
905b4d
-    }
905b4d
-
905b4d
-    /* Start by copying explicitly allowed attributes */
905b4d
-    for (i = 0; i < ai; i++) {
905b4d
-        /* if the attribute is explicitly denied, skip it */
905b4d
-        if (attr_in_list(deny, di, allow[i])) {
905b4d
-            continue;
905b4d
-        }
905b4d
-
905b4d
-        list[li] = talloc_strdup(list, allow[i]);
905b4d
-        if (list[li] == NULL) {
905b4d
-            goto done;
905b4d
-        }
905b4d
-        li++;
905b4d
-
905b4d
-        DEBUG(SSSDBG_TRACE_INTERNAL,
905b4d
-              "Added allowed attr %s to whitelist\n", allow[i]);
905b4d
-    }
905b4d
-
905b4d
-    /* Add defaults */
905b4d
-    for (i = 0; defaults[i]; i++) {
905b4d
-        /* if the attribute is explicitly denied, skip it */
905b4d
-        if (attr_in_list(deny, di, defaults[i])) {
905b4d
-            continue;
905b4d
-        }
905b4d
-
905b4d
-        list[li] = talloc_strdup(list, defaults[i]);
905b4d
-        if (list[li] == NULL) {
905b4d
-            goto done;
905b4d
-        }
905b4d
-        li++;
905b4d
-
905b4d
-        DEBUG(SSSDBG_TRACE_INTERNAL,
905b4d
-              "Added default attr %s to whitelist\n", defaults[i]);
905b4d
-    }
905b4d
-
905b4d
-    res = talloc_steal(mem_ctx, list);
905b4d
-done:
905b4d
-    talloc_free(tmp_ctx);
905b4d
-    return res;
905b4d
+    return parse_attr_list_ex(mem_ctx, conf_str, defaults);
905b4d
 }
905b4d
 
905b4d
 bool
905b4d
diff --git a/src/tests/cmocka/test_ifp.c b/src/tests/cmocka/test_ifp.c
905b4d
index b0f6e09900a956a51c17d1c4cf1a7772dccc3a68..d6e41706d5f55414c0376bd04d299ec6ad73c11e 100644
905b4d
--- a/src/tests/cmocka/test_ifp.c
905b4d
+++ b/src/tests/cmocka/test_ifp.c
905b4d
@@ -246,6 +246,29 @@ static void attr_parse_test(const char *expected[], const char *input)
905b4d
     talloc_free(test_ctx);
905b4d
 }
905b4d
 
905b4d
+static void attr_parse_test_ex(const char *expected[], const char *input,
905b4d
+                               const char **defaults)
905b4d
+{
905b4d
+    const char **res;
905b4d
+    TALLOC_CTX *test_ctx;
905b4d
+
905b4d
+    test_ctx = talloc_new(NULL);
905b4d
+    assert_non_null(test_ctx);
905b4d
+
905b4d
+    res = parse_attr_list_ex(test_ctx, input, defaults);
905b4d
+
905b4d
+    if (expected) {
905b4d
+        /* Positive test */
905b4d
+        assert_non_null(res);
905b4d
+        assert_string_list_equal(res, expected);
905b4d
+    } else {
905b4d
+        /* Negative test */
905b4d
+        assert_null(res);
905b4d
+    }
905b4d
+
905b4d
+    talloc_free(test_ctx);
905b4d
+}
905b4d
+
905b4d
 void test_attr_acl(void **state)
905b4d
 {
905b4d
     /* Test defaults */
905b4d
@@ -296,6 +319,33 @@ void test_attr_acl(void **state)
905b4d
     attr_parse_test(NULL,  "missing_plus_or_minus");
905b4d
 }
905b4d
 
905b4d
+void test_attr_acl_ex(void **state)
905b4d
+{
905b4d
+    /* Test defaults */
905b4d
+    const char *exp_defaults[] = { "abc", "123", "xyz", NULL };
905b4d
+    attr_parse_test_ex(exp_defaults, NULL, exp_defaults);
905b4d
+
905b4d
+    /* Test adding some attributes to the defaults */
905b4d
+    const char *exp_add[] = { "telephoneNumber", "streetAddress",
905b4d
+                              "abc", "123", "xyz",
905b4d
+                              NULL };
905b4d
+    attr_parse_test_ex(exp_add, "+telephoneNumber, +streetAddress",
905b4d
+                       exp_defaults);
905b4d
+
905b4d
+    /* Test removing some attributes to the defaults */
905b4d
+    const char *exp_rm[] = { "123", NULL };
905b4d
+    attr_parse_test_ex(exp_rm, "-abc, -xyz", exp_defaults);
905b4d
+
905b4d
+    /* Test adding with empty defaults */
905b4d
+    const char *exp_add_empty[] = { "telephoneNumber", "streetAddress",
905b4d
+                                    NULL };
905b4d
+    attr_parse_test_ex(exp_add_empty, "+telephoneNumber, +streetAddress", NULL);
905b4d
+
905b4d
+    /* Test removing with empty defaults */
905b4d
+    const char *rm_all[] = { NULL };
905b4d
+    attr_parse_test_ex(rm_all, "-telephoneNumber, -streetAddress", NULL);
905b4d
+}
905b4d
+
905b4d
 void test_attr_allowed(void **state)
905b4d
 {
905b4d
     const char *whitelist[] = { "name", "gecos", NULL };
905b4d
@@ -452,6 +502,7 @@ int main(int argc, const char *argv[])
905b4d
         unit_test(test_path_prefix),
905b4d
         unit_test(test_el_to_dict),
905b4d
         unit_test(test_attr_acl),
905b4d
+        unit_test(test_attr_acl_ex),
905b4d
         unit_test(test_attr_allowed),
905b4d
         unit_test(test_path_escape_unescape),
905b4d
         unit_test_setup_teardown(test_reply_path,
905b4d
-- 
905b4d
1.9.3
905b4d