public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* cygwin utils can access directory and its contents, but W10 utils claim to have no access, why?
@ 2024-01-22  6:18 John Ruckstuhl
  2024-01-22  7:33 ` Brian Inglis
  2024-01-22  9:48 ` Corinna Vinschen
  0 siblings, 2 replies; 5+ messages in thread
From: John Ruckstuhl @ 2024-01-22  6:18 UTC (permalink / raw)
  To: cygwin

I am seeing a weird phenomenon, hopefully someone can illuminate and teach.
Or point me to an archived thread.

I have some folders that Cygwin utils can readily access,
but W10 utils claim to have no access to.
It feels as if
*   the Cygwin utils try to do what they are commanded to do, and it's
    up to the OS to refuse if the ACLs are insufficient.
*   the W10 utils are written to decline to attempt access, due to some
    convention or gentlemen's agreement (built into some API?).
But wouldn't that lead Windows users to a false sense of protection, a
false sense of security?

Environment
*   Cygwin 3.4.9-1 on W10.  64-bit.
*   UAC is not active (based on EnableLUA=0 at boot)

I have a 3rd-party program “yabba” that many different users run (on the
same shared PC).
It leaves behind a “temporary” dir (under
C:/Users/username/AppData/Local/Temp), each time it’s run.
Many times per day.
These dirs are approx. 1000 files and 20 MB.
The 3rd-party program is an exe-file compiled with pyinstaller.
It unpacks a python script and a python interpreter, and runs the python
script.
But in our workflow, we usually terminate the execution brutally, so the
pyinstaller cleanup does not happen, leaving the 20 MB behind.

I want Bob, a member of the local group Administrators, to remove these folders.

For example, ordinary user Alice runs yabba a couple of times and leaves
behind 20 MB  in each of
    C:/Users/Alice/AppData/Local/Temp/_MEI21002
    C:/Users/Alice/AppData/Local/Temp/_MEI21282

Now for Local Administrator Bob, no impediment seeing these two dirs...
    $ cd C\:/Users/Alice/AppData/Local/Temp
    $ D1=_MEI21002
    $ D2=_MEI21282
    $ du -sh $D1 $D2
    21M     _MEI21002
    21M     _MEI21282
    $ for D in $D1 $D2; do printf "%s\t%s\n" $D "$(find "$D" -mindepth
1 -type d -printf "dirs\n" -o -printf "files\n" | sort | uniq -c |
paste - -)"; done
    _MEI21002            34 dirs        940 files
    _MEI21282            33 dirs        929 files
    $ getfacl $D1 $D2
    # file: _MEI21002
    # owner: Alice
    # group: Domain Users
    user::rwx
    group::---
    group:OWNER RIGHTS:rwx
    mask::rwx
    other::---


    # file: _MEI21282
    # owner: Alice
    # group: Domain Users
    user::rwx
    group::---
    group:OWNER RIGHTS:rwx
    mask::rwx
    other::---

And (for Local Administrator Bob) no impediment to removing them, for example,
    $ rm -r _MEI21282
(success!)

BUT Windows utils run by Bob the Administrator on the remaining dir
are blocked, like this
(cmd, "Run as administrator"):
    C:\Users\Alice\AppData\Local\Temp>dir _MEI21002
    Volume in drive C is OSDisk
    Volume Serial Number is 581C-10F2

    Directory of C:\Users\Alice\AppData\Local\Temp\_MEI21002

    File Not Found

    C:\Users\Alice\AppData\Local\Temp>icacls _MEI21002
    _MEI21002: Access is denied.
    Successfully processed 0 files; Failed processing 1 files

As a consequence, Windows utils run by Bob the Administrator cannot
delete Alice's directory.  Until they do a takeown.

The first try to delete fails:
    C:\Users\Alice\AppData\Local\Temp>del /S /Q _MEI21002
    Could Not Find C:\Users\Alice\AppData\Local\Temp\_MEI21002\*

But a takeown succeeds
    C:\Users\Alice\AppData\Local\Temp>takeown /A /F _MEI21002 /R /D Y

Now icacls has access
    C:\Users\Alice\AppData\Local\Temp>icacls _MEI21002
    _MEI21002 BUILTIN\Administrators:(OI)(IO)(F)
              BUILTIN\Administrators:(CI)(F)

    Successfully processed 1 files; Failed processing 0 files

And the second try to delete succeeds
    C:\Users\Alice\AppData\Local\Temp>del /S /Q _MEI21002

In summary, why is it that Bob the Administrator can Cygwin "rm.exe" to
delete these folders without taking ownership, but to delete with
Windows utils, he needs to take ownership first?

Thanks for teaching,
John Ruckstuhl

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: cygwin utils can access directory and its contents, but W10 utils claim to have no access, why?
  2024-01-22  6:18 cygwin utils can access directory and its contents, but W10 utils claim to have no access, why? John Ruckstuhl
@ 2024-01-22  7:33 ` Brian Inglis
  2024-01-22  9:48 ` Corinna Vinschen
  1 sibling, 0 replies; 5+ messages in thread
From: Brian Inglis @ 2024-01-22  7:33 UTC (permalink / raw)
  To: cygwin

On 2024-01-21 23:18, John Ruckstuhl via Cygwin wrote:
> I am seeing a weird phenomenon, hopefully someone can illuminate and teach.
> Or point me to an archived thread.
> 
> I have some folders that Cygwin utils can readily access,
> but W10 utils claim to have no access to.
> It feels as if
> *   the Cygwin utils try to do what they are commanded to do, and it's
>      up to the OS to refuse if the ACLs are insufficient.
> *   the W10 utils are written to decline to attempt access, due to some
>      convention or gentlemen's agreement (built into some API?).
> But wouldn't that lead Windows users to a false sense of protection, a
> false sense of security?
> 
> Environment
> *   Cygwin 3.4.9-1 on W10.  64-bit.
> *   UAC is not active (based on EnableLUA=0 at boot)
> 
> I have a 3rd-party program “yabba” that many different users run (on the
> same shared PC).
> It leaves behind a “temporary” dir (under
> C:/Users/username/AppData/Local/Temp), each time it’s run.
> Many times per day.
> These dirs are approx. 1000 files and 20 MB.
> The 3rd-party program is an exe-file compiled with pyinstaller.
> It unpacks a python script and a python interpreter, and runs the python
> script.
> But in our workflow, we usually terminate the execution brutally, so the
> pyinstaller cleanup does not happen, leaving the 20 MB behind.
> 
> I want Bob, a member of the local group Administrators, to remove these folders.
> 
> For example, ordinary user Alice runs yabba a couple of times and leaves
> behind 20 MB  in each of
>      C:/Users/Alice/AppData/Local/Temp/_MEI21002
>      C:/Users/Alice/AppData/Local/Temp/_MEI21282
> 
> Now for Local Administrator Bob, no impediment seeing these two dirs...
>      $ cd C\:/Users/Alice/AppData/Local/Temp
>      $ D1=_MEI21002
>      $ D2=_MEI21282
>      $ du -sh $D1 $D2
>      21M     _MEI21002
>      21M     _MEI21282
>      $ for D in $D1 $D2; do printf "%s\t%s\n" $D "$(find "$D" -mindepth
> 1 -type d -printf "dirs\n" -o -printf "files\n" | sort | uniq -c |
> paste - -)"; done
>      _MEI21002            34 dirs        940 files
>      _MEI21282            33 dirs        929 files
>      $ getfacl $D1 $D2
>      # file: _MEI21002
>      # owner: Alice
>      # group: Domain Users
>      user::rwx
>      group::---
>      group:OWNER RIGHTS:rwx
>      mask::rwx
>      other::---
> 
> 
>      # file: _MEI21282
>      # owner: Alice
>      # group: Domain Users
>      user::rwx
>      group::---
>      group:OWNER RIGHTS:rwx
>      mask::rwx
>      other::---
> 
> And (for Local Administrator Bob) no impediment to removing them, for example,
>      $ rm -r _MEI21282
> (success!)
> 
> BUT Windows utils run by Bob the Administrator on the remaining dir
> are blocked, like this
> (cmd, "Run as administrator"):
>      C:\Users\Alice\AppData\Local\Temp>dir _MEI21002
>      Volume in drive C is OSDisk
>      Volume Serial Number is 581C-10F2
> 
>      Directory of C:\Users\Alice\AppData\Local\Temp\_MEI21002
> 
>      File Not Found
> 
>      C:\Users\Alice\AppData\Local\Temp>icacls _MEI21002
>      _MEI21002: Access is denied.
>      Successfully processed 0 files; Failed processing 1 files
> 
> As a consequence, Windows utils run by Bob the Administrator cannot
> delete Alice's directory.  Until they do a takeown.
> 
> The first try to delete fails:
>      C:\Users\Alice\AppData\Local\Temp>del /S /Q _MEI21002
>      Could Not Find C:\Users\Alice\AppData\Local\Temp\_MEI21002\*
> 
> But a takeown succeeds
>      C:\Users\Alice\AppData\Local\Temp>takeown /A /F _MEI21002 /R /D Y
> 
> Now icacls has access
>      C:\Users\Alice\AppData\Local\Temp>icacls _MEI21002
>      _MEI21002 BUILTIN\Administrators:(OI)(IO)(F)
>                BUILTIN\Administrators:(CI)(F)
> 
>      Successfully processed 1 files; Failed processing 0 files
> 
> And the second try to delete succeeds
>      C:\Users\Alice\AppData\Local\Temp>del /S /Q _MEI21002
> 
> In summary, why is it that Bob the Administrator can Cygwin "rm.exe" to
> delete these folders without taking ownership, but to delete with
> Windows utils, he needs to take ownership first?

I normally find the problem is that a directory has no useful Windows DACLs 
defined, so directories or files created in it by Cygwin programs are not 
accessible to Windows programs.
It seems to me, that when Cygwin creates directories or files in those 
directories, they have no Windows ACLs defaulted, but they seem to look fine to 
Cygwin's assumed POSIX permissions, as if on FAT drives?
Better explanations would be welcome.

For directories, run:

	$ lsattr -adl 	$D
	$ ls -adlL	$D
	$ getfacl	$D
	$ icalcs "$(cygpath -m "$D")"

and for files, skip lsattr.

This should show you all the views of permissions you need to figure out the issue.

-- 
Take care. Thanks, Brian Inglis              Calgary, Alberta, Canada

La perfection est atteinte                   Perfection is achieved
non pas lorsqu'il n'y a plus rien à ajouter  not when there is no more to add
mais lorsqu'il n'y a plus rien à retirer     but when there is no more to cut
                                 -- Antoine de Saint-Exupéry

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: cygwin utils can access directory and its contents, but W10 utils claim to have no access, why?
  2024-01-22  6:18 cygwin utils can access directory and its contents, but W10 utils claim to have no access, why? John Ruckstuhl
  2024-01-22  7:33 ` Brian Inglis
@ 2024-01-22  9:48 ` Corinna Vinschen
  2024-01-22 18:59   ` John Ruckstuhl
  1 sibling, 1 reply; 5+ messages in thread
From: Corinna Vinschen @ 2024-01-22  9:48 UTC (permalink / raw)
  To: cygwin; +Cc: John.Ruckstuhl

On Jan 21 22:18, John Ruckstuhl via Cygwin wrote:
> I am seeing a weird phenomenon, hopefully someone can illuminate and teach.
> Or point me to an archived thread.
> 
> I have some folders that Cygwin utils can readily access,
> but W10 utils claim to have no access to.
> It feels as if
> *   the Cygwin utils try to do what they are commanded to do, and it's
>     up to the OS to refuse if the ACLs are insufficient.
> *   the W10 utils are written to decline to attempt access, due to some
>     convention or gentlemen's agreement (built into some API?).
> But wouldn't that lead Windows users to a false sense of protection, a
> false sense of security?

No, this has nothing to do with security, just with a weird concept
of user privileges.

Here's what happens:

> And (for Local Administrator Bob) no impediment to removing them, for example,
>     $ rm -r _MEI21282
> (success!)
> 
> BUT Windows utils run by Bob the Administrator on the remaining dir
> are blocked, like this

As you know, a "root" user on a Unix system has the right to ignore file
permissions.

That's why root users often have "rm" aliased to "rm -i" :)

Windows OTOH manages so called user privileges stored in the user's
access token.  One of these privileges is the right to ignore
permissions while reading (SE_BACKUP_PRIVILEGE), another privilege is
the right to set the ACL of a file to arbitrary permissions
(SE_RESTORE_PRIVILEGE).  These are the two privileges covering what a
"root" user can do to files.  As the names of these privileges suggest,
they were originally thought of privileges you only need for backup
tools.

Users in the Administrators group have these privileges in their user
token.  Under UAC, both privileges are removed from the token.  In an
elevated shell, though, both privileges are present.

The funny thing here is this: While both privileges are present in the
token, they are disabled by default.

They have to be enabled explicitely before you can exercise the
privileges.  Usually you do this in the same application
programatically.

Apart from backup tool, standard Windows tools practically *never*
enable these privileges, so they fail in various circumstances.  For
instance, a standard "del" in the CMD shell is not able to delete a file
even as administrator, if the file permissions don't allow delete access
for the Administrators group.

That's when you have to "take ownership" in the GUI as a last resort.
In NT4 times, even that had a good chance to fail for some reason I
never understood, back in the days.

However, since this concept is pretty weird and not a Unix concept, the
Cygwin DLL enables both privileges by default right at process startup.
If the privileges are not in the user token, nothing happens.  But if
the privileges are present, as for an elevated process of a user in the
Administrators group, then they will be enabled, and you're a "root"
user in the Unix sense.  And then it's "alias rm = rm -i" time again ;)


HTH,
Corinna

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: cygwin utils can access directory and its contents, but W10 utils claim to have no access, why?
  2024-01-22  9:48 ` Corinna Vinschen
@ 2024-01-22 18:59   ` John Ruckstuhl
  2024-04-03  2:07     ` John Ruckstuhl
  0 siblings, 1 reply; 5+ messages in thread
From: John Ruckstuhl @ 2024-01-22 18:59 UTC (permalink / raw)
  To: cygwin, John.Ruckstuhl

Thanks for the replies Brian & Corinna, I learned a lot.

On Mon, Jan 22, 2024 at 1:48 AM Corinna Vinschen
<corinna-cygwin@cygwin.com> wrote:
> Users in the Administrators group have these privileges in their user
> token.  Under UAC, both privileges are removed from the token.  In an
> elevated shell, though, both privileges are present.
>
> The funny thing here is this: While both privileges are present in the
> token, they are disabled by default.
>
> They have to be enabled explicitely before you can exercise the
> privileges.  Usually you do this in the same application
> programatically.

Now I see...
Local administrator Bob reports his User Access Token info
(with Windows whoami, not cygwin whoami)
    C:\>whoami /priv

    PRIVILEGES INFORMATION
    ----------------------

    Privilege Name                            ... State
    ========================================= ... ========
      ...
      SeBackupPrivilege                         ... Disabled
      SeRestorePrivilege                        ... Disabled
      ...

      C:\>

Thanks very much.
John Ruckstuhl

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: cygwin utils can access directory and its contents, but W10 utils claim to have no access, why?
  2024-01-22 18:59   ` John Ruckstuhl
@ 2024-04-03  2:07     ` John Ruckstuhl
  0 siblings, 0 replies; 5+ messages in thread
From: John Ruckstuhl @ 2024-04-03  2:07 UTC (permalink / raw)
  To: cygwin, John.Ruckstuhl

On Mon, Jan 22, 2024 at 10:59 AM John Ruckstuhl
<john.ruckstuhl@gmail.com> wrote:
>
> Thanks for the replies Brian & Corinna, I learned a lot.
>
> On Mon, Jan 22, 2024 at 1:48 AM Corinna Vinschen
> <corinna-cygwin@cygwin.com> wrote:
> > Users in the Administrators group have these privileges in their user
> > token.  Under UAC, both privileges are removed from the token.  In an
> > elevated shell, though, both privileges are present.
> >
> > The funny thing here is this: While both privileges are present in the
> > token, they are disabled by default.
> >
> > They have to be enabled explicitely before you can exercise the
> > privileges.  Usually you do this in the same application
> > programatically.
>
> Now I see...
> Local administrator Bob reports his User Access Token info
> (with Windows whoami, not cygwin whoami)
>     C:\>whoami /priv
>
>     PRIVILEGES INFORMATION
>     ----------------------
>
>     Privilege Name                            ... State
>     ========================================= ... ========
>       ...
>       SeBackupPrivilege                         ... Disabled
>       SeRestorePrivilege                        ... Disabled
>       ...
>
>       C:\>
>
> Thanks very much.
> John Ruckstuhl

The clue about UAT and disabled privileges was crucial.
Thank you again, Corinna.

I'm still doing my cleanup with ordinary Python (not the Cygwin Python
linked to the cygwin dll).
But I wrote an EnablePrivilege function to enable the privs if if necessary.
Best regards,
John Ruckstuhl

      1 """
      2 This module exports functions for removing old files and directories.
      3
      4 Functions
      5     myremove -- Remove the file or dir, and return the number
of bytes freed.
      6 """
      7
      8 # standard library imports
      9 import logging
     10 import os
     11 import shutil
     12 import subprocess
     13
     14 # related third party imports
     15 import win32api
     16 import win32security
     17
     18 # no local application/library specific imports
     19
     20
     21 logger = logging.getLogger(__name__)
     22
     23 # this custom startupinfo is used to suppress display of the
subprocess window
     24 startupinfo = subprocess.STARTUPINFO()
     25 startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
     26
     27
     28 def _remove(path):
     29     """Remove the file or dir, and return the number of bytes freed."""
     30
     31     ...
     32
     33
     34 def myremove(path):
     35     """Remove the file or dir, and return the number of bytes freed.
     36
     37     Attempt removal different ways, until successful (or defeated).
     38
     39     1.  Attempt call _remove (without additional prep).
     40     2.  Attempt to enable privileges SeBackupPrivilege and
     41         SeRestorePrivilege, then call _remove.
     42     3.  Attempt to takeown, then call _remove.
     43
     44     The enable privileges approach is ~6x faster than the
takeown approach,
     45     because takeown of an MEI dir containing ~1K files takes
time (8-9 sec).
     46
     47     Example results, enable privs approach
     48         MEI dirs: 113/113 removed, 2047.5 MB recovered in 2.0 minutes
     49
     50     Example results, takeown approach
     51         MEI dirs: 126/126 removed, 2453.8 MB recovered in 15.0 minutes
     52
     53     By default, the User Access Token for a member of local group
     54     Administrators has the privileges SeBackupPrivilege and
SeRestorePrivilege,
     55     but they are disabled.
     56
     57     The MEI dirs are typically ~1000 files occupying ~20 MB.
     58     The MEI dirs are created by users running the pyinstaller -generated
     59     executables ...
     60
     61     Presumably the process that calls this function is run as a user
     62     which is a member of local group "Administrators".  So
this process will
     63     have privileges SeBackupPrivilege and SeRestorePrivilege granted but
     64     disabled.  Also this process will be able to take
ownership, if needed.
     65     """
     66
     67     logger.debug('%s(%r)', 'myremove', path)
     68
     69     # first try, attempt _remove
     70     try:
     71         logger.debug('%s(%r)', '_remove', path)
     72         nbytes = _remove(path)
     73         return nbytes
     74     except WindowsError as e:
     75         if e.args == (5, 'Access is denied'):
     76             # report the exception and carry on to next attempt
     77             logger.debug(e)
     78         else:
     79             # re-raise any other WindowsError
     80             raise
     81
     82     # second try, attempt enable privs then _remove
     83     try:
     84         logger.debug('%s(%r)', '_remove', path)
     85         EnablePrivilege(win32security.SE_BACKUP_NAME)
     86         EnablePrivilege(win32security.SE_RESTORE_NAME)
     87         nbytes = _remove(path)
     88         return nbytes
     89     except Exception as e:
     90         # report the exception and carry on to next attempt
     91         logger.debug(e)
     92
     93     # third try, attempt takeown then _remove
     94     try:
     95         logger.debug('%s(%r)', '_remove', path)
     96         takeown(path)
     97         nbytes = _remove(path)
     98         return nbytes
     99     except Exception as e:
    100         # report the exception and carry on ...
    101         logger.debug(e)
    102
    103     # accept defeat
    104     raise
    105
    106
    107 def takeown(path):
    108     subprocess.check_call(
    109         [
    110             'takeown',
    111             '/A',
    112             '/F', path.replace('/', '\\'),
    113             '/R',
    114             '/D', 'Y',
    115         ],
    116         startupinfo=startupinfo)
    117
    118
    119 def EnablePrivilege(privilege):
    120     """Enable a privilege, if it's already granted in the User
Access Token.
    121
    122     From [1]:
    123         When a user holds a privilege, it allows that user to
do things that
    124         other users without that privilege are not allowed to
do. For example,
    125         the SeBackupPrivilege allows a user to read any file,
even if the
    126         security descriptor denies access.
    127         But just having the SeBackupPrivilege is not enough:
it needs to be
    128         enabled
    129
    130     [1]
https://blog.didierstevens.com/2021/07/19/using-sebackupprivilege-with-python
 # noqa: E501
    131     """
    132     hToken = win32security.OpenProcessToken(
    133         win32api.GetCurrentProcess(),
    134         win32security.TOKEN_ADJUST_PRIVILEGES |
win32security.TOKEN_QUERY
    135     )
    136     win32security.AdjustTokenPrivileges(
    137         hToken,
    138         0,
    139         [(
    140             win32security.LookupPrivilegeValue(None, privilege),
    141             win32security.SE_PRIVILEGE_ENABLED
    142         )]
    143     )
    144     win32api.CloseHandle(hToken)

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-04-03  2:08 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-22  6:18 cygwin utils can access directory and its contents, but W10 utils claim to have no access, why? John Ruckstuhl
2024-01-22  7:33 ` Brian Inglis
2024-01-22  9:48 ` Corinna Vinschen
2024-01-22 18:59   ` John Ruckstuhl
2024-04-03  2:07     ` John Ruckstuhl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).