diff --git a/include/nss_files.h b/include/nss_files.h
index adf934f3ea..852c64da99 100644
--- a/include/nss_files.h
+++ b/include/nss_files.h
@@ -26,7 +26,7 @@
 #endif

 /* Open PATH for reading, as a data source for nss_files.  */
-FILE *__nss_files_fopen (const char *path);
+FILE *__nss_files_fopen (const char *path, const char *fallback_path);
 libc_hidden_proto (__nss_files_fopen)

 /* Read a line from FP, storing it BUF.  Strip leading blanks and skip
@@ -89,7 +89,7 @@ enum nss_files_file
    null.  */
 enum nss_status __nss_files_data_open (struct nss_files_per_file_data **pdata,
                                        enum nss_files_file file,
-                                       const char *path,
+                                       const char *path, const char *fallback_path,
                                        int *errnop, int *herrnop);
 libc_hidden_proto (__nss_files_data_open)

@@ -101,7 +101,7 @@ libc_hidden_proto (__nss_files_data_put)
 /* Performs the set*ent operation for FILE.  PATH is the file to
    open.  */
 enum nss_status __nss_files_data_setent (enum nss_files_file file,
-                                           const char *path);
+                                         const char *path, const char *fallback_path);
 libc_hidden_proto (__nss_files_data_setent)

 /* Performs the end*ent operation for FILE.  */
diff --git a/nss/nss_compat/compat-grp.c b/nss/nss_compat/compat-grp.c
index ede7503de7..bacad5b583 100644
--- a/nss/nss_compat/compat-grp.c
+++ b/nss/nss_compat/compat-grp.c
@@ -108,7 +108,7 @@ internal_setgrent (ent_t *ent, int stayopen, int needent)

   if (ent->stream == NULL)
     {
-      ent->stream = __nss_files_fopen ("/etc/group");
+      ent->stream = __nss_files_fopen ("/etc/group", "/usr/share/group");

       if (ent->stream == NULL)
 	status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
diff --git a/nss/nss_compat/compat-initgroups.c b/nss/nss_compat/compat-initgroups.c
index 2598cfbc9a..37eb4b17af 100644
--- a/nss/nss_compat/compat-initgroups.c
+++ b/nss/nss_compat/compat-initgroups.c
@@ -122,7 +122,7 @@ internal_setgrent (ent_t *ent)
   else
     ent->blacklist.current = 0;

-  ent->stream = __nss_files_fopen ("/etc/group");
+  ent->stream = __nss_files_fopen ("/etc/group", "/usr/share/group");

   if (ent->stream == NULL)
     status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
diff --git a/nss/nss_compat/compat-pwd.c b/nss/nss_compat/compat-pwd.c
index 2f37e0f621..2a3b012c33 100644
--- a/nss/nss_compat/compat-pwd.c
+++ b/nss/nss_compat/compat-pwd.c
@@ -223,7 +223,7 @@ internal_setpwent (ent_t *ent, int stayopen, int needent)

   if (ent->stream == NULL)
     {
-      ent->stream = __nss_files_fopen ("/etc/passwd");
+      ent->stream = __nss_files_fopen ("/etc/passwd", "/usr/share/passwd");

       if (ent->stream == NULL)
 	status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
diff --git a/nss/nss_compat/compat-spwd.c b/nss/nss_compat/compat-spwd.c
index fac1e766cb..fc6984bcb4 100644
--- a/nss/nss_compat/compat-spwd.c
+++ b/nss/nss_compat/compat-spwd.c
@@ -178,7 +178,7 @@ internal_setspent (ent_t *ent, int stayopen, int needent)

   if (ent->stream == NULL)
     {
-      ent->stream = __nss_files_fopen ("/etc/shadow");
+      ent->stream = __nss_files_fopen ("/etc/shadow", "/usr/share/shadow");

       if (ent->stream == NULL)
 	status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
diff --git a/nss/nss_files/files-XXX.c b/nss/nss_files/files-XXX.c
index 558b2c364f..fa47dec277 100644
--- a/nss/nss_files/files-XXX.c
+++ b/nss/nss_files/files-XXX.c
@@ -39,7 +39,8 @@

 #define ENTNAME_r	CONCAT(ENTNAME,_r)

-#define DATAFILE	"/etc/" DATABASE
+#define DATAFILE	  "/etc/" DATABASE
+#define DATAFILE_FALLBACK "/usr/share/" DATABASE

 #ifdef NEED_H_ERRNO
 # include <netdb.h>
@@ -73,7 +74,7 @@ internal_setent (FILE **stream)

   if (*stream == NULL)
     {
-      *stream = __nss_files_fopen (DATAFILE);
+      *stream = __nss_files_fopen (DATAFILE, DATAFILE_FALLBACK);

       if (*stream == NULL)
 	status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
@@ -89,7 +90,7 @@ internal_setent (FILE **stream)
 enum nss_status
 CONCAT(_nss_files_set,ENTNAME) (int stayopen)
 {
-  return __nss_files_data_setent (CONCAT (nss_file_, ENTNAME), DATAFILE);
+  return __nss_files_data_setent (CONCAT (nss_file_, ENTNAME), DATAFILE, DATAFILE_FALLBACK);
 }
 libc_hidden_def (CONCAT (_nss_files_set,ENTNAME))

@@ -170,7 +171,7 @@ CONCAT(_nss_files_get,ENTNAME_r) (struct STRUCTURE *result, char *buffer,
   struct nss_files_per_file_data *data;
   enum nss_status status = __nss_files_data_open (&data,
 						  CONCAT (nss_file_, ENTNAME),
-						  DATAFILE,
+						  DATAFILE, DATAFILE_FALLBACK,
 						  errnop, H_ERRNO_ARG_OR_NULL);
   if (status != NSS_STATUS_SUCCESS)
     return status;
diff --git a/nss/nss_files/files-alias.c b/nss/nss_files/files-alias.c
index 14a59b4655..d0b1ce2a8e 100644
--- a/nss/nss_files/files-alias.c
+++ b/nss/nss_files/files-alias.c
@@ -42,7 +42,7 @@ internal_setent (FILE **stream)

   if (*stream == NULL)
     {
-      *stream = __nss_files_fopen ("/etc/aliases");
+      *stream = __nss_files_fopen ("/etc/aliases", "/usr/share/aliases");

       if (*stream == NULL)
 	status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
@@ -58,7 +58,7 @@ internal_setent (FILE **stream)
 enum nss_status
 _nss_files_setaliasent (void)
 {
-  return __nss_files_data_setent (nss_file_aliasent, "/etc/aliases");
+   return __nss_files_data_setent (nss_file_aliasent, "/etc/aliases", "/usr/share/aliases");
 }
 libc_hidden_def (_nss_files_setaliasent)

@@ -182,7 +182,7 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result,

 		      first_unused = cp;

-		      listfile = __nss_files_fopen (&cp[9]);
+		      listfile = __nss_files_fopen (&cp[9], NULL);
 		      /* If the file does not exist we simply ignore
 			 the statement.  */
 		      if (listfile != NULL
@@ -338,7 +338,8 @@ _nss_files_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen,

   struct nss_files_per_file_data *data;
   enum nss_status status = __nss_files_data_open (&data, nss_file_aliasent,
-						  "/etc/aliases", errnop, NULL);
+						  "/etc/aliases", "/usr/share/aliases",
+                                                  errnop, NULL);
   if (status != NSS_STATUS_SUCCESS)
     return status;

diff --git a/nss/nss_files/files-initgroups.c b/nss/nss_files/files-initgroups.c
index 65189d3929..896fa50c5a 100644
--- a/nss/nss_files/files-initgroups.c
+++ b/nss/nss_files/files-initgroups.c
@@ -33,7 +33,7 @@ _nss_files_initgroups_dyn (const char *user, gid_t group, long int *start,
 			   long int *size, gid_t **groupsp, long int limit,
 			   int *errnop)
 {
-  FILE *stream = __nss_files_fopen ("/etc/group");
+  FILE *stream = __nss_files_fopen ("/etc/group", "/usr/share/group");
   if (stream == NULL)
     {
       *errnop = errno;
diff --git a/nss/nss_files/files-netgrp.c b/nss/nss_files/files-netgrp.c
index 92d8062e43..7f71eebf60 100644
--- a/nss/nss_files/files-netgrp.c
+++ b/nss/nss_files/files-netgrp.c
@@ -27,7 +27,8 @@
 #include "netgroup.h"
 #include <nss_files.h>

-#define DATAFILE	"/etc/netgroup"
+#define DATAFILE          "/etc/netgroup"
+#define DATAFILE_FALLBACK "/usr/share/netgroup"

 libc_hidden_proto (_nss_files_endnetgrent)

@@ -62,7 +63,7 @@ _nss_files_setnetgrent (const char *group, struct __netgrent *result)
     return NSS_STATUS_UNAVAIL;

   /* Find the netgroups file and open it.  */
-  fp = __nss_files_fopen (DATAFILE);
+  fp = __nss_files_fopen (DATAFILE, DATAFILE_FALLBACK);
   if (fp == NULL)
     status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
   else
diff --git a/nss/nss_files_data.c b/nss/nss_files_data.c
index 261a01a775..c6af527e6d 100644
--- a/nss/nss_files_data.c
+++ b/nss/nss_files_data.c
@@ -74,13 +74,13 @@ __nss_files_data_get (struct nss_files_per_file_data **pdata,
 /* Helper function for opening the backing file at PATH.  */
 static enum nss_status
 __nss_files_data_internal_open (struct nss_files_per_file_data *data,
-                                const char *path)
+                                const char *path, const char *fallback_path)
 {
   enum nss_status status = NSS_STATUS_SUCCESS;

   if (data->stream == NULL)
     {
-      data->stream = __nss_files_fopen (path);
+      data->stream = __nss_files_fopen (path, fallback_path);

       if (data->stream == NULL)
         status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
@@ -93,6 +93,7 @@ __nss_files_data_internal_open (struct nss_files_per_file_data *data,
 enum nss_status
 __nss_files_data_open (struct nss_files_per_file_data **pdata,
                        enum nss_files_file file, const char *path,
+                       const char *fallback_path,
                        int *errnop, int *herrnop)
 {
   enum nss_status status = __nss_files_data_get (pdata, file, errnop, herrnop);
@@ -103,7 +104,7 @@ __nss_files_data_open (struct nss_files_per_file_data **pdata,
   if ((*pdata)->stream == NULL)
     {
       int saved_errno = errno;
-      status = __nss_files_data_internal_open (*pdata, path);
+      status = __nss_files_data_internal_open (*pdata, path, fallback_path);
       __set_errno (saved_errno);
       if (status != NSS_STATUS_SUCCESS)
         __nss_files_data_put (*pdata);
@@ -122,7 +123,7 @@ __nss_files_data_put (struct nss_files_per_file_data *data)
 libc_hidden_def (__nss_files_data_put)

 enum nss_status
-__nss_files_data_setent (enum nss_files_file file, const char *path)
+__nss_files_data_setent (enum nss_files_file file, const char *path, const char *fallback_path)
 {
   struct nss_files_per_file_data *data;
   enum nss_status status = __nss_files_data_get (&data, file, NULL, NULL);
@@ -130,7 +131,7 @@ __nss_files_data_setent (enum nss_files_file file, const char *path)
     return status;

   if (data->stream == NULL)
-    status = __nss_files_data_internal_open (data, path);
+    status = __nss_files_data_internal_open (data, path, fallback_path);
   else
     rewind (data->stream);

diff --git a/nss/nss_files_fopen.c b/nss/nss_files_fopen.c
index e7c48d7bd8..a2b7affdb4 100644
--- a/nss/nss_files_fopen.c
+++ b/nss/nss_files_fopen.c
@@ -22,11 +22,18 @@
 #include <stdio_ext.h>

 FILE *
-__nss_files_fopen (const char *path)
+__nss_files_fopen (const char *path, const char *fallback_path)
 {
   FILE *fp = fopen (path, "rce");
   if (fp == NULL)
-    return NULL;
+    {
+      if (errno != ENOENT || fallback_path == NULL)
+        return NULL;
+
+      fp = fopen (fallback_path, "rce");
+      if (fp == NULL)
+        return NULL;
+    }

   /* The stream is not shared across threads.  */
   __fsetlocking (fp, FSETLOCKING_BYCALLER);
