You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Fernando Vicente <fv...@mwneo.com> on 2017/03/30 13:55:02 UTC

apr_file_copy with APR_FILE_SOURCE_PERMS not copying permissions if destination already exists

Hi list,

apr_file_copy does not copies permissions from source if the destination
already exists, even when the flag APR_FILE_SOURCE_PERMS is set.
I made a quick test by creating 3 files with the following permissions:
-rwx------. test1.txt
-rwxrwx---. test2.txt
-rwxrwx---. test3.txt

then I copied test1.txt over test3.txt, using apr_file_copy with the
APR_FILE_SOURCE_PERMS flag, so I was expecting that test3.txt permissions
would be copied from test1.txt, but that didn't happened. The content of
the file was copied correctly, I can see that test3.txt now has the content
of test1.txt, however the permissions were not copied from the source.

Is this the expected behaviour? should documentation warn that if the
destination already exists, then permissions will not be copied even with
that flag?


// TEST PROGRAM
apr_status_t    rc                      = APR_SUCCESS;  /* APR error code */
apr_file_t              *file           = NULL;                 /* file
handle */
apr_pool_t                      *pool;          /**< memory pool */

apr_pool_create(&pool,NULL);

if(APR_SUCCESS != (rc=apr_file_open(&file,"test1.txt",APR_WRITE|APR_
CREATE|APR_TRUNCATE,(apr_fileperms_t)APR_UREAD|APR_UWRITE|APR_UEXECUTE,pool)))
{
        return 1;
}
if(APR_SUCCESS != (rc=apr_file_write_full(file,(
void*)"1",(apr_size_t)1,NULL))) {
        SYS_XLOG_ERROR("Error writing to file: %s. rc:
%pm","test1.txt",&rc);
        return 1;
}
apr_file_close(file);
printf("test1.txt created with permissions: APR_UREAD|APR_UWRITE|APR_
UEXECUTE\n");

if(APR_SUCCESS != (rc=apr_file_open(&file,"test2.txt",APR_WRITE|APR_
CREATE|APR_TRUNCATE,(apr_fileperms_t)APR_UREAD|APR_
UWRITE|APR_UEXECUTE|APR_GREAD|APR_GWRITE|APR_GEXECUTE,pool))) {
        return 1;
}
if(APR_SUCCESS != (rc=apr_file_write_full(file,(
void*)"2",(apr_size_t)1,NULL))) {
        return 1;
}
apr_file_close(file);
printf("test2.txt created with permissions: APR_UREAD|APR_UWRITE|APR_
UEXECUTE|APR_GREAD|APR_GWRITE|APR_GEXECUTE\n");

if(APR_SUCCESS != (rc=apr_file_open(&file,"test3.txt",APR_WRITE|APR_
CREATE|APR_TRUNCATE,(apr_fileperms_t)APR_UREAD|APR_
UWRITE|APR_UEXECUTE|APR_GREAD|APR_GWRITE|APR_GEXECUTE,pool))) {
        return 1;
}
if(APR_SUCCESS != (rc=apr_file_write_full(file,(
void*)"3",(apr_size_t)1,NULL))) {
        return 1;
}
apr_file_close(file);
printf("test3.txt created with permissions: APR_UREAD|APR_UWRITE|APR_
UEXECUTE|APR_GREAD|APR_GWRITE|APR_GEXECUTE\n");

if(APR_SUCCESS !=
(rc=apr_file_copy("test1.txt","test3.txt",APR_FILE_SOURCE_PERMS,pool)))
{
        return 1;
}
printf("copied test1.txt to test3.txt\n");
return 0;

Re: apr_file_copy with APR_FILE_SOURCE_PERMS not copying permissions if destination already exists

Posted by William A Rowe Jr <wr...@rowe-clan.net>.
On Thu, Mar 30, 2017 at 11:30 AM, Nick Kew <ni...@apache.org> wrote:
> On Thu, 2017-03-30 at 09:59 -0500, William A Rowe Jr wrote:
>
>> > Is this the expected behaviour? should documentation warn that if the
>> > destination already exists, then permissions will not be copied even with
>> > that flag?
>>
>> Since we make no statement either way I wouldn't call this 'expected'.
>>
>> The linux behavior of cp -p differs from the APR 1.5.x and earlier behavior.
>
> Is Linux in any sense definitive?  Is there any standard
> with unix roots (or even from the Windows world)?
> Does the flag mirror anything from stdio & friends ?

There is no alternate implementation, the same file/unix/copy.c
source is used on all architectures.

Looking at a Win32 API for accomplishing the same, there are no
flags to surpress copying the permissions/security attributes, these
are always duplicated
https://msdn.microsoft.com/en-us/library/windows/desktop/aa363852%28v=vs.85%29.aspx
The CopyFile2 API is slightly richer (prepare for headspin);
COPY_FILE_REQUEST_SECURITY_PRIVILEGES
The copy is attempted, specifying ACCESS_SYSTEM_SECURITY for the
source file and ACCESS_SYSTEM_SECURITY | WRITE_DAC | WRITE_OWNER for
the destination file. If these requests are denied the access request
will be reduced to the highest privilege level for which access is
granted. For more information see SACL Access Right. This can be used
to allow theCopyFile2ProgressRoutine callback to perform operations
requiring higher privileges, such as copying the security attributes
for the file.

So in short, I don't think there is a good analog in the Win32 API,
and I'm not aware a posix file copy facility. There are convoluted
ioctl approaches, but nothing for general consumption, e.g.
http://lists.gnu.org/archive/html/coreutils/2011-08/msg00006.html

We should at least note that right now, permissions are only copied
or assigned if the file is absent when apr_file_copy() is invoked.

Re: apr_file_copy with APR_FILE_SOURCE_PERMS not copying permissions if destination already exists

Posted by Nick Kew <ni...@apache.org>.
On Thu, 2017-03-30 at 09:59 -0500, William A Rowe Jr wrote:

> > Is this the expected behaviour? should documentation warn that if the
> > destination already exists, then permissions will not be copied even with
> > that flag?
> 
> Since we make no statement either way I wouldn't call this 'expected'.
> 
> The linux behavior of cp -p differs from the APR 1.5.x and earlier behavior.

Is Linux in any sense definitive?  Is there any standard
with unix roots (or even from the Windows world)?
Does the flag mirror anything from stdio & friends ?

-- 
Nick Kew


Re: apr_file_copy with APR_FILE_SOURCE_PERMS not copying permissions if destination already exists

Posted by William A Rowe Jr <wr...@rowe-clan.net>.
On Fri, Mar 31, 2017 at 10:04 AM, Nick Kew <ni...@apache.org> wrote:
>
>> On 30 Mar 2017, at 15:59, William A Rowe Jr <wr...@rowe-clan.net> wrote:
>>
>> I'd suggest we treat it as a bug, change the behavior accordingly in 1.6.0,
>> and @bug the API to indicate the old vs new behavior. Thoughts?
>
> On reflection, +1 to all that.

The only objection I've considered is that the application of the perms
outside of the file create call will cost an additional syscall, it's slightly
less efficient.

It probably makes the most sense to simply re-apply the chmod again
without testing to determine whether the file had existed or not.

Others thoughts?

Re: apr_file_copy with APR_FILE_SOURCE_PERMS not copying permissions if destination already exists

Posted by Nick Kew <ni...@apache.org>.
> On 30 Mar 2017, at 15:59, William A Rowe Jr <wr...@rowe-clan.net> wrote:
> 
> I'd suggest we treat it as a bug, change the behavior accordingly in 1.6.0,
> and @bug the API to indicate the old vs new behavior. Thoughts?

On reflection, +1 to all that.

— 
Nick Kew

Re: apr_file_copy with APR_FILE_SOURCE_PERMS not copying permissions if destination already exists

Posted by William A Rowe Jr <wr...@rowe-clan.net>.
On Thu, Mar 30, 2017 at 8:55 AM, Fernando Vicente <fv...@mwneo.com> wrote:
>
> apr_file_copy does not copies permissions from source if the destination
> already exists, even when the flag APR_FILE_SOURCE_PERMS is set.
> I made a quick test by creating 3 files with the following permissions:
> -rwx------. test1.txt
> -rwxrwx---. test2.txt
> -rwxrwx---. test3.txt
>
> then I copied test1.txt over test3.txt, using apr_file_copy with the
> APR_FILE_SOURCE_PERMS flag, so I was expecting that test3.txt permissions
> would be copied from test1.txt, but that didn't happened. The content of the
> file was copied correctly, I can see that test3.txt now has the content of
> test1.txt, however the permissions were not copied from the source.
>
> Is this the expected behaviour? should documentation warn that if the
> destination already exists, then permissions will not be copied even with
> that flag?

Since we make no statement either way I wouldn't call this 'expected'.

The linux behavior of cp -p differs from the APR 1.5.x and earlier behavior.

We will need to @bug the API docs page either way as an informational
entry. We can certainly fix this behavior in APR 2.0.x.

I'd suggest we treat it as a bug, change the behavior accordingly in 1.6.0,
and @bug the API to indicate the old vs new behavior. Thoughts?