summaryrefslogtreecommitdiffstats
path: root/src/responder/ifp
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2014-05-11 16:15:24 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-05-22 17:16:01 +0200
commit1a546ae8250c6dbcff0ce775fc811529e02c360c (patch)
tree3f7bab044826e198804619b1e7d4c6641ab79e23 /src/responder/ifp
parent35d420c5d4609b6e999920e38a9b2ec40a0e1ac4 (diff)
downloadsssd-1a546ae8250c6dbcff0ce775fc811529e02c360c.tar.gz
sssd-1a546ae8250c6dbcff0ce775fc811529e02c360c.tar.xz
sssd-1a546ae8250c6dbcff0ce775fc811529e02c360c.zip
IFP: Add utility functions to escape and unescape object paths
D-Bus spec says: Each element must only contain the ASCII characters "[A-Z][a-z][0-9]_" This patch adds two utility functions to escape raw input into format suitable for DBus and conversely transform escaped paths back into raw paths. Reviewed-by: Stef Walter <stefw@redhat.com> Reviewed-by: Pavel Březina <pbrezina@redhat.com>
Diffstat (limited to 'src/responder/ifp')
-rw-r--r--src/responder/ifp/ifp_private.h5
-rw-r--r--src/responder/ifp/ifpsrv_util.c130
2 files changed, 134 insertions, 1 deletions
diff --git a/src/responder/ifp/ifp_private.h b/src/responder/ifp/ifp_private.h
index e7fcaa4c3..75be038e4 100644
--- a/src/responder/ifp/ifp_private.h
+++ b/src/responder/ifp/ifp_private.h
@@ -69,9 +69,12 @@ errno_t ifp_req_create(struct sbus_request *dbus_req,
int ifp_req_create_handle_failure(struct sbus_request *dbus_req, errno_t err);
const char *ifp_path_strip_prefix(const char *path, const char *prefix);
+
+char *ifp_bus_path_unescape(TALLOC_CTX *mem_ctx, const char *path);
+char *ifp_bus_path_escape(TALLOC_CTX *mem_ctx, const char *path);
+
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);
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 4ef0be6af..6fcd22479 100644
--- a/src/responder/ifp/ifpsrv_util.c
+++ b/src/responder/ifp/ifpsrv_util.c
@@ -106,6 +106,136 @@ const char *ifp_path_strip_prefix(const char *path, const char *prefix)
return NULL;
}
+/* The following path related functions are based on similar code in
+ * storaged, just tailored to use talloc instead of glib
+ */
+char *ifp_bus_path_escape(TALLOC_CTX *mem_ctx, const char *path)
+{
+ size_t n;
+ char *safe_path = NULL;
+ TALLOC_CTX *tmp_ctx = NULL;
+
+ /* The path must be valid */
+ if (path == NULL) {
+ return NULL;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return NULL;
+ }
+
+ safe_path = talloc_strdup(tmp_ctx, "");
+ if (safe_path == NULL) {
+ goto done;
+ }
+
+ /* Special case for an empty string */
+ if (strcmp(path, "") == 0) {
+ /* the for loop would just fall through */
+ safe_path = talloc_asprintf_append_buffer(safe_path, "_");
+ }
+
+ for (n = 0; path[n]; n++) {
+ int c = path[n];
+ /* D-Bus spec says:
+ * *
+ * * Each element must only contain the ASCII characters
+ * "[A-Z][a-z][0-9]_"
+ * */
+ if ((c >= 'A' && c <= 'Z')
+ || (c >= 'a' && c <= 'z')
+ || (c >= '0' && c <= '9')) {
+ safe_path = talloc_asprintf_append_buffer(safe_path, "%c", c);
+ if (safe_path == NULL) {
+ goto done;
+ }
+ } else {
+ safe_path = talloc_asprintf_append_buffer(safe_path, "_%02x", c);
+ if (safe_path == NULL) {
+ goto done;
+ }
+ }
+ }
+
+ safe_path = talloc_steal(mem_ctx, safe_path);
+done:
+ talloc_free(tmp_ctx);
+ return safe_path;
+}
+
+static inline int unhexchar(char c)
+{
+ if (c >= '0' && c <= '9') {
+ return c - '0';
+ }
+
+ if (c >= 'a' && c <= 'f') {
+ return c - 'a' + 10;
+ }
+
+ if (c >= 'A' && c <= 'F') {
+ return c - 'A' + 10;
+ }
+
+ return -1;
+}
+
+char *ifp_bus_path_unescape(TALLOC_CTX *mem_ctx, const char *path)
+{
+ char *safe_path;
+ const char *p;
+ int a, b, c;
+ TALLOC_CTX *tmp_ctx = NULL;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return NULL;
+ }
+
+ safe_path = talloc_strdup(tmp_ctx, "");
+ if (safe_path == NULL) {
+ goto done;
+ }
+
+ /* Special case for the empty string */
+ if (strcmp(path, "_") == 0) {
+ safe_path = talloc_steal(mem_ctx, safe_path);
+ goto done;
+ }
+
+ for (p = path; *p; p++) {
+ if (*p == '_') {
+ /* There must be at least two more chars after underscore */
+ if (p[1] == '\0' || p[2] == '\0') {
+ safe_path = NULL;
+ goto done;
+ }
+
+ if ((a = unhexchar(p[1])) < 0
+ || (b = unhexchar(p[2])) < 0) {
+ /* Invalid escape code, let's take it literal then */
+ c = '_';
+ } else {
+ c = ((a << 4) | b);
+ p += 2;
+ }
+ } else {
+ c = *p;
+ }
+
+ safe_path = talloc_asprintf_append_buffer(safe_path, "%c", c);
+ if (safe_path == NULL) {
+ goto done;
+ }
+ }
+
+ safe_path = talloc_steal(mem_ctx, safe_path);
+done:
+ talloc_free(tmp_ctx);
+ return safe_path;
+}
+
errno_t ifp_add_ldb_el_to_dict(DBusMessageIter *iter_dict,
struct ldb_message_element *el)
{