From 02631abee74acab38f8b5f856b4d2ad7628bf2ff Mon Sep 17 00:00:00 2001
From: Yassir Elley <yelley@redhat.com>
Date: Fri, 30 May 2014 08:36:25 -0400
Subject: [PATCH] AD-GPO: Add support for gpo permissive mode

---
 src/providers/ad/ad_gpo.c | 20 ++++++++++++++++++--
 src/util/sss_log.c        | 19 ++++++++++++++-----
 src/util/util.h           |  1 +
 3 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index 519c0dbec4d85e7f6e41db672ae0f2c2f720d81b..a677133e38aac541aaf4197ee914d67f8b42e5c6 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -34,6 +34,7 @@
 #include <libsmbclient.h>
 #include <ini_configobj.h>
 #include <ini_config.h>
+#include <syslog.h>
 #include "util/util.h"
 #include "util/strtonum.h"
 #include "providers/data_provider.h"
@@ -728,6 +729,7 @@ check_rights(char **privilege_sids,
  */
 static errno_t
 ad_gpo_access_check(TALLOC_CTX *mem_ctx,
+                    enum gpo_access_control_mode gpo_mode,
                     const char *user,
                     struct sss_domain_info *domain,
                     char **allowed_sids,
@@ -790,7 +792,19 @@ ad_gpo_access_check(TALLOC_CTX *mem_ctx,
     if (access_granted && !access_denied) {
         return EOK;
     } else {
-        return EACCES;
+        switch (gpo_mode) {
+        case GPO_ACCESS_CONTROL_ENFORCING:
+            return EACCES;
+        case GPO_ACCESS_CONTROL_PERMISSIVE:
+            DEBUG(SSSDBG_TRACE_FUNC, "access denied: permissive mode\n");
+            sss_log_ext(SSS_LOG_WARNING, LOG_AUTHPRIV, "Warning: user would " \
+                        "have been denied GPO-based logon access if the " \
+                        "ad_gpo_access_control option were set to enforcing " \
+                        "mode.");
+            return EOK;
+        default:
+            return EINVAL;
+        }
     }
 
  done:
@@ -814,6 +828,7 @@ struct ad_gpo_access_state {
     int timeout;
     struct sss_domain_info *domain;
     const char *user;
+    enum gpo_access_control_mode gpo_mode;
     const char *ad_hostname;
     const char *target_dn;
     struct gp_gpo **dacl_filtered_gpos;
@@ -858,6 +873,7 @@ ad_gpo_access_send(TALLOC_CTX *mem_ctx,
     state->ev = ev;
     state->user = user;
     state->ldb_ctx = sysdb_ctx_get_ldb(domain->sysdb);
+    state->gpo_mode = ctx->gpo_access_control_mode;
     state->ad_hostname = dp_opt_get_string(ctx->ad_options, AD_HOSTNAME);
     state->opts = ctx->sdap_access_ctx->id_ctx->opts;
     state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT);
@@ -1285,7 +1301,7 @@ ad_gpo_cse_done(struct tevent_req *subreq)
 
     /* TBD: allowed/denied_sids/size, should be retrieved from cache */
     ret = ad_gpo_access_check
-        (state, state->user, state->domain,
+        (state, state->gpo_mode, state->user, state->domain,
          allowed_sids, allowed_size, denied_sids, denied_size);
 
     if (ret == EOK) {
diff --git a/src/util/sss_log.c b/src/util/sss_log.c
index b6b922785b03f8d9673aebdeb33a83c3f6b14076..7a2dce6352ef63e08d15c2537ff2994acd1c4d98 100644
--- a/src/util/sss_log.c
+++ b/src/util/sss_log.c
@@ -57,11 +57,20 @@ static int sss_to_syslog(int priority)
     }
 }
 
-#ifdef WITH_JOURNALD
-
 void sss_log(int priority, const char *format, ...)
 {
     va_list ap;
+
+    va_start(ap, format);
+    sss_log_ext(priority, LOG_DAEMON, format, ap);
+    va_end(ap);
+}
+
+#ifdef WITH_JOURNALD
+
+void sss_log_ext(int priority, int facility, const char *format, ...)
+{
+    va_list ap;
     int syslog_priority;
     int ret;
     char *message;
@@ -85,7 +94,7 @@ void sss_log(int priority, const char *format, ...)
     sd_journal_send("MESSAGE=%s", message,
                     "SSSD_DOMAIN=%s", domain,
                     "PRIORITY=%i", syslog_priority,
-                    "SYSLOG_FACILITY=%i", LOG_FAC(LOG_DAEMON),
+                    "SYSLOG_FACILITY=%i", LOG_FAC(facility),
                     "SYSLOG_IDENTIFIER=%s", debug_prg_name,
                     NULL);
 
@@ -94,14 +103,14 @@ void sss_log(int priority, const char *format, ...)
 
 #else /* WITH_JOURNALD */
 
-void sss_log(int priority, const char *format, ...)
+void sss_log_ext(int priority, int facility, const char *format, ...)
 {
     va_list ap;
     int syslog_priority;
 
     syslog_priority = sss_to_syslog(priority);
 
-    openlog(debug_prg_name, 0, LOG_DAEMON);
+    openlog(debug_prg_name, 0, facility);
 
     va_start(ap, format);
     vsyslog(syslog_priority, format, ap);
diff --git a/src/util/util.h b/src/util/util.h
index 38d9fca4c30a3be46f5dccc28a8a061fa3190c2b..27fdd5ba3c42b28818cd15600039fbcf18c39a4c 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -217,6 +217,7 @@ void talloc_log_fn(const char *msg);
 #define SSS_LOG_DEBUG   7   /* debug-level messages */
 
 void sss_log(int priority, const char *format, ...) SSS_ATTRIBUTE_PRINTF(2, 3);
+void sss_log_ext(int priority, int facility, const char *format, ...) SSS_ATTRIBUTE_PRINTF(3, 4);
 
 /* from server.c */
 struct main_context {
-- 
1.8.5.3

