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>
This commit is contained in:
parent
1955fabf41
commit
603968d22b
@ -10,7 +10,8 @@ SYNOPSIS
|
|||||||
[verse]
|
[verse]
|
||||||
'git-daemon' [--verbose] [--syslog] [--inetd | --port=n] [--export-all]
|
'git-daemon' [--verbose] [--syslog] [--inetd | --port=n] [--export-all]
|
||||||
[--timeout=n] [--init-timeout=n] [--strict-paths]
|
[--timeout=n] [--init-timeout=n] [--strict-paths]
|
||||||
[--base-path=path] [directory...]
|
[--base-path=path] [--user-path | --user-path=path]
|
||||||
|
[directory...]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
@ -42,8 +43,7 @@ OPTIONS
|
|||||||
This is sort of "GIT root" - if you run git-daemon with
|
This is sort of "GIT root" - if you run git-daemon with
|
||||||
'--base-path=/srv/git' on example.com, then if you later try to pull
|
'--base-path=/srv/git' on example.com, then if you later try to pull
|
||||||
'git://example.com/hello.git', `git-daemon` will interpret the path
|
'git://example.com/hello.git', `git-daemon` will interpret the path
|
||||||
as '/srv/git/hello.git'. Home directories (the '~login' notation)
|
as '/srv/git/hello.git'.
|
||||||
access is disabled.
|
|
||||||
|
|
||||||
--export-all::
|
--export-all::
|
||||||
Allow pulling from all directories that look like GIT repositories
|
Allow pulling from all directories that look like GIT repositories
|
||||||
@ -70,6 +70,15 @@ OPTIONS
|
|||||||
Log to syslog instead of stderr. Note that this option does not imply
|
Log to syslog instead of stderr. Note that this option does not imply
|
||||||
--verbose, thus by default only error conditions will be logged.
|
--verbose, thus by default only error conditions will be logged.
|
||||||
|
|
||||||
|
--user-path, --user-path=path::
|
||||||
|
Allow ~user notation to be used in requests. When
|
||||||
|
specified with no parameter, requests to
|
||||||
|
git://host/~alice/foo is taken as a request to access
|
||||||
|
'foo' repository in the home directory of user `alice`.
|
||||||
|
If `--user-path=path` is specified, the same request is
|
||||||
|
taken as a request to access `path/foo` repository in
|
||||||
|
the home directory of user `alice`.
|
||||||
|
|
||||||
--verbose::
|
--verbose::
|
||||||
Log details about the incoming connections and requested files.
|
Log details about the incoming connections and requested files.
|
||||||
|
|
||||||
|
49
daemon.c
49
daemon.c
@ -18,7 +18,8 @@ static int reuseaddr;
|
|||||||
static const char daemon_usage[] =
|
static const char daemon_usage[] =
|
||||||
"git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n"
|
"git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n"
|
||||||
" [--timeout=n] [--init-timeout=n] [--strict-paths]\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 */
|
/* List of acceptable pathname prefixes */
|
||||||
static char **ok_paths = NULL;
|
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 */
|
/* Take all paths relative to this one if non-NULL */
|
||||||
static char *base_path = 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 */
|
/* Timeout, and initial timeout */
|
||||||
static unsigned int timeout = 0;
|
static unsigned int timeout = 0;
|
||||||
static unsigned int init_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 *path_ok(char *dir)
|
||||||
{
|
{
|
||||||
|
static char rpath[PATH_MAX];
|
||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
if (avoid_alias(dir)) {
|
if (avoid_alias(dir)) {
|
||||||
@ -144,12 +152,31 @@ static char *path_ok(char *dir)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base_path) {
|
if (*dir == '~') {
|
||||||
static char rpath[PATH_MAX];
|
if (!user_path) {
|
||||||
if (!strict_paths && *dir == '~')
|
logerror("'%s': User-path not allowed", dir);
|
||||||
; /* allow user relative paths */
|
return NULL;
|
||||||
else if (*dir != '/') {
|
}
|
||||||
/* otherwise allow only absolute */
|
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);
|
logerror("'%s': Non-absolute path denied (base-path active)", dir);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -688,6 +715,14 @@ int main(int argc, char **argv)
|
|||||||
reuseaddr = 1;
|
reuseaddr = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!strcmp(arg, "--user-path")) {
|
||||||
|
user_path = "";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strncmp(arg, "--user-path=", 12)) {
|
||||||
|
user_path = arg + 12;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!strcmp(arg, "--")) {
|
if (!strcmp(arg, "--")) {
|
||||||
ok_paths = &argv[i+1];
|
ok_paths = &argv[i+1];
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user