Skip to content

Commit a666b47

Browse files
kusmagitster
authored andcommitted
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>
1 parent 9cddf56 commit a666b47

File tree

2 files changed

+73
-29
lines changed

2 files changed

+73
-29
lines changed

Makefile

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ EXTRA_PROGRAMS =
401401
# ... and all the rest that could be moved out of bindir to gitexecdir
402402
PROGRAMS += $(EXTRA_PROGRAMS)
403403

404+
PROGRAM_OBJS += daemon.o
404405
PROGRAM_OBJS += fast-import.o
405406
PROGRAM_OBJS += imap-send.o
406407
PROGRAM_OBJS += shell.o
@@ -1066,7 +1067,6 @@ ifeq ($(uname_S),Windows)
10661067
NO_SVN_TESTS = YesPlease
10671068
NO_PERL_MAKEMAKER = YesPlease
10681069
RUNTIME_PREFIX = YesPlease
1069-
NO_POSIX_ONLY_PROGRAMS = YesPlease
10701070
NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
10711071
NO_NSEC = YesPlease
10721072
USE_WIN32_MMAP = YesPlease
@@ -1077,6 +1077,7 @@ ifeq ($(uname_S),Windows)
10771077
NO_CURL = YesPlease
10781078
NO_PYTHON = YesPlease
10791079
BLK_SHA1 = YesPlease
1080+
NO_POSIX_GOODIES = UnfortunatelyYes
10801081
NATIVE_CRLF = YesPlease
10811082

10821083
CC = compat/vcbuild/scripts/clink.pl
@@ -1119,7 +1120,6 @@ ifneq (,$(findstring MINGW,$(uname_S)))
11191120
NO_SVN_TESTS = YesPlease
11201121
NO_PERL_MAKEMAKER = YesPlease
11211122
RUNTIME_PREFIX = YesPlease
1122-
NO_POSIX_ONLY_PROGRAMS = YesPlease
11231123
NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
11241124
NO_NSEC = YesPlease
11251125
USE_WIN32_MMAP = YesPlease
@@ -1130,6 +1130,9 @@ ifneq (,$(findstring MINGW,$(uname_S)))
11301130
NO_PYTHON = YesPlease
11311131
BLK_SHA1 = YesPlease
11321132
ETAGS_TARGET = ETAGS
1133+
NO_INET_PTON = YesPlease
1134+
NO_INET_NTOP = YesPlease
1135+
NO_POSIX_GOODIES = UnfortunatelyYes
11331136
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch -Icompat/win32
11341137
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
11351138
COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o \
@@ -1249,9 +1252,6 @@ ifdef ZLIB_PATH
12491252
endif
12501253
EXTLIBS += -lz
12511254

1252-
ifndef NO_POSIX_ONLY_PROGRAMS
1253-
PROGRAM_OBJS += daemon.o
1254-
endif
12551255
ifndef NO_OPENSSL
12561256
OPENSSL_LIBSSL = -lssl
12571257
ifdef OPENSSLDIR
@@ -1419,6 +1419,10 @@ ifdef NO_DEFLATE_BOUND
14191419
BASIC_CFLAGS += -DNO_DEFLATE_BOUND
14201420
endif
14211421

1422+
ifdef NO_POSIX_GOODIES
1423+
BASIC_CFLAGS += -DNO_POSIX_GOODIES
1424+
endif
1425+
14221426
ifdef BLK_SHA1
14231427
SHA1_HEADER = "block-sha1/sha1.h"
14241428
LIB_OBJS += block-sha1/sha1.o

daemon.c

Lines changed: 64 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,62 @@ static void sanitize_stdfds(void)
940940
close(fd);
941941
}
942942

943+
#ifdef NO_POSIX_GOODIES
944+
945+
struct credentials;
946+
947+
static void drop_privileges(struct credentials *cred)
948+
{
949+
/* nothing */
950+
}
951+
952+
static void daemonize(void)
953+
{
954+
die("--detach not supported on this platform");
955+
}
956+
957+
static struct credentials *prepare_credentials(const char *user_name,
958+
const char *group_name)
959+
{
960+
die("--user not supported on this platform");
961+
}
962+
963+
#else
964+
965+
struct credentials {
966+
struct passwd *pass;
967+
gid_t gid;
968+
};
969+
970+
static void drop_privileges(struct credentials *cred)
971+
{
972+
if (cred && (initgroups(cred->pass->pw_name, cred->gid) ||
973+
setgid (cred->gid) || setuid(cred->pass->pw_uid)))
974+
die("cannot drop privileges");
975+
}
976+
977+
static struct credentials *prepare_credentials(const char *user_name,
978+
const char *group_name)
979+
{
980+
static struct credentials c;
981+
982+
c.pass = getpwnam(user_name);
983+
if (!c.pass)
984+
die("user not found - %s", user_name);
985+
986+
if (!group_name)
987+
c.gid = c.pass->pw_gid;
988+
else {
989+
struct group *group = getgrnam(group_name);
990+
if (!group)
991+
die("group not found - %s", group_name);
992+
993+
c.gid = group->gr_gid;
994+
}
995+
996+
return &c;
997+
}
998+
943999
static void daemonize(void)
9441000
{
9451001
switch (fork()) {
@@ -957,6 +1013,7 @@ static void daemonize(void)
9571013
close(2);
9581014
sanitize_stdfds();
9591015
}
1016+
#endif
9601017

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

970-
static int serve(struct string_list *listen_addr, int listen_port, struct passwd *pass, gid_t gid)
1027+
static int serve(struct string_list *listen_addr, int listen_port,
1028+
struct credentials *cred)
9711029
{
9721030
struct socketlist socklist = { NULL, 0, 0 };
9731031

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

979-
if (pass && gid &&
980-
(initgroups(pass->pw_name, gid) || setgid (gid) ||
981-
setuid(pass->pw_uid)))
982-
die("cannot drop privileges");
1037+
drop_privileges(cred);
9831038

9841039
return service_loop(&socklist);
9851040
}
@@ -991,9 +1046,7 @@ int main(int argc, char **argv)
9911046
int serve_mode = 0, inetd_mode = 0;
9921047
const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
9931048
int detach = 0;
994-
struct passwd *pass = NULL;
995-
struct group *group;
996-
gid_t gid = 0;
1049+
struct credentials *cred = NULL;
9971050
int i;
9981051

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

1142-
if (user_name) {
1143-
pass = getpwnam(user_name);
1144-
if (!pass)
1145-
die("user not found - %s", user_name);
1146-
1147-
if (!group_name)
1148-
gid = pass->pw_gid;
1149-
else {
1150-
group = getgrnam(group_name);
1151-
if (!group)
1152-
die("group not found - %s", group_name);
1153-
1154-
gid = group->gr_gid;
1155-
}
1156-
}
1195+
if (user_name)
1196+
cred = prepare_credentials(user_name, group_name);
11571197

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

1190-
return serve(&listen_addr, listen_port, pass, gid);
1230+
return serve(&listen_addr, listen_port, cred);
11911231
}

0 commit comments

Comments
 (0)