diff --git a/.gitignore b/.gitignore index 7f5acaa..ec5307a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.swp *.o pidfilewrapper +setruid diff --git a/Makefile b/Makefile index a926566..3173bc1 100644 --- a/Makefile +++ b/Makefile @@ -9,21 +9,24 @@ CFLAGS += -std=c11 -Os -g -Wall -Wextra -pedantic CPPFLAGS += LDFLAGS += -all: pidfilewrapper +all: pidfilewrapper setruid pidfilewrapper: pidfilewrapper.c $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< +setruid: setruid.c + $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $< + .PHONY: all install uninstall clean distclean -install: all +install: all pidfilewrapper.1 setruid.1 mkdir -p $(BINDIR) - install pidfilewrapper $(BINDIR) + install pidfilewrapper setruid $(BINDIR) mkdir -p $(DESTDIR)$(MANDIR)/man1 - cp pidfilewrapper.1 $(DESTDIR)$(MANDIR)/man1/pidfilewrapper.1 + cp pidfilewrapper.1 setruid.1 $(DESTDIR)$(MANDIR) uninstall: - rm -f $(BINDIR)/pidfilewrapper $(DESTDIR)$(MANDIR)/man1/pidfilewrapper.1 + rm -f $(BINDIR)/pidfilewrapper $(BINDIR)/setruid $(DESTDIR)$(MANDIR)/man1/pidfilewrapper.1 $(DESTDIR)$(MANDIR)/setruid.1 clean: rm -f pidfilewrapper diff --git a/setruid.1 b/setruid.1 new file mode 100644 index 0000000..9218f39 --- /dev/null +++ b/setruid.1 @@ -0,0 +1,25 @@ +.Dd Jul 11, 2018 +.Dt setruid 1 +.Os +.Sh NAME +.Nm setruid +.Nd set the real UID for a command +.Sh SYNOPSIS +.Nm +.Ar command +.Op Ar arguments +.Sh DESCRIPTION +.Nm +sets the real UID while keeping the effective UID the same. It is indended for +simple servers that need to bind on a low port and drop privileges by setting +effective UID to real UID. +.Pp +.Nm +executes the given command as the same process. +.Sh EXIT STATUS +.Nm +will exit with status 1 if it fails to set the UID or execute the given command. +If it is succesful, exit status will be that of the given command. +.Sh AUTHORS +.Nm +has been written by nortti. diff --git a/setruid.c b/setruid.c new file mode 100644 index 0000000..96a87d8 --- /dev/null +++ b/setruid.c @@ -0,0 +1,36 @@ +#define _BSD_SOURCE +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + if(argc < 3) { + fprintf(stderr, "Usage: %s username command [arguments]\n", argv[0]); + return 1; + } + + const char *username = argv[1]; + errno = 0; + struct passwd *passwd_entry = getpwnam(username); + if(passwd_entry == NULL) { + perror("getpwnam"); + return 1; + } + + uid_t ruid = passwd_entry->pw_uid; + + if(setreuid(ruid, -1) != 0) { + perror("getpwnam"); + return 1; + } + + char **daemon_argv = &argv[2]; + const char *daemon_command = daemon_argv[0]; + + execvp(daemon_command, daemon_argv); + + perror("execvp"); + return 1; +}