I recently had a discussion with Garrett Rooney and William A. Rowe Jr. about a bug in apr_file_open (on Windows in APR 0.9.7) that when fixed created "problems" in apr_stat (for Subversion). Spurred by this discussion, I decided to look for the root cause of the problem.

And what I found was that apr_stat(&finfo, path, APR_FINFO_PROT, &pool) does indeed not behave (on Windows) as I imagine it would behave on Unix/Linux. The difference is that unpatched, the result in finfo.protection is *only* the world rights (translated into the group "Everyone" on Windows), and no group or user rights. With this patch, the finfo.protection includes the rights for the current user, and the rights for his/her primary group (plus of course world/Everyone). Which is much more like the way I believe it works on Unix/Linux.

In more detail, more_finfo() asks for user and group information based on "(wanted & (APR_FINFO_USER | APR_FINFO_UPROT))" and vice versa for groups. But when it calls GetSecurityInfo (and friends depending on input), it only supplies the user argument if "(wanted & APR_FINFO_USER)". Which means that when the routine later checks if "user" is valid, it isn't, which means that when we in resolve_prot() check to see if we can use the user information, it fails. The interesting thing is that resolve_prot() seems to be written as if this scenario should work from the beginning.

Note that I am by no means fluent in Unix/Linux, so if I have misunderstood that part, please set me straight immediately.

Regards,
/Andreas
Index: file_io/win32/filestat.c
===================================================================
--- file_io/win32/filestat.c    (revision 370999)
+++ file_io/win32/filestat.c    (working copy)
@@ -242,8 +242,8 @@
             }
             rv = GetNamedSecurityInfoW(wfile + fix, 
                                  SE_FILE_OBJECT, sinf,
-                                 ((wanted & APR_FINFO_USER) ? &user : NULL),
-                                 ((wanted & APR_FINFO_GROUP) ? &grp : NULL),
+                                 ((wanted & (APR_FINFO_USER | 
APR_FINFO_UPROT)) ? &user : NULL),
+                                 ((wanted & (APR_FINFO_GROUP | 
APR_FINFO_GPROT)) ? &grp : NULL),
                                  ((wanted & APR_FINFO_PROT) ? &dacl : NULL),
                                  NULL, &pdesc);
             if (fix == 6)
@@ -252,15 +252,15 @@
         else if (whatfile == MORE_OF_FSPEC)
             rv = GetNamedSecurityInfoA((char*)ufile, 
                                  SE_FILE_OBJECT, sinf,
-                                 ((wanted & APR_FINFO_USER) ? &user : NULL),
-                                 ((wanted & APR_FINFO_GROUP) ? &grp : NULL),
+                                 ((wanted & (APR_FINFO_USER | 
APR_FINFO_UPROT)) ? &user : NULL),
+                                 ((wanted & (APR_FINFO_GROUP | 
APR_FINFO_GPROT)) ? &grp : NULL),
                                  ((wanted & APR_FINFO_PROT) ? &dacl : NULL),
                                  NULL, &pdesc);
         else if (whatfile == MORE_OF_HANDLE)
             rv = GetSecurityInfo((HANDLE)ufile, 
                                  SE_FILE_OBJECT, sinf,
-                                 ((wanted & APR_FINFO_USER) ? &user : NULL),
-                                 ((wanted & APR_FINFO_GROUP) ? &grp : NULL),
+                                 ((wanted & (APR_FINFO_USER | 
APR_FINFO_UPROT)) ? &user : NULL),
+                                 ((wanted & (APR_FINFO_GROUP | 
APR_FINFO_GPROT)) ? &grp : NULL),
                                  ((wanted & APR_FINFO_PROT) ? &dacl : NULL),
                                  NULL, &pdesc);
         else

Reply via email to