THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Browse Source

daemon: opt-out on features that require posix

Windows does not supply the POSIX-functions fork(), setuuid(), setgid(),
setsid() and initgroups(). Error out if --user or --detach is specified
when if so.

MinGW doesn't have prototypes and headers for inet_ntop and inet_pton,
so include our implementation instead. MSVC does, so avoid doing so
there.

Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
tags/v1.7.4-rc0
Erik Faye-Lund Junio C Hamano 9 years ago
parent
commit
a666b472c7
2 changed files with 73 additions and 29 deletions
  1. +9
    -5
      Makefile
  2. +64
    -24
      daemon.c

+ 9
- 5
Makefile View File

@@ -401,6 +401,7 @@ EXTRA_PROGRAMS =
# ... and all the rest that could be moved out of bindir to gitexecdir
PROGRAMS += $(EXTRA_PROGRAMS)

PROGRAM_OBJS += daemon.o
PROGRAM_OBJS += fast-import.o
PROGRAM_OBJS += imap-send.o
PROGRAM_OBJS += shell.o
@@ -1066,7 +1067,6 @@ ifeq ($(uname_S),Windows)
NO_SVN_TESTS = YesPlease
NO_PERL_MAKEMAKER = YesPlease
RUNTIME_PREFIX = YesPlease
NO_POSIX_ONLY_PROGRAMS = YesPlease
NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
NO_NSEC = YesPlease
USE_WIN32_MMAP = YesPlease
@@ -1077,6 +1077,7 @@ ifeq ($(uname_S),Windows)
NO_CURL = YesPlease
NO_PYTHON = YesPlease
BLK_SHA1 = YesPlease
NO_POSIX_GOODIES = UnfortunatelyYes
NATIVE_CRLF = YesPlease

CC = compat/vcbuild/scripts/clink.pl
@@ -1119,7 +1120,6 @@ ifneq (,$(findstring MINGW,$(uname_S)))
NO_SVN_TESTS = YesPlease
NO_PERL_MAKEMAKER = YesPlease
RUNTIME_PREFIX = YesPlease
NO_POSIX_ONLY_PROGRAMS = YesPlease
NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
NO_NSEC = YesPlease
USE_WIN32_MMAP = YesPlease
@@ -1130,6 +1130,9 @@ ifneq (,$(findstring MINGW,$(uname_S)))
NO_PYTHON = YesPlease
BLK_SHA1 = YesPlease
ETAGS_TARGET = ETAGS
NO_INET_PTON = YesPlease
NO_INET_NTOP = YesPlease
NO_POSIX_GOODIES = UnfortunatelyYes
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch -Icompat/win32
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o \
@@ -1249,9 +1252,6 @@ ifdef ZLIB_PATH
endif
EXTLIBS += -lz

ifndef NO_POSIX_ONLY_PROGRAMS
PROGRAM_OBJS += daemon.o
endif
ifndef NO_OPENSSL
OPENSSL_LIBSSL = -lssl
ifdef OPENSSLDIR
@@ -1419,6 +1419,10 @@ ifdef NO_DEFLATE_BOUND
BASIC_CFLAGS += -DNO_DEFLATE_BOUND
endif

ifdef NO_POSIX_GOODIES
BASIC_CFLAGS += -DNO_POSIX_GOODIES
endif

ifdef BLK_SHA1
SHA1_HEADER = "block-sha1/sha1.h"
LIB_OBJS += block-sha1/sha1.o


+ 64
- 24
daemon.c View File

@@ -940,6 +940,62 @@ static void sanitize_stdfds(void)
close(fd);
}

#ifdef NO_POSIX_GOODIES

struct credentials;

static void drop_privileges(struct credentials *cred)
{
/* nothing */
}

static void daemonize(void)
{
die("--detach not supported on this platform");
}

static struct credentials *prepare_credentials(const char *user_name,
const char *group_name)
{
die("--user not supported on this platform");
}

#else

struct credentials {
struct passwd *pass;
gid_t gid;
};

static void drop_privileges(struct credentials *cred)
{
if (cred && (initgroups(cred->pass->pw_name, cred->gid) ||
setgid (cred->gid) || setuid(cred->pass->pw_uid)))
die("cannot drop privileges");
}

static struct credentials *prepare_credentials(const char *user_name,
const char *group_name)
{
static struct credentials c;

c.pass = getpwnam(user_name);
if (!c.pass)
die("user not found - %s", user_name);

if (!group_name)
c.gid = c.pass->pw_gid;
else {
struct group *group = getgrnam(group_name);
if (!group)
die("group not found - %s", group_name);

c.gid = group->gr_gid;
}

return &c;
}

static void daemonize(void)
{
switch (fork()) {
@@ -957,6 +1013,7 @@ static void daemonize(void)
close(2);
sanitize_stdfds();
}
#endif

static void store_pid(const char *path)
{
@@ -967,7 +1024,8 @@ static void store_pid(const char *path)
die_errno("failed to write pid file '%s'", path);
}

static int serve(struct string_list *listen_addr, int listen_port, struct passwd *pass, gid_t gid)
static int serve(struct string_list *listen_addr, int listen_port,
struct credentials *cred)
{
struct socketlist socklist = { NULL, 0, 0 };

@@ -976,10 +1034,7 @@ static int serve(struct string_list *listen_addr, int listen_port, struct passwd
die("unable to allocate any listen sockets on port %u",
listen_port);

if (pass && gid &&
(initgroups(pass->pw_name, gid) || setgid (gid) ||
setuid(pass->pw_uid)))
die("cannot drop privileges");
drop_privileges(cred);

return service_loop(&socklist);
}
@@ -991,9 +1046,7 @@ int main(int argc, char **argv)
int serve_mode = 0, inetd_mode = 0;
const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
int detach = 0;
struct passwd *pass = NULL;
struct group *group;
gid_t gid = 0;
struct credentials *cred = NULL;
int i;

git_extract_argv0_path(argv[0]);
@@ -1139,21 +1192,8 @@ int main(int argc, char **argv)
if (group_name && !user_name)
die("--group supplied without --user");

if (user_name) {
pass = getpwnam(user_name);
if (!pass)
die("user not found - %s", user_name);

if (!group_name)
gid = pass->pw_gid;
else {
group = getgrnam(group_name);
if (!group)
die("group not found - %s", group_name);

gid = group->gr_gid;
}
}
if (user_name)
cred = prepare_credentials(user_name, group_name);

if (strict_paths && (!ok_paths || !*ok_paths))
die("option --strict-paths requires a whitelist");
@@ -1187,5 +1227,5 @@ int main(int argc, char **argv)
cld_argv[argc] = "--serve";
cld_argv[argc+1] = NULL;

return serve(&listen_addr, listen_port, pass, gid);
return serve(&listen_addr, listen_port, cred);
}

Loading…
Cancel
Save