- 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);
- if (status != NSS_STATUS_SUCCESS)
+ status = get_local_group(MAGIC_NONLOCAL_GROUPNAME,
+ &nonlocal_users_group, &buffer, errnop);
+ if (status == NSS_STATUS_SUCCESS) {
+ free(buffer);
+ if (is_nonlocal) {
+ if (!add_group(nonlocal_users_group.gr_gid, start, size, groupsp,
+ limit, errnop, &status))
+ return status;
+ } else {
+ int i;
+ for (i = 0; i < *start; ++i) {
+ if ((*groupsp)[i] == nonlocal_users_group.gr_gid) {
+ is_nonlocal = true;
+ break;
+ }
+ }
+
+ if (is_nonlocal) {
+ struct passwd pwbuf;
+ char *buf;
+ int nonlocal_errno = *errnop;
+ status = get_nonlocal_passwd(user, &pwbuf, &buf, errnop);
+
+ if (status == NSS_STATUS_SUCCESS) {
+ nonlocal_errno = *errnop;
+ status = check_nonlocal_gid(user, NULL, pwbuf.pw_gid,
+ &nonlocal_errno);
+ free(buf);
+ }
+
+ if (status == NSS_STATUS_SUCCESS) {
+ if (!add_group(pwbuf.pw_gid, start, size, groupsp, limit,
+ errnop, &status))
+ return status;
+ } else if (status == NSS_STATUS_TRYAGAIN) {
+ *errnop = nonlocal_errno;
+ return status;
+ }
+ }
+ }
+ } else if (status == NSS_STATUS_TRYAGAIN) {
+ if (is_nonlocal)
+ return status;
+ } else {
+ syslog(LOG_WARNING, "nss_nonlocal: Group %s does not exist locally!",
+ MAGIC_NONLOCAL_GROUPNAME);
+ }
+
+ if (!is_nonlocal)
+ return NSS_STATUS_SUCCESS;
+
+ in = out = *start;
+
+#define args (user, group, start, size, groupsp, limit, errnop)
+#include "walk_nss.h"
+#undef args
+ if (status == NSS_STATUS_NOTFOUND || status == NSS_STATUS_UNAVAIL)
+ return NSS_STATUS_SUCCESS;
+ else if (status != NSS_STATUS_SUCCESS)