mirror of
https://github.com/git/git
synced 2024-10-12 11:32:34 +00:00
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>
This commit is contained in:
parent
9cddf56ef1
commit
a666b472c7
14
Makefile
14
Makefile
|
@ -401,6 +401,7 @@ EXTRA_PROGRAMS =
|
||||||
# ... and all the rest that could be moved out of bindir to gitexecdir
|
# ... and all the rest that could be moved out of bindir to gitexecdir
|
||||||
PROGRAMS += $(EXTRA_PROGRAMS)
|
PROGRAMS += $(EXTRA_PROGRAMS)
|
||||||
|
|
||||||
|
PROGRAM_OBJS += daemon.o
|
||||||
PROGRAM_OBJS += fast-import.o
|
PROGRAM_OBJS += fast-import.o
|
||||||
PROGRAM_OBJS += imap-send.o
|
PROGRAM_OBJS += imap-send.o
|
||||||
PROGRAM_OBJS += shell.o
|
PROGRAM_OBJS += shell.o
|
||||||
|
@ -1066,7 +1067,6 @@ ifeq ($(uname_S),Windows)
|
||||||
NO_SVN_TESTS = YesPlease
|
NO_SVN_TESTS = YesPlease
|
||||||
NO_PERL_MAKEMAKER = YesPlease
|
NO_PERL_MAKEMAKER = YesPlease
|
||||||
RUNTIME_PREFIX = YesPlease
|
RUNTIME_PREFIX = YesPlease
|
||||||
NO_POSIX_ONLY_PROGRAMS = YesPlease
|
|
||||||
NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
|
NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
|
||||||
NO_NSEC = YesPlease
|
NO_NSEC = YesPlease
|
||||||
USE_WIN32_MMAP = YesPlease
|
USE_WIN32_MMAP = YesPlease
|
||||||
|
@ -1077,6 +1077,7 @@ ifeq ($(uname_S),Windows)
|
||||||
NO_CURL = YesPlease
|
NO_CURL = YesPlease
|
||||||
NO_PYTHON = YesPlease
|
NO_PYTHON = YesPlease
|
||||||
BLK_SHA1 = YesPlease
|
BLK_SHA1 = YesPlease
|
||||||
|
NO_POSIX_GOODIES = UnfortunatelyYes
|
||||||
NATIVE_CRLF = YesPlease
|
NATIVE_CRLF = YesPlease
|
||||||
|
|
||||||
CC = compat/vcbuild/scripts/clink.pl
|
CC = compat/vcbuild/scripts/clink.pl
|
||||||
|
@ -1119,7 +1120,6 @@ ifneq (,$(findstring MINGW,$(uname_S)))
|
||||||
NO_SVN_TESTS = YesPlease
|
NO_SVN_TESTS = YesPlease
|
||||||
NO_PERL_MAKEMAKER = YesPlease
|
NO_PERL_MAKEMAKER = YesPlease
|
||||||
RUNTIME_PREFIX = YesPlease
|
RUNTIME_PREFIX = YesPlease
|
||||||
NO_POSIX_ONLY_PROGRAMS = YesPlease
|
|
||||||
NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
|
NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
|
||||||
NO_NSEC = YesPlease
|
NO_NSEC = YesPlease
|
||||||
USE_WIN32_MMAP = YesPlease
|
USE_WIN32_MMAP = YesPlease
|
||||||
|
@ -1130,6 +1130,9 @@ ifneq (,$(findstring MINGW,$(uname_S)))
|
||||||
NO_PYTHON = YesPlease
|
NO_PYTHON = YesPlease
|
||||||
BLK_SHA1 = YesPlease
|
BLK_SHA1 = YesPlease
|
||||||
ETAGS_TARGET = ETAGS
|
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 += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch -Icompat/win32
|
||||||
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
|
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
|
||||||
COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o \
|
COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o \
|
||||||
|
@ -1249,9 +1252,6 @@ ifdef ZLIB_PATH
|
||||||
endif
|
endif
|
||||||
EXTLIBS += -lz
|
EXTLIBS += -lz
|
||||||
|
|
||||||
ifndef NO_POSIX_ONLY_PROGRAMS
|
|
||||||
PROGRAM_OBJS += daemon.o
|
|
||||||
endif
|
|
||||||
ifndef NO_OPENSSL
|
ifndef NO_OPENSSL
|
||||||
OPENSSL_LIBSSL = -lssl
|
OPENSSL_LIBSSL = -lssl
|
||||||
ifdef OPENSSLDIR
|
ifdef OPENSSLDIR
|
||||||
|
@ -1419,6 +1419,10 @@ ifdef NO_DEFLATE_BOUND
|
||||||
BASIC_CFLAGS += -DNO_DEFLATE_BOUND
|
BASIC_CFLAGS += -DNO_DEFLATE_BOUND
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef NO_POSIX_GOODIES
|
||||||
|
BASIC_CFLAGS += -DNO_POSIX_GOODIES
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef BLK_SHA1
|
ifdef BLK_SHA1
|
||||||
SHA1_HEADER = "block-sha1/sha1.h"
|
SHA1_HEADER = "block-sha1/sha1.h"
|
||||||
LIB_OBJS += block-sha1/sha1.o
|
LIB_OBJS += block-sha1/sha1.o
|
||||||
|
|
88
daemon.c
88
daemon.c
|
@ -940,6 +940,62 @@ static void sanitize_stdfds(void)
|
||||||
close(fd);
|
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)
|
static void daemonize(void)
|
||||||
{
|
{
|
||||||
switch (fork()) {
|
switch (fork()) {
|
||||||
|
@ -957,6 +1013,7 @@ static void daemonize(void)
|
||||||
close(2);
|
close(2);
|
||||||
sanitize_stdfds();
|
sanitize_stdfds();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void store_pid(const char *path)
|
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);
|
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 };
|
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",
|
die("unable to allocate any listen sockets on port %u",
|
||||||
listen_port);
|
listen_port);
|
||||||
|
|
||||||
if (pass && gid &&
|
drop_privileges(cred);
|
||||||
(initgroups(pass->pw_name, gid) || setgid (gid) ||
|
|
||||||
setuid(pass->pw_uid)))
|
|
||||||
die("cannot drop privileges");
|
|
||||||
|
|
||||||
return service_loop(&socklist);
|
return service_loop(&socklist);
|
||||||
}
|
}
|
||||||
|
@ -991,9 +1046,7 @@ int main(int argc, char **argv)
|
||||||
int serve_mode = 0, inetd_mode = 0;
|
int serve_mode = 0, inetd_mode = 0;
|
||||||
const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
|
const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
|
||||||
int detach = 0;
|
int detach = 0;
|
||||||
struct passwd *pass = NULL;
|
struct credentials *cred = NULL;
|
||||||
struct group *group;
|
|
||||||
gid_t gid = 0;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
git_extract_argv0_path(argv[0]);
|
git_extract_argv0_path(argv[0]);
|
||||||
|
@ -1139,21 +1192,8 @@ int main(int argc, char **argv)
|
||||||
if (group_name && !user_name)
|
if (group_name && !user_name)
|
||||||
die("--group supplied without --user");
|
die("--group supplied without --user");
|
||||||
|
|
||||||
if (user_name) {
|
if (user_name)
|
||||||
pass = getpwnam(user_name);
|
cred = prepare_credentials(user_name, group_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 (strict_paths && (!ok_paths || !*ok_paths))
|
if (strict_paths && (!ok_paths || !*ok_paths))
|
||||||
die("option --strict-paths requires a whitelist");
|
die("option --strict-paths requires a whitelist");
|
||||||
|
@ -1187,5 +1227,5 @@ int main(int argc, char **argv)
|
||||||
cld_argv[argc] = "--serve";
|
cld_argv[argc] = "--serve";
|
||||||
cld_argv[argc+1] = NULL;
|
cld_argv[argc+1] = NULL;
|
||||||
|
|
||||||
return serve(&listen_addr, listen_port, pass, gid);
|
return serve(&listen_addr, listen_port, cred);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue