delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2024/04/02/22:08:40

X-Recipient: archive-cygwin AT delorie DOT com
DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E68DE3858D39
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cygwin.com;
s=default; t=1712110117;
bh=fdKlHAm97PJV5XN9WDMd+CPVe57T3+wgEO2b7P5SJO4=;
h=References:In-Reply-To:Date:Subject:To:List-Id:List-Unsubscribe:
List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:
From;
b=vwiz2UGOlIY1XVK78/kWPLekhC+inz0suS3t51fdn2vfT2IgDROkXbMo+8OEtUTXy
d/0BFISkTiSAU4PJq7K9oKguf1UBs+nc52Yjl8cJ51zfX5mKOklEMkloxVyr5GwX6W
fFsutVllH0tBDsYwoH+QuR5IVObicvyJuqZVZacM=
X-Original-To: cygwin AT cygwin DOT com
Delivered-To: cygwin AT cygwin DOT com
DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AF41B3858D39
ARC-Filter: OpenARC Filter v1.0.0 sourceware.org AF41B3858D39
ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1712110089; cv=none;
b=SaclE4Rju9y+lEVE+DWaBMIGtDZyVqYvrRTMLTA2CViRVgWx7kZ/U3SH4c1c2xdDhC8v2xyp0BTFwsxmQ17pG74UYwkkOIcZolV9rxR5tnSe37wEBF+snM33ZyMtXSUg81nHiAst8aXbuVsGPglJ8/7VEHWBZDGdVno8AXQAm5k=
ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key;
t=1712110089; c=relaxed/simple;
bh=ab0S2NphcxxFRQbB8m/dKcJopLj+DR9XhADmM/Ytpck=;
h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To;
b=lZMLCLy8UJd7WniFQKabt6/eB4xn+AgXwm7uqvOhOgNTGYKoM6M6YkFPE25NMZlvk6qqi5WD7Q5CdAsQdn4AIsbKjEABzqk8Ad8IRkINa/bMytidG1Cv+1jfGE2goW6Nya4Ua8MlDx8LEBW1mGQjCW6us0XMZY/NRXZ6QLAxHXQ=
ARC-Authentication-Results: i=1; server2.sourceware.org
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=1e100.net; s=20230601; t=1712110086; x=1712714886;
h=content-transfer-encoding:to:subject:message-id:date:from:reply-to
:in-reply-to:references:mime-version:x-gm-message-state:from:to:cc
:subject:date:message-id:reply-to;
bh=M7s7kMVliNsjvpdi0OsbC3GXahdo2yp2MmPSMZcBMQs=;
b=kG1/MdPmkEncYZ3Z8eLEMEUkaM0WRgsoRmXJhcQ7JBvQ1T4CoMEJt4xmhILg8W/MUM
Jd/NoWWuQJpezADX2PolNylE+5XXTJ0qh3Z6pgoS8EVhok9LfbTnNVjy8tteF3s5lKSA
MFcrlehGcvW9hAWGHykanS6ERxvQgXHBA9PhZtjfxLXWzLPYEUMlDYAJJw4SgnI0N9iE
QRftC7tk/Mnp+/3u6p56QWwcRnvVmoWn/oyx8u4pzFxTSZnSxaeOyaJU40+nhDAuRiU2
N+BOGwZLHWPqu7IIfZ+ePcvtyi+WHOstNSs0PGNzA32PxDrTv9SzcA4xfufftEH00ssB
DMzg==
X-Gm-Message-State: AOJu0YxK3bed4yN2pGOSygx9Kk52we3Az5t6P3F9P8FeNxlI9nuFHVuC
WRhdPpr53QVdrZBmvHxjTYIYxcGFtA4+OrUep9X7AhOlCDDb3umU3lrs3mvoysSGtOFe365aGkg
deErxVrLFcTmb8kOpEK7e9EZzE+ctTpF3tLc=
X-Google-Smtp-Source: AGHT+IE0KnTFwQTwjByFOnOeHIHC5p7tEzsE4lirx+wEGqZWa2GMV8U73ZbipXUU7XoPyO73nOVN+87YNzhVbhMGEW0=
X-Received: by 2002:a25:8a84:0:b0:dbe:4f15:b5cf with SMTP id
h4-20020a258a84000000b00dbe4f15b5cfmr1244320ybl.15.1712110086333; Tue, 02 Apr
2024 19:08:06 -0700 (PDT)
MIME-Version: 1.0
References: <CAOBROv1Jgj1cZ6nL64Y=rYRR5cvd8VRw3XH0xD4E57c_=MKU=w AT mail DOT gmail DOT com>
<Za454au_liWSTwhw AT calimero DOT vinschen DOT de>
<CAOBROv25QD8w703nim4yU0EzXz-Gw3WzrsUicYbm6q9u5y0ozQ AT mail DOT gmail DOT com>
In-Reply-To: <CAOBROv25QD8w703nim4yU0EzXz-Gw3WzrsUicYbm6q9u5y0ozQ@mail.gmail.com>
Date: Tue, 2 Apr 2024 19:07:54 -0700
Message-ID: <CAOBROv0RwvjeCFZ0W0C4LA4i56P8W+QmWbgMn7MfVFY5yo_OCw@mail.gmail.com>
Subject: Re: cygwin utils can access directory and its contents, but W10 utils
claim to have no access, why?
To: cygwin AT cygwin DOT com, John DOT Ruckstuhl AT gmail DOT com
X-Spam-Status: No, score=1.5 required=5.0 tests=BAYES_00, CLAIM_SUBJECT,
DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM,
RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS,
TXREP autolearn=no autolearn_force=no version=3.4.6
X-Spam-Level: *
X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on
server2.sourceware.org
X-BeenThere: cygwin AT cygwin DOT com
X-Mailman-Version: 2.1.30
List-Id: General Cygwin discussions and problem reports <cygwin.cygwin.com>
List-Archive: <https://cygwin.com/pipermail/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-request AT cygwin DOT com?subject=help>
List-Subscribe: <https://cygwin.com/mailman/listinfo/cygwin>,
<mailto:cygwin-request AT cygwin DOT com?subject=subscribe>
From: John Ruckstuhl via Cygwin <cygwin AT cygwin DOT com>
Reply-To: John DOT Ruckstuhl AT gmail DOT com
Sender: "Cygwin" <cygwin-bounces+archive-cygwin=delorie DOT com AT cygwin DOT com>
X-MIME-Autoconverted: from base64 to 8bit by delorie.com id 43328dLe2067931

On Mon, Jan 22, 2024 at 10:59 AM John Ruckstuhl
<john DOT ruckstuhl AT gmail DOT 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 AT cygwin DOT 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)

-- 
Problem reports:      https://cygwin.com/problems.html
FAQ:                  https://cygwin.com/faq/
Documentation:        https://cygwin.com/docs.html
Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019