cannot run setup64.exe without admin privileges (even if renamed foo.exe)

Shaddy Baddah
Tue Oct 15 15:18:00 GMT 2013

Hi Corinna,

On 15/10/13 23:22, Corinna Vinschen wrote:
> Hi Shaddy,
> On Oct 15 21:21, Shaddy Baddah wrote:
>> Hi Corinna,
>> On 15/10/13 20:08, Corinna Vinschen wrote:
>>> [...]
>>> Assuming setup would get an "asInvoker" manifest, so it runs with the
>>> privileges of the current user.  First thing it would check its user
>>> token.  There are three cases:
>>> - When started by a non-admin user, the user token would contain no
>>>    trace of the administrators group in the user token group list.
>>>    In this case, setup would just run along as usual for the current user.
>>> - When started elevated (with "Run as administrator...", for instance),
>>>    the user token group list would contain the administrators group,
>>>    enabled.  So setup knows it has admin rights anyway and just runs along
>>>    as in the non-admin user case.  So, in fact, these two cases are just
>>>    one case.
>>> - Now, when started by an admin user, but not elevated, the group list
>>>    would contain the administrators group, too, but with the "Use for
>>>    deny only" flag set.  If setup recognizes this flag, rather than running
>>>    along, it calls ShellExecute on itself, with the "runas" flag set.
>>>    So it elevates a copy of itself and just exits.  The elevated copy
>>>    then runs as usual.
>>> The only downside with this concept, as far as I can see, is, somebody
>>> would have to implement it...
>>> Does that sound feasible?
>> I apologise... I've been sitting on an almost-there implementation of
>> this for almost two weeks, waiting for a moment to polish it properly
>> for patch submission.
>> I can't elaborate on the pros and cons of the patch at the moment, as
>> I am accessing my desktop remotely. But I will follow-up later tonight
>> with more details.
> thanks for letting us know and your patch.  I had a look and it looks
> good for a start.  You just call the CheckTokenMembership function,
> though.  The problem is, you won't know if the process has been started
> by a non-admin or by an admin without elevation.  So you always call
> ShellExecute if setup is started without admin rights, for non-admins
> and non-elevated admins alike, unless the --no-admin option is given.

Yes that is deliberate. Initially I coded this for how I viewed was
desirable, that being that it would use CheckTokenMembership to see if
it was elevated (or just run as Administrator on XP). If it was not, it
would attempt to elevate using "runas" flag. If that was rejected, it
would carry on. The --no-admin was still used as per the patch
submitted to avoid infinite loop just in-case ShellExecuteEx didn't
honour "runas" and just ran setup all over again with no Administrator

However I sensed from previous discussions that really it was desirable
to steer users towards running as Admin/elevated privilege. Unless they
really knew what they were doing. So much so that building a custom
setup.exe was being recommended without much discussion of an
alternative... until now.

So this patch tries to be as backwards compatible as possible. That is,
unless the user has already explicitly elevated privilege (context
menu -> Run as ...), setup.exe forces an attempt. And fails if it does
not elevate. The forced attempt can be avoided by explicitly specifying

The patch I provided doesn't match exactly the behaviour of setup on
various systems at the moment, in the following ways:

* I don't know how, and did not bother too much about emulating the
   "access denied" when the user rejects the privilege elevation.

* Under x86 (32bit), where the user has performed the rename magic that
   normally circumvents the UAC Installer Detection Technology, setup
   will still behave as if they hadn't and continue to try to elevate.
   IMO this is minor, but if we were going for 100% compatibility, we
   could check the exe filename against the same list that cygports uses,
   and avoid the privilege elevation attempt:

/usr/share/cygport/lib/src_postinst.cygpart:1112:       find * -type f 
-executable -a \( -name '*instal*.exe' -o -name '*patch*.exe' -o -name 
'*setup*.exe' -o -name '*update*.exe' \) -print0 | \

* Under XP (32 bit... I don't know about any other archs (if they
   exist?) or other XP like editions (server???)), for a
   non-Administrator the attempt to elevate privilege is also an extra
   behaviour that wouldn't have been normally encountered. Again, it
   may have been easy to detect that and do something about it too.

Another bit of polish this patch needs is a effective way to close off
logging once and for all when we are about to call ShellExecuteEx.
Putting in the line:

+          l->msg.clear();

staved off the doubling up of logging when LogFile::exit was being
called. But unfortunately a bunch of newlines where being logged
instead. I never got around to knocking all that on the head.

> Is that what we want?  Or should the process only be elevated when
> started by a non-elevated admin as I proposed.  I'm not sure, really.

If I understand right, you were proposing that if the user was not an
Admin at all, then just let them run as they were.

As I wrote earlier, it seemed from discussion that it was desirable (if
not pseudo policy) that regular Cygwin users run with privilege
elevated. And knowing of various features built into setup that require
elevated privilege, eg. replace on boot, I can see why that is.

But I am happy to be guided either way. I can help out too, but as you
can see by the latency in my communication/implementation, I am not
a pillar of reliability :-(


More information about the Cygwin-apps mailing list