mirror of
https://github.com/troglobit/finit.git
synced 2026-09-30 21:13:01 +07:00
Add support for supplementary groups
Implement supplementary group support for services, allowing them to access resources owned by multiple groups. Uses the @user:group,sup1,sup2 syntax to explicitly specify supplementary groups, in addition to now reading group membership from /etc/group.
This commit is contained in:
+16
-1
@@ -116,10 +116,25 @@ Non-privileged Services
|
|||||||
|
|
||||||
Every `run`, `task`, or `service` can also list the privileges the
|
Every `run`, `task`, or `service` can also list the privileges the
|
||||||
`/path/to/cmd` should be executed with. Prefix the command with
|
`/path/to/cmd` should be executed with. Prefix the command with
|
||||||
`@USR[:GRP]`, group is optional, like this:
|
`@USR[:GRP[,SUPP,...]]`, where group and supplementary groups are
|
||||||
|
optional, like this:
|
||||||
|
|
||||||
run [2345] @joe:users logger "Hello world"
|
run [2345] @joe:users logger "Hello world"
|
||||||
|
|
||||||
|
Finit reads the user's supplementary group membership from `/etc/group`
|
||||||
|
automatically. Any groups the user belongs to will be inherited by
|
||||||
|
the service.
|
||||||
|
|
||||||
|
To specify additional supplementary groups beyond those in `/etc/group`,
|
||||||
|
append them after the primary group, separated by commas:
|
||||||
|
|
||||||
|
service @caddy:caddy,ssl-cert /usr/bin/caddy run
|
||||||
|
|
||||||
|
This runs the `caddy` service as user `caddy`, with primary group
|
||||||
|
`caddy`, inheriting any groups `caddy` is a member of in `/etc/group`,
|
||||||
|
plus the additional `ssl-cert` group. This is useful when a service
|
||||||
|
needs access to resources owned by groups not listed in `/etc/group`.
|
||||||
|
|
||||||
For multiple instances of the same command, e.g. a DHCP client or
|
For multiple instances of the same command, e.g. a DHCP client or
|
||||||
multiple web servers, add `:ID` somewhere between the `run`, `task`,
|
multiple web servers, add `:ID` somewhere between the `run`, `task`,
|
||||||
`service` keyword and the command, like this:
|
`service` keyword and the command, like this:
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include "config.h" /* Generated by configure script */
|
#include "config.h" /* Generated by configure script */
|
||||||
|
|
||||||
#include <ctype.h> /* isblank() */
|
#include <ctype.h> /* isblank() */
|
||||||
|
#include <grp.h> /* setgroups() */
|
||||||
#include <sched.h> /* sched_yield() */
|
#include <sched.h> /* sched_yield() */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/reboot.h>
|
#include <sys/reboot.h>
|
||||||
@@ -560,6 +561,42 @@ static pid_t service_fork(svc_t *svc)
|
|||||||
svc_ident(svc, NULL, 0), rlim2str(i));
|
svc_ident(svc, NULL, 0), rlim2str(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef ENABLE_STATIC
|
||||||
|
/* Set supplementary groups from /etc/group and config */
|
||||||
|
{
|
||||||
|
gid_t supgids[NGROUPS_MAX];
|
||||||
|
int ngroups = NGROUPS_MAX;
|
||||||
|
int i, j, n = 0;
|
||||||
|
|
||||||
|
/* Get user's supplementary groups from /etc/group */
|
||||||
|
if (uid >= 0 && getgrouplist(svc->username, gid >= 0 ? gid : 0, supgids, &ngroups) >= 0)
|
||||||
|
n = ngroups;
|
||||||
|
|
||||||
|
/* Add explicitly configured supplementary groups */
|
||||||
|
for (i = 0; i < svc->num_supgroups && n < NGROUPS_MAX; i++) {
|
||||||
|
int g = getgroup(svc->supgroups[i]);
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
if (g < 0) {
|
||||||
|
warn("%s: unknown supplementary group '%s'",
|
||||||
|
svc_ident(svc, NULL, 0), svc->supgroups[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Skip if already in list from /etc/group */
|
||||||
|
for (j = 0; j < n; j++) {
|
||||||
|
if (supgids[j] == (gid_t)g) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
supgids[n++] = g;
|
||||||
|
}
|
||||||
|
if (n > 0 && setgroups(n, supgids))
|
||||||
|
err(1, "%s: failed setgroups()", svc_ident(svc, NULL, 0));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Set desired user+group */
|
/* Set desired user+group */
|
||||||
if (gid >= 0) {
|
if (gid >= 0) {
|
||||||
if (setgid(gid))
|
if (setgid(gid))
|
||||||
@@ -1957,7 +1994,29 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
char *ptr = strchr(username, ':');
|
char *ptr = strchr(username, ':');
|
||||||
|
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
|
char *sup;
|
||||||
|
|
||||||
*ptr++ = 0;
|
*ptr++ = 0;
|
||||||
|
/* Check for supplementary groups: group,sup1,sup2,... */
|
||||||
|
sup = strchr(ptr, ',');
|
||||||
|
if (sup) {
|
||||||
|
*sup++ = 0;
|
||||||
|
svc->num_supgroups = 0;
|
||||||
|
while (sup) {
|
||||||
|
char *next = strchr(sup, ',');
|
||||||
|
if (next)
|
||||||
|
*next++ = 0;
|
||||||
|
if (svc->num_supgroups >= MAX_NUM_SUPGROUPS) {
|
||||||
|
warn("%s: too many supplementary groups, max %d",
|
||||||
|
svc->cmd, MAX_NUM_SUPGROUPS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
strlcpy(svc->supgroups[svc->num_supgroups], sup,
|
||||||
|
sizeof(svc->supgroups[0]));
|
||||||
|
svc->num_supgroups++;
|
||||||
|
sup = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
strlcpy(svc->group, ptr, sizeof(svc->group));
|
strlcpy(svc->group, ptr, sizeof(svc->group));
|
||||||
}
|
}
|
||||||
strlcpy(svc->username, username, sizeof(svc->username));
|
strlcpy(svc->username, username, sizeof(svc->username));
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ typedef enum {
|
|||||||
#define MAX_STR_LEN 64
|
#define MAX_STR_LEN 64
|
||||||
#define MAX_COND_LEN (MAX_ARG_LEN * 3)
|
#define MAX_COND_LEN (MAX_ARG_LEN * 3)
|
||||||
#define MAX_USER_LEN 16
|
#define MAX_USER_LEN 16
|
||||||
|
#define MAX_NUM_SUPGROUPS 4
|
||||||
#define MAX_NUM_FDS 64 /* Max number of I/O plugins */
|
#define MAX_NUM_FDS 64 /* Max number of I/O plugins */
|
||||||
#define MAX_NUM_SVC_ARGS 64
|
#define MAX_NUM_SVC_ARGS 64
|
||||||
|
|
||||||
@@ -191,6 +192,8 @@ typedef struct svc {
|
|||||||
/* Identity */
|
/* Identity */
|
||||||
char username[MAX_USER_LEN];
|
char username[MAX_USER_LEN];
|
||||||
char group[MAX_USER_LEN];
|
char group[MAX_USER_LEN];
|
||||||
|
char supgroups[MAX_NUM_SUPGROUPS][MAX_USER_LEN];
|
||||||
|
int num_supgroups;
|
||||||
char capabilities[MAX_CMD_LEN];
|
char capabilities[MAX_CMD_LEN];
|
||||||
|
|
||||||
/* Command, arguments and service description */
|
/* Command, arguments and service description */
|
||||||
|
|||||||
Reference in New Issue
Block a user