{"thread":{"id":"30968","subject":"git clone fails \"with error: RPC failed; result=22, HTTP code = 401","startedAt":"2012-07-06T12:04:10Z","lastAt":"2012-07-10T20:51:28Z","messageCount":2,"participants":["Ilya Ruprecht","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"194718","messageId":"CAEpEX_7xrGR+Uk5601iKKPr0uQDkT2sQ4ziPVmqCASYy51hBCQ@mail.gmail.com","threadId":"30968","inReplyTo":null,"subject":"git clone fails \"with error: RPC failed; result=22, HTTP code = 401","fromName":"Ilya Ruprecht","fromEmail":"ilya.ruprecht@googlemail.com","sentAt":"2012-07-06T12:04:10Z","receivedAt":"2012-07-06T12:04:10Z","isPatch":false,"sender":{"key":"ilya.ruprecht@googlemail.com","avatar":null},"body":"Hi all,\n\nfollowing enviroment:\n\nstock debian squeeze + apache2 + gitweb.\nApache handles user authentication over ldap.\n\n\nthe apache git-related config is:\n\n\n---\n(taken from the\nhttp://www.kernel.org/pub/software/scm/git/docs/git-http-backend.html)\n\n[...]\nSetEnv GIT_PROJECT_ROOT /mnt/system/git\n\nAliasMatch ^/git/(.*/objects/[0-9a-f]{2}/[0-9a-f]{38})$\n/mnt/system/git/$1\nAliasMatch ^/git/(.*/objects/pack/pack-[0-9a-f]{40}.(pack|idx))$\n/mnt/system/git/$1\nScriptAliasMatch \\\n        \"(?x)^/git/(.*/(HEAD | \\\n                        info/refs | \\\n                        objects/info/[^/]+ | \\\n                        git-(upload|receive)-pack))$\" \\\n        /usr/lib/git-core/git-http-backend/$1\nScriptAlias /git/ /usr/lib/cgi-bin/gitweb.cgi/\n\n[...]\n        <Location \"/git/repo1.git\">\n                # read access\n                <Limit GET>\n                        require ldap-group repo.writers\n                        require ldap-group repo.readers\n                </Limit>\n\n                # write access\n                <Limit GET PUT POST DELETE PROPPATCH MKCOL COPY MOVE\nLOCK UNLOCK>\n                        require ldap-group repo.writers\n                </Limit>\n\n        </Location>\n----------\n\nThe ldap group \"repo.writers\" has \"repo.writer\" user in it.\nThe ldap group \"repo.readers\" has \"repo.reader\" user in it.\n\nUsing the \"repo.writer\" User, i can successfully clone the repo / push\ninto the repo.\nThe appropriate apache-log entries are:\n\n----------------------------------------------------\n10.13.99.59 - - [06/Jul/2012:13:28:57 +0200] \"GET\n/git/repo1.git/info/refs?service=git-receive-pack HTTP/1.1\" 401 2427\n\"-\" \"git/1.7.2.5\"\n10.13.99.59 - repo.writer [06/Jul/2012:13:28:57 +0200] \"GET\n/git/repo1.git/info/refs?service=git-receive-pack HTTP/1.1\" 200 728\n\"-\" \"git/1.7.2.5\"\n10.13.99.59 - repo.writer [06/Jul/2012:13:28:57 +0200] \"POST\n/git/repo1.git/git-receive-pack HTTP/1.1\" 200 754 \"-\" \"git/1.7.2.5\"\n----------------------------------------------------\n\nBut if i try to use the \"repo.reader\" account to CLONE the repo, then it fails:\n\noutput@shell:\n----------------------------------------------------\nilya@brick:/tmp $ git clone https://repo.reader@git-host/git/repo1.git\nCloning into repo1...\nPassword:\nerror: RPC failed; result=22, HTTP code = 401\nfatal: The remote end hung up unexpectedly\nilya@brick:\n----------------------------------------------------\n\n\noutput@apache-logs\n----------------------------------------------------\n10.13.99.59 - - [06/Jul/2012:13:28:13 +0200] \"GET\n/git/repo1.git/info/refs?service=git-upload-pack HTTP/1.1\" 401 2427\n\"-\" \"git/1.7.2.5\"\n10.13.99.59 - repo.reader [06/Jul/2012:13:28:13 +0200] \"GET\n/git/repo1.git/info/refs?service=git-upload-pack HTTP/1.1\" 200 935 \"-\"\n\"git/1.7.2.5\"\n10.13.99.59 - repo.reader [06/Jul/2012:13:28:13 +0200] \"POST\n/git/repo1.git/git-upload-pack HTTP/1.1\" 401 894 \"-\" \"git/1.7.2.5\"\n----------------------------------------------------\n\nThe reason why the cloning fails is pretty clear\n\n1. the repo.reader is trying to \"POST /git/repo1.git/git-upload-pack\",\n2. accordingly the rule \"<Limit POST>\" for \"writers\" is matching,\n3. apache makes a lookup into LDAP and OF COURSE cannot fint the\n\"repo.reader\"-User in the group \"repo.writers\"\n4. as a result the 401 is replied by apache.\n\nWhen i put the \"repo.reader\" user into the \"repo.writers\"-group, then,\nof course, he can clone the repo.\nBut then he also can push into the repo...\n\n\nThe question is now - why, damn, the git client is trying to post\nsomething on CLONE!??!\n\nAnd the second question - how do i solve it?\n\n\nI need the authenticated read / authenticated writes separation.\n\n\nThanks in advance!\n\n\nIlya\n"},{"id":"194884","messageId":"20120710205128.GD23798@sigill.intra.peff.net","threadId":"30968","inReplyTo":"CAEpEX_7xrGR+Uk5601iKKPr0uQDkT2sQ4ziPVmqCASYy51hBCQ@mail.gmail.com","subject":"Re: git clone fails \"with error: RPC failed; result=22, HTTP code = 401","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-07-10T20:51:28Z","receivedAt":"2012-07-10T20:51:28Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Jul 06, 2012 at 02:04:10PM +0200, Ilya Ruprecht wrote:\n\n>         <Location \"/git/repo1.git\">\n>                 # read access\n>                 <Limit GET>\n>                         require ldap-group repo.writers\n>                         require ldap-group repo.readers\n>                 </Limit>\n> \n>                 # write access\n>                 <Limit GET PUT POST DELETE PROPPATCH MKCOL COPY MOVE\n> LOCK UNLOCK>\n>                         require ldap-group repo.writers\n>                 </Limit>\n\nAs you noticed, this will not do what you want. Git's smart-http\nprotocol uses POST requests to send the list of heads during ref\nnegotiation. So even a fetch request will require both GETs and POSTs.\n\nThe right way to restrict reading versus writing over smart-http is to\ncheck which git service is being requested (confusingly, \"git-upload-pack\"\nis for clones and fetches, and \"git-receive-pack\" is for pushes; the\nnames are based on what the _server_ is doing). There is an example in\nthe git-http-backend documentation, which uses a LocationMatch along\nwith a \"require\" directive.\n\n-Peff\n"}]}