diff --git a/grp/Makefile b/grp/Makefile
index 4f1809cea55b7c2f407c4c527c5198509934e342..b4d52e2928668507ec59f3b23b8b97afd4645565 100644
--- a/grp/Makefile
+++ b/grp/Makefile
@@ -20,15 +20,16 @@
 #
 subdir	:= grp
 
 include ../Makeconfig
 
-headers := grp.h
+headers := grp.h grp-merge.h
 
 routines := fgetgrent initgroups setgroups \
 	    getgrent getgrgid getgrnam putgrent \
-	    getgrent_r getgrgid_r getgrnam_r fgetgrent_r
+	    getgrent_r getgrgid_r getgrnam_r fgetgrent_r \
+	    grp-merge
 
 tests := testgrp tst-putgrent
 
 ifeq (yes,$(build-shared))
 test-srcs :=  tst_fgetgrent
diff --git a/grp/Versions b/grp/Versions
index e01360da42ceed83b9f7ac2e51378ba9520e07d2..096caa47c50dead9c209e0cbdbe58c9ddcc11b55 100644
--- a/grp/Versions
+++ b/grp/Versions
@@ -26,6 +26,9 @@ libc {
   }
   GLIBC_2.2.4 {
     # g*
     getgrouplist;
   }
+  GLIBC_PRIVATE {
+    __merge_grp; __copy_grp;
+  }
 }
diff --git a/grp/getgrgid_r.c b/grp/getgrgid_r.c
index 9da834ac98d97e2bc83c3b989036c3222ff851c7..ed326c8424116373323bad01c27fad93f127d49b 100644
--- a/grp/getgrgid_r.c
+++ b/grp/getgrgid_r.c
@@ -16,14 +16,17 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
 #include <grp.h>
 
+#include "grp-merge.h"
 
 #define LOOKUP_TYPE	struct group
 #define FUNCTION_NAME	getgrgid
 #define DATABASE_NAME	group
 #define ADD_PARAMS	gid_t gid
 #define ADD_VARIABLES	gid
 #define BUFLEN		NSS_BUFLEN_GROUP
+#define DEEPCOPY_FN	__copy_grp
+#define MERGE_FN	__merge_grp
 
 #include <nss/getXXbyYY_r.c>
diff --git a/grp/getgrnam_r.c b/grp/getgrnam_r.c
index 80960825c0a6ace837e720e47325b8899cc5c908..b8eb7cab9ca10abe56e5570817b0d719e1381d89 100644
--- a/grp/getgrnam_r.c
+++ b/grp/getgrnam_r.c
@@ -16,13 +16,17 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
 #include <grp.h>
 
+#include "grp-merge.h"
 
 #define LOOKUP_TYPE	struct group
 #define FUNCTION_NAME	getgrnam
 #define DATABASE_NAME	group
 #define ADD_PARAMS	const char *name
 #define ADD_VARIABLES	name
 
+#define DEEPCOPY_FN	__copy_grp
+#define MERGE_FN	__merge_grp
+
 #include <nss/getXXbyYY_r.c>
diff --git a/grp/grp-merge.c b/grp/grp-merge.c
new file mode 100644
index 0000000000000000000000000000000000000000..398ee852fde3fad82caf6ac04c89bbc249951d4b
--- /dev/null
+++ b/grp/grp-merge.c
@@ -0,0 +1,180 @@
+/* Group merging implementation.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <grp.h>
+#include "grp-merge.h"
+
+#define BUFCHECK(size)		\
+  do {						\
+    if (c + size > buflen)	\
+    {						\
+        free (members);		\
+        return ERANGE;		\
+    }						\
+  } while(0)
+
+int
+internal_function
+__copy_grp (const struct group srcgrp, const size_t buflen,
+	    struct group *destgrp, char *destbuf, char **endptr)
+{
+  size_t i;
+  size_t c = 0;
+  size_t len;
+  size_t memcount;
+  char **members = NULL;
+
+  /* Copy the GID.  */
+  destgrp->gr_gid = srcgrp.gr_gid;
+
+  /* Copy the name.  */
+  len = strlen (srcgrp.gr_name) + 1;
+  BUFCHECK (len);
+  memcpy (&destbuf[c], srcgrp.gr_name, len);
+  destgrp->gr_name = &destbuf[c];
+  c += len;
+
+  /* Copy the password.  */
+  len = strlen (srcgrp.gr_passwd) + 1;
+  BUFCHECK (len);
+  memcpy (&destbuf[c], srcgrp.gr_passwd, len);
+  destgrp->gr_passwd = &destbuf[c];
+  c += len;
+
+  /* Count all of the members.  */
+  for (memcount = 0; srcgrp.gr_mem[memcount]; memcount++)
+    ;
+
+  /* Allocate a temporary holding area for the pointers to the member
+     contents, including space for a NULL-terminator.  */
+  members = malloc (sizeof (char *) * (memcount + 1));
+  if (members == NULL)
+    return ENOMEM;
+
+  /* Copy all of the group members to destbuf and add a pointer to each of
+     them into the 'members' array.  */
+  for (i = 0; srcgrp.gr_mem[i]; i++)
+    {
+      len = strlen (srcgrp.gr_mem[i]) + 1;
+      BUFCHECK (len);
+      memcpy (&destbuf[c], srcgrp.gr_mem[i], len);
+      members[i] = &destbuf[c];
+      c += len;
+    }
+  members[i] = NULL;
+
+  /* Copy the pointers from the members array into the buffer and assign them
+     to the gr_mem member of destgrp.  */
+  destgrp->gr_mem = (char **) &destbuf[c];
+  len = sizeof (char *) * (memcount + 1);
+  BUFCHECK (len);
+  memcpy (&destbuf[c], members, len);
+  c += len;
+  free (members);
+  members = NULL;
+
+  /* Save the count of members at the end.  */
+  BUFCHECK (sizeof (size_t));
+  memcpy (&destbuf[c], &memcount, sizeof (size_t));
+  c += sizeof (size_t);
+
+  if (endptr)
+    *endptr = destbuf + c;
+  return 0;
+}
+
+/* Check that the name, GID and passwd fields match, then
+   copy in the gr_mem array.  */
+int
+internal_function
+__merge_grp (struct group *savedgrp, char *savedbuf, char *savedend,
+	     size_t buflen, struct group *mergegrp, char *mergebuf)
+{
+  size_t c, i, len;
+  size_t savedmemcount;
+  size_t memcount;
+  size_t membersize;
+  char **members = NULL;
+
+  /* We only support merging members of groups with identical names and
+     GID values. If we hit this case, we need to overwrite the current
+     buffer with the saved one (which is functionally equivalent to
+     treating the new lookup as NSS_STATUS NOTFOUND.  */
+  if (mergegrp->gr_gid != savedgrp->gr_gid
+      || strcmp (mergegrp->gr_name, savedgrp->gr_name))
+    return __copy_grp (*savedgrp, buflen, mergegrp, mergebuf, NULL);
+
+  /* Get the count of group members from the last sizeof (size_t) bytes in the
+     mergegrp buffer.  */
+  savedmemcount = (size_t) *(savedend - sizeof (size_t));
+
+  /* Get the count of new members to add.  */
+  for (memcount = 0; mergegrp->gr_mem[memcount]; memcount++)
+    ;
+
+  /* Create a temporary array to hold the pointers to the member values from
+     both the saved and merge groups.  */
+  membersize = savedmemcount + memcount + 1;
+  members = malloc (sizeof (char *) * membersize);
+  if (members == NULL)
+    return ENOMEM;
+
+  /* Copy in the existing member pointers from the saved group
+     Note: this is not NULL-terminated yet.  */
+  memcpy (members, savedgrp->gr_mem, sizeof (char *) * savedmemcount);
+
+  /* Back up into the savedbuf until we get back to the NULL-terminator of the
+     group member list. (This means walking back savedmemcount + 1 (char *) pointers
+     and the member count value.
+     The value of c is going to be the used length of the buffer backed up by
+     the member count and further backed up by the size of the pointers.  */
+  c = savedend - savedbuf
+      - sizeof (size_t)
+      - sizeof (char *) * (savedmemcount + 1);
+
+  /* Add all the new group members, overwriting the old NULL-terminator while
+     adding the new pointers to the temporary array.  */
+  for (i = 0; mergegrp->gr_mem[i]; i++)
+    {
+      len = strlen (mergegrp->gr_mem[i]) + 1;
+      BUFCHECK (len);
+      memcpy (&savedbuf[c], mergegrp->gr_mem[i], len);
+      members[savedmemcount + i] = &savedbuf[c];
+      c += len;
+    }
+  /* Add the NULL-terminator.  */
+  members[savedmemcount + memcount] = NULL;
+
+  /* Copy the member array back into the buffer after the member list and free
+     the member array.  */
+  savedgrp->gr_mem = (char **) &savedbuf[c];
+  len = sizeof (char *) * membersize;
+  BUFCHECK (len);
+  memcpy (&savedbuf[c], members, len);
+  c += len;
+
+  free (members);
+  members = NULL;
+
+  /* Finally, copy the results back into mergebuf, since that's the buffer
+     that we were provided by the caller.  */
+  return __copy_grp (*savedgrp, buflen, mergegrp, mergebuf, NULL);
+}
diff --git a/grp/grp-merge.h b/grp/grp-merge.h
new file mode 100644
index 0000000000000000000000000000000000000000..969612b34dd389c0cc63913f1d32b52b2a2a75fd
--- /dev/null
+++ b/grp/grp-merge.h
@@ -0,0 +1,37 @@
+/* Group merging implementation.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GRP_MERGE_H
+#define _GRP_MERGE_H 1
+
+#include <grp.h>
+
+/* Duplicate a grp struct (and its members). When no longer needed, the
+   calling function must free(newbuf).  */
+int
+__copy_grp (const struct group srcgrp, const size_t buflen,
+	    struct group *destgrp, char *destbuf, char **endptr)
+	    internal_function;
+
+/* Merge the member lists of two grp structs together.  */
+int
+__merge_grp (struct group *savedgrp, char *savedbuf, char *savedend,
+	     size_t buflen, struct group *mergegrp, char *mergebuf)
+	     internal_function;
+
+#endif /* _GRP_MERGE_H */
diff --git a/manual/nss.texi b/manual/nss.texi
index 66dcceffe01f225f078e88dd006bb90e80c85723..ddc16026c0bd57f54225ef57cb9cc0a337e400d1 100644
--- a/manual/nss.texi
+++ b/manual/nss.texi
@@ -178,11 +178,11 @@ where
 @var{action} @result{} return | continue
 @end smallexample
 
 The case of the keywords is insignificant.  The @var{status}
 values are the results of a call to a lookup function of a specific
-service.  They mean
+service.  They mean:
 
 @ftable @samp
 @item success
 No error occurred and the wanted entry is returned.  The default action
 for this is @code{return}.
@@ -202,10 +202,54 @@ The service is temporarily unavailable.  This could mean a file is
 locked or a server currently cannot accept more connections.  The
 default action is @code{continue}.
 @end ftable
 
 @noindent
+The @var{action} values mean:
+
+@ftable @samp
+@item return
+
+If the status matches, stop the lookup process at this service
+specification.  If an entry is available, provide it to the application.
+If an error occurred, report it to the application.  In case of a prior
+@samp{merge} action, the data is combined with previous lookup results,
+as explained below.
+
+@item continue
+
+If the status matches, proceed with the lookup process at the next
+entry, discarding the result of the current lookup (and any merged
+data).  An exception is the @samp{initgroups} database and the
+@samp{success} status, where @samp{continue} acts like @code{merge}
+below.
+
+@item merge
+
+Proceed with the lookup process, retaining the current lookup result.
+This action is useful only with the @samp{success} status.  If a
+subsequent service lookup succeeds and has a matching @samp{return}
+specification, the results are merged, the lookup process ends, and the
+merged results are returned to the application.  If the following service
+has a matching @samp{merge} action, the lookup process continues,
+retaining the combined data from this and any previous lookups.
+
+After a @code{merge} action, errors from subsequent lookups are ignored,
+and the data gathered so far will be returned.
+
+The @samp{merge} only applies to the @samp{success} status.  It is
+currently implemented for the @samp{group} database and its group
+members field, @samp{gr_mem}.  If specified for other databases, it
+causes the lookup to fail (if the @var{status} matches).
+
+When processing @samp{merge} for @samp{group} membership, the group GID
+and name must be identical for both entries.  If only one or the other is
+a match, the behavior is undefined.
+
+@end ftable
+
+@noindent
 If we have a line like
 
 @smallexample
 ethers: nisplus [NOTFOUND=return] db files
 @end smallexample
diff --git a/nscd/getgrgid_r.c b/nscd/getgrgid_r.c
index 8039f86ea842645aad144dd24ef75165eafd7a2b..de96262f55a50f08437eff735e80417cf6fd8041 100644
--- a/nscd/getgrgid_r.c
+++ b/nscd/getgrgid_r.c
@@ -15,17 +15,21 @@
    You should have received a copy of the GNU General Public License
    along with this program; if not, see <http://www.gnu.org/licenses/>.  */
 
 #include <grp.h>
 
+#include "grp/grp-merge.h"
 
 #define LOOKUP_TYPE	struct group
 #define FUNCTION_NAME	getgrgid
 #define DATABASE_NAME	group
 #define ADD_PARAMS	gid_t gid
 #define ADD_VARIABLES	gid
 #define BUFLEN		NSS_BUFLEN_GROUP
 
+#define DEEPCOPY_FN	__copy_grp
+#define MERGE_FN	__merge_grp
+
 /* We are nscd, so we don't want to be talking to ourselves.  */
 #undef	USE_NSCD
 
 #include <nss/getXXbyYY_r.c>
diff --git a/nscd/getgrnam_r.c b/nscd/getgrnam_r.c
index 67e4cd1e0aacaee6b8dabb4f4375493361a4620b..703c234a4d14d305a7868620fa662a59fef8cb65 100644
--- a/nscd/getgrnam_r.c
+++ b/nscd/getgrnam_r.c
@@ -15,16 +15,20 @@
    You should have received a copy of the GNU General Public License
    along with this program; if not, see <http://www.gnu.org/licenses/>.  */
 
 #include <grp.h>
 
+#include "grp/grp-merge.h"
 
 #define LOOKUP_TYPE	struct group
 #define FUNCTION_NAME	getgrnam
 #define DATABASE_NAME	group
 #define ADD_PARAMS	const char *name
 #define ADD_VARIABLES	name
 
+#define DEEPCOPY_FN	__copy_grp
+#define MERGE_FN	__merge_grp
+
 /* We are nscd, so we don't want to be talking to ourselves.  */
 #undef	USE_NSCD
 
 #include <nss/getXXbyYY_r.c>
diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c
index 113c687e064a585fe8152d4ed1374dc0f8adb370..43b55d1a93fa204b59901b1d9ef9265035fad450 100644
--- a/nss/getXXbyYY_r.c
+++ b/nss/getXXbyYY_r.c
@@ -129,10 +129,52 @@
 # define AF_VAL af
 #else
 # define AF_VAL AF_INET
 #endif
 
+
+/* Set defaults for merge functions that haven't been defined.  */
+#ifndef DEEPCOPY_FN
+static inline int
+__copy_einval (LOOKUP_TYPE a,
+	       const size_t b,
+	       LOOKUP_TYPE *c,
+	       char *d,
+	       char **e)
+{
+  return EINVAL;
+}
+# define DEEPCOPY_FN __copy_einval
+#endif
+
+#ifndef MERGE_FN
+static inline int
+__merge_einval (LOOKUP_TYPE *a,
+		char *b,
+		char *c,
+		size_t d,
+		LOOKUP_TYPE *e,
+		char *f)
+{
+  return EINVAL;
+}
+# define MERGE_FN __merge_einval
+#endif
+
+#define CHECK_MERGE(err, status)	\
+do {					\
+  if (err)				\
+    {					\
+      __set_errno (err);		\
+      if (err == ERANGE)		\
+	status = NSS_STATUS_TRYAGAIN;	\
+      else				\
+	status = NSS_STATUS_UNAVAIL;	\
+      break;				\
+    }					\
+} while (0)
+
 /* Type of the lookup function we need here.  */
 typedef enum nss_status (*lookup_function) (ADD_PARAMS, LOOKUP_TYPE *, char *,
 					    size_t, int * H_ERRNO_PARM
 					    EXTRA_PARAMS);
 
@@ -150,17 +192,20 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
 {
   static bool startp_initialized;
   static service_user *startp;
   static lookup_function start_fct;
   service_user *nip;
+  int do_merge = 0;
+  LOOKUP_TYPE mergegrp;
+  char *mergebuf = NULL;
+  char *endptr = NULL;
   union
   {
     lookup_function l;
     void *ptr;
   } fct;
-
-  int no_more;
+  int no_more, err;
   enum nss_status status = NSS_STATUS_UNAVAIL;
 #ifdef USE_NSCD
   int nscd_status;
 #endif
 #ifdef NEED_H_ERRNO
@@ -276,13 +321,70 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
 	  && *h_errnop == NETDB_INTERNAL
 #endif
 	  && errno == ERANGE)
 	break;
 
+      if (do_merge)
+	{
+
+	  if (status == NSS_STATUS_SUCCESS)
+	    {
+	      /* The previous loop saved a buffer for merging.
+		 Perform the merge now.  */
+	      err = MERGE_FN (&mergegrp, mergebuf, endptr, buflen, resbuf,
+			      buffer);
+	      CHECK_MERGE (err,status);
+	      do_merge = 0;
+	    }
+	  else
+	    {
+	      /* If the result wasn't SUCCESS, copy the saved buffer back
+	         into the result buffer and set the status back to
+	         NSS_STATUS_SUCCESS to match the previous pass through the
+	         loop.
+	          * If the next action is CONTINUE, it will overwrite the value
+	            currently in the buffer and return the new value.
+	          * If the next action is RETURN, we'll return the previously-
+	            acquired values.
+	          * If the next action is MERGE, then it will be added to the
+	            buffer saved from the previous source.  */
+	      err = DEEPCOPY_FN (mergegrp, buflen, resbuf, buffer, NULL);
+	      CHECK_MERGE (err, status);
+	      status = NSS_STATUS_SUCCESS;
+	    }
+	}
+
+      /* If we were are configured to merge this value with the next one,
+         save the current value of the group struct.  */
+      if (nss_next_action (nip, status) == NSS_ACTION_MERGE
+	  && status == NSS_STATUS_SUCCESS)
+	{
+	  /* Copy the current values into a buffer to be merged with the next
+	     set of retrieved values.  */
+	  if (mergebuf == NULL)
+	    {
+	      /* Only allocate once and reuse it for as many merges as we need
+	         to perform.  */
+	      mergebuf = malloc (buflen);
+	      if (mergebuf == NULL)
+		{
+		  __set_errno (ENOMEM);
+		  status = NSS_STATUS_UNAVAIL;
+		  break;
+		}
+	    }
+
+	  err = DEEPCOPY_FN (*resbuf, buflen, &mergegrp, mergebuf, &endptr);
+	  CHECK_MERGE (err, status);
+	  do_merge = 1;
+	}
+
       no_more = __nss_next2 (&nip, REENTRANT_NAME_STRING,
 			     REENTRANT2_NAME_STRING, &fct.ptr, status, 0);
     }
+  free (mergebuf);
+  mergebuf = NULL;
 
 #ifdef HANDLE_DIGITS_DOTS
 done:
 #endif
   *result = status == NSS_STATUS_SUCCESS ? resbuf : NULL;
diff --git a/nss/getnssent_r.c b/nss/getnssent_r.c
index 456907b018d44991f4020b0ee234fcfc4baeb1a0..e8a1f7574d1a6c5469b7ced9732f48e32818b8e6 100644
--- a/nss/getnssent_r.c
+++ b/nss/getnssent_r.c
@@ -77,11 +77,25 @@ __nss_setent (const char *func_name, db_lookup_function lookup_fct,
       if (stayopen_tmp)
 	status = DL_CALL_FCT (fct.f, (*stayopen_tmp));
       else
 	status = DL_CALL_FCT (fct.f, (0));
 
-      no_more = __nss_next2 (nip, func_name, NULL, &fct.ptr, status, 0);
+      if (nss_next_action (*nip, status) == NSS_ACTION_MERGE)
+	{
+	  /* This is a special-case.  When [SUCCESS=merge] is in play,
+	     _nss_next2() will skip to the next database.  Due to the
+	     implementation of that function, we can't know whether we're
+	     in an enumeration or an individual lookup, which behaves
+	     differently with regards to merging.  We'll treat SUCCESS as
+	     an indication to start the enumeration at this database. */
+	  no_more = 1;
+	}
+      else
+	{
+	  no_more = __nss_next2 (nip, func_name, NULL, &fct.ptr, status, 0);
+	}
+
       if (is_last_nip)
 	*last_nip = *nip;
     }
 
   if (stayopen_tmp)
@@ -173,12 +187,26 @@ __nss_getent_r (const char *getent_func_name,
 	  && errno == ERANGE)
 	break;
 
       do
 	{
-	  no_more = __nss_next2 (nip, getent_func_name, NULL, &fct.ptr,
-				 status, 0);
+	  if (status == NSS_STATUS_SUCCESS
+	      && nss_next_action (*nip, status) == NSS_ACTION_MERGE)
+	    {
+	      /* This is a special-case.  When [SUCCESS=merge] is in play,
+	         _nss_next2() will skip to the next database.  Due to the
+	         implementation of that function, we can't know whether we're
+	         in an enumeration or an individual lookup, which behaves
+	         differently with regards to merging.  We'll treat SUCCESS as
+	         an indication to return the results here. */
+	      no_more = 1;
+	    }
+	  else
+	    {
+	      no_more = __nss_next2 (nip, getent_func_name, NULL, &fct.ptr,
+				     status, 0);
+	    }
 
 	  if (is_last_nip)
 	    *last_nip = *nip;
 
 	  if (! no_more)
diff --git a/nss/nsswitch.c b/nss/nsswitch.c
index bb644cb373add1cf5c3bce854e7b38d16b77ba1d..d7706506f02886dbf63782f4af3d9f7242d309fd 100644
--- a/nss/nsswitch.c
+++ b/nss/nsswitch.c
@@ -710,10 +710,13 @@ nss_parse_service_list (const char *line)
 	      if (line - name == 6 && __strncasecmp (name, "RETURN", 6) == 0)
 		action = NSS_ACTION_RETURN;
 	      else if (line - name == 8
 		       && __strncasecmp (name, "CONTINUE", 8) == 0)
 		action = NSS_ACTION_CONTINUE;
+	      else if (line - name == 5
+		       && __strncasecmp (name, "MERGE", 5) == 0)
+		action = NSS_ACTION_MERGE;
 	      else
 		goto finish;
 
 	      if (not)
 		{
diff --git a/nss/nsswitch.h b/nss/nsswitch.h
index 0074ee1d655827e787ed5de296d5a6a421a001d8..54c8b656f70a8cb531483afc21bf93db0639bc42 100644
--- a/nss/nsswitch.h
+++ b/nss/nsswitch.h
@@ -30,11 +30,12 @@
 
 /* Actions performed after lookup finished.  */
 typedef enum
 {
   NSS_ACTION_CONTINUE,
-  NSS_ACTION_RETURN
+  NSS_ACTION_RETURN,
+  NSS_ACTION_MERGE
 } lookup_actions;
 
 
 typedef struct service_library
 {
