{"thread":{"id":"13845","subject":"[RFC PATCH] Use SUDO_UID to guess committer identity","startedAt":"2008-06-07T07:11:30Z","lastAt":"2008-06-08T00:57:28Z","messageCount":4,"participants":["Shawn O. Pearce","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"79020","messageId":"20080607071130.GZ12896@spearce.org","threadId":"13845","inReplyTo":null,"subject":"[RFC PATCH] Use SUDO_UID to guess committer identity","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2008-06-07T07:11:30Z","receivedAt":"2008-06-07T07:11:30Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"When invoking Git commands though sudo against a bare repository\nwith reflogs enabled we should attempt to record the actual user's\ninformation in the reflog, not the identity of the user sudo entered.\n\nFor example when executing:\n\n\tsudo -u gitadm git --git-dir=/srv/git.git branch -f pu master\n\nWe want record information about the caller of sudo, not gitadm.\n\nRelying on $SUDO_UID in this case isn't as bad as it might seem.\nUnder sudo $HOME is left as the real user's home directory and\n$HOME/.gitconfig is used to supply user.name and user.email.\nHowever if the real user does not have ~/.gitconfig or did not set\nuser.name/email we need to guess it from their GECOS information.\n\nNO SBO - FOR DISCUSSION ONLY\n---\n ident.c |   21 ++++++++++++++++++---\n 1 files changed, 18 insertions(+), 3 deletions(-)\n\ndiff --git a/ident.c b/ident.c\nindex b35504a..c821d5f 100644\n--- a/ident.c\n+++ b/ident.c\n@@ -7,6 +7,21 @@\n  */\n #include \"cache.h\"\n \n+static uid_t caller_uid(void)\n+{\n+\tconst char *sudo_uid = getenv(\"SUDO_UID\");\n+\tchar *end;\n+\tunsigned long who;\n+\n+\tif (!sudo_uid || !*sudo_uid)\n+\t\treturn getuid();\n+\n+\twho = strtoul(sudo_uid, &end, 10)\n+\tif (*end)\n+\t\treturn getuid();\n+\treturn (uid_t)who;\n+}\n+\n static char git_default_date[50];\n \n static void copy_gecos(const struct passwd *w, char *name, size_t sz)\n@@ -76,7 +91,7 @@ static void setup_ident(void)\n \n \t/* Get the name (\"gecos\") */\n \tif (!git_default_name[0]) {\n-\t\tpw = getpwuid(getuid());\n+\t\tpw = getpwuid(caller_uid());\n \t\tif (!pw)\n \t\t\tdie(\"You don't exist. Go away!\");\n \t\tcopy_gecos(pw, git_default_name, sizeof(git_default_name));\n@@ -90,7 +105,7 @@ static void setup_ident(void)\n \t\t\t\tsizeof(git_default_email));\n \t\telse {\n \t\t\tif (!pw)\n-\t\t\t\tpw = getpwuid(getuid());\n+\t\t\t\tpw = getpwuid(caller_uid());\n \t\t\tif (!pw)\n \t\t\t\tdie(\"You don't exist. Go away!\");\n \t\t\tcopy_email(pw);\n@@ -208,7 +223,7 @@ const char *fmt_ident(const char *name, const char *email,\n \t\t}\n \t\tif (error_on_no_name)\n \t\t\tdie(\"empty ident %s <%s> not allowed\", name, email);\n-\t\tpw = getpwuid(getuid());\n+\t\tpw = getpwuid(caller_uid());\n \t\tif (!pw)\n \t\t\tdie(\"You don't exist. Go away!\");\n \t\tstrlcpy(git_default_name, pw->pw_name,\n-- \nShawn.\n"},{"id":"79068","messageId":"7v63slnegm.fsf@gitster.siamese.dyndns.org","threadId":"13845","inReplyTo":"20080607071130.GZ12896@spearce.org","subject":"Re: [RFC PATCH] Use SUDO_UID to guess committer identity","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-06-07T21:05:13Z","receivedAt":"2008-06-07T21:05:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Shawn O. Pearce\" <spearce@spearce.org> writes:\n\n> When invoking Git commands though sudo against a bare repository\n> with reflogs enabled we should attempt to record the actual user's\n> information in the reflog, not the identity of the user sudo entered.\n>\n> For example when executing:\n>\n> \tsudo -u gitadm git --git-dir=/srv/git.git branch -f pu master\n>\n> We want record information about the caller of sudo, not gitadm.\n\nIf you are using something esoteric like pseudo, isn't it too much to ask\nto also use existing GIT_COMMITTER_NAME, or are there reasons why it is\nnot sufficient?\n"},{"id":"79075","messageId":"20080608002343.GG12896@spearce.org","threadId":"13845","inReplyTo":"7v63slnegm.fsf@gitster.siamese.dyndns.org","subject":"Re: [RFC PATCH] Use SUDO_UID to guess committer identity","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2008-06-08T00:23:43Z","receivedAt":"2008-06-08T00:23:43Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Junio C Hamano <gitster@pobox.com> wrote:\n> \"Shawn O. Pearce\" <spearce@spearce.org> writes:\n> \n> > When invoking Git commands though sudo against a bare repository\n> > with reflogs enabled we should attempt to record the actual user's\n> > information in the reflog, not the identity of the user sudo entered.\n> >\n> > For example when executing:\n> >\n> > \tsudo -u gitadm git --git-dir=/srv/git.git branch -f pu master\n> >\n> > We want record information about the caller of sudo, not gitadm.\n> \n> If you are using something esoteric like pseudo, isn't it too much to ask\n> to also use existing GIT_COMMITTER_NAME, or are there reasons why it is\n> not sufficient?\n\nThe issue is when users run commands though sudo, but forget to set a\nvalue for GIT_COMMITTER_NAME/EMAIL, or to configure ~/.gitconfig in\ntheir personal account.  Now git has to guess the values for these\nbased on the gecos of getuid(), and getuid() is returning the uid\nof the service account sudo entered (gitadm), not the real user's\naccount.  So the reflogs show generic \"GIT Admin\" and not who it was.\n\nEh, I'm myself not entirely happy with the patch.  It honors the\nreal user's $HOME/.gitconfig user.name/email settings and not the\nSUDO_UID data.  I'd almost prefer favoring SUDO_UID over whatever\nwe inherit in from the enviroment or from $HOME/.gitconfig when it\ncomes to committer identity.\n\n-- \nShawn.\n"},{"id":"79081","messageId":"7vprqsn3pj.fsf@gitster.siamese.dyndns.org","threadId":"13845","inReplyTo":"20080608002343.GG12896@spearce.org","subject":"Re: [RFC PATCH] Use SUDO_UID to guess committer identity","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-06-08T00:57:28Z","receivedAt":"2008-06-08T00:57:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Shawn O. Pearce\" <spearce@spearce.org> writes:\n\n> Junio C Hamano <gitster@pobox.com> wrote:\n>> \"Shawn O. Pearce\" <spearce@spearce.org> writes:\n>> \n>> > When invoking Git commands though sudo against a bare repository\n>> > with reflogs enabled we should attempt to record the actual user's\n>> > information in the reflog, not the identity of the user sudo entered.\n>> >\n>> > For example when executing:\n>> >\n>> > \tsudo -u gitadm git --git-dir=/srv/git.git branch -f pu master\n>> >\n>> > We want record information about the caller of sudo, not gitadm.\n> ...\n> The issue is when users run commands though sudo, but forget to set a\n> value for GIT_COMMITTER_NAME/EMAIL, or to configure ~/.gitconfig in\n> their personal account.\n\nIn your scenario, is the above \"sudo -u gitadm\" the exact command line\nthe end users type, or is it wrapped in the script you give to them?\n\n> Eh, I'm myself not entirely happy with the patch.  It honors the\n> real user's $HOME/.gitconfig user.name/email settings and not the\n> SUDO_UID data.  I'd almost prefer favoring SUDO_UID over whatever\n> we inherit in from the enviroment or from $HOME/.gitconfig when it\n> comes to committer identity.\n\nThe thing is, I personally hate pseudo and wish that your solution did not\nrely on SUDO_UID which is too specific to that hack.\n\nSometimes people need to lie to their SCM when doing things in behalf of\nsomebody else, and I agree we would want to give them a way to do so.  And\nwe do, just like RCS and CVS honor LOGNAME.\n\nIf you have /etc/hosts under RCS control but you do not want all the log\nentries to say 'root', and you would do:\n\n\t$ cd /etc\n\t$ su\n\troot# edit /etc/hosts\n\troot# LOGNAME=me ci -u -m 'Add host bar' hosts\n\nWhen omebody asks you to help him fixing his bug, you go to his keyboard,\nshow him how it should be done, and you concude the session with:\n\n\this shell$ LOGNAME=me ci -u -m 'Fix foo' foo.c\n\nThe point is that the same mechanism works (because it is designed to) in\nboth cases.\n"}]}