diff options
author | Junio C Hamano <junkio@cox.net> | 2006-02-04 22:27:29 -0800 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2006-02-05 16:51:01 -0800 |
commit | 603968d22b19d1b98ff355cc32575a4d9845c151 (patch) | |
tree | f1901a61dd0af200460f8c4ecfb7db9cfcecc868 /daemon.c | |
parent | 1955fabf4194f3629e028778d0081bb2aa16c06c (diff) | |
download | git-603968d22b19d1b98ff355cc32575a4d9845c151.tar.gz git-603968d22b19d1b98ff355cc32575a4d9845c151.tar.xz |
daemon: extend user-relative path notation.
Earlier, we made --base-path to automatically forbid
user-relative paths, which was probably a mistake. This
introduces --user-path (or --user-path=path) option to control
the use of user-relative paths independently. The latter form
of the option can be used to restrict accesses to a part of each
user's home directory, similar to "public_html" some webservers
supports.
If we're invoked with --user-path=FOO option, then a URL of the
form git://~USER/PATH/... resolves to the path HOME/FOO/PATH/...,
where HOME is USER's home directory.
[jc: This is much reworked by me so bugs are mine, but the
original patch was done by Mark Wooding.]
Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'daemon.c')
-rw-r--r-- | daemon.c | 49 |
1 files changed, 42 insertions, 7 deletions
@@ -18,7 +18,8 @@ static int reuseaddr; static const char daemon_usage[] = "git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n" " [--timeout=n] [--init-timeout=n] [--strict-paths]\n" -" [--base-path=path] [--reuseaddr] [directory...]"; +" [--base-path=path] [--user-path | --user-path=path]\n" +" [--reuseaddr] [directory...]"; /* List of acceptable pathname prefixes */ static char **ok_paths = NULL; @@ -30,6 +31,12 @@ static int export_all_trees = 0; /* Take all paths relative to this one if non-NULL */ static char *base_path = NULL; +/* If defined, ~user notation is allowed and the string is inserted + * after ~user/. E.g. a request to git://host/~alice/frotz would + * go to /home/alice/pub_git/frotz with --user-path=pub_git. + */ +static char *user_path = NULL; + /* Timeout, and initial timeout */ static unsigned int timeout = 0; static unsigned int init_timeout = 0; @@ -137,6 +144,7 @@ static int avoid_alias(char *p) static char *path_ok(char *dir) { + static char rpath[PATH_MAX]; char *path; if (avoid_alias(dir)) { @@ -144,12 +152,31 @@ static char *path_ok(char *dir) return NULL; } - if (base_path) { - static char rpath[PATH_MAX]; - if (!strict_paths && *dir == '~') - ; /* allow user relative paths */ - else if (*dir != '/') { - /* otherwise allow only absolute */ + if (*dir == '~') { + if (!user_path) { + logerror("'%s': User-path not allowed", dir); + return NULL; + } + if (*user_path) { + /* Got either "~alice" or "~alice/foo"; + * rewrite them to "~alice/%s" or + * "~alice/%s/foo". + */ + int namlen, restlen = strlen(dir); + char *slash = strchr(dir, '/'); + if (!slash) + slash = dir + restlen; + namlen = slash - dir; + restlen -= namlen; + loginfo("userpath <%s>, request <%s>, namlen %d, restlen %d, slash <%s>", user_path, dir, namlen, restlen, slash); + snprintf(rpath, PATH_MAX, "%.*s/%s%.*s", + namlen, dir, user_path, restlen, slash); + dir = rpath; + } + } + else if (base_path) { + if (*dir != '/') { + /* Allow only absolute */ logerror("'%s': Non-absolute path denied (base-path active)", dir); return NULL; } @@ -688,6 +715,14 @@ int main(int argc, char **argv) reuseaddr = 1; continue; } + if (!strcmp(arg, "--user-path")) { + user_path = ""; + continue; + } + if (!strncmp(arg, "--user-path=", 12)) { + user_path = arg + 12; + continue; + } if (!strcmp(arg, "--")) { ok_paths = &argv[i+1]; break; |