// SPDX-FileCopyrightText: 1989-1994, Julianne Frances Haugh // SPDX-FileCopyrightText: 1996-1998, Marek Michałkiewicz // SPDX-FileCopyrightText: 2001-2006, Tomasz Kłoczko // SPDX-FileCopyrightText: 2007-2009, Nicolas François // SPDX-FileCopyrightText: 2024, Alejandro Colomar // SPDX-License-Identifier: BSD-3-Clause #include "config.h" #if !defined(USE_PAM) #include "prototypes.h" #include "defines.h" #include #include #include #include #include #include "alloc/reallocf.h" #include "search/l/lsearch.h" #include "shadow/grp/agetgroups.h" #include "shadowlog.h" #include "string/strchr/strchrscnt.h" #include "string/strcmp/streq.h" #include "string/strerrno.h" /* * Add groups with names from LIST (separated by commas or colons) * to the supplementary group set. Silently ignore groups which are * already there. */ int add_groups(const char *list) { char *dup; FILE *shadow_logfd = log_get_logfd(); gid_t *gids; size_t n; gids = agetgroups(&n); if (gids == NULL) return -1; gids = reallocf_T(gids, n + strchrscnt(list, ",:") + 1, gid_t); if (gids == NULL) return -1; dup = strdup(list); if (dup == NULL) goto free_gids; if (!streq(dup, "")) { char *g, *p; p = dup; while (NULL != (g = strsep(&p, ",:"))) { struct group *grp; grp = getgrnam(g); /* local, no need for xgetgrnam */ if (NULL == grp) { fprintf(shadow_logfd, _("Warning: unknown group %s\n"), g); continue; } LSEARCH(gid_t, &grp->gr_gid, gids, &n); } } free(dup); if (setgroups(n, gids) == -1) { fprintf(shadow_logfd, "setgroups: %s\n", strerrno()); goto free_gids; } free(gids); return 0; free_gids: free(gids); return -1; } #else /* !USE_PAM */ extern int ISO_C_forbids_an_empty_translation_unit; #endif /* !USE_PAM */