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>
Erik Faye-Lund committed
Nov 4, 2010 at 02:35 UTC
a666b472c7d9e72bfacf4145405dbe8924ee153d
2 files changed
+73
-29
Makefile
+9
-5
@@ -401,6 +401,7 @@ EXTRA_PROGRAMS =
401
# ... and all the rest that could be moved out of bindir to gitexecdir
402
PROGRAMS += $(EXTRA_PROGRAMS)
403
404
+PROGRAM_OBJS += daemon.o
405
PROGRAM_OBJS += fast-import.o
406
PROGRAM_OBJS += imap-send.o
407
PROGRAM_OBJS += shell.o
@@ -1066,7 +1067,6 @@ ifeq ($(uname_S),Windows)
1067
NO_SVN_TESTS = YesPlease
1068
NO_PERL_MAKEMAKER = YesPlease
1069
RUNTIME_PREFIX = YesPlease
1069
- NO_POSIX_ONLY_PROGRAMS = YesPlease
1070
NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
1071
NO_NSEC = YesPlease
1072
USE_WIN32_MMAP = YesPlease
@@ -1077,6 +1077,7 @@ ifeq ($(uname_S),Windows)
1077
NO_CURL = YesPlease
1078
NO_PYTHON = YesPlease
1079
BLK_SHA1 = YesPlease
1080
+ NO_POSIX_GOODIES = UnfortunatelyYes
1081
NATIVE_CRLF = YesPlease
1082
1083
CC = compat/vcbuild/scripts/clink.pl
@@ -1119,7 +1120,6 @@ ifneq (,$(findstring MINGW,$(uname_S)))
1120
NO_SVN_TESTS = YesPlease
1121
NO_PERL_MAKEMAKER = YesPlease
1122
RUNTIME_PREFIX = YesPlease
1122
- NO_POSIX_ONLY_PROGRAMS = YesPlease
1123
NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
1124
NO_NSEC = YesPlease
1125
USE_WIN32_MMAP = YesPlease
@@ -1130,6 +1130,9 @@ ifneq (,$(findstring MINGW,$(uname_S)))
1130
NO_PYTHON = YesPlease
1131
BLK_SHA1 = YesPlease
1132
ETAGS_TARGET = ETAGS
1133
+ NO_INET_PTON = YesPlease
1134
+ NO_INET_NTOP = YesPlease
1135
+ NO_POSIX_GOODIES = UnfortunatelyYes
1136
COMPAT_CFLAGS += -D__USE_MINGW_ACCESS -DNOGDI -Icompat -Icompat/fnmatch -Icompat/win32
1137
COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\"
1138
COMPAT_OBJS += compat/mingw.o compat/fnmatch/fnmatch.o compat/winansi.o \
@@ -1249,9 +1252,6 @@ ifdef ZLIB_PATH
1252
endif
1253
EXTLIBS += -lz
1254
1252
-ifndef NO_POSIX_ONLY_PROGRAMS
1253
- PROGRAM_OBJS += daemon.o
1254
-endif
1255
ifndef NO_OPENSSL
1256
OPENSSL_LIBSSL = -lssl
1257
ifdef OPENSSLDIR
@@ -1419,6 +1419,10 @@ ifdef NO_DEFLATE_BOUND
1419
BASIC_CFLAGS += -DNO_DEFLATE_BOUND
1420
endif
1421
1422
+ifdef NO_POSIX_GOODIES
1423
+ BASIC_CFLAGS += -DNO_POSIX_GOODIES
1424
+endif
1425
+
1426
ifdef BLK_SHA1
1427
SHA1_HEADER = "block-sha1/sha1.h"
1428
LIB_OBJS += block-sha1/sha1.o
daemon.c
+64
-24
@@ -940,6 +940,62 @@ static void sanitize_stdfds(void)
940
close(fd);
941
}
942
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
+
999
static void daemonize(void)
1000
{
1001
switch (fork()) {
@@ -957,6 +1013,7 @@ static void daemonize(void)
1013
close(2);
1014
sanitize_stdfds();
1015
}
1016
+#endif
1017
1018
static void store_pid(const char *path)
1019
{
@@ -967,7 +1024,8 @@ static void store_pid(const char *path)
1024
die_errno("failed to write pid file '%s'", path);
1025
}
1026
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)
1029
{
1030
struct socketlist socklist = { NULL, 0, 0 };
1031
@@ -976,10 +1034,7 @@ static int serve(struct string_list *listen_addr, int listen_port, struct passwd
1034
die("unable to allocate any listen sockets on port %u",
1035
listen_port);
1036
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);
1038
1039
return service_loop(&socklist);
1040
}
@@ -991,9 +1046,7 @@ int main(int argc, char **argv)
1046
int serve_mode = 0, inetd_mode = 0;
1047
const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
1048
int detach = 0;
994
- struct passwd *pass = NULL;
995
- struct group *group;
996
- gid_t gid = 0;
1049
+ struct credentials *cred = NULL;
1050
int i;
1051
1052
git_extract_argv0_path(argv[0]);
@@ -1139,21 +1192,8 @@ int main(int argc, char **argv)
1192
if (group_name && !user_name)
1193
die("--group supplied without --user");
1194
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);
1197
1198
if (strict_paths && (!ok_paths || !*ok_paths))
1199
die("option --strict-paths requires a whitelist");
@@ -1187,5 +1227,5 @@ int main(int argc, char **argv)
1227
cld_argv[argc] = "--serve";
1228
cld_argv[argc+1] = NULL;
1229
1190
- return serve(&listen_addr, listen_port, pass, gid);
1230
+ return serve(&listen_addr, listen_port, cred);
1231
}