From e6cb48fc29fa64113034c62bbda976bc164cc9a9 Mon Sep 17 00:00:00 2001
From: Yassir Elley <yelley@redhat.com>
Date: Sat, 5 Jul 2014 15:37:23 -0400
Subject: [PATCH] AD-GPO: Store policy settings in local files

---
 Makefile.am                     |   2 +
 configure.ac                    |   1 +
 contrib/sssd.spec.in            |   3 +
 src/conf_macros.m4              |  17 ++
 src/providers/ad/ad_gpo.c       | 413 +++++++++++++++++++++++-----------
 src/providers/ad/ad_gpo_child.c | 481 ++++++++++++++++------------------------
 6 files changed, 496 insertions(+), 421 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 1c423fc6d40754852a9775dc72016703e398f17c..9aa9fed2be398be6293398bf1c885c8e704c1cb2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -61,6 +61,7 @@ systemdunitdir = @systemdunitdir@
 systemdconfdir = @systemdconfdir@
 logpath = @logpath@
 pubconfpath = @pubconfpath@
+gpocachepath = @gpocachepath@
 pkgconfigdir = $(libdir)/pkgconfig
 krb5rcachedir = @krb5rcachedir@
 sudolibdir = @sudolibpath@
@@ -2536,6 +2537,7 @@ installsssddirs::
     $(DESTDIR)$(logpath) \
     $(DESTDIR)$(pubconfpath) \
     $(DESTDIR)$(pubconfpath)/krb5.include.d \
+    $(DESTDIR)$(gpocachepath) \
     $(DESTDIR)$(sudolibdir) \
     $(DESTDIR)$(autofslibdir)
 
diff --git a/configure.ac b/configure.ac
index dcf2494de62be08af2d0ebb25d1ed9f83b4517d5..023278f9a1c2ef56fd7011fcedaacc8cf04e6184 100644
--- a/configure.ac
+++ b/configure.ac
@@ -112,6 +112,7 @@ WITH_CIFS_PLUGIN_PATH
 WITH_SELINUX
 WITH_NSCD
 WITH_SEMANAGE
+WITH_GPO_CACHE_PATH
 WITH_NOLOGIN_SHELL
 WITH_APP_LIBS
 WITH_SUDO
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index 2b8bac993954050365ae0937c03ac5f43311d271..6988e42949dd6802eebb34c0b99b3f5b4abba518 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -77,6 +77,7 @@ Requires: python-sssdconfig = %{version}-%{release}
 %global pipepath %{sssdstatedir}/pipes
 %global mcpath %{sssdstatedir}/mc
 %global pubconfpath %{sssdstatedir}/pubconf
+%global gpocachepath %{sssdstatedir}/gpo_cache
 
 ### Build Dependencies ###
 
@@ -447,6 +448,7 @@ autoreconf -ivf
     --with-mcache-path=%{mcpath} \
     --with-pipe-path=%{pipepath} \
     --with-pubconf-path=%{pubconfpath} \
+    --with-gpo-cache-path=%{gpocachepath} \
     --with-init-dir=%{_initrddir} \
     --with-krb5-rcache-dir=%{_localstatedir}/cache/krb5rcache \
     --enable-nsslibdir=/%{_lib} \
@@ -614,6 +616,7 @@ rm -rf $RPM_BUILD_ROOT
 %ghost %attr(0644,root,root) %verify(not md5 size mtime) %{mcpath}/group
 %attr(755,root,root) %dir %{pipepath}
 %attr(755,root,root) %dir %{pubconfpath}
+%attr(755,root,root) %dir %{gpocachepath}
 %attr(700,root,root) %dir %{pipepath}/private
 %attr(750,root,root) %dir %{_var}/log/%{name}
 %attr(711,root,root) %dir %{_sysconfdir}/sssd
diff --git a/src/conf_macros.m4 b/src/conf_macros.m4
index 3a042a81bf6399a55ee2a66a3fcb8e208ba2cd3f..3c9827b4d4e1750fc06af8ab8b69ecf99226a8f6 100644
--- a/src/conf_macros.m4
+++ b/src/conf_macros.m4
@@ -453,6 +453,23 @@ AC_DEFUN([WITH_SEMANAGE],
     AM_CONDITIONAL([BUILD_SEMANAGE], [test x"$with_semanage" = xyes])
   ])
 
+AC_DEFUN([WITH_GPO_CACHE_PATH],
+  [ AC_ARG_WITH([gpo-cache-path],
+                [AC_HELP_STRING([--with-gpo-cache-path=PATH],
+                                [Where to store GPO policy files [/var/lib/sss/gpo_cache]]
+                               )
+                ]
+               )
+    config_gpocachepath="\"VARDIR\"/lib/sss/gpo_cache"
+    gpocachepath="${localstatedir}/lib/sss/gpo_cache"
+    if test x"$with_gpo_cache_path" != x; then
+        config_gpocachepath=$with_gpo_cache_path
+        gpocachepath=$with_gpo_cache_path
+    fi
+    AC_SUBST(gpocachepath)
+    AC_DEFINE_UNQUOTED(GPO_CACHE_PATH, "$config_gpocachepath", [Where to store GPO policy files])
+  ])
+
 AC_DEFUN([WITH_LIBNL],
   [ AC_ARG_WITH([libnl],
                 [AC_HELP_STRING([--with-libnl],
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index 32ef852f3d1e265ac391d0f0781adebd6bf5ab53..8ed4ba5d3fc2db11cd116f6760030b1e140bc5d2 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -33,6 +33,8 @@
 
 #include <security/pam_modules.h>
 #include <syslog.h>
+#include <fcntl.h>
+#include <ini_configobj.h>
 #include "util/util.h"
 #include "util/strtonum.h"
 #include "util/child_common.h"
@@ -74,10 +76,15 @@
 /* == gpo-smb constants ==================================================== */
 
 #define SMB_STANDARD_URI "smb://"
+#define BUFSIZE 65536
 
 #define GPO_VERSION_USER(x) (x >> 16)
 #define GPO_VERSION_MACHINE(x) (x & 0xffff)
 
+#define RIGHTS_SECTION "Privilege Rights"
+#define ALLOW_LOGON_LOCALLY "SeInteractiveLogonRight"
+#define DENY_LOGON_LOCALLY "SeDenyInteractiveLogonRight"
+
 #define GP_EXT_GUID_SECURITY "{827D319E-6EAC-11D2-A4EA-00C04F79F83A}"
 #define GP_EXT_GUID_SECURITY_SUFFIX "/Microsoft/Windows NT/SecEdit/GptTmpl.inf"
 
@@ -109,6 +116,7 @@ struct gp_gpo {
     const char *gpo_guid;
     const char *gpo_display_name;
     const char *gpo_file_sys_path;
+    const char *gpo_unix_path;
     uint32_t gpo_container_version;
     const char **gpo_cse_guids;
     int num_gpo_cse_guids;
@@ -148,7 +156,8 @@ int ad_gpo_process_gpo_recv(struct tevent_req *req,
                             int *num_candidate_gpos);
 struct tevent_req *ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx,
                                            struct tevent_context *ev,
-                                           char *smb_uri);
+                                           char *cse_smb_uri,
+                                           char *cse_unix_path);
 int ad_gpo_process_cse_recv(struct tevent_req *req,
                             TALLOC_CTX *mem_ctx,
                             int *_allowed_size,
@@ -1289,7 +1298,8 @@ ad_gpo_cse_step(struct tevent_req *req)
 {
     struct tevent_req *subreq;
     struct ad_gpo_access_state *state;
-    char *smb_uri;
+    char *cse_smb_uri;
+    char *cse_unix_path;
     int i = 0;
 
     state = tevent_req_data(req, struct ad_gpo_access_state);
@@ -1303,19 +1313,21 @@ ad_gpo_cse_step(struct tevent_req *req)
 
     DEBUG(SSSDBG_TRACE_FUNC, "cse filtered_gpos[%d]->gpo_guid is %s\n",
           state->cse_gpo_index, cse_filtered_gpo->gpo_guid);
-    DEBUG(SSSDBG_TRACE_FUNC, "cse filtered_gpos[%d]->file_sys_path is %s\n",
-          state->cse_gpo_index, cse_filtered_gpo->gpo_file_sys_path);
     for (i = 0; i < cse_filtered_gpo->num_gpo_cse_guids; i++) {
         DEBUG(SSSDBG_TRACE_ALL,
               "cse_filtered_gpos[%d]->gpo_cse_guids[%d]->gpo_guid is %s\n",
               state->cse_gpo_index, i, cse_filtered_gpo->gpo_cse_guids[i]);
     }
 
-    smb_uri = talloc_asprintf(state, "%s%s",
-                              cse_filtered_gpo->gpo_file_sys_path,
-                              GP_EXT_GUID_SECURITY_SUFFIX);
+    cse_smb_uri = talloc_asprintf(state, "%s%s",
+                                  cse_filtered_gpo->gpo_file_sys_path,
+                                  GP_EXT_GUID_SECURITY_SUFFIX);
 
-    subreq = ad_gpo_process_cse_send(state, state->ev, smb_uri);
+    cse_unix_path = talloc_asprintf(state, "%s%s",
+                                    cse_filtered_gpo->gpo_unix_path,
+                                    GP_EXT_GUID_SECURITY_SUFFIX);
+
+    subreq = ad_gpo_process_cse_send(state, state->ev, cse_smb_uri, cse_unix_path);
 
     tevent_req_set_callback(subreq, ad_gpo_cse_done, req);
     return EAGAIN;
@@ -1344,8 +1356,8 @@ ad_gpo_cse_done(struct tevent_req *subreq)
     req = tevent_req_callback_data(subreq, struct tevent_req);
     state = tevent_req_data(req, struct ad_gpo_access_state);
 
-    ret = ad_gpo_process_cse_recv(subreq, state, &allowed_size, &allowed_sids,
-                                  &denied_size, &denied_sids);
+    ret = ad_gpo_process_cse_recv(subreq, state, &allowed_size,
+                                  &allowed_sids, &denied_size, &denied_sids);
 
     talloc_zfree(subreq);
 
@@ -2262,39 +2274,48 @@ ad_gpo_populate_candidate_gpos(TALLOC_CTX *mem_ctx,
 }
 
 /*
- * This function converts the input_path to an smb uri, which is used to
- * populate the _converted_path output parameter. The output is constructed by
- * concatenating the following elements:
+ * This function converts the input_path to an smb uri and a unix_path, which
+ * are used to populate the _smb_uri and _unix_path output parameters,
+ * respectively.
+ *
+ * The smb_path starts with the slash immediately after the domain name, while
+ * the unix_path starts with the following slash (immediately after the share name).
+ *
+ * The _smb_uri output is constructed by concatenating the following elements:
  * - SMB_STANDARD_URI ("smb://")
  * - server_hostname (which replaces domain_name in input path)
- * - smb_path (which starts with the slash immediately after the domain name
+ * - smb_path
  * Additionally, each forward slash ('\') is replaced with a back slash ('/')
  *
  * Example: if input_path = "\\foo.com\SysVol\foo.com\..." and
- * server_hostname = "adserver.foo.com", then _converted_path would be
- * "smb://adserver.foo.com/SysVol/foo.com/..."
+ * server_hostname = "adserver.foo.com", then
+ * _smb_uri = "smb://adserver.foo.com/SysVol/foo.com/..."; and
+ * _unix_path = "/foo.com/..."
  *
- * Note that the input_path must have at least three forward slash separators.
- * For example, input_path = "\\foo.com" is not a valid input_path, because
- * it has only two forward slash separators.
+ * Note that the input_path must have at least four forward slash separators.
+ * For example, input_path = "\\foo.com\SysVol" is not a valid input_path,
+ * because it has only three forward slash separators.
  */
 static errno_t
 ad_gpo_convert_to_smb_uri(TALLOC_CTX *mem_ctx,
                           char *server_hostname,
                           char *input_path,
-                          const char **_converted_path)
+                          const char **_smb_uri,
+                          const char **_unix_path)
 {
     char *ptr;
     const char delim = '\\';
     int ret;
     int num_seps = 0;
     char *smb_path = NULL;
+    char *unix_path = NULL;
 
     DEBUG(SSSDBG_TRACE_ALL, "input_path: %s\n", input_path);
 
     if (input_path == NULL ||
         *input_path == '\0' ||
-        _converted_path == NULL) {
+        _smb_uri == NULL ||
+        _unix_path == NULL) {
         ret = EINVAL;
         goto done;
     }
@@ -2305,6 +2326,9 @@ ad_gpo_convert_to_smb_uri(TALLOC_CTX *mem_ctx,
         if (num_seps == 3) {
             /* keep track of path from third slash onwards (after domain name) */
             smb_path = ptr;
+        } else if (num_seps == 4) {
+            /* keep track of path from fourth slash onwards (after share name) */
+            unix_path = ptr;
         }
         *ptr = '/';
         ptr++;
@@ -2315,15 +2339,19 @@ ad_gpo_convert_to_smb_uri(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
-    if (smb_path == NULL) {
+    if (smb_path == NULL || unix_path == NULL)  {
         ret = EINVAL;
         goto done;
     }
 
-    *_converted_path = talloc_asprintf(mem_ctx, "%s%s%s",
-                                       SMB_STANDARD_URI,
-                                       server_hostname,
-                                       smb_path);
+
+    *_smb_uri = talloc_asprintf(mem_ctx, "%s%s%s",
+                                 SMB_STANDARD_URI,
+                                 server_hostname,
+                                 smb_path);
+
+    *_unix_path = talloc_strdup(mem_ctx, unix_path);
+
     ret = EOK;
 
  done:
@@ -2595,6 +2623,7 @@ ad_gpo_get_gpo_attrs_done(struct tevent_req *subreq)
     struct ldb_message_element *el = NULL;
     const char *gpo_guid = NULL;
     const char *smb_uri = NULL;
+    const char *unix_path = NULL;
     const char *gpo_display_name = NULL;
     const char *raw_file_sys_path = NULL;
     char *file_sys_path = NULL;
@@ -2681,7 +2710,7 @@ ad_gpo_get_gpo_attrs_done(struct tevent_req *subreq)
 
     file_sys_path = talloc_strdup(gp_gpo, raw_file_sys_path);
     ad_gpo_convert_to_smb_uri(state, state->server_hostname, file_sys_path,
-                              &smb_uri);
+                              &smb_uri, &unix_path);
 
     gp_gpo->gpo_file_sys_path = talloc_asprintf(gp_gpo, "%s/Machine",
                                                 smb_uri);
@@ -2693,6 +2722,16 @@ ad_gpo_get_gpo_attrs_done(struct tevent_req *subreq)
     DEBUG(SSSDBG_TRACE_FUNC, "gpo_file_sys_path: %s\n",
           gp_gpo->gpo_file_sys_path);
 
+    gp_gpo->gpo_unix_path = talloc_asprintf(gp_gpo, "%s/Machine",
+                                            unix_path);
+    if (gp_gpo->gpo_unix_path == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    DEBUG(SSSDBG_TRACE_FUNC, "gpo_unix_path: %s\n",
+          gp_gpo->gpo_unix_path);
+
     /* retrieve AD_AT_VERSION_NUMBER */
     ret = sysdb_attrs_get_uint32_t(results[0], AD_AT_VERSION_NUMBER,
                                    &gp_gpo->gpo_container_version);
@@ -2807,17 +2846,17 @@ ad_gpo_process_gpo_recv(struct tevent_req *req,
 
 static errno_t
 create_cse_send_buffer(TALLOC_CTX *mem_ctx,
-                       char *smb_uri,
+                       char *cse_smb_uri,
+                       char *cse_unix_path,
                        struct io_buffer **io_buf)
 {
     struct io_buffer *buf;
     size_t rp;
-    int smb_uri_length;
+    int cse_smb_uri_length;
+    int cse_unix_path_length;
 
-    smb_uri_length = strlen(smb_uri);
-
-    DEBUG(SSSDBG_TRACE_FUNC, "smb_uri: %s\n", smb_uri);
-    DEBUG(SSSDBG_TRACE_FUNC, "strlen(smb_uri): %d\n", smb_uri_length);
+    cse_smb_uri_length = strlen(cse_smb_uri);
+    cse_unix_path_length = strlen(cse_unix_path);
 
     buf = talloc(mem_ctx, struct io_buffer);
     if (buf == NULL) {
@@ -2825,8 +2864,8 @@ create_cse_send_buffer(TALLOC_CTX *mem_ctx,
         return ENOMEM;
     }
 
-    buf->size = 1 * sizeof(uint32_t);
-    buf->size += smb_uri_length;
+    buf->size = 2 * sizeof(uint32_t);
+    buf->size += cse_smb_uri_length + cse_unix_path_length;
 
     DEBUG(SSSDBG_TRACE_ALL, "buffer size: %zu\n", buf->size);
 
@@ -2838,103 +2877,207 @@ create_cse_send_buffer(TALLOC_CTX *mem_ctx,
     }
 
     rp = 0;
-    /* smb_uri */
-    SAFEALIGN_SET_UINT32(&buf->data[rp], smb_uri_length, &rp);
-    safealign_memcpy(&buf->data[rp], smb_uri, smb_uri_length, &rp);
+    /* cse_smb_uri */
+    SAFEALIGN_SET_UINT32(&buf->data[rp], cse_smb_uri_length, &rp);
+    safealign_memcpy(&buf->data[rp], cse_smb_uri, cse_smb_uri_length, &rp);
+
+    /* cse_unix_path */
+    SAFEALIGN_SET_UINT32(&buf->data[rp], cse_unix_path_length, &rp);
+    safealign_memcpy(&buf->data[rp], cse_unix_path, cse_unix_path_length, &rp);
 
     *io_buf = buf;
     return EOK;
 }
 
+/*
+ * This function uses the input ini_config object to parse the logon right value
+ * associated with the input name. This value is a list of sids, and is used
+ * to populate the output parameters. The input name can be either
+ * ALLOW_LOGON_LOCALLY or DENY_LOGON_LOCALLY.
+ */
+static errno_t
+parse_logon_right_with_libini(TALLOC_CTX *mem_ctx,
+                              struct ini_cfgobj *ini_config,
+                              const char *name,
+                              int *_size,
+                              char ***_sids)
+{
+    int ret = 0;
+    struct value_obj *vobj = NULL;
+    char **ini_sids = NULL;
+    char *ini_sid = NULL;
+    int num_ini_sids = 0;
+    char **sids = NULL;
+    int i;
+    TALLOC_CTX *tmp_ctx = NULL;
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    ret = ini_get_config_valueobj(RIGHTS_SECTION, name, ini_config,
+                                  INI_GET_FIRST_VALUE, &vobj);
+    if (ret != 0) {
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "ini_get_config_valueobj failed [%d][%s]\n", ret, strerror(ret));
+        goto done;
+    }
+    if (vobj == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "section/name not found: [%s][%s]\n",
+              RIGHTS_SECTION, name);
+        ret = EOK;
+        goto done;
+    }
+    ini_sids = ini_get_string_config_array(vobj, NULL, &num_ini_sids, &ret);
+
+    if (ret != 0) {
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "ini_get_string_config_array failed [%d][%s]\n", ret, strerror(ret));
+        goto done;
+    }
+
+    sids = talloc_array(tmp_ctx, char *, num_ini_sids + 1);
+    if (sids == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    for (i = 0; i < num_ini_sids; i++) {
+        ini_sid = ini_sids[i];
+
+        /* remove the asterisk prefix found on sids in the .inf policy file */
+        if (ini_sid[0] == '*') {
+            ini_sid++;
+        }
+        sids[i] = talloc_strdup(sids, ini_sid);
+        if (sids[i] == NULL) {
+            ret = ENOMEM;
+            goto done;
+        }
+    }
+    sids[i] = NULL;
+
+    *_size = num_ini_sids;
+    *_sids = talloc_steal(mem_ctx, sids);
+
+    ret = EOK;
+
+ done:
+
+    ini_free_string_config_array(ini_sids);
+    talloc_free(tmp_ctx);
+    return ret;
+}
+
+/*
+ * This function parses the cse-specific (GP_EXT_GUID_SECURITY) input data_buf,
+ * and uses the results to populate the output parameters with the list of
+ * allowed_sids and denied_sids
+ */
+static errno_t
+ad_gpo_parse_security_cse_buffer(TALLOC_CTX *mem_ctx,
+                                 const char *filename,
+                                 char ***allowed_sids,
+                                 int *allowed_size,
+                                 char ***denied_sids,
+                                 int *denied_size)
+{
+    struct ini_cfgfile *file_ctx = NULL;
+    struct ini_cfgobj *ini_config = NULL;
+    int ret;
+    char **allow_sids = NULL;
+    char **deny_sids = NULL;
+    int allow_size = 0;
+    int deny_size = 0;
+    const char *key = NULL;
+    TALLOC_CTX *tmp_ctx = NULL;
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    ret = ini_config_create(&ini_config);
+    if (ret != 0) {
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "ini_config_create failed [%d][%s]\n", ret, strerror(ret));
+        goto done;
+    }
+
+    ret = ini_config_file_open(filename, 0, &file_ctx);
+    if (ret != 0) {
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "ini_config_file_open failed [%d][%s]\n", ret, strerror(ret));
+        goto done;
+    }
+
+    ret = ini_config_parse(file_ctx, INI_STOP_ON_NONE, 0, 0, ini_config);
+    if (ret != 0) {
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "ini_config_parse failed [%d][%s]\n", ret, strerror(ret));
+        goto done;
+    }
+
+    key = ALLOW_LOGON_LOCALLY;
+    ret = parse_logon_right_with_libini(tmp_ctx,
+                                        ini_config,
+                                        key,
+                                        &allow_size,
+                                        &allow_sids);
+    if (ret != 0) {
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "parse_logon_right_with_libini failed for %s [%d][%s]\n",
+              key, ret, strerror(ret));
+        goto done;
+    }
+
+    key = DENY_LOGON_LOCALLY;
+    ret = parse_logon_right_with_libini(tmp_ctx,
+                                        ini_config,
+                                        DENY_LOGON_LOCALLY,
+                                        &deny_size,
+                                        &deny_sids);
+    if (ret != 0) {
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "parse_logon_right_with_libini failed for %s [%d][%s]\n",
+              key, ret, strerror(ret));
+        goto done;
+    }
+
+    *allowed_sids = talloc_steal(mem_ctx, allow_sids);
+    *allowed_size = allow_size;
+    *denied_sids = talloc_steal(mem_ctx, deny_sids);
+    *denied_size = deny_size;
+
+ done:
+
+    if (ret != EOK) {
+      DEBUG(SSSDBG_CRIT_FAILURE, "Error encountered: %d.\n", ret);
+    }
+
+    ini_config_file_destroy(file_ctx);
+    ini_config_destroy(ini_config);
+    talloc_free(tmp_ctx);
+    return ret;
+}
+
 static errno_t
 parse_gpo_child_response(TALLOC_CTX *mem_ctx,
-                         uint8_t *buf, ssize_t size,
-                         char ***_allowed_sids,
-                         int *_allowed_size,
-                         char ***_denied_sids,
-                         int *_denied_size)
+                         uint8_t *buf, ssize_t size, uint32_t *_result)
 {
+
+    int ret;
     size_t p = 0;
-    uint32_t res;
-    errno_t ret;
-    int allowed_size = 0;
-    int denied_size = 0;
-    int i = 0;
-    int sid_len = 0;
-    char **allowed_sids;
-    char **denied_sids;
-    TALLOC_CTX *tmp_ctx = NULL;
-
-    tmp_ctx = talloc_new(NULL);
-    if (tmp_ctx == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
+    uint32_t result;
 
     /* operation result code */
-    SAFEALIGN_COPY_UINT32_CHECK(&res, buf + p, size, &p);
-
-    /* allowed_size */
-    SAFEALIGN_COPY_UINT32_CHECK(&allowed_size, buf + p, size, &p);
-    DEBUG(SSSDBG_TRACE_FUNC, "child response allowed_size: %d\n", allowed_size);
-
-    allowed_sids = talloc_array(tmp_ctx, char *, allowed_size);
-    if (allowed_sids == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    for (i = 0; i < allowed_size; i++) {
-        SAFEALIGN_COPY_UINT32_CHECK(&sid_len, buf + p, size, &p);
-        if ((p + sid_len ) > size) {
-            ret = EINVAL;
-            goto done;
-        }
-        allowed_sids[i] = talloc_strndup(allowed_sids,
-                                         (const char *)buf + p,
-                                         sid_len);
-        if (allowed_sids[i] == NULL) {
-            ret = ENOMEM;
-            goto done;
-        }
-        p += sid_len;
-    }
-
-    /* denied_size */
-    SAFEALIGN_COPY_UINT32_CHECK(&denied_size, buf + p, size, &p);
-    DEBUG(SSSDBG_TRACE_FUNC, "child response denied_size: %d\n", denied_size);
-
-    denied_sids = talloc_array(tmp_ctx, char *, denied_size);
-    if (denied_sids == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    for (i = 0; i < denied_size; i++) {
-        SAFEALIGN_COPY_UINT32_CHECK(&sid_len, buf + p, size, &p);
-        if ((p + sid_len ) > size) {
-            ret = EINVAL;
-            goto done;
-        }
-        denied_sids[i] = talloc_strndup(denied_sids,
-                                        (const char *)buf + p,
-                                        sid_len);
-        if (denied_sids[i] == NULL) {
-            ret = ENOMEM;
-            goto done;
-        }
-        p += sid_len;
-    }
-
-    *_allowed_size = allowed_size;
-    *_allowed_sids = talloc_steal(mem_ctx, allowed_sids);
-    *_denied_size = denied_size;
-    *_denied_sids = talloc_steal(mem_ctx, denied_sids);
+    SAFEALIGN_COPY_UINT32_CHECK(&result, buf + p, size, &p);
 
+    *_result = result;
     ret = EOK;
-
- done:
-    talloc_free(tmp_ctx);
     return ret;
 }
 
@@ -2942,6 +3085,7 @@ parse_gpo_child_response(TALLOC_CTX *mem_ctx,
 
 struct ad_gpo_process_cse_state {
     struct tevent_context *ev;
+    const char *cse_unix_path;
     pid_t child_pid;
     uint8_t *buf;
     ssize_t len;
@@ -2997,7 +3141,8 @@ static void gpo_cse_done(struct tevent_req *subreq);
 struct tevent_req *
 ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx,
                         struct tevent_context *ev,
-                        char *smb_uri)
+                        char *cse_smb_uri,
+                        char *cse_unix_path)
 {
     struct tevent_req *req;
     struct tevent_req *subreq;
@@ -3012,6 +3157,7 @@ ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx,
     }
 
     state->ev = ev;
+    state->cse_unix_path = cse_unix_path;
     state->buf = NULL;
     state->len = 0;
 
@@ -3027,7 +3173,7 @@ ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx,
     talloc_set_destructor((void *) state->io, gpo_child_io_destructor);
 
     /* prepare the data to pass to child */
-    ret = create_cse_send_buffer(state, smb_uri, &buf);
+    ret = create_cse_send_buffer(state, cse_smb_uri, cse_unix_path, &buf);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE, "create_cse_send_buffer failed.\n");
         goto fail;
@@ -3114,21 +3260,36 @@ int ad_gpo_process_cse_recv(struct tevent_req *req,
                             char ***_denied_sids)
 {
     int ret;
+    uint32_t result;
     char **allowed_sids;
     int allowed_size;
     char **denied_sids;
     int denied_size;
     struct ad_gpo_process_cse_state *state;
+    const char *filename = NULL;
 
     state = tevent_req_data(req, struct ad_gpo_process_cse_state);
 
     TEVENT_REQ_RETURN_ON_ERROR(req);
 
-    ret = parse_gpo_child_response(mem_ctx, state->buf, state->len,
-                                   &allowed_sids,
-                                   &allowed_size,
-                                   &denied_sids,
-                                   &denied_size);
+    parse_gpo_child_response(state, state->buf, state->len, &result);
+    if (result != 0){
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "Error in gpo_child: [%d][%s]\n", result, strerror(result));
+        return result;
+    }
+
+    filename = talloc_asprintf(mem_ctx, GPO_CACHE_PATH"%s", state->cse_unix_path);
+
+    ret = ad_gpo_parse_security_cse_buffer(state,
+                                           filename,
+                                           &allowed_sids,
+                                           &allowed_size,
+                                           &denied_sids,
+                                           &denied_size);
+
+
+
 
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE,
diff --git a/src/providers/ad/ad_gpo_child.c b/src/providers/ad/ad_gpo_child.c
index 0b6a4cde38bdc04675ec220615a3390ba478b5ae..794a832e84bc73367b5cc1c860d46dce690e4882 100644
--- a/src/providers/ad/ad_gpo_child.c
+++ b/src/providers/ad/ad_gpo_child.c
@@ -27,7 +27,6 @@
 #include <sys/stat.h>
 #include <popt.h>
 #include <libsmbclient.h>
-#include <ini_configobj.h>
 #include <security/pam_modules.h>
 
 #include "util/util.h"
@@ -42,6 +41,7 @@
 
 struct input_buffer {
     const char *smb_uri;
+    const char *unix_path;
 };
 
 static errno_t
@@ -52,12 +52,10 @@ unpack_buffer(uint8_t *buf,
     size_t p = 0;
     uint32_t len;
 
-    DEBUG(SSSDBG_TRACE_FUNC, "total buffer size: %zu\n", size);
-
     /* smb_uri size and length */
     SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p);
 
-    DEBUG(SSSDBG_TRACE_FUNC, "smb_uri size: %d\n", len);
+    DEBUG(SSSDBG_TRACE_ALL, "smb_uri size: %d\n", len);
 
     if (len == 0) {
         return EINVAL;
@@ -65,7 +63,22 @@ unpack_buffer(uint8_t *buf,
         if ((p + len ) > size) return EINVAL;
         ibuf->smb_uri = talloc_strndup(ibuf, (char *)(buf + p), len);
         if (ibuf->smb_uri == NULL) return ENOMEM;
-        DEBUG(SSSDBG_TRACE_FUNC, "got smb_uri: %s\n", ibuf->smb_uri);
+        DEBUG(SSSDBG_TRACE_ALL, "got smb_uri: %s\n", ibuf->smb_uri);
+        p += len;
+    }
+
+    /* unix_path size and length */
+    SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p);
+
+    DEBUG(SSSDBG_TRACE_ALL, "unix_path size: %d\n", len);
+
+    if (len == 0) {
+        return EINVAL;
+    } else {
+        if ((p + len ) > size) return EINVAL;
+        ibuf->unix_path = talloc_strndup(ibuf, (char *)(buf + p), len);
+        if (ibuf->unix_path == NULL) return ENOMEM;
+        DEBUG(SSSDBG_TRACE_ALL, "got unix_path: %s\n", ibuf->unix_path);
         p += len;
     }
 
@@ -75,91 +88,36 @@ unpack_buffer(uint8_t *buf,
 
 static errno_t
 pack_buffer(struct response *r,
-            int result,
-            int allowed_size,
-            char **allowed_sids,
-            int denied_size,
-            char **denied_sids)
+            int result)
 {
-    int len = 0;
     size_t p = 0;
-    int i;
-    int sid_len = 0;
 
     /* A buffer with the following structure must be created:
      *   uint32_t status of the request (required)
-     *   uint32_t allowed_size (required)
-     *   sid_message* (allowed_size instances)
-     *   uint32_t denied_size (required)
-     *   sid_message* (denied_size instances)
-     *
-     * A sid_message consists of:
-     *   uint32_t sid_len
-     *   uint8_t[sid_len] sid string
      */
-
-    DEBUG(SSSDBG_TRACE_FUNC, "entering pack_buffer\n");
-
-    for (i = 0; i < allowed_size; i++) {
-        len += strlen(allowed_sids[i]);
-    }
-
-    for (i = 0; i < denied_size; i++) {
-        len += strlen(denied_sids[i]);
-    }
-
-    r->size = (3 + allowed_size + denied_size) * sizeof(uint32_t) + len;
-
-    DEBUG(SSSDBG_TRACE_FUNC, "response size: %zu\n",r->size);
+    r->size = sizeof(uint32_t);
 
     r->buf = talloc_array(r, uint8_t, r->size);
     if(r->buf == NULL) {
         return ENOMEM;
     }
 
-    DEBUG(SSSDBG_TRACE_FUNC,
-          "result [%d] allowed_size [%d] denied_size [%d]\n",
-          result, allowed_size, denied_size);
+    DEBUG(SSSDBG_TRACE_FUNC, "result [%d]\n", result);
 
     /* result */
     SAFEALIGN_SET_UINT32(&r->buf[p], result, &p);
 
-    /* allowed_size */
-    SAFEALIGN_SET_UINT32(&r->buf[p], allowed_size, &p);
-
-    /* allowed_sids */
-    for (i = 0; i < allowed_size; i++) {
-        sid_len = strlen(allowed_sids[i]);
-        SAFEALIGN_SET_UINT32(&r->buf[p], sid_len, &p);
-        safealign_memcpy(&r->buf[p], allowed_sids[i], sid_len, &p);
-    }
-
-    /* denied_size */
-    SAFEALIGN_SET_UINT32(&r->buf[p], denied_size, &p);
-
-    /* denied_sids */
-    for (i = 0; i < denied_size; i++) {
-        sid_len = strlen(denied_sids[i]);
-        SAFEALIGN_SET_UINT32(&r->buf[p], sid_len, &p);
-        safealign_memcpy(&r->buf[p], denied_sids[i], sid_len, &p);
-    }
-
     return EOK;
 }
 
 static errno_t
 prepare_response(TALLOC_CTX *mem_ctx,
                  int result,
-                 int allowed_size,
-                 char **allowed_sids,
-                 int denied_size,
-                 char **denied_sids,
                  struct response **rsp)
 {
     int ret;
     struct response *r = NULL;
 
-    DEBUG(SSSDBG_TRACE_FUNC, "entering prepare_response.\n");
     r = talloc_zero(mem_ctx, struct response);
     if (r == NULL) {
         return ENOMEM;
@@ -168,7 +126,7 @@ prepare_response(TALLOC_CTX *mem_ctx,
     r->buf = NULL;
     r->size = 0;
 
-    ret = pack_buffer(r, result, allowed_size, allowed_sids, denied_size, denied_sids);
+    ret = pack_buffer(r, result);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE, "pack_buffer failed\n");
         return ret;
@@ -179,182 +137,6 @@ prepare_response(TALLOC_CTX *mem_ctx,
     return EOK;
 }
 
-/*
- * This function uses the input ini_config object to parse the logon right value
- * associated with the input name. This value is a list of sids, and is used
- * to populate the output parameters. The input name can be either
- * ALLOW_LOGON_LOCALLY or DENY_LOGON_LOCALLY.
- */
-static errno_t
-parse_logon_right_with_libini(TALLOC_CTX *mem_ctx,
-                              struct ini_cfgobj *ini_config,
-                              const char *name,
-                              int *_size,
-                              char ***_sids)
-{
-    int ret = 0;
-    struct value_obj *vobj = NULL;
-    char **ini_sids = NULL;
-    char *ini_sid = NULL;
-    int num_ini_sids = 0;
-    char **sids = NULL;
-    int i;
-    TALLOC_CTX *tmp_ctx = NULL;
-
-    tmp_ctx = talloc_new(NULL);
-    if (tmp_ctx == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    ret = ini_get_config_valueobj(RIGHTS_SECTION, name, ini_config,
-                                  INI_GET_FIRST_VALUE, &vobj);
-    if (ret != 0) {
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              "ini_get_config_valueobj failed [%d][%s]\n", ret, strerror(ret));
-        goto done;
-    }
-    if (vobj == NULL) {
-        DEBUG(SSSDBG_CRIT_FAILURE, "section/name not found: [%s][%s]\n",
-              RIGHTS_SECTION, name);
-        ret = EOK;
-        goto done;
-    }
-    ini_sids = ini_get_string_config_array(vobj, NULL, &num_ini_sids, &ret);
-
-    if (ret != 0) {
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              "ini_get_string_config_array failed [%d][%s]\n", ret, strerror(ret));
-        goto done;
-    }
-
-    sids = talloc_array(tmp_ctx, char *, num_ini_sids + 1);
-    if (sids == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    for (i = 0; i < num_ini_sids; i++) {
-        ini_sid = ini_sids[i];
-
-        /* remove the asterisk prefix found on sids in the .inf policy file */
-        if (ini_sid[0] == '*') {
-            ini_sid++;
-        }
-        sids[i] = talloc_strdup(sids, ini_sid);
-        if (sids[i] == NULL) {
-            ret = ENOMEM;
-            goto done;
-        }
-    }
-    sids[i] = NULL;
-
-    *_size = num_ini_sids;
-    *_sids = talloc_steal(mem_ctx, sids);
-
-    ret = EOK;
-
- done:
-
-    ini_free_string_config_array(ini_sids);
-    talloc_free(tmp_ctx);
-    return ret;
-}
-
-/*
- * This function parses the cse-specific (GP_EXT_GUID_SECURITY) input data_buf,
- * and uses the results to populate the output parameters with the list of
- * allowed_sids and denied_sids
- */
-static errno_t
-ad_gpo_parse_security_cse_buffer(TALLOC_CTX *mem_ctx,
-                                 uint8_t *data_buf,
-                                 int data_len,
-                                 char ***allowed_sids,
-                                 int *allowed_size,
-                                 char ***denied_sids,
-                                 int *denied_size)
-{
-    struct ini_cfgfile *file_ctx = NULL;
-    struct ini_cfgobj *ini_config = NULL;
-    int ret;
-    char **allow_sids = NULL;
-    char **deny_sids = NULL;
-    int allow_size = 0;
-    int deny_size = 0;
-    const char *key = NULL;
-    TALLOC_CTX *tmp_ctx = NULL;
-
-    tmp_ctx = talloc_new(NULL);
-    if (tmp_ctx == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    ret = ini_config_create(&ini_config);
-    if (ret != 0) {
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              "ini_config_create failed [%d][%s]\n", ret, strerror(ret));
-        goto done;
-    }
-
-    ret = ini_config_file_from_mem(data_buf, data_len, &file_ctx);
-    if (ret != 0) {
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              "ini_config_file_from_mem failed [%d][%s]\n", ret, strerror(ret));
-        goto done;
-    }
-
-    ret = ini_config_parse(file_ctx, INI_STOP_ON_NONE, 0, 0, ini_config);
-    if (ret != 0) {
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              "ini_config_parse failed [%d][%s]\n", ret, strerror(ret));
-        goto done;
-    }
-
-    key = ALLOW_LOGON_LOCALLY;
-    ret = parse_logon_right_with_libini(tmp_ctx,
-                                        ini_config,
-                                        key,
-                                        &allow_size,
-                                        &allow_sids);
-    if (ret != 0) {
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              "parse_logon_right_with_libini failed for %s [%d][%s]\n",
-              key, ret, strerror(ret));
-        goto done;
-    }
-
-    key = DENY_LOGON_LOCALLY;
-    ret = parse_logon_right_with_libini(tmp_ctx,
-                                        ini_config,
-                                        DENY_LOGON_LOCALLY,
-                                        &deny_size,
-                                        &deny_sids);
-    if (ret != 0) {
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              "parse_logon_right_with_libini failed for %s [%d][%s]\n",
-              key, ret, strerror(ret));
-        goto done;
-    }
-
-    *allowed_sids = talloc_steal(mem_ctx, allow_sids);
-    *allowed_size = allow_size;
-    *denied_sids = talloc_steal(mem_ctx, deny_sids);
-    *denied_size = deny_size;
-
- done:
-
-    if (ret != EOK) {
-      DEBUG(SSSDBG_CRIT_FAILURE, "Error encountered: %d.\n", ret);
-    }
-
-    ini_config_file_destroy(file_ctx);
-    ini_config_destroy(ini_config);
-    talloc_free(tmp_ctx);
-    return ret;
-}
-
 static void
 sssd_krb_get_auth_data_fn(const char * pServer,
                           const char * pShare,
@@ -369,29 +151,173 @@ sssd_krb_get_auth_data_fn(const char * pServer,
     return;
 }
 
+/*
+ * This function prepares the gpo_cache by:
+ * - parsing the input_unix_path into its component directories
+ * - creating each component directory (if it doesn't already exist)
+ */
+static errno_t prepare_gpo_cache(TALLOC_CTX *mem_ctx,
+                                 const char *cache_dir,
+                                 const char *input_unix_path)
+{
+    char *current_dir;
+    char *ptr;
+    const char delim = '/';
+    int num_dirs = 0;
+    int i;
+    char *first = NULL;
+    char *last = NULL;
+    char *unix_path = NULL;
+
+    unix_path = talloc_strdup(mem_ctx, input_unix_path);
+    if (unix_path == NULL) {
+        return ENOMEM;
+    }
+
+    current_dir = talloc_strdup(mem_ctx, cache_dir);
+    if (current_dir == NULL) {
+        return ENOMEM;
+    }
+
+    ptr = unix_path + 1;
+    while ((ptr = strchr(ptr, delim))) {
+        ptr++;
+        num_dirs++;
+    }
+
+    ptr = unix_path + 1;
+
+    for (i = 0; i < num_dirs; i++) {
+        first = ptr;
+        last = strchr(first, delim);
+        if (last == NULL) {
+            return EINVAL;
+        }
+        *last = '\0';
+        last++;
+
+        current_dir = talloc_asprintf(mem_ctx, "%s/%s", current_dir, first);
+        if ((mkdir(current_dir, 0644)) < 0 && errno != EEXIST) {
+            return EINVAL;
+        }
+
+        ptr = last;
+    }
+
+    return EOK;
+
+}
+
+/*
+ * This function stores the input buf to a local file, whose file path
+ * is constructed by concatenating GPO_CACHE_PATH to the input unix_path.
+ * Note that the backend will later read the policy file from the same file path.
+ */
+static errno_t store_bytes_in_gpo_cache(const char *unix_path,
+                                        uint8_t *buf,
+                                        int buflen)
+{
+    int ret;
+    int fd = -1;
+    char *tmp_name = NULL;
+    ssize_t written;
+    mode_t old_umask;
+    char *filename = NULL;
+    TALLOC_CTX *tmp_ctx = NULL;
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    /* create component directories of unix_path, if needed */
+    ret = prepare_gpo_cache(tmp_ctx, GPO_CACHE_PATH, unix_path);
+
+    filename = talloc_asprintf(tmp_ctx, GPO_CACHE_PATH"%s", unix_path);
+    tmp_name = talloc_asprintf(tmp_ctx, "%sXXXXXX", filename);
+    if (tmp_name == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
+        ret = ENOMEM;
+        goto done;
+    }
+
+    old_umask = umask(077);
+    fd = mkstemp(tmp_name);
+    umask(old_umask);
+    if (fd == -1) {
+        ret = errno;
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "mkstemp failed [%d][%s].\n", ret, strerror(ret));
+        goto done;
+    }
+
+    errno = 0;
+    written = sss_atomic_write_s(fd, buf, buflen);
+    if (written == -1) {
+        ret = errno;
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "write failed [%d][%s].\n", ret, strerror(ret));
+        goto done;
+    }
+
+    if (written != buflen) {
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "Write error, wrote [%zd] bytes, expected [%d]\n",
+               written, buflen);
+        ret = EIO;
+        goto done;
+    }
+
+    ret = fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+    if (ret == -1) {
+        ret = errno;
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "fchmod failed [%d][%s].\n", ret, strerror(ret));
+        goto done;
+    }
+
+    ret = close(fd);
+    if (ret == -1) {
+        ret = errno;
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "close failed [%d][%s].\n", ret, strerror(ret));
+        goto done;
+    }
+
+    ret = rename(tmp_name, filename);
+    if (ret == -1) {
+        ret = errno;
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "rename failed [%d][%s].\n", ret, strerror(ret));
+        goto done;
+    }
+
+ done:
+
+    if (ret != EOK) {
+      DEBUG(SSSDBG_CRIT_FAILURE, "Error encountered: %d.\n", ret);
+    }
+
+    talloc_free(tmp_ctx);
+    return ret;
+}
 
 /*
  * This cse-specific function (GP_EXT_GUID_SECURITY) opens an SMB connection,
  * retrieves the data referenced by the input smb_uri, and then closes the SMB
- * connection. The data is then parsed and the results are used to populate the
- * output parameters with the list of allowed_sids and denied_sids
+ * connection. The data is then written to a file in the GPO_CACHE directory,
+ * to be read by the backend.
  */
 static errno_t
 process_security_settings_cse(TALLOC_CTX *mem_ctx,
                               const char *smb_uri,
-                              char ***_allowed_sids,
-                              int *_allowed_size,
-                              char ***_denied_sids,
-                              int *_denied_size)
+                              const char *unix_path)
 {
     SMBCCTX *context;
     int ret = 0;
     uint8_t *buf = NULL;
-    int bytesread = 0;
-    char **allowed_sids;
-    char **denied_sids;
-    int allowed_size = 0;
-    int denied_size = 0;
+    int buflen = 0;
     TALLOC_CTX *tmp_ctx = NULL;
 
     tmp_ctx = talloc_new(NULL);
@@ -400,6 +326,7 @@ process_security_settings_cse(TALLOC_CTX *mem_ctx,
     }
 
     DEBUG(SSSDBG_TRACE_ALL, "%s\n", smb_uri);
+    DEBUG(SSSDBG_TRACE_ALL, "%s\n", unix_path);
 
     context = smbc_new_context();
     if (context == NULL) {
@@ -429,39 +356,25 @@ process_security_settings_cse(TALLOC_CTX *mem_ctx,
     }
 
     buf = talloc_array(tmp_ctx, uint8_t, SMB_BUFFER_SIZE);
-    bytesread = smbc_read(remotehandle, buf, SMB_BUFFER_SIZE);
-    if(bytesread < 0) {
+    buflen = smbc_read(remotehandle, buf, SMB_BUFFER_SIZE);
+    if(buflen < 0) {
         DEBUG(SSSDBG_CRIT_FAILURE, "smbc_read failed\n");
         ret = EPIPE;
         goto done;
     }
 
-    DEBUG(SSSDBG_CRIT_FAILURE, "bytesread: %d\n", bytesread);
+    DEBUG(SSSDBG_CRIT_FAILURE, "buflen: %d\n", buflen);
 
     smbc_close(remotehandle);
 
-    ret = ad_gpo_parse_security_cse_buffer(tmp_ctx,
-                                           buf,
-                                           bytesread,
-                                           &allowed_sids,
-                                           &allowed_size,
-                                           &denied_sids,
-                                           &denied_size);
-
+    ret = store_bytes_in_gpo_cache(unix_path, buf, buflen);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE,
-              "ad_gpo_parse_security_cse_buffer failed [%d][%s]\n",
+              "store_bytes_in_gpo_cache failed [%d][%s]\n",
               ret, strerror(ret));
         goto done;
     }
 
-    /* TBD: allowed/denied_sids/size should be stored in cache */
-
-    *_allowed_sids = talloc_steal(mem_ctx, allowed_sids);
-    *_allowed_size = allowed_size;
-    *_denied_sids = talloc_steal(mem_ctx, denied_sids);
-    *_denied_size = denied_size;
-
  done:
     smbc_free_context(context, 0);
     talloc_free(tmp_ctx);
@@ -482,11 +395,6 @@ main(int argc, const char *argv[])
     struct input_buffer *ibuf = NULL;
     struct response *resp = NULL;
     size_t written;
-    char **allowed_sids;
-    int allowed_size;
-    char **denied_sids;
-    int denied_size;
-    int j;
 
     struct poptOption long_options[] = {
         POPT_AUTOHELP
@@ -577,30 +485,14 @@ main(int argc, const char *argv[])
 
     result = process_security_settings_cse(main_ctx,
                                            ibuf->smb_uri,
-                                           &allowed_sids,
-                                           &allowed_size,
-                                           &denied_sids,
-                                           &denied_size);
+                                           ibuf->unix_path);
     if (result != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE,
               "process_security_settings_cse failed.[%d][%s].\n",
-              ret, strerror(ret));
-        goto fail;
+              result, strerror(result));
     }
 
-    DEBUG(SSSDBG_CRIT_FAILURE, "allowed_size = %d\n", allowed_size);
-    for (j= 0; j < allowed_size; j++) {
-        DEBUG(SSSDBG_CRIT_FAILURE, "allowed_sids[%d] = %s\n", j,
-              allowed_sids[j]);
-    }
-
-    DEBUG(SSSDBG_CRIT_FAILURE, "denied_size = %d\n", denied_size);
-    for (j= 0; j < denied_size; j++) {
-        DEBUG(SSSDBG_CRIT_FAILURE, " denied_sids[%d] = %s\n", j,
-              denied_sids[j]);
-    }
-
-    ret = prepare_response(main_ctx, result, allowed_size, allowed_sids, denied_size, denied_sids, &resp);
+    ret = prepare_response(main_ctx, result, &resp);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE, "prepare_response failed. [%d][%s].\n",
                     ret, strerror(ret));
@@ -608,7 +500,6 @@ main(int argc, const char *argv[])
     }
 
     errno = 0;
-    DEBUG(SSSDBG_TRACE_FUNC, "resp->size: %zu\n", resp->size);
 
     written = sss_atomic_write_s(STDOUT_FILENO, resp->buf, resp->size);
     if (written == -1) {
-- 
1.8.5.3

