URL: https://github.com/SSSD/sssd/pull/485
Author: justin-stephenson
 Title: #485:  Support alternative sources for the files provider 
Action: opened

PR body:
"""
This PR allows the configuration of different(one or multiple) passwd and group 
files to be managed by the files provider with new options `alt_passwd_files` 
and `alt_group_files`.

Primary testing steps include ensuring that alternate passwd and group entries 
are consistently accessible with 'getent -s sss' commands, and testing that 
inotify watches dynamically detect changes to any alternate source files.

Ticket: https://pagure.io/SSSD/sssd/issue/3402
"""

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/485/head:pr485
git checkout pr485
From 8f0793071b3b349efb80e0f98423b13cb14fcc54 Mon Sep 17 00:00:00 2001
From: Justin Stephenson <jstep...@redhat.com>
Date: Fri, 14 Jul 2017 16:08:37 -0400
Subject: [PATCH 1/2] CONFDB: Add alternate files options

Add alternate passwd and group files options to the files provider.
These options allow an administrator to specify which file or multiple
files to be read and monitored by the files provider.
---
 Makefile.am                               |  3 ++-
 src/confdb/confdb.h                       |  4 ++++
 src/config/SSSDConfig/__init__.py.in      |  6 +++++-
 src/config/cfg_rules.ini                  |  4 ++++
 src/config/etc/sssd.api.d/sssd-files.conf |  3 +++
 src/man/sssd-files.5.xml                  | 36 +++++++++++++++++++++++++++++--
 src/providers/files/files_init.c          |  1 +
 7 files changed, 53 insertions(+), 4 deletions(-)
 create mode 100644 src/config/etc/sssd.api.d/sssd-files.conf

diff --git a/Makefile.am b/Makefile.am
index 5917bd904..e7b1d18e2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4532,7 +4532,8 @@ dist_sssdapiplugin_DATA = \
     src/config/etc/sssd.api.d/sssd-ldap.conf \
     src/config/etc/sssd.api.d/sssd-local.conf \
     src/config/etc/sssd.api.d/sssd-proxy.conf \
-    src/config/etc/sssd.api.d/sssd-simple.conf
+    src/config/etc/sssd.api.d/sssd-simple.conf \
+    src/config/etc/sssd.api.d/sssd-files.conf
 
 edit_cmd = $(SED) \
         -e 's|@sbindir[@]|$(sbindir)|g' \
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index 147194962..e20bfb301 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -242,6 +242,10 @@
 #define CONFDB_PROXY_FAST_ALIAS "proxy_fast_alias"
 #define CONFDB_PROXY_MAX_CHILDREN "proxy_max_children"
 
+/* Files Provider */
+#define CONFDB_FILES_ALT_PASSWD "alt_passwd_files"
+#define CONFDB_FILES_ALT_GROUP "alt_group_files"
+
 /* Secrets Service */
 #define CONFDB_SEC_CONF_ENTRY "config/secrets"
 #define CONFDB_SEC_CONTAINERS_NEST_LEVEL "containers_nest_level"
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index d2bb709d6..ec7d53a16 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -473,7 +473,11 @@ option_strings = {
     'proxy_fast_alias' : _('Whether to look up canonical group name from cache if possible'),
 
     # [provider/proxy/auth]
-    'proxy_pam_target' : _('PAM stack to use')
+    'proxy_pam_target' : _('PAM stack to use'),
+
+    # [provider/files]
+    'alt_passwd_files' : _('Path of alternate passwd file.'),
+    'alt_group_files' : _('Path of alternate group file.')
 }
 
 def striplist(l):
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
index 4e70bf7b6..84d5324e2 100644
--- a/src/config/cfg_rules.ini
+++ b/src/config/cfg_rules.ini
@@ -404,6 +404,10 @@ option = dyndns_force_tcp
 option = dyndns_auth
 option = dyndns_server
 
+# files provider specific options
+option = alt_passwd_files
+option = alt_group_files
+
 # local provider specific options
 option = create_homedir
 option = remove_homedir
diff --git a/src/config/etc/sssd.api.d/sssd-files.conf b/src/config/etc/sssd.api.d/sssd-files.conf
new file mode 100644
index 000000000..f4e0c3112
--- /dev/null
+++ b/src/config/etc/sssd.api.d/sssd-files.conf
@@ -0,0 +1,3 @@
+[provider/files]
+alt_passwd_files = str, None, false
+alt_group_files = str, None, false
diff --git a/src/man/sssd-files.5.xml b/src/man/sssd-files.5.xml
index d44fffc03..952cefc97 100644
--- a/src/man/sssd-files.5.xml
+++ b/src/man/sssd-files.5.xml
@@ -56,14 +56,46 @@
     <refsect1 id='configuration-options'>
         <title>CONFIGURATION OPTIONS</title>
         <para>
-            The files provider has no specific options of its own, however,
-            generic SSSD domain options can be set where applicable.
+            In addition to the options listed below, generic SSSD domain options
+            can be set where applicable.
             Refer to the section <quote>DOMAIN SECTIONS</quote> of the
             <citerefentry>
                 <refentrytitle>sssd.conf</refentrytitle>
                 <manvolnum>5</manvolnum>
             </citerefentry> manual page for details on the configuration
             of an SSSD domain.
+            <variablelist>
+                <varlistentry>
+                    <term>alt_passwd_files (string)</term>
+                    <listitem>
+                        <para>
+                            Comma-separated list of one or multiple password
+                            files to be read and enumerated by the files
+                            provider, inotify monitor watches will be set on
+                            each file to detect changes dynamically.
+                        </para>
+                        <para>
+                            Default: /etc/passwd
+                        </para>
+                    </listitem>
+                </varlistentry>
+
+                <varlistentry>
+                    <term>alt_group_files (string)</term>
+                    <listitem>
+                        <para>
+                            Comma-separated list of one or multiple group
+                            files to be read and enumerated by the files
+                            provider, inotify monitor watches will be set on
+                            each file to detect changes dynamically.
+                        </para>
+                        <para>
+                            Default: /etc/group
+                        </para>
+                    </listitem>
+                </varlistentry>
+
+            </variablelist>
         </para>
     </refsect1>
 
diff --git a/src/providers/files/files_init.c b/src/providers/files/files_init.c
index 8e5cd4cf9..b8a051c34 100644
--- a/src/providers/files/files_init.c
+++ b/src/providers/files/files_init.c
@@ -21,6 +21,7 @@
 
 #include "providers/data_provider/dp.h"
 #include "providers/files/files_private.h"
+#include "util/util.h"
 
 int sssm_files_init(TALLOC_CTX *mem_ctx,
                     struct be_ctx *be_ctx,

From ba1d6a05e7bce52db09c5980f2313d035e0350e6 Mon Sep 17 00:00:00 2001
From: Justin Stephenson <jstep...@redhat.com>
Date: Mon, 17 Jul 2017 15:01:36 -0400
Subject: [PATCH 2/2] FILES: Handle alternate sources

Setup watches on multiple or alternate passwd and group files for the
files provider

Resolves:
https://pagure.io/SSSD/sssd/issue/3402
---
 src/providers/files/files_init.c    | 183 ++++++++++++++++++++++++++++++++----
 src/providers/files/files_ops.c     | 146 +++++++++++++++++-----------
 src/providers/files/files_private.h |  13 ++-
 3 files changed, 267 insertions(+), 75 deletions(-)

diff --git a/src/providers/files/files_init.c b/src/providers/files/files_init.c
index b8a051c34..e9abbc267 100644
--- a/src/providers/files/files_init.c
+++ b/src/providers/files/files_init.c
@@ -23,6 +23,156 @@
 #include "providers/files/files_private.h"
 #include "util/util.h"
 
+#define DEFAULT_PASSWD_FILE "/etc/passwd"
+#define DEFAULT_GROUP_FILE "/etc/group"
+
+
+static errno_t files_init_alt_files(TALLOC_CTX *mem_ctx,
+                                    struct be_ctx *be_ctx,
+                                    const char ***_passwd_files,
+                                    const char ***_group_files,
+                                    int *_num_passwd_files,
+                                    int *_num_group_files)
+{
+    TALLOC_CTX *tmp_ctx = NULL;
+    char *alt_passwd_files;
+    char *alt_group_files;
+    char **passwd_list = NULL;
+    char **group_list = NULL;
+    int num_passwd_files = 0;
+    int num_group_files = 0;
+    const char **passwd_files = NULL;
+    const char **group_files = NULL;
+    int i;
+    errno_t ret;
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    ret = confdb_get_string(be_ctx->cdb, tmp_ctx, be_ctx->conf_path,
+                            CONFDB_FILES_ALT_PASSWD, NULL, &alt_passwd_files);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to retrieve confdb alt passwd!\n");
+        goto done;
+    }
+
+    ret = confdb_get_string(be_ctx->cdb, tmp_ctx, be_ctx->conf_path,
+                            CONFDB_FILES_ALT_GROUP, NULL, &alt_group_files);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to retrieve confdb alt group!\n");
+        goto done;
+    }
+
+    /* Default to /etc/passwd standard */
+    if (alt_passwd_files == NULL) {
+        num_passwd_files = 1;
+
+        passwd_files = talloc_zero_array(tmp_ctx, const char *, 2);
+        if (passwd_files == NULL) {
+            DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n");
+            ret = ENOMEM;
+            goto done;
+        }
+
+        DEBUG(SSSDBG_TRACE_FUNC,
+              "Using default passwd file: [%s].\n", DEFAULT_PASSWD_FILE);
+        passwd_files[0] = talloc_strdup(passwd_files, DEFAULT_PASSWD_FILE);
+        if (passwd_files[0] == NULL) {
+            ret = ENOMEM;
+            goto done;
+        }
+    /* Retrieve list of passwd files */
+    } else {
+        ret = split_on_separator(tmp_ctx, alt_passwd_files, ',', true, true,
+                                 &passwd_list, &num_passwd_files);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  "Failed to parse alternate passwd list!\n");
+            goto done;
+        }
+
+        passwd_files = talloc_zero_array(tmp_ctx, const char *,
+                                         num_passwd_files + 1);
+        if (passwd_files == NULL) {
+            DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n");
+            ret = ENOMEM;
+            goto done;
+        }
+
+        for (i = 0; i < num_passwd_files; i++) {
+            DEBUG(SSSDBG_TRACE_FUNC,
+                  "Using passwd file: [%s].\n", passwd_list[i]);
+
+            passwd_files[i] = talloc_strdup(passwd_files, passwd_list[i]);
+                if (passwd_files[i] == NULL) {
+                    ret = ENOMEM;
+                    goto done;
+                }
+        }
+    }
+
+    /* Default to /etc/group standard */
+    if (alt_group_files == NULL) {
+        num_group_files = 1;
+
+        group_files = talloc_zero_array(tmp_ctx, const char *, 2);
+        if (group_files == NULL) {
+            DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n");
+            ret = ENOMEM;
+            goto done;
+        }
+
+        DEBUG(SSSDBG_TRACE_FUNC,
+              "Using default group file: [%s].\n", DEFAULT_GROUP_FILE);
+        group_files[0] = talloc_strdup(group_files, DEFAULT_GROUP_FILE);
+        if (group_files[0] == NULL) {
+            ret = ENOMEM;
+            goto done;
+        }
+    /* Retrieve list of group files */
+    } else {
+        ret = split_on_separator(tmp_ctx, alt_group_files, ',', true, true,
+                                 &group_list, &num_group_files);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  "Failed to parse alternate group files!\n");
+            goto done;
+        }
+
+        group_files = talloc_zero_array(tmp_ctx, const char *,
+                                         num_group_files + 1);
+        if (group_files == NULL) {
+            DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n");
+            ret = ENOMEM;
+            goto done;
+        }
+
+        for (i = 0; i < num_group_files; i++) {
+            DEBUG(SSSDBG_TRACE_FUNC,
+                  "Using group file: [%s].\n", group_list[i]);
+            group_files[i] = talloc_strdup(group_files, group_list[i]);
+                if (group_files[i] == NULL) {
+                    ret = ENOMEM;
+                    goto done;
+                }
+        }
+    }
+
+    *_passwd_files = talloc_steal(mem_ctx, passwd_files);
+    *_group_files = talloc_steal(mem_ctx, group_files);
+    *_num_passwd_files = num_passwd_files;
+    *_num_group_files = num_group_files;
+
+    ret = EOK;
+
+done:
+    talloc_free(tmp_ctx);
+    return ret;
+}
+
 int sssm_files_init(TALLOC_CTX *mem_ctx,
                     struct be_ctx *be_ctx,
                     struct data_provider *provider,
@@ -30,32 +180,33 @@ int sssm_files_init(TALLOC_CTX *mem_ctx,
                     void **_module_data)
 {
     struct files_id_ctx *ctx;
-    int ret;
-    const char *passwd_file = NULL;
-    const char *group_file = NULL;
-
-    /* So far this is mostly useful for tests */
-    passwd_file = getenv("SSS_FILES_PASSWD");
-    if (passwd_file == NULL) {
-        passwd_file = "/etc/passwd";
-    }
+    const char **passwd_files = NULL;
+    const char **group_files = NULL;
+    int num_passwd_files = 0;
+    int num_group_files = 0;
+    errno_t ret;
 
-    group_file = getenv("SSS_FILES_GROUP");
-    if (group_file == NULL) {
-        group_file = "/etc/group";
-    }
+    ret = files_init_alt_files(mem_ctx, be_ctx, &passwd_files,
+                               &group_files, &num_passwd_files,
+                               &num_group_files);
 
     ctx = talloc_zero(mem_ctx, struct files_id_ctx);
     if (ctx == NULL) {
         return ENOMEM;
     }
+
     ctx->be = be_ctx;
     ctx->domain = be_ctx->domain;
-    ctx->passwd_file = passwd_file;
-    ctx->group_file = group_file;
+    ctx->passwd_files = passwd_files;
+    ctx->group_files = group_files;
+    ctx->num_passwd_files = num_passwd_files;
+    ctx->num_group_files = num_group_files;
 
     ctx->fctx = sf_init(ctx, be_ctx->ev,
-                        ctx->passwd_file, ctx->group_file,
+                        ctx->passwd_files,
+                        ctx->group_files,
+                        ctx->num_passwd_files,
+                        ctx->num_group_files,
                         ctx);
     if (ctx->fctx == NULL) {
         ret = ENOMEM;
diff --git a/src/providers/files/files_ops.c b/src/providers/files/files_ops.c
index b59a94252..b7addd647 100644
--- a/src/providers/files/files_ops.c
+++ b/src/providers/files/files_ops.c
@@ -44,6 +44,7 @@ struct files_ctx {
 
 static errno_t enum_files_users(TALLOC_CTX *mem_ctx,
                                 struct files_id_ctx *id_ctx,
+                                const char *passwd_file,
                                 struct passwd ***_users)
 {
     errno_t ret, close_ret;
@@ -53,12 +54,12 @@ static errno_t enum_files_users(TALLOC_CTX *mem_ctx,
     FILE *pwd_handle = NULL;
     size_t n_users = 0;
 
-    pwd_handle = fopen(id_ctx->passwd_file, "r");
+    pwd_handle = fopen(passwd_file, "r");
     if (pwd_handle == NULL) {
         ret = errno;
         DEBUG(SSSDBG_CRIT_FAILURE,
               "Cannot open passwd file %s [%d]\n",
-              id_ctx->passwd_file, ret);
+              passwd_file, ret);
         goto done;
     }
 
@@ -133,7 +134,7 @@ static errno_t enum_files_users(TALLOC_CTX *mem_ctx,
             close_ret = errno;
             DEBUG(SSSDBG_CRIT_FAILURE,
                   "Cannot close passwd file %s [%d]\n",
-                  id_ctx->passwd_file, close_ret);
+                  passwd_file, close_ret);
         }
     }
     return ret;
@@ -141,6 +142,7 @@ static errno_t enum_files_users(TALLOC_CTX *mem_ctx,
 
 static errno_t enum_files_groups(TALLOC_CTX *mem_ctx,
                                  struct files_id_ctx *id_ctx,
+                                 const char *group_file,
                                  struct group ***_groups)
 {
     errno_t ret, close_ret;
@@ -150,12 +152,12 @@ static errno_t enum_files_groups(TALLOC_CTX *mem_ctx,
     size_t n_groups = 0;
     FILE *grp_handle = NULL;
 
-    grp_handle = fopen(id_ctx->group_file, "r");
+    grp_handle = fopen(group_file, "r");
     if (grp_handle == NULL) {
         ret = errno;
         DEBUG(SSSDBG_CRIT_FAILURE,
               "Cannot open group file %s [%d]\n",
-              id_ctx->group_file, ret);
+              group_file, ret);
         goto done;
     }
 
@@ -237,7 +239,7 @@ static errno_t enum_files_groups(TALLOC_CTX *mem_ctx,
             close_ret = errno;
             DEBUG(SSSDBG_CRIT_FAILURE,
                   "Cannot close group file %s [%d]\n",
-                  id_ctx->group_file, close_ret);
+                  group_file, close_ret);
         }
     }
     return ret;
@@ -446,9 +448,11 @@ static errno_t refresh_override_attrs(struct files_id_ctx *id_ctx,
     return ret;
 }
 
-static errno_t sf_enum_groups(struct files_id_ctx *id_ctx);
+static errno_t sf_enum_groups(struct files_id_ctx *id_ctx,
+                              const char *group_file);
 
-errno_t sf_enum_users(struct files_id_ctx *id_ctx)
+errno_t sf_enum_users(struct files_id_ctx *id_ctx,
+                      const char *passwd_file)
 {
     errno_t ret;
     errno_t tret;
@@ -461,7 +465,8 @@ errno_t sf_enum_users(struct files_id_ctx *id_ctx)
         return ENOMEM;
     }
 
-    ret = enum_files_users(tmp_ctx, id_ctx, &users);
+    ret = enum_files_users(tmp_ctx, id_ctx, passwd_file,
+                           &users);
     if (ret != EOK) {
         goto done;
     }
@@ -472,13 +477,6 @@ errno_t sf_enum_users(struct files_id_ctx *id_ctx)
     }
     in_transaction = true;
 
-    /* remove previous cache contents */
-    /* FIXME - this is terribly inefficient */
-    ret = delete_all_users(id_ctx->domain);
-    if (ret != EOK) {
-        goto done;
-    }
-
     for (size_t i = 0; users[i]; i++) {
         ret = save_file_user(id_ctx, users[i]);
         if (ret != EOK) {
@@ -506,11 +504,18 @@ errno_t sf_enum_users(struct files_id_ctx *id_ctx)
      * only then edits passwd and adds the user. The reverse is not needed,
      * because member/memberof links are established when groups are saved.
      */
-    ret = sf_enum_groups(id_ctx);
+/*  BROKEN: This causes a negative cache lookup failure
+
+    getent passwd foo # see that there is no user foo
+    useradd foo       # OK, let's add it then
+    getent passwd foo # still no user returned until the negative cache expires
+
+    ret = sf_enum_groups(id_ctx, id_ctx->group_files[i]);
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE, "Cannot refresh groups\n");
         goto done;
     }
+*/
 
     ret = EOK;
 done:
@@ -698,7 +703,8 @@ static errno_t save_file_group(struct files_id_ctx *id_ctx,
     return ret;
 }
 
-static errno_t sf_enum_groups(struct files_id_ctx *id_ctx)
+static errno_t sf_enum_groups(struct files_id_ctx *id_ctx,
+                              const char *group_file)
 {
     errno_t ret;
     errno_t tret;
@@ -712,7 +718,8 @@ static errno_t sf_enum_groups(struct files_id_ctx *id_ctx)
         return ENOMEM;
     }
 
-    ret = enum_files_groups(tmp_ctx, id_ctx, &groups);
+    ret = enum_files_groups(tmp_ctx, id_ctx, group_file,
+                            &groups);
     if (ret != EOK) {
         goto done;
     }
@@ -728,12 +735,6 @@ static errno_t sf_enum_groups(struct files_id_ctx *id_ctx)
     }
     in_transaction = true;
 
-    /* remove previous cache contents */
-    ret = delete_all_groups(id_ctx->domain);
-    if (ret != EOK) {
-        goto done;
-    }
-
     for (size_t i = 0; groups[i]; i++) {
         ret = save_file_group(id_ctx, groups[i], cached_users);
         if (ret != EOK) {
@@ -791,13 +792,6 @@ static int sf_passwd_cb(const char *filename, uint32_t flags, void *pvt)
 
     DEBUG(SSSDBG_TRACE_FUNC, "passwd notification\n");
 
-    if (strcmp(filename, id_ctx->passwd_file) != 0) {
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              "Wrong file, expected %s, got %s\n",
-              id_ctx->passwd_file, filename);
-        return EINVAL;
-    }
-
     id_ctx->updating_passwd = true;
     dp_sbus_domain_inconsistent(id_ctx->be->provider, id_ctx->domain);
 
@@ -805,7 +799,16 @@ static int sf_passwd_cb(const char *filename, uint32_t flags, void *pvt)
     dp_sbus_reset_users_memcache(id_ctx->be->provider);
     dp_sbus_reset_initgr_memcache(id_ctx->be->provider);
 
-    ret = sf_enum_users(id_ctx);
+    ret = delete_all_users(id_ctx->domain);
+    if (ret != EOK) {
+        return ret;
+    }
+
+    /* All users were deleted, therefore we need to enumerate each file again */
+    for (size_t i = 0; i < id_ctx->num_passwd_files; i++)
+    {
+        ret = sf_enum_users(id_ctx, id_ctx->passwd_files[i]);
+    }
 
     id_ctx->updating_passwd = false;
     sf_cb_done(id_ctx);
@@ -825,13 +828,6 @@ static int sf_group_cb(const char *filename, uint32_t flags, void *pvt)
 
     DEBUG(SSSDBG_TRACE_FUNC, "group notification\n");
 
-    if (strcmp(filename, id_ctx->group_file) != 0) {
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              "Wrong file, expected %s, got %s\n",
-              id_ctx->group_file, filename);
-        return EINVAL;
-    }
-
     id_ctx->updating_groups = true;
     dp_sbus_domain_inconsistent(id_ctx->be->provider, id_ctx->domain);
 
@@ -839,7 +835,16 @@ static int sf_group_cb(const char *filename, uint32_t flags, void *pvt)
     dp_sbus_reset_groups_memcache(id_ctx->be->provider);
     dp_sbus_reset_initgr_memcache(id_ctx->be->provider);
 
-    ret = sf_enum_groups(id_ctx);
+    ret = delete_all_groups(id_ctx->domain);
+    if (ret != EOK) {
+        return ret;
+    }
+
+    /* All users were deleted, therefore we need to enumerate each file again */
+    for (size_t i = 0; i < id_ctx->num_group_files; i++)
+    {
+        ret = sf_enum_groups(id_ctx, id_ctx->group_files[i]);
+    }
 
     id_ctx->updating_groups = false;
     sf_cb_done(id_ctx);
@@ -853,20 +858,42 @@ static void startup_enum_files(struct tevent_context *ev,
 {
     struct files_id_ctx *id_ctx = talloc_get_type(pvt, struct files_id_ctx);
     errno_t ret;
+    int i;
 
     talloc_zfree(imm);
 
-    ret = sf_enum_users(id_ctx);
-    if (ret != EOK) {
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              "Enumerating users failed, data might be inconsistent!\n");
+    for (i = 0; i < id_ctx->num_passwd_files; i++) {
+        if (fopen(id_ctx->passwd_files[i], "r") == NULL) {
+            DEBUG(SSSDBG_MINOR_FAILURE,
+                  "Cannot open passwd file [%s]\n", id_ctx->passwd_files[i]);
+            continue;
+        }
+
+        DEBUG(SSSDBG_TRACE_FUNC,
+              "Startup enumeration of [%s]\n", id_ctx->passwd_files[i]);
+        ret = sf_enum_users(id_ctx, id_ctx->passwd_files[i]);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  "Enumerating users failed, data might be inconsistent!\n");
+        }
     }
 
-    ret = sf_enum_groups(id_ctx);
-    if (ret != EOK) {
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              "Enumerating groups failed, data might be inconsistent!\n");
+    for (i = 0; i < id_ctx->num_group_files; i++) {
+        if (fopen(id_ctx->group_files[i], "r") == NULL) {
+            DEBUG(SSSDBG_MINOR_FAILURE,
+                  "Cannot open group file [%s]\n", id_ctx->group_files[i]);
+            continue;
+        }
+
+        DEBUG(SSSDBG_TRACE_FUNC,
+              "Startup enumeration of [%s]\n", id_ctx->group_files[i]);
+        ret = sf_enum_groups(id_ctx, id_ctx->group_files[i]);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  "Enumerating groups failed, data might be inconsistent!\n");
+        }
     }
+
 }
 
 static struct snotify_ctx *sf_setup_watch(TALLOC_CTX *mem_ctx,
@@ -884,22 +911,31 @@ static struct snotify_ctx *sf_setup_watch(TALLOC_CTX *mem_ctx,
 
 struct files_ctx *sf_init(TALLOC_CTX *mem_ctx,
                           struct tevent_context *ev,
-                          const char *passwd_file,
-                          const char *group_file,
+                          const char **passwd_files,
+                          const char **group_files,
+                          int num_passwd_files,
+                          int num_group_files,
                           struct files_id_ctx *id_ctx)
 {
     struct files_ctx *fctx;
     struct tevent_immediate *imm;
+    int i;
 
     fctx = talloc(mem_ctx, struct files_ctx);
     if (fctx == NULL) {
         return NULL;
     }
 
-    fctx->pwd_watch = sf_setup_watch(fctx, ev, passwd_file,
-                                     sf_passwd_cb, id_ctx);
-    fctx->grp_watch = sf_setup_watch(fctx, ev, group_file,
-                                     sf_group_cb, id_ctx);
+    for (i = 0; i < num_passwd_files; i++) {
+        fctx->pwd_watch = sf_setup_watch(fctx, ev, passwd_files[i],
+                                         sf_passwd_cb, id_ctx);
+        }
+
+    for (i = 0; i < num_group_files; i++) {
+        fctx->grp_watch = sf_setup_watch(fctx, ev, group_files[i],
+                                         sf_group_cb, id_ctx);
+    }
+
     if (fctx->pwd_watch == NULL || fctx->grp_watch == NULL) {
         talloc_free(fctx);
         return NULL;
diff --git a/src/providers/files/files_private.h b/src/providers/files/files_private.h
index a7d195c90..7598c4442 100644
--- a/src/providers/files/files_private.h
+++ b/src/providers/files/files_private.h
@@ -39,8 +39,11 @@ struct files_id_ctx {
     struct sss_domain_info *domain;
     struct files_ctx *fctx;
 
-    const char *passwd_file;
-    const char *group_file;
+    const char **passwd_files;
+    const char **group_files;
+
+    int num_passwd_files;
+    int num_group_files;
 
     bool updating_passwd;
     bool updating_groups;
@@ -53,8 +56,10 @@ struct files_id_ctx {
 /* files_ops.c */
 struct files_ctx *sf_init(TALLOC_CTX *mem_ctx,
                           struct tevent_context *ev,
-                          const char *passwd_file,
-                          const char *group_file,
+                          const char **passwd_files,
+                          const char **group_files,
+                          int num_passwd_files,
+                          int num_group_files,
                           struct files_id_ctx *id_ctx);
 
 /* files_id.c */
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org

Reply via email to