From 5509ced1f4082c9864f669ee19d727f15f57ecff Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh@redhat.com>
Date: Tue, 19 Apr 2016 11:58:35 -0400
Subject: [PATCH 3/3] CONFIG: Use default config when none provided

This patch makes SSSD possibly useful "out of the box" by allowing
packagers to provide a default config file located in $LIBDIR/sssd/conf
that will be copied by the monitor to /etc/sssd if no file already
exists in that location. This will make it possible to have SSSD set up
to have distribution-specific default configuration, such as enabling
the proxy provider to cache /etc/passwd (such as in the provided
example in this patch).
---
 Makefile.am                   | 12 +++++++++++-
 contrib/sssd.spec.in          |  3 +++
 src/confdb/confdb.h           |  1 +
 src/confdb/confdb_setup.c     | 40 ++++++++++++++++++++++++++++++++++++----
 src/examples/sssd-shadowutils |  6 ++++++
 src/examples/sssd.conf        | 17 +++++++++++++++++
 6 files changed, 74 insertions(+), 5 deletions(-)
 create mode 100644 src/examples/sssd-shadowutils
 create mode 100644 src/examples/sssd.conf

diff --git a/Makefile.am b/Makefile.am
index 85c1256684b96406cabcf4c0f10f25ce9c7aa82b..178ee2507649b3b0208a9135b48c3aaa9f6b7ec7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -31,10 +31,11 @@ if HAVE_DEBIAN
 DISTSETUPOPTS += --install-layout=deb
 endif
 
 sssdlibexecdir = $(libexecdir)/sssd
 sssdlibdir = $(libdir)/sssd
+sssddefaultconfdir = $(sssdlibdir)/conf
 ldblibdir = @ldblibdir@
 if BUILD_KRB5_LOCATOR_PLUGIN
 krb5plugindir = @krb5pluginpath@
 endif
 if BUILD_KRB5_LOCALAUTH_PLUGIN
@@ -75,10 +76,11 @@ gpocachepath = @gpocachepath@
 keytabdir = $(sss_statedir)/keytabs
 pkgconfigdir = $(libdir)/pkgconfig
 krb5rcachedir = @krb5rcachedir@
 sudolibdir = @sudolibpath@
 polkitdir = @polkitdir@
+pamconfdir = $(sysconfdir)/pam.d
 
 UNICODE_LIBS=@UNICODE_LIBS@
 
 MKDIR_P = @MKDIR_P@
 INSTALL = @INSTALL@
@@ -430,10 +432,11 @@ AM_CPPFLAGS = \
     -DSSS_STATEDIR=\"$(sss_statedir)\" \
     -DSYSCONFDIR=\"$(sysconfdir)\" \
     -DSHLIBEXT=\"$(SHLIBEXT)\" \
     -DSSSD_LIBEXEC_PATH=\"$(sssdlibexecdir)\" \
     -DSSSD_CONF_DIR=\"$(sssdconfdir)\" \
+    -DSSSD_DEFAULT_CONF_DIR=\"$(sssddefaultconfdir)\" \
     -DSSS_NSS_MCACHE_DIR=\"$(mcpath)\" \
     -DSSS_NSS_SOCKET_NAME=\"$(pipepath)/nss\" \
     -DSSS_PAM_SOCKET_NAME=\"$(pipepath)/pam\" \
     -DSSS_PAC_SOCKET_NAME=\"$(pipepath)/pac\" \
     -DSSS_PAM_PRIV_SOCKET_NAME=\"$(pipepath)/private/pam\" \
@@ -1100,12 +1103,12 @@ BUILT_SOURCES = $(CODEGEN_CODE)
 ####################
 sssd_SOURCES = \
     src/monitor/monitor.c \
     src/monitor/monitor_netlink.c \
     src/confdb/confdb_setup.c \
-    src/util/nscd.c \
     src/monitor/monitor_iface_generated.c \
+    $(SSSD_TOOLS_OBJ) \
     $(NULL)
 sssd_LDADD = \
     $(SSSD_LIBS) \
     $(INOTIFY_LIBS) \
     $(LIBNL_LIBS) \
@@ -1264,10 +1267,16 @@ dist_noinst_DATA += \
     src/providers/sssd_be.exports \
     src/sss_client/COPYING \
     src/sss_client/COPYING.LESSER \
     src/m4
 
+dist_sssddefaultconf_DATA = \
+    src/examples/sssd.conf
+
+dist_pamconf_DATA = \
+    src/examples/sssd-shadowutils
+
 ######################
 # Command-line Tools #
 ######################
 sss_useradd_SOURCES = \
     src/tools/sss_useradd.c \
@@ -3547,10 +3556,11 @@ SSSD_USER_DIRS = \
     $(DESTDIR)$(pipepath)/private \
     $(DESTDIR)$(pubconfpath) \
     $(DESTDIR)$(pubconfpath)/krb5.include.d \
     $(DESTDIR)$(gpocachepath) \
     $(DESTDIR)$(sssdconfdir) \
+    $(DESTDIR)$(sssddefaultconfdir) \
     $(DESTDIR)$(logpath) \
     $(NULL)
 
 installsssddirs::
 	$(MKDIR_P) \
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index 2ba6a4d4c919a0697b18c4293f5e33e12b996cac..355b9510994b2f5ea470febca670d8982ad4bfce 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -764,10 +764,13 @@ done
 %dir %{_sysconfdir}/logrotate.d
 %config(noreplace) %{_sysconfdir}/logrotate.d/sssd
 %dir %{_sysconfdir}/rwtab.d
 %config(noreplace) %{_sysconfdir}/rwtab.d/sssd
 %dir %{_datadir}/sssd
+%{_sysconfdir}/pam.d/sssd-shadowutils
+%{_libdir}/%{name}/conf/sssd.conf
+
 %{_datadir}/sssd/sssd.api.conf
 %{_datadir}/sssd/sssd.api.d
 %{_mandir}/man1/sss_ssh_authorizedkeys.1*
 %{_mandir}/man1/sss_ssh_knownhostsproxy.1*
 %{_mandir}/man5/sssd.conf.5*
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index b90ced2bb3c7ded76950ce2b16586c995cda798d..a9b1c4362b5c0c6b158830b1bf2ef68db09d8d06 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -38,10 +38,11 @@
  * @{
  */
 
 #define CONFDB_DEFAULT_CFG_FILE_VER 2
 #define CONFDB_FILE "config.ldb"
+#define SSSD_DEFAULT_CONFIG_FILE SSSD_DEFAULT_CONF_DIR"/sssd.conf"
 #define SSSD_CONFIG_FILE SSSD_CONF_DIR"/sssd.conf"
 #define SSSD_MIN_ID 1
 #define SSSD_LOCAL_MINID 1000
 #define CONFDB_DEFAULT_SHELL_FALLBACK "/bin/sh"
 
diff --git a/src/confdb/confdb_setup.c b/src/confdb/confdb_setup.c
index 694a7f0161304f3c7ac94bb9307181f56ca25f05..dfdcae56697123c414968cfaaabe3e1cd68ca21f 100644
--- a/src/confdb/confdb_setup.c
+++ b/src/confdb/confdb_setup.c
@@ -19,16 +19,18 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "config.h"
 #include <sys/stat.h>
+#include <unistd.h>
 #include "util/util.h"
 #include "db/sysdb.h"
 #include "confdb.h"
 #include "confdb_private.h"
 #include "confdb_setup.h"
 #include "util/sss_ini.h"
+#include "tools/tools_util.h"
 
 
 int confdb_test(struct confdb_ctx *cdb)
 {
     char **values;
@@ -157,15 +159,45 @@ int confdb_init_db(const char *config_file, struct confdb_ctx *cdb)
     ret = sss_ini_config_file_open(init_data, config_file);
     if (ret != EOK) {
         DEBUG(SSSDBG_TRACE_FUNC,
               "sss_ini_config_file_open failed: %s [%d]\n", strerror(ret),
                ret);
-        if (ret == ENOENT) {
-            /* sss specific error denoting missing configuration file */
-            ret = ERR_MISSING_CONF;
+        if (ret != ENOENT) {
+            /* Anything other than ENOENT is unrecoverable */
+            goto done;
+        } else {
+            /* Copy the default configuration file to the standard location
+             * and then retry
+             */
+             ret = copy_file_secure(SSSD_DEFAULT_CONFIG_FILE,
+                                    SSSD_CONFIG_FILE,
+                                    0600,
+                                    getuid(),
+                                    getgid(),
+                                    false);
+             if (ret != EOK) {
+                 DEBUG(SSSDBG_FATAL_FAILURE,
+                       "Could not copy default configuration: %s",
+                       sss_strerror(ret));
+                 /* sss specific error denoting missing configuration file */
+                 ret = ERR_MISSING_CONF;
+                 goto done;
+             }
+
+             /* Try again */
+             ret = sss_ini_config_file_open(init_data, config_file);
+            if (ret != EOK) {
+                DEBUG(SSSDBG_TRACE_FUNC,
+                      "sss_ini_config_file_open(default) failed: %s [%d]\n",
+                      strerror(ret), ret);
+                if (ret == ENOENT) {
+                    /* sss specific error denoting missing configuration file */
+                    ret = ERR_MISSING_CONF;
+                }
+                goto done;
+            }
         }
-        goto done;
     }
 
     ret = sss_ini_config_access_check(init_data);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE,
diff --git a/src/examples/sssd-shadowutils b/src/examples/sssd-shadowutils
new file mode 100644
index 0000000000000000000000000000000000000000..626c7d075dfbf97dd91e259f94c6061689c83e9e
--- /dev/null
+++ b/src/examples/sssd-shadowutils
@@ -0,0 +1,6 @@
+#%PAM-1.0
+auth        [success=done ignore=ignore default=die] pam_unix.so nullok try_first_pass
+auth        required      pam_deny.so
+
+account     required      pam_unix.so
+account     required      pam_permit.so
diff --git a/src/examples/sssd.conf b/src/examples/sssd.conf
new file mode 100644
index 0000000000000000000000000000000000000000..a851dbb7ecd5c3220fbd6a946a6c7be2822dbd27
--- /dev/null
+++ b/src/examples/sssd.conf
@@ -0,0 +1,17 @@
+[sssd]
+config_file_version = 2
+services = nss, pam
+domains = shadowutils
+
+[nss]
+
+[pam]
+
+[domain/shadowutils]
+id_provider = proxy
+proxy_lib_name = files
+
+auth_provider = proxy
+proxy_pam_target = sssd-shadowutils
+
+proxy_fast_alias = True
-- 
2.7.3

