"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
Re: gotwebd: honor all groups for gotwebd user
To:
Anton Lindqvist <anton@basename.se>
Cc:
gameoftrees@openbsd.org
Date:
Sat, 26 Apr 2025 21:23:18 +0200

Download raw body.

Thread
On Sat, Apr 26, 2025 at 08:45:43PM +0200, Anton Lindqvist wrote:
> Hi,
> I wanted to give gotwebd a try now that it can access repositories
> outside its chroot. I added the _gotwebd user to my vcs group required
> to access my repositories. However, only the user group as given by
> getpwnam() is currently passed down to setgroups(). Here's one solution
> making use of getgrouplist.

Thanks, nice catch. I don't think I've tested putting _gotwebd into a
shared group. I only tested having repositories writable by group _gotwebd.
Either approach is valid, and I like your solution. ok by me.

> diff --git gotwebd/gotwebd.c gotwebd/gotwebd.c
> index f66b9f38c71d..162f7f952a51 100644
> --- gotwebd/gotwebd.c
> +++ gotwebd/gotwebd.c
> @@ -357,12 +357,13 @@ main(int argc, char **argv)
>  	struct event_base	*evb;
>  	struct gotwebd		*env;
>  	struct passwd		*pw;
> -	int			 ch, i;
> +	int			 ch, i, gotwebd_ngroups;
>  	int			 no_action = 0;
>  	int			 proc_type = GOTWEBD_PROC_PARENT;
>  	const char		*conffile = GOTWEBD_CONF;
>  	const char		*gotwebd_username = GOTWEBD_DEFAULT_USER;
>  	const char		*www_username = GOTWEBD_WWW_USER;
> +	gid_t			 gotwebd_groups[NGROUPS_MAX];
>  	gid_t			 www_gid;
>  	const char		*argv0;
>  
> @@ -440,6 +441,9 @@ main(int argc, char **argv)
>  	pw = getpwnam(gotwebd_username);
>  	if (pw == NULL)
>  		fatalx("unknown user %s", gotwebd_username);
> +	if (getgrouplist(gotwebd_username, pw->pw_gid, gotwebd_groups,
> +	    &gotwebd_ngroups) == -1)
> +		fatalx("too many groups for user %s", gotwebd_username);
>  
>  	/* check for root privileges */
>  	if (geteuid())
> @@ -469,7 +473,7 @@ main(int argc, char **argv)
>  		setproctitle("gotweb");
>  		log_procinit("gotweb");
>  
> -		if (setgroups(1, &pw->pw_gid) == -1 ||
> +		if (setgroups(gotwebd_ngroups, gotwebd_groups) == -1 ||
>  		    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1 ||
>  		    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)
>  			fatal("failed to drop privileges");
> 
>