From: Dmitry Potapov <dpotapov@gmail.com>
To: Git Mailing List <git@vger.kernel.org>
Subject: [RFC] Single system account for multiple git users
Date: Mon, 30 Jun 2008 19:11:14 +0400 [thread overview]
Message-ID: <20080630151113.GO5737@dpotapov.dyndns.org> (raw)
Hi,
Using SSH access with restricted git-shell as login shell and using
the script from the update-hook-example.txt works fine, but it requres
that every Git user has a separate system account on the server, which
is often frowned upon by system administrators, who would prefer to have
a single system account for access to Git repo.
I have looked on gitosis, but it requires normal shell account for
the git user, which was vetoed by sysadmin. Also, I found its
configuration more complex than necessary and not flexible enough
to differentiate what branches can have non-fast-forward pushes on
it and what cannot.
In fact, the simple solution for me would be to have authorized_key
for the git user being like this:
environment="GIT_USER=user1" ssh-rsa USER1-SSH-PUBLIC-KEY
environment="GIT_USER=user2" ssh-rsa USER2-SSH-PUBLIC-KEY
...
In this case, with one line change to update-hook-example from
username=$(id -u -n)
to
username="$GIT_USER"
I would get exactly what I want.
However, the environment option in authorized_key works only if
PermitUserEnvironment is set in sshd configuration, and this option
will allow _all_ users to overwrite their environment, which may be
not desirable in some settings for security reasons.
So, instead, I have to write a simple program, which is placed as
the login shell and interprets the given command as user name, sets
GIT_USER to it, and invokes git-shell with SSH_ORIGINAL_COMMAND.
Thus authorized_key looks like that:
command="git-su user1" ssh-rsa USER1-SSH-PUBLIC-KEY
command="git-su user2" ssh-rsa USER2-SSH-PUBLIC-KEY
...
But then I realized that it is simpler and more efficient to add
some built-in command to git-shell to do that.
You can see my patch below. I hope it will be useful for people
who wants to user git on server with a single system account for
all git users.
Dmitry
-- 8< --
From: Dmitry Potapov <dpotapov@gmail.com>
Date: Wed, 25 Jun 2008 08:14:22 +0400
Subject: [PATCH] git-shell: add git-su command
git-su interprets the given command as a user name that must be set to the
GIT_USER environment variable and then executing SSH_ORIGINAL_COMMAND as
it were the command given to git-shell. This allows to have different
values for GIT_USER variable for different ssh public keys, which is
necessary to have a single system for many Git users. With this command
the typical authorized_key will for git user will be look like this:
command="git-su user1" ssh-rsa USER1-SSH-PUBLIC-KEY
command="git-su user2" ssh-rsa USER2-SSH-PUBLIC-KEY
...
The alternative of using the "environment" option in authorized_key may be
problematic as it requires that the PermitUserEnvironment option was set
in sshd_config and by default this option is not enabled, because it may
allow some users to bypass access restrictions.
Signed-off-by: Dmitry Potapov <dpotapov@gmail.com>
---
I moved command parsing logic from main() to a separate function,
(which makes the patch a bit bigger than it actually is) and then
added do_su_cmd(), which reuses this functionality.
shell.c | 51 ++++++++++++++++++++++++++++++++++-----------------
1 files changed, 34 insertions(+), 17 deletions(-)
diff --git a/shell.c b/shell.c
index 91ca7de..05bd3cc 100644
--- a/shell.c
+++ b/shell.c
@@ -41,6 +41,19 @@ static int do_cvs_cmd(const char *me, char *arg)
return execv_git_cmd(cvsserver_argv);
}
+static int exec_cmd(char *prog);
+
+static int do_su_cmd(const char *me, char *arg)
+{
+ char *cmd = getenv("SSH_ORIGINAL_COMMAND");
+ if (!cmd)
+ die("SSH_ORIGINAL_COMMAND is not set");
+ if (setenv("GIT_USER", arg, 1))
+ die ("setenv failed: %s", strerror(errno));
+ if (unsetenv("SSH_ORIGINAL_COMMAND"))
+ die ("unsetenv failed: %s", strerror(errno));
+ return exec_cmd(cmd);
+}
static struct commands {
const char *name;
@@ -49,28 +62,14 @@ static struct commands {
{ "git-receive-pack", do_generic_cmd },
{ "git-upload-pack", do_generic_cmd },
{ "cvs", do_cvs_cmd },
+ { "git-su", do_su_cmd },
{ NULL },
};
-int main(int argc, char **argv)
+static int exec_cmd(char *prog)
{
- char *prog;
struct commands *cmd;
- /*
- * Special hack to pretend to be a CVS server
- */
- if (argc == 2 && !strcmp(argv[1], "cvs server"))
- argv--;
-
- /*
- * We do not accept anything but "-c" followed by "cmd arg",
- * where "cmd" is a very limited subset of git commands.
- */
- else if (argc != 3 || strcmp(argv[1], "-c"))
- die("What do you think I am? A shell?");
-
- prog = argv[2];
if (!strncmp(prog, "git", 3) && isspace(prog[3]))
/* Accept "git foo" as if the caller said "git-foo". */
prog[3] = '-';
@@ -91,7 +90,25 @@ int main(int argc, char **argv)
default:
continue;
}
- exit(cmd->exec(cmd->name, arg));
+ return cmd->exec(cmd->name, arg);
}
die("unrecognized command '%s'", prog);
}
+
+int main(int argc, char **argv)
+{
+ /*
+ * Special hack to pretend to be a CVS server
+ */
+ if (argc == 2 && !strcmp(argv[1], "cvs server"))
+ argv--;
+
+ /*
+ * We do not accept anything but "-c" followed by "cmd arg",
+ * where "cmd" is a very limited subset of git commands.
+ */
+ else if (argc != 3 || strcmp(argv[1], "-c"))
+ die("What do you think I am? A shell?");
+
+ return exec_cmd(argv[2]);
+}
--
1.5.6.1
next reply other threads:[~2008-06-30 15:12 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-06-30 15:11 Dmitry Potapov [this message]
2008-06-30 15:59 ` [RFC] Single system account for multiple git users Asheesh Laroia
2008-06-30 16:51 ` Dmitry Potapov
2008-06-30 16:56 ` Jon Loeliger
2008-06-30 17:07 ` Dmitry Potapov
2008-06-30 16:04 ` Jakub Narebski
2008-06-30 17:05 ` Dmitry Potapov
2008-07-01 8:55 ` Melchior FRANZ
2008-07-02 14:45 ` Dmitry Potapov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080630151113.GO5737@dpotapov.dyndns.org \
--to=dpotapov@gmail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).