- do {
- if (fct.ptr == NULL)
- status = NSS_STATUS_UNAVAIL;
- else
- status = DL_CALL_FCT(fct.l, (user, group, start, size, groupsp, limit, errnop));
- if (status == NSS_STATUS_TRYAGAIN && *errnop == ERANGE)
- break;
- } while (__nss_next(&nip, fct_name, &fct.ptr, status, 0) == 0);
+ status = get_local_group(MAGIC_LOCAL_GROUPNAME,
+ &local_users_group, &buffer, errnop);
+ if (status == NSS_STATUS_SUCCESS) {
+ local_users_gid = local_users_group.gr_gid;
+ free(buffer);
+ } else if (status == NSS_STATUS_TRYAGAIN) {
+ return status;
+ } else {
+ syslog(LOG_WARNING, "nss_nonlocal: Group %s does not exist locally!",
+ MAGIC_LOCAL_GROUPNAME);
+ local_users_gid = -1;
+ }
+
+ if (is_local) {
+ gid = local_users_gid;
+ } else {
+ status = get_local_group(MAGIC_NONLOCAL_GROUPNAME,
+ &nonlocal_users_group, &buffer, errnop);
+ if (status == NSS_STATUS_SUCCESS) {
+ gid = nonlocal_users_group.gr_gid;
+ free(buffer);
+ } else if (status == NSS_STATUS_TRYAGAIN) {
+ return status;
+ } else {
+ syslog(LOG_WARNING, "nss_nonlocal: Group %s does not exist locally!",
+ MAGIC_NONLOCAL_GROUPNAME);
+ gid = -1;
+ }
+ }
+
+ if (gid != -1) {
+ int i;
+ for (i = 0; i < *start; ++i)
+ if ((*groupsp)[i] == gid)
+ break;
+ if (i >= *start) {
+ if (*start + 1 > *size) {
+ gid_t *newgroups;
+ long int newsize = 2 * *size;
+ if (limit > 0) {
+ if (*size >= limit)
+ return NSS_STATUS_SUCCESS;
+ if (newsize > limit)
+ newsize = limit;
+ }
+ newgroups = realloc(*groupsp, newsize * sizeof((*groupsp)[0]));
+ errno = old_errno;
+ if (newgroups == NULL) {
+ *errnop = ENOMEM;
+ return NSS_STATUS_TRYAGAIN;
+ }
+ *groupsp = newgroups;
+ *size = newsize;
+ }
+ (*groupsp)[(*start)++] = gid;
+ }
+ }
+
+ if (is_local)
+ return NSS_STATUS_SUCCESS;
+
+ in = out = *start;
+
+#define args (user, group, start, size, groupsp, limit, errnop)
+#include "walk_nss.h"
+#undef args