X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=daemon.c;h=63cd12cd9c1909edbaab49aea066ff6fe03c3542;hb=ad5fa3cc0e115a8b111868af2f727322feb144cb;hp=a3f2ac1d81a21883c5ec7e9f1270c9109c675f12;hpb=1924d64f6e070edf1ad1949bf2eb95d4d2451f30;p=git.git diff --git a/daemon.c b/daemon.c index a3f2ac1d8..63cd12cd9 100644 --- a/daemon.c +++ b/daemon.c @@ -9,6 +9,10 @@ #define HOST_NAME_MAX 256 #endif +#ifndef NI_MAXSERV +#define NI_MAXSERV 32 +#endif + static int log_syslog; static int verbose; static int reuseaddr; @@ -16,7 +20,8 @@ static int reuseaddr; static const char daemon_usage[] = "git-daemon [--verbose] [--syslog] [--export-all]\n" " [--timeout=n] [--init-timeout=n] [--strict-paths]\n" -" [--base-path=path] [--user-path | --user-path=path]\n" +" [--base-path=path] [--base-path-relaxed]\n" +" [--user-path | --user-path=path]\n" " [--interpolated-path=path]\n" " [--reuseaddr] [--detach] [--pid-file=file]\n" " [--[enable|disable|allow-override|forbid-override]=service]\n" @@ -34,6 +39,7 @@ static int export_all_trees; /* Take all paths relative to this one if non-NULL */ static char *base_path; static char *interpolated_path; +static int base_path_relaxed; /* Flag indicating client sent extra args. */ static int saw_extended_args; @@ -180,6 +186,7 @@ static char *path_ok(struct interp *itable) { static char rpath[PATH_MAX]; static char interp_path[PATH_MAX]; + int retried_path = 0; char *path; char *dir; @@ -235,7 +242,22 @@ static char *path_ok(struct interp *itable) dir = rpath; } - path = enter_repo(dir, strict_paths); + do { + path = enter_repo(dir, strict_paths); + if (path) + break; + + /* + * if we fail and base_path_relaxed is enabled, try without + * prefixing the base path + */ + if (base_path && base_path_relaxed && !retried_path) { + dir = itable[INTERP_SLOT_DIR].value; + retried_path = 1; + continue; + } + break; + } while (1); if (!path) { logerror("'%s': unable to chdir or not a git archive", dir); @@ -284,7 +306,7 @@ struct daemon_service { static struct daemon_service *service_looking_at; static int service_enabled; -static int git_daemon_config(const char *var, const char *value) +static int git_daemon_config(const char *var, const char *value, void *cb) { if (!prefixcmp(var, "daemon.") && !strcmp(var + 7, service_looking_at->config_name)) { @@ -334,7 +356,7 @@ static int run_service(struct interp *itable, struct daemon_service *service) if (service->overridable) { service_looking_at = service; service_enabled = -1; - git_config(git_daemon_config); + git_config(git_daemon_config, NULL); if (0 <= service_enabled) enabled = service_enabled; } @@ -384,7 +406,8 @@ static struct daemon_service daemon_service[] = { { "receive-pack", "receivepack", receive_pack, 0, 1 }, }; -static void enable_service(const char *name, int ena) { +static void enable_service(const char *name, int ena) +{ int i; for (i = 0; i < ARRAY_SIZE(daemon_service); i++) { if (!strcmp(daemon_service[i].name, name)) { @@ -395,7 +418,8 @@ static void enable_service(const char *name, int ena) { die("No such service %s", name); } -static void make_service_overridable(const char *name, int ena) { +static void make_service_overridable(const char *name, int ena) +{ int i; for (i = 0; i < ARRAY_SIZE(daemon_service); i++) { if (!strcmp(daemon_service[i].name, name)) { @@ -518,7 +542,7 @@ static int execute(struct sockaddr *addr) if (addr->sa_family == AF_INET) { struct sockaddr_in *sin_addr = (void *) addr; inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf)); - port = sin_addr->sin_port; + port = ntohs(sin_addr->sin_port); #ifndef NO_IPV6 } else if (addr && addr->sa_family == AF_INET6) { struct sockaddr_in6 *sin6_addr = (void *) addr; @@ -528,7 +552,7 @@ static int execute(struct sockaddr *addr) inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(addrbuf) - 1); strcat(buf, "]"); - port = sin6_addr->sin6_port; + port = ntohs(sin6_addr->sin6_port); #endif } loginfo("Connection from %s:%d", addrbuf, port); @@ -1061,6 +1085,10 @@ int main(int argc, char **argv) base_path = arg+12; continue; } + if (!strcmp(arg, "--base-path-relaxed")) { + base_path_relaxed = 1; + continue; + } if (!prefixcmp(arg, "--interpolated-path=")) { interpolated_path = arg+20; continue; @@ -1121,6 +1149,11 @@ int main(int argc, char **argv) usage(daemon_usage); } + if (log_syslog) { + openlog("git-daemon", 0, LOG_DAEMON); + set_die_routine(daemon_die); + } + if (inetd_mode && (group_name || user_name)) die("--user and --group are incompatible with --inetd"); @@ -1148,14 +1181,17 @@ int main(int argc, char **argv) } } - if (log_syslog) { - openlog("git-daemon", 0, LOG_DAEMON); - set_die_routine(daemon_die); - } - if (strict_paths && (!ok_paths || !*ok_paths)) die("option --strict-paths requires a whitelist"); + if (base_path) { + struct stat st; + + if (stat(base_path, &st) || !S_ISDIR(st.st_mode)) + die("base-path '%s' does not exist or " + "is not a directory", base_path); + } + if (inetd_mode) { struct sockaddr_storage ss; struct sockaddr *peer = (struct sockaddr *)&ss;