diff options
-rw-r--r-- | Documentation/git-shell.txt | 82 | ||||
-rw-r--r-- | shell.c | 13 |
2 files changed, 82 insertions, 13 deletions
diff --git a/Documentation/git-shell.txt b/Documentation/git-shell.txt index 9b9250600..c35051ba5 100644 --- a/Documentation/git-shell.txt +++ b/Documentation/git-shell.txt @@ -9,25 +9,81 @@ git-shell - Restricted login shell for Git-only SSH access SYNOPSIS -------- [verse] -'git shell' [-c <command> <argument>] +'chsh' -s $(command -v git-shell) <user> +'git clone' <user>`@localhost:/path/to/repo.git` +'ssh' <user>`@localhost` DESCRIPTION ----------- -A login shell for SSH accounts to provide restricted Git access. When -'-c' is given, the program executes <command> non-interactively; -<command> can be one of 'git receive-pack', 'git upload-pack', 'git -upload-archive', 'cvs server', or a command in COMMAND_DIR. The shell -is started in interactive mode when no arguments are given; in this -case, COMMAND_DIR must exist, and any of the executables in it can be -invoked. +This is a login shell for SSH accounts to provide restricted Git access. +It permits execution only of server-side Git commands implementing the +pull/push functionality, plus custom commands present in a subdirectory +named `git-shell-commands` in the user's home directory. -'cvs server' is a special command which executes git-cvsserver. +COMMANDS +-------- + +'git shell' accepts the following commands after the '-c' option: + +'git receive-pack <argument>':: +'git upload-pack <argument>':: +'git upload-archive <argument>':: + Call the corresponding server-side command to support + the client's 'git push', 'git fetch', or 'git archive --remote' + request. +'cvs server':: + Imitate a CVS server. See linkgit:git-cvsserver[1]. + +If a `~/git-shell-commands` directory is present, 'git shell' will +also handle other, custom commands by running +"`git-shell-commands/<command> <arguments>`" from the user's home +directory. + +INTERACTIVE USE +--------------- + +By default, the commands above can be executed only with the '-c' +option; the shell is not interactive. -COMMAND_DIR is the path "$HOME/git-shell-commands". The user must have -read and execute permissions to the directory in order to execute the -programs in it. The programs are executed with a cwd of $HOME, and -<argument> is parsed as a command-line string. +If a `~/git-shell-commands` directory is present, 'git shell' +can also be run interactively (with no arguments). If a `help` +command is present in the `git-shell-commands` directory, it is +run to provide the user with an overview of allowed actions. Then a +"git> " prompt is presented at which one can enter any of the +commands from the `git-shell-commands` directory, or `exit` to close +the connection. + +Generally this mode is used as an administrative interface to allow +users to list repositories they have access to, create, delete, or +rename repositories, or change repository descriptions and +permissions. + +If a `no-interactive-login` command exists, then it is run and the +interactive shell is aborted. + +EXAMPLE +------- + +To disable interactive logins, displaying a greeting instead: ++ +---------------- +$ chsh -s /usr/bin/git-shell +$ mkdir $HOME/git-shell-commands +$ cat >$HOME/git-shell-commands/no-interactive-login <<\EOF +#!/bin/sh +printf '%s\n' "Hi $USER! You've successfully authenticated, but I do not" +printf '%s\n' "provide interactive shell access." +exit 128 +EOF +$ chmod +x $HOME/git-shell-commands/no-interactive-login +---------------- + +SEE ALSO +-------- +ssh(1), +linkgit:git-daemon[1], +contrib/git-shell-commands/README GIT --- @@ -6,6 +6,7 @@ #define COMMAND_DIR "git-shell-commands" #define HELP_COMMAND COMMAND_DIR "/help" +#define NOLOGIN_COMMAND COMMAND_DIR "/no-interactive-login" static int do_generic_cmd(const char *me, char *arg) { @@ -65,6 +66,18 @@ static void run_shell(void) { int done = 0; static const char *help_argv[] = { HELP_COMMAND, NULL }; + + if (!access(NOLOGIN_COMMAND, F_OK)) { + /* Interactive login disabled. */ + const char *argv[] = { NOLOGIN_COMMAND, NULL }; + int status; + + status = run_command_v_opt(argv, 0); + if (status < 0) + exit(127); + exit(status); + } + /* Print help if enabled */ run_command_v_opt(help_argv, RUN_SILENT_EXEC_FAILURE); |