You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@subversion.apache.org by Jeff Squyres <js...@open-mpi.org> on 2005/09/10 14:23:37 UTC

"svn cp" has different permissions semantics than "svn co"

Greetings.

I have found some unexpected behavior (at least from our perspective), 
and we're not sure if it's a bug or a deliberate design/implementation 
decision -- I supposed one could argue it either way.  So I bring the 
issue up to the SVN community to ask for some advice...

The issue is that if a restricted directory (via authz) exists in a 
tree where an unprivileged user tries to copy that tree, the user will 
get amorphous errors and finally fail.

Here's an example (this is with SVN client v1.2.3, server v1.1.4):

-----
svn co --username god https://svn.example.com/svn/test-repo/trunk 
god-test-repo
cd god-rest-repo
mkdir open-directory closed-directory
touch open-directory/file
touch closed-directory/file
svn add open-directory
svn add closed-directory
svn ci --username god -m "commit it all"
-----

Now go edit the corresponding authz file and set the following 
permissions:

-----
[test:/]
* = rw

[test:/trunk/closed-directory]
* =
god = rw
-----

Now try to checkout as a different user (i.e., one that does not have 
permissions in /trunk/closed-directory):

-----
svn co --username human https://svn.example.com/svn/test-repo/trunk 
human-test-repo
-----

That works with no problem -- the "closed-directory" directory is 
silently omitted.   However, the problem is if the "human" user tries 
to copy the /trunk into, say, /tags:

-----
svn cp --username human -m "make a tag" \
	https://svn.example.com/svn/test-repo/trunk \
	https://svn.example.com/svn/test-repo/tags/tag1
Authentication realm: <https://svn.example.com:443> Test Access
Password for 'human':
--> enter the human's password, even though it should already be cached
Authentication realm: <https://svn.example.com:443> Test Access
Username:
--> enter human
Password for 'human':
--> enter human's password
Authentication realm: <https://svn.example.com:443> Test Access
Username:
--> enter human
Password for 'human':
--> enter human's password
svn: COPY of tags/tag1: authorization failed (https://svn.example.com)
svn: Your commit message was left in a temporary file:
svn:    'svn-commit.tmp'
-----

In one sense, you can see why the copy failed -- the "human" user was 
not able to read the full source tree (i.e., human couldn't read 
closed-directory).

But on the other hand, human *was* able to successfully check out the 
trunk without error.  So why shouldn't human be able to cp as well?

The flip side of that argument, though, is that if any user (including 
a restricted user such as "human") is allowed to cp any tree regardless 
of permissions, then the results of that copy are dependent on who made 
the copy.

But then again, this is just like normal unix filesystem permissions -- 
the contents of a "cp -rf" are dependent on who executed the command.

... this argument goes on ad nauseam.  Each side has valid points.

This difference in permission semantics confused us for a while before 
we figured out what was going on.  It actually is somewhat painful -- 
it means that we cannot have restricted-access directories within our 
source tree, because then *only* developers with full access to the 
entire /trunk can make branches (we're in the habit of making lots of 
developer-private temporary branches when someone needs to go off and 
break the trunk for a while; they merge back up to the trunk when 
they're done).

More specifically, it would be fine (from our perspective) if the 
results of a "cp" are dependent upon the permissions of the user who 
executed it.  To ground this in the concrete example from above: it 
would be fine for human to have a copy of the trunk in /tags that does 
not have the closed-directory.

Comments?

-- 
{+} Jeff Squyres
{+} The Open MPI Project
{+} http://www.open-mpi.org/


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: "svn cp" has different permissions semantics than "svn co"

Posted by Jeff Squyres <js...@open-mpi.org>.
On Sep 12, 2005, at 10:11 AM, Joshua Varner wrote:

>> I would agree -- printing warnings would be a good first step (in both
>> cases -- co and cp).  But it would be quite preferable to allow the cp
>> to complete without erroring out.  If you don't, it would be pretty
>> hard for a user to complete the "cp" operation without a fairly
>> complicated script that checks for which trees were fully copied,
>> re-performs a subset of the cp, etc.  Even worse, this would lead to
>> lots of commits rather than a single, atomic commit.
>
> Printed warnings are a form of security leak though. If a user does
> not have access to the data, you may not want them to even know
> it exists, so these warnings need to be a server side configuration
> option.

Not a bad idea.  I can definitely see how silent rejection is good in 
some cases.

But I think that the default configuration should follow the Law of 
Least Surprise.  If something is deliberately not being done (e.g., not 
getting a directory on a checkout, or skipping a directory in a cp), a 
warning should be printed so that the user knows.  E.g.:

svn checkout: no authorization for "/trunk/foo/bar"; skipping and 
continuing...

Someone obviously thought about this when they implemented "co" that 
will silently skip directories that you don't have permission for -- 
but perhaps it would be better to:

a) print a warning (perhaps only the first time you "svn co" or "svn 
up" and get a restricted directory -- I can see how it could get 
annoying if you got that warning *every* time you did a "svn ci" or 
"svn diff" [or whatever] and it told you that there was a directory you 
couldn't access)

and/or

b) leave an empty directory there as a token (e.g., so that the user 
doesn't try to add another directory of the same name, which will 
currently fail with mysterious errors), and if the the user tries to 
svn add/commit/update/whatever inside that directory, the svn client 
should say, "Sorry, you don't have access in here".

Just another $0.02...

-- 
{+} Jeff Squyres
{+} The Open MPI Project
{+} http://www.open-mpi.org/


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: "svn cp" has different permissions semantics than "svn co"

Posted by Joshua Varner <jl...@gmail.com>.
On 9/12/05, Jeff Squyres <js...@open-mpi.org> wrote:
> On Sep 11, 2005, at 4:44 AM, Kalin KOZHUHAROV wrote:
> 
> > Can you give a reason why only god can read the
> > test:/trunk/closed-directory ?
> > I perfectly understand why only he can write, but putting it "ro" is
> > normal, IMHO.
> > So far I cannot think of a case like that...
> 
> Sure -- here's an easy one: some directories are simply not suitable
> for public access.
> 
> For example, the specific repository that I'm thinking of is an
> academic project that is available for anonymous / read-only access.
> However, given the "publish [first] or perish" survival strategy in
> academia, sometimes we want to be able to do something new in a tree
> that the public cannot [yet] access.  That is, in order to be "first"
> in academia, sometimes to have to operate in stealth mode for a little
> while, and when you finally have reportable results, open it to the
> world for public inspection, etc.
> 
> I can think of a number of related scenarios for vendor-based SVN
> repositories, too.
> 
> What it boils down to is: every project has different requirements.
> Now that one can have technology-enforced permissions in a source code
> repository (i.e., authz), you can bet that someone will have a scenario
> where locking out users from certain trees is a requirement (you could
> hack up similar scenarios in CVS, IIRC).  This is just like the normal
> filesystem -- it's perfectly normal to have some users have limited (or
> no) access in a given tree.  Why shouldn't that also apply to a
> repository?
> 
> More specifically -- why *wouldn't* it be reasonable to have this kind
> of scenario?
> 
> </philosophical_rant>
> 

This also might be required when working on government contracts
or when dealing with customers' trade secrets.

[snip]

> >
> > Hmm, very interesting... I haven't run into this (and I didn't bother
> > testing
> > it - I trust you :-) but I don't like this behaviour as well. Which
> > side
> > is better is also a difficult argument, but something has to be done.
> > A first step might be to print warning MSG on `svn co`:
> >
> > WARNING: Directory bla-bla skipped. Access denied
> >
> > or similar. The next step might be implementing a new command option,
> > say
> > --fail-on-error that will abort the chekout on such warnings.
> >
> > Any other comments?
> 
> I would agree -- printing warnings would be a good first step (in both
> cases -- co and cp).  But it would be quite preferable to allow the cp
> to complete without erroring out.  If you don't, it would be pretty
> hard for a user to complete the "cp" operation without a fairly
> complicated script that checks for which trees were fully copied,
> re-performs a subset of the cp, etc.  Even worse, this would lead to
> lots of commits rather than a single, atomic commit.
> 
> Just my $0.02...
> 

Printed warnings are a form of security leak though. If a user does
not have access to the data, you may not want them to even know
it exists, so these warnings need to be a server side configuration
option.

Josh

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org


Re: "svn cp" has different permissions semantics than "svn co"

Posted by Jeff Squyres <js...@open-mpi.org>.
On Sep 11, 2005, at 4:44 AM, Kalin KOZHUHAROV wrote:

> Can you give a reason why only god can read the 
> test:/trunk/closed-directory ?
> I perfectly understand why only he can write, but putting it "ro" is 
> normal, IMHO.
> So far I cannot think of a case like that...

Sure -- here's an easy one: some directories are simply not suitable 
for public access.

For example, the specific repository that I'm thinking of is an 
academic project that is available for anonymous / read-only access.  
However, given the "publish [first] or perish" survival strategy in 
academia, sometimes we want to be able to do something new in a tree 
that the public cannot [yet] access.  That is, in order to be "first" 
in academia, sometimes to have to operate in stealth mode for a little 
while, and when you finally have reportable results, open it to the 
world for public inspection, etc.

I can think of a number of related scenarios for vendor-based SVN 
repositories, too.

What it boils down to is: every project has different requirements.  
Now that one can have technology-enforced permissions in a source code 
repository (i.e., authz), you can bet that someone will have a scenario 
where locking out users from certain trees is a requirement (you could 
hack up similar scenarios in CVS, IIRC).  This is just like the normal 
filesystem -- it's perfectly normal to have some users have limited (or 
no) access in a given tree.  Why shouldn't that also apply to a 
repository?

More specifically -- why *wouldn't* it be reasonable to have this kind 
of scenario?

</philosophical_rant>

>> [snipped]
>> In one sense, you can see why the copy failed -- the "human" user was 
>> not able to read the full source tree (i.e., human couldn't read 
>> closed-directory).
>> But on the other hand, human *was* able to successfully check out the 
>> trunk without error.  So why shouldn't human be able to cp as well?
>> The flip side of that argument, though, is that if any user 
>> (including a restricted user such as "human") is allowed to cp any 
>> tree regardless of permissions, then the results of that copy are 
>> dependent on who made the copy.
>
> What about having a working directory?
>
> svn co -N --username human https://svn.example.com/svn/test-repo/
> svn co --username human https://svn.example.com/svn/test-repo/trunk 
> test-repo/trunk
> svn co -N --username human https://svn.example.com/svn/test-repo/tags 
> test-repo/tags
> cd test-repo
> svn cp trunk tags/tag1
> svn commit --username human -m "make a tag"
>
> Can this be done? Please try, as I just have this in my head, not 
> tested.

Unfortunately, I get the same results (I took a shortcut from what you 
typed above -- since I have a simple/small test repository explicitly 
for the purposes of this thread, I just checked the whole thing out as 
"human"):

% svn co --username human https://svn.example.com/svn/test human-full
A  human-full/trunk
A  human-full/trunk/open-directory
A  human-full/trunk/open-directory/file
A  human-full/branches
A  human-full/tags
Checked out revision 509.
% cd human-full/
% l
total 24
drwxrwxr-x  3 jsquyres research 4096 Sep 12 05:58 branches/
drwxrwxr-x  3 jsquyres research 4096 Sep 12 05:58 tags/
drwxrwxr-x  4 jsquyres research 4096 Sep 12 05:58 trunk/
% svn cp trunk tags/human-v1
A         tags/human-v1
% svn ci --username human -m "foo"
Adding         tags/human-v1
Authentication realm: <https://svn.example.com:443> Test Access
Password for 'human':
Authentication realm: <https://svn.example.com:443> Test Access
Username: human
Password for 'human':
Authentication realm: <https://svn.example.com:443> Test Access
Username: human
Password for 'human':
svn: Commit failed (details follow):
svn: COPY of human-v1: authorization failed (https://svn.osl.iu.edu)
svn: Your commit message was left in a temporary file:
svn:    '/blah/jsquyres/svn/test/human-full/svn-commit.tmp'

>> But then again, this is just like normal unix filesystem permissions 
>> -- the contents of a "cp -rf" are dependent on who executed the 
>> command.
>> ... this argument goes on ad nauseam.  Each side has valid points.
>> This difference in permission semantics confused us for a while 
>> before we figured out what was going on.  It actually is somewhat 
>> painful -- it means that we cannot have restricted-access directories 
>> within our source tree, because then *only* developers with full 
>> access to the entire /trunk can make branches (we're in the habit of 
>> making lots of developer-private temporary branches when someone 
>> needs to go off and break the trunk for a while; they merge back up 
>> to the trunk when they're done).
>> More specifically, it would be fine (from our perspective) if the 
>> results of a "cp" are dependent upon the permissions of the user who 
>> executed it.  To ground this in the concrete example from above: it 
>> would be fine for human to have a copy of the trunk in /tags that 
>> does not have the closed-directory.
>> Comments?
>
> Hmm, very interesting... I haven't run into this (and I didn't bother 
> testing
> it - I trust you :-) but I don't like this behaviour as well. Which 
> side
> is better is also a difficult argument, but something has to be done.
> A first step might be to print warning MSG on `svn co`:
>
> WARNING: Directory bla-bla skipped. Access denied
>
> or similar. The next step might be implementing a new command option, 
> say
> --fail-on-error that will abort the chekout on such warnings.
>
> Any other comments?

I would agree -- printing warnings would be a good first step (in both 
cases -- co and cp).  But it would be quite preferable to allow the cp 
to complete without erroring out.  If you don't, it would be pretty 
hard for a user to complete the "cp" operation without a fairly 
complicated script that checks for which trees were fully copied, 
re-performs a subset of the cp, etc.  Even worse, this would lead to 
lots of commits rather than a single, atomic commit.

Just my $0.02...

-- 
{+} Jeff Squyres
{+} The Open MPI Project
{+} http://www.open-mpi.org/


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: "svn cp" has different permissions semantics than "svn co"

Posted by Kalin KOZHUHAROV <ka...@thinrope.net>.
Jeff Squyres wrote:
> Greetings.
> 
> I have found some unexpected behavior (at least from our perspective), 
> and we're not sure if it's a bug or a deliberate design/implementation 
> decision -- I supposed one could argue it either way.  So I bring the 
> issue up to the SVN community to ask for some advice...
> 
> The issue is that if a restricted directory (via authz) exists in a tree 
> where an unprivileged user tries to copy that tree, the user will get 
> amorphous errors and finally fail.
> 
> Here's an example (this is with SVN client v1.2.3, server v1.1.4):
> 
> -----
> svn co --username god https://svn.example.com/svn/test-repo/trunk 
> god-test-repo
> cd god-rest-repo
> mkdir open-directory closed-directory
> touch open-directory/file
> touch closed-directory/file
> svn add open-directory
> svn add closed-directory
> svn ci --username god -m "commit it all"
> -----
> 
> Now go edit the corresponding authz file and set the following permissions:
> 
> -----
> [test:/]
> * = rw
> 
> [test:/trunk/closed-directory]
> * =
> god = rw
> -----

Can you give a reason why only god can read the test:/trunk/closed-directory ?
I perfectly understand why only he can write, but putting it "ro" is normal, IMHO.
So far I cannot think of a case like that...

> Now try to checkout as a different user (i.e., one that does not have 
> permissions in /trunk/closed-directory):
> 
> -----
> svn co --username human https://svn.example.com/svn/test-repo/trunk 
> human-test-repo
> -----
> 
> That works with no problem -- the "closed-directory" directory is 
> silently omitted.   However, the problem is if the "human" user tries to 
> copy the /trunk into, say, /tags:
> 
> -----
> svn cp --username human -m "make a tag" \
>     https://svn.example.com/svn/test-repo/trunk \
>     https://svn.example.com/svn/test-repo/tags/tag1
> Authentication realm: <https://svn.example.com:443> Test Access
> Password for 'human':
> --> enter the human's password, even though it should already be cached
> Authentication realm: <https://svn.example.com:443> Test Access
> Username:
> --> enter human
> Password for 'human':
> --> enter human's password
> Authentication realm: <https://svn.example.com:443> Test Access
> Username:
> --> enter human
> Password for 'human':
> --> enter human's password
> svn: COPY of tags/tag1: authorization failed (https://svn.example.com)
> svn: Your commit message was left in a temporary file:
> svn:    'svn-commit.tmp'
> -----
> 
> In one sense, you can see why the copy failed -- the "human" user was 
> not able to read the full source tree (i.e., human couldn't read 
> closed-directory).
> 
> But on the other hand, human *was* able to successfully check out the 
> trunk without error.  So why shouldn't human be able to cp as well?
> 
> The flip side of that argument, though, is that if any user (including a 
> restricted user such as "human") is allowed to cp any tree regardless of 
> permissions, then the results of that copy are dependent on who made the 
> copy.

What about having a working directory?

svn co -N --username human https://svn.example.com/svn/test-repo/
svn co --username human https://svn.example.com/svn/test-repo/trunk test-repo/trunk
svn co -N --username human https://svn.example.com/svn/test-repo/tags test-repo/tags
cd test-repo
svn cp trunk tags/tag1
svn commit --username human -m "make a tag"

Can this be done? Please try, as I just have this in my head, not tested.

I know that will be a PITA with big repos and it is a bit of typing :-(
It will actually not mage a good use, as tag1 and trunk will be different
from the beginnig.

But then, why do you have such permissions (see above question).

> But then again, this is just like normal unix filesystem permissions -- 
> the contents of a "cp -rf" are dependent on who executed the command.
> 
> ... this argument goes on ad nauseam.  Each side has valid points.
> 
> This difference in permission semantics confused us for a while before 
> we figured out what was going on.  It actually is somewhat painful -- it 
> means that we cannot have restricted-access directories within our 
> source tree, because then *only* developers with full access to the 
> entire /trunk can make branches (we're in the habit of making lots of 
> developer-private temporary branches when someone needs to go off and 
> break the trunk for a while; they merge back up to the trunk when 
> they're done).
> 
> More specifically, it would be fine (from our perspective) if the 
> results of a "cp" are dependent upon the permissions of the user who 
> executed it.  To ground this in the concrete example from above: it 
> would be fine for human to have a copy of the trunk in /tags that does 
> not have the closed-directory.
> 
> Comments?

Hmm, very interesting... I haven't run into this (and I didn't bother testing
it - I trust you :-) but I don't like this behaviour as well. Which side
is better is also a difficult argument, but something has to be done.
A first step might be to print warning MSG on `svn co`:

WARNING: Directory bla-bla skipped. Access denied

or similar. The next step might be implementing a new command option, say
--fail-on-error that will abort the chekout on such warnings.

Any other comments?

Kalin.
-- 
|[ ~~~~~~~~~~~~~~~~~~~~~~ ]|
+-> http://ThinRope.net/ <-+
|[ ______________________ ]|


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org