struct passwd *pwdst, char *buf,
size_t buflen, struct passwd **pwdstp);
void (*nw_endpwent)(struct nwrap_backend *b);
- int (*nw_initgroups)(struct nwrap_backend *b,
- const char *user, gid_t group);
int (*nw_initgroups_dyn)(struct nwrap_backend *b,
const char *user,
gid_t group,
struct passwd *pwdst, char *buf,
size_t buflen, struct passwd **pwdstp);
static void nwrap_files_endpwent(struct nwrap_backend *b);
-static int nwrap_files_initgroups(struct nwrap_backend *b,
- const char *user, gid_t group);
+static int nwrap_files_initgroups_dyn(struct nwrap_backend *b,
+ const char *user,
+ gid_t group,
+ long int *start,
+ long int *size,
+ gid_t **groups,
+ long int limit,
+ int *errnop);
static struct group *nwrap_files_getgrnam(struct nwrap_backend *b,
const char *name);
static int nwrap_files_getgrnam_r(struct nwrap_backend *b,
.nw_getpwent = nwrap_files_getpwent,
.nw_getpwent_r = nwrap_files_getpwent_r,
.nw_endpwent = nwrap_files_endpwent,
- .nw_initgroups = nwrap_files_initgroups,
+ .nw_initgroups_dyn = nwrap_files_initgroups_dyn,
.nw_getgrnam = nwrap_files_getgrnam,
.nw_getgrnam_r = nwrap_files_getgrnam_r,
.nw_getgrgid = nwrap_files_getgrgid,
#endif /* defined(HAVE_SHADOW_H) && defined(HAVE_GETSPNAM) */
/* misc functions */
-static int nwrap_files_initgroups(struct nwrap_backend *b,
- const char *user,
- gid_t group)
+static int nwrap_files_initgroups_dyn(struct nwrap_backend *b,
+ const char *user,
+ gid_t group,
+ long int *start,
+ long int *size,
+ gid_t **groups,
+ long int limit,
+ int *errnop)
{
struct group *grp;
- gid_t *groups;
- int size = 1;
- int rc;
-
- groups = (gid_t *)malloc(size * sizeof(gid_t));
- if (groups == NULL) {
- NWRAP_LOG(NWRAP_LOG_ERROR, "Out of memory");
- errno = ENOMEM;
- return -1;
- }
- groups[0] = group;
+ int i = 0;
+ (void)errnop; /* unused */
nwrap_files_setgrent(b);
while ((grp = nwrap_files_getgrent(b)) != NULL) {
- int i = 0;
-
NWRAP_LOG(NWRAP_LOG_DEBUG,
"Inspecting %s for group membership",
grp->gr_name);
user,
grp->gr_name);
- groups = (gid_t *)realloc(groups,
- (size + 1) * sizeof(gid_t));
- if (groups == NULL) {
- NWRAP_LOG(NWRAP_LOG_ERROR,
- "Out of memory");
- errno = ENOMEM;
- return -1;
+ if (*start == *size) {
+ long int newsize;
+ gid_t *newgroups;
+
+ newsize = 2 * (*size);
+ if (limit > 0 && newsize > limit) {
+ newsize = MAX(limit, *size);
+ }
+ newgroups = (gid_t *) realloc((*groups),
+ newsize * sizeof(**groups));
+ if (!newgroups) {
+ errno = ENOMEM;
+ return -1;
+ }
+ *groups = newgroups;
+ *size = newsize;
}
-
- groups[size] = grp->gr_gid;
- size++;
+ (*groups)[*start] = grp->gr_gid;
+ (*start)++;
}
}
}
nwrap_files_endgrent(b);
-
- NWRAP_LOG(NWRAP_LOG_DEBUG,
- "%s is member of %d groups",
- user, size);
-
- /* This really only works if uid_wrapper is loaded */
- rc = setgroups(size, groups);
-
- free(groups);
-
- return rc;
+ return *start;
}
/* group functions */