@matheusbsbs / matheus-bagliano / commits / a666b472c7
Fork 0

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 }