|
25 | 25 | #include "config.h" /* Generated by configure script */ |
26 | 26 |
|
27 | 27 | #include <ctype.h> /* isblank() */ |
| 28 | +#include <grp.h> /* setgroups() */ |
28 | 29 | #include <sched.h> /* sched_yield() */ |
29 | 30 | #include <string.h> |
30 | 31 | #include <sys/reboot.h> |
@@ -560,6 +561,42 @@ static pid_t service_fork(svc_t *svc) |
560 | 561 | svc_ident(svc, NULL, 0), rlim2str(i)); |
561 | 562 | } |
562 | 563 |
|
| 564 | +#ifndef ENABLE_STATIC |
| 565 | + /* Set supplementary groups from /etc/group and config */ |
| 566 | + { |
| 567 | + gid_t supgids[NGROUPS_MAX]; |
| 568 | + int ngroups = NGROUPS_MAX; |
| 569 | + int i, j, n = 0; |
| 570 | + |
| 571 | + /* Get user's supplementary groups from /etc/group */ |
| 572 | + if (uid >= 0 && getgrouplist(svc->username, gid >= 0 ? gid : 0, supgids, &ngroups) >= 0) |
| 573 | + n = ngroups; |
| 574 | + |
| 575 | + /* Add explicitly configured supplementary groups */ |
| 576 | + for (i = 0; i < svc->num_supgroups && n < NGROUPS_MAX; i++) { |
| 577 | + int g = getgroup(svc->supgroups[i]); |
| 578 | + int found = 0; |
| 579 | + |
| 580 | + if (g < 0) { |
| 581 | + warn("%s: unknown supplementary group '%s'", |
| 582 | + svc_ident(svc, NULL, 0), svc->supgroups[i]); |
| 583 | + continue; |
| 584 | + } |
| 585 | + /* Skip if already in list from /etc/group */ |
| 586 | + for (j = 0; j < n; j++) { |
| 587 | + if (supgids[j] == (gid_t)g) { |
| 588 | + found = 1; |
| 589 | + break; |
| 590 | + } |
| 591 | + } |
| 592 | + if (!found) |
| 593 | + supgids[n++] = g; |
| 594 | + } |
| 595 | + if (n > 0 && setgroups(n, supgids)) |
| 596 | + err(1, "%s: failed setgroups()", svc_ident(svc, NULL, 0)); |
| 597 | + } |
| 598 | +#endif |
| 599 | + |
563 | 600 | /* Set desired user+group */ |
564 | 601 | if (gid >= 0) { |
565 | 602 | if (setgid(gid)) |
@@ -1957,7 +1994,29 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file) |
1957 | 1994 | char *ptr = strchr(username, ':'); |
1958 | 1995 |
|
1959 | 1996 | if (ptr) { |
| 1997 | + char *sup; |
| 1998 | + |
1960 | 1999 | *ptr++ = 0; |
| 2000 | + /* Check for supplementary groups: group,sup1,sup2,... */ |
| 2001 | + sup = strchr(ptr, ','); |
| 2002 | + if (sup) { |
| 2003 | + *sup++ = 0; |
| 2004 | + svc->num_supgroups = 0; |
| 2005 | + while (sup) { |
| 2006 | + char *next = strchr(sup, ','); |
| 2007 | + if (next) |
| 2008 | + *next++ = 0; |
| 2009 | + if (svc->num_supgroups >= MAX_NUM_SUPGROUPS) { |
| 2010 | + warn("%s: too many supplementary groups, max %d", |
| 2011 | + svc->cmd, MAX_NUM_SUPGROUPS); |
| 2012 | + break; |
| 2013 | + } |
| 2014 | + strlcpy(svc->supgroups[svc->num_supgroups], sup, |
| 2015 | + sizeof(svc->supgroups[0])); |
| 2016 | + svc->num_supgroups++; |
| 2017 | + sup = next; |
| 2018 | + } |
| 2019 | + } |
1961 | 2020 | strlcpy(svc->group, ptr, sizeof(svc->group)); |
1962 | 2021 | } |
1963 | 2022 | strlcpy(svc->username, username, sizeof(svc->username)); |
|
0 commit comments