Tcl Source Code

View Ticket
Login
Ticket UUID: 855923
Title: [file readable/writable] broken on W2K (CVS HEAD)
Type: Bug Version: obsolete: 8.5a0
Submitter: cc_benny Created on: 2003-12-07 21:56:24
Subsystem: 37. File System Assigned To: vincentdarley
Priority: 5 Medium Severity:
Status: Closed Last Modified: 2003-12-09 22:12:17
Resolution: Fixed Closed By: vincentdarley
    Closed on: 2003-12-09 15:12:17
Description:
[file readable] returns 0 for files on my system.
Below is the output of the attached test script.
The also attached patch fixes the problem for
me.

The root of the problem seems to be an incorrect
use of the MapGenericMask API.

>>>>>>>>>>>>
% source test.fileaccess.tcl
% test
Owner: BUILTIN\Administrators
User: CAESAR\benny

Test no access
OK

Test readable only
1 != [file readable test.dat]
Actual rights are:
I:\Projects\test.dat CAESAR\benny:R

Test writable only
1 != [file writable test.dat]
Actual rights are:
I:\Projects\test.dat CAESAR\benny:(special access:)

                                  READ_CONTROL
                                  SYNCHRONIZE
                                  FILE_GENERIC_WRITE
                                  FILE_WRITE_DATA
                                  FILE_APPEND_DATA
                                  FILE_WRITE_EA
                                  FILE_EXECUTE
                                  FILE_WRITE_ATTRIBUTES

Test read+write
1 != [file readable test.dat]
1 != [file writable test.dat]
Actual rights are:
I:\Projects\test.dat CAESAR\benny:(special access:)

                                  READ_CONTROL
                                  SYNCHRONIZE
                                  FILE_GENERIC_READ
                                  FILE_GENERIC_WRITE
                                  FILE_GENERIC_EXECUTE
                                  FILE_READ_DATA
                                  FILE_WRITE_DATA
                                  FILE_APPEND_DATA
                                  FILE_READ_EA
                                  FILE_WRITE_EA
                                  FILE_EXECUTE
                                  FILE_READ_ATTRIBUTES
                                  FILE_WRITE_ATTRIBUTES

Test full access
1 != [file readable test.dat]
1 != [file writable test.dat]
Actual rights are:
I:\Projects\test.dat CAESAR\benny:F
% 
<<<<<<<<<<
User Comments: vincentdarley added on 2003-12-09 21:05:18:
Logged In: YES 
user_id=32170

Ok, that's works!  Thanks...

I'll set about adding some tests to Tcl's suite.

cc_benny added on 2003-12-09 20:49:48:

File Deleted - 69866: 



File Added - 70042: test.fileaccess.tcl

Logged In: YES 
user_id=143885

> Test no access
> 0 != [file readable test.dat]
> 0 != [test_read test.dat]
> 0 != [file writable test.dat]
> 0 != [test_writ test.dat]
> Actual rights are:
> C:Documents and SettingsVinceDest.dat NT AUTHORITYSYSTEM:F 
>                                          
> BUILTINAdministrators:F

If you followed my advice literally, you should have now

catch {cacls $fname /E /R "Everyone"} result
catch {cacls $fname /E /R $user} result
cacls $fname /E /P $user:N
catch {cacls $fname /E /R $owner} result

Try this instead

catch {cacls $fname /E /R "Everyone"} result
catch {cacls $fname /E /R $user} result
catch {cacls $fname /E /R $owner} result
cacls $fname /E /P $user:N

> Test readable only
> 0 != [file writable test.dat]
> 0 != [test_writ test.dat]
> Actual rights are:
> C:Documents and SettingsVinceDest.dat NT AUTHORITYSYSTEM:F 
>                                          
> BUILTINAdministrators:F 
>                                           TURINGVinceD:R

And after

puts "
Test readable only"

Also add

cacls $fname /E /P $user:N

Anyway.  I'll just upload my new version of the script
;-).

vincentdarley added on 2003-12-09 19:05:03:
Logged In: YES 
user_id=32170

With that cacls addition, I now get:

Test no access
0 != [file readable test.dat]
0 != [test_read test.dat]
0 != [file writable test.dat]
0 != [test_writ test.dat]
Actual rights are:
C:Documents and SettingsVinceDest.dat NT AUTHORITYSYSTEM:F 
                                         
BUILTINAdministrators:F

Test readable only
0 != [file writable test.dat]
0 != [test_writ test.dat]
Actual rights are:
C:Documents and SettingsVinceDest.dat NT AUTHORITYSYSTEM:F 
                                         
BUILTINAdministrators:F 
                                          TURINGVinceD:R

Test writable only
OK

Test read+write
OK

Test full access
OK

-- so it's a bit closer!

cc_benny added on 2003-12-09 18:46:14:
Logged In: YES 
user_id=143885

Hi Vince,

Sure, here is some extended commentary on the script.
Note that I am not sure at all how portable this is or
can be made.  This relies on command-line tools and
especially localization can make interaction with
command-line tools very ugly on Windows.  In addition
the cacls tool is very tricky, and some of the problem
I have had may just be bugs, which may be fixed later.


> proc cacls {fname args} {

A small proc to encapsulate the NT cacls command-line
tool.  A "y" is piped into the command to cover a
possible question for confirmation.  Only one "y", so
only one file can be given, I think.

See the output of cacls /? on a command prompt for all
I know about cacls. 

I'm not sure how portable this is to XP.  The tool is
also probably localized for non-english systems.

> proc getuser {fname} {

Parses the output of the "dir/q" command to find the
owner of a file.  I haven't found a specialized tool
for this and cacls doesn't say either.

> proc test_read {fname} {

A test for readablity by actually reading the file. 

> proc test_writ {fname} {

A test for writability by actually writing the file
(overwrites the contents).

> proc test_access {fname read writ} {

Test the readablilty and writability of a file.  Output
to stdout, if a test does not agree with the parameters
"read" or "writ".  This tests with [file
readable/writable] as well as with [test_read] and
test_writ].  If any differences between the test and
the given parameters are detected, cacls is called at
the end to output the actual rights of the file for
diagnosis.

See calls in [test] below.


> proc test {} {

A bunch of actual test scenarios. 

> set owner [getuser $fname]
> set user $::env(USERDOMAIN)\$::env(USERNAME)
> puts "Owner: $owner"
> puts "User: $user"

Determine and print what we know about user and file
owner.

> # Clean out all well-known ACLs
> catch {cacls $fname /E /R "Everyone"} result
> catch {cacls $fname /E /R $user} result
> catch {cacls $fname /E /R $owner} result

Remove all ACLs that are known to be added
automatically to new files. 

> puts "
Test no access"
> test_access $fname 0 0

Without ACLs there should be no access. 

> puts "
Test readable only"
> cacls $fname /E /G $user:R
> test_access $fname 1 0

Add GENERIC_READ ACL for current user.  Now there
should be only read access. 

> puts "
Test writable only"
> catch {cacls $fname /E /R $user} result
> cacls $fname /E /G $user:W
> test_access $fname 0 1

Remove ACL for current user.  Add GENERIC_WRITE ACL.
Now there should be only write access.

> puts "
Test read+write"
> catch {cacls $fname /E /R $user} result
> cacls $fname /E /G $user:R
> cacls $fname /E /G $user:W
> test_access $fname 1 1

Remove ACL for current user.  Add GENERIC_READ ACL and
GENERIC_WRITE ACL.  Now there should be both read and
write access.

> puts "
Test full access"
> catch {cacls $fname /E /R $user} result
> cacls $fname /E /G $user:F
> test_access $fname 1 1

Remove ACL for current user.  Add GENERIC_ALL (full)
ACL.  There should be both read and write access.


To your test run:

> Owner: TURINGVinceD
> User: TURINGVinceD

So you are user TURINGVinceD (where did that backslash
go?) and you own the file yourself.

> Test no access
> 0 != [file readable test.dat]
> 0 != [test_read test.dat]
> 0 != [file writable test.dat]
> 0 != [test_writ test.dat]
> Actual rights are:
> C:Documents and SettingsVinceDest.dat NT AUTHORITYSYSTEM:F 
>                                          
> BUILTINAdministrators:F

We have a problem here, because "System" and the
"Administrators" still have full access, and that
access seems to be used for the tests.  Can you try
this to add to all occurrences of

catch {cacls $fname /E /R $user} result

also this rule:

cacls $fname /E /P $user:N

That adds an explicit ACL to deny access for the
current user.

benny

vincentdarley added on 2003-12-09 16:11:48:
Logged In: YES 
user_id=32170

Could you explain the test script please (both so I
understand it and so I can add tests to winFile.test)... 
When I run it I get:

Owner: TURINGVinceD
User: TURINGVinceD

Test no access
0 != [file readable test.dat]
0 != [test_read test.dat]
0 != [file writable test.dat]
0 != [test_writ test.dat]
Actual rights are:
C:Documents and SettingsVinceDest.dat NT AUTHORITYSYSTEM:F 
                                         
BUILTINAdministrators:F

Test readable only
0 != [file writable test.dat]
0 != [test_writ test.dat]
Actual rights are:
C:Documents and SettingsVinceDest.dat NT AUTHORITYSYSTEM:F 
                                         
BUILTINAdministrators:F 
                                          TURINGVinceD:R

Test writable only
0 != [file readable test.dat]
0 != [test_read test.dat]
Actual rights are:
C:Documents and SettingsVinceDest.dat NT AUTHORITYSYSTEM:F 
                                         
BUILTINAdministrators:F 
                                         
TURINGVinceD:(special access:)

                                                       
READ_CONTROL
                                                       
SYNCHRONIZE
                                                       
FILE_GENERIC_WRITE
                                                       
FILE_WRITE_DATA
                                                       
FILE_APPEND_DATA
                                                       
FILE_WRITE_EA
                                                       
FILE_EXECUTE
                                                       
FILE_WRITE_ATTRIBUTES

Test read+write
OK

Test full access
OK
(VinceD) 2 % 
-- which appears as if some tests in it have failed??

cc_benny added on 2003-12-08 04:58:13:

File Added - 69867: tclWinFile.c.patch

cc_benny added on 2003-12-08 04:56:24:

File Added - 69866: test.fileaccess.tcl

Attachments: