Discussion:
MSI Custom Action Privileges
(too old to reply)
Uwe
2008-02-01 17:00:17 UTC
Permalink
[I inadvertently posted this question in another thread, so I'm reposting in
a new thread and answering Rob Hamflet's question at the same time. Sorry.]

I have a question about the kind of privileges MSI grants custom actions:

As part of our product's installation on Vista, we place a file in our
product's ProgramData directory and then create a symbolic link to that file
from our product's Program Files directory. This worked when we were
performing an installation using an old pre-Vista Install Shield installer,
probably because the code that was creating the link was in a DLL that was
being called by the InstallShield setup program. However, we now are
converting our installations to MSI and we're encountering a problem
creating this symbolic link. The code that creates the link has been moved
to a Deferred Execution EXE and it is executed after all of the other files
have been installed. (It is after the RegisterFonts action.)

The error that we get when we try to create the symbolic link is 1314
(ERROR_PRIVILEGE_NOT_HELD). I made my Custom Action program Elevated by
setting requireAdministrator in the manifest, and that didn't help. I have
set the msidbCustomActionTypeNoImpersonate flag on the custom action, and it
didn't make any difference. I have tried to grant
SE_CREATE_SYMBOLIC_LINK_NAME privilege to my process, and all I got was
ERROR_NOT_ALL_ASSIGNED from AdjustTokenPrivilege for my trouble, which it
not what happens when I run the EXE from a command prompt. So, I've decided
that MSI must be running my custom action with reduced privileges.

Here are my questions:

1) Am I correct-- is MSI is doing this on purpose? (Am I doing
something wrong?)

2) Is there anyway to get MSI to give my in-script custom action the
privilege to create symbolic links?

3) What privileges does the in-script custom action actually have?
Where is this documented? (I've tried looking.)

In response to Rob's question,
Do you get the UAC prompt at all? Either right at the start or when
things are passed over to the
server side?
We get the UAC prompt after pressing the [Finish] button in the GUI. I
believe that's when things are passed over to the server side.

--- Uwe
Adrian Accinelli
2008-02-01 19:08:56 UTC
Permalink
Post by Uwe
[I inadvertently posted this question in another thread, so I'm reposting
in a new thread and answering Rob Hamflet's question at the same time.
Sorry.]
As part of our product's installation on Vista, we place a file in our
product's ProgramData directory and then create a symbolic link to that
file from our product's Program Files directory. This worked when we were
performing an installation using an old pre-Vista Install Shield
installer, probably because the code that was creating the link was in a
DLL that was being called by the InstallShield setup program. However, we
now are converting our installations to MSI and we're encountering a
problem creating this symbolic link. The code that creates the link has
been moved to a Deferred Execution EXE and it is executed after all of the
other files have been installed. (It is after the RegisterFonts action.)
The error that we get when we try to create the symbolic link is 1314
(ERROR_PRIVILEGE_NOT_HELD). I made my Custom Action program Elevated by
setting requireAdministrator in the manifest, and that didn't help. I
have set the msidbCustomActionTypeNoImpersonate flag on the custom action,
and it didn't make any difference. I have tried to grant
SE_CREATE_SYMBOLIC_LINK_NAME privilege to my process, and all I got was
ERROR_NOT_ALL_ASSIGNED from AdjustTokenPrivilege for my trouble, which it
not what happens when I run the EXE from a command prompt. So, I've
decided that MSI must be running my custom action with reduced privileges.
1) Am I correct-- is MSI is doing this on purpose? (Am I doing
something wrong?)
2) Is there anyway to get MSI to give my in-script custom action the
privilege to create symbolic links?
3) What privileges does the in-script custom action actually have?
Where is this documented? (I've tried looking.)
In response to Rob's question,
Do you get the UAC prompt at all? Either right at the start or when
things are passed over to the
server side?
We get the UAC prompt after pressing the [Finish] button in the GUI. I
believe that's when things are passed over to the server side.
--- Uwe
In Windows Vista, the Windows Installer service is "hardened" to present a
smaller surface for attacks. They removed all but the following privileges
from the service itself:

SeTcbPrivilege,
SeCreatePagefilePrivilege,
SeLockMemoryPrivilege,
SeIncreaseBasePriorityPrivilege,
SeCreatePermanentPrivilege,
SeAuditPrivilege,
SeSecurityPrivilege,
SeChangeNotifyPrivilege,
SeProfileSingleProcessPrivilege,
SeImpersonatePrivilege,
SeCreateGlobalPrivilege,
SeAssignPrimaryTokenPrivilege,
SeRestorePrivilege,
SeIncreaseQuotaPrivilege,
SeShutdownPrivilege,
SeTakeOwnershipPrivilege,
SeLoadDriverPrivilege.

This essentially means that any custom actions launched from msiexec.exe
itself will not be able to gain privileges beyond what is included in the
list. Since SE_CREATE_SYMBOLIC_LINK_NAME (SeCreateSymbolicLinkPrivilege)
privilege is not in this list you are out of luck.

So what to do?

The recommended solution is to create a service which runs in unfiltered
system context and because it has access to all privileges it could do the
work required and then exit.

There's the temporary way (hidden way):
Move your custom action code into an service executable. Extract to temp
from MSI binary and then have another deferred non-impersonated custom
action register it as a service, start it and then wait until it
completes/timeout before removing the service reference and deleting the
temp file. Maybe not exactly like this but some variation on this theme
anyways.

And the transparent MSI table way:
Add the service permanently into your product (manual startup, etc) and use
MSI Service tables to install/start/stop/remove.

Sincerely,
Adrian Accinelli
Uwe
2008-02-01 19:50:33 UTC
Permalink
Post by Adrian Accinelli
Post by Uwe
[I inadvertently posted this question in another thread, so I'm reposting
in a new thread and answering Rob Hamflet's question at the same time.
Sorry.]
As part of our product's installation on Vista, we place a file in our
product's ProgramData directory and then create a symbolic link to that
file from our product's Program Files directory. This worked when we
were performing an installation using an old pre-Vista Install Shield
installer, probably because the code that was creating the link was in a
DLL that was being called by the InstallShield setup program. However,
we now are converting our installations to MSI and we're encountering a
problem creating this symbolic link. The code that creates the link has
been moved to a Deferred Execution EXE and it is executed after all of
the other files have been installed. (It is after the RegisterFonts
action.)
The error that we get when we try to create the symbolic link is 1314
(ERROR_PRIVILEGE_NOT_HELD). I made my Custom Action program Elevated by
setting requireAdministrator in the manifest, and that didn't help. I
have set the msidbCustomActionTypeNoImpersonate flag on the custom
action, and it didn't make any difference. I have tried to grant
SE_CREATE_SYMBOLIC_LINK_NAME privilege to my process, and all I got was
ERROR_NOT_ALL_ASSIGNED from AdjustTokenPrivilege for my trouble, which it
not what happens when I run the EXE from a command prompt. So, I've
decided that MSI must be running my custom action with reduced privileges.
1) Am I correct-- is MSI is doing this on purpose? (Am I doing
something wrong?)
2) Is there anyway to get MSI to give my in-script custom action
the privilege to create symbolic links?
3) What privileges does the in-script custom action actually have?
Where is this documented? (I've tried looking.)
In response to Rob's question,
Do you get the UAC prompt at all? Either right at the start or when
things are passed over to the
server side?
We get the UAC prompt after pressing the [Finish] button in the GUI. I
believe that's when things are passed over to the server side.
--- Uwe
In Windows Vista, the Windows Installer service is "hardened" to present a
smaller surface for attacks. They removed all but the following
SeTcbPrivilege,
SeCreatePagefilePrivilege,
SeLockMemoryPrivilege,
SeIncreaseBasePriorityPrivilege,
SeCreatePermanentPrivilege,
SeAuditPrivilege,
SeSecurityPrivilege,
SeChangeNotifyPrivilege,
SeProfileSingleProcessPrivilege,
SeImpersonatePrivilege,
SeCreateGlobalPrivilege,
SeAssignPrimaryTokenPrivilege,
SeRestorePrivilege,
SeIncreaseQuotaPrivilege,
SeShutdownPrivilege,
SeTakeOwnershipPrivilege,
SeLoadDriverPrivilege.
This essentially means that any custom actions launched from msiexec.exe
itself will not be able to gain privileges beyond what is included in the
list. Since SE_CREATE_SYMBOLIC_LINK_NAME (SeCreateSymbolicLinkPrivilege)
privilege is not in this list you are out of luck.
So what to do?
The recommended solution is to create a service which runs in unfiltered
system context and because it has access to all privileges it could do
the work required and then exit.
Move your custom action code into an service executable. Extract to temp
from MSI binary and then have another deferred non-impersonated custom
action register it as a service, start it and then wait until it
completes/timeout before removing the service reference and deleting the
temp file. Maybe not exactly like this but some variation on this theme
anyways.
Add the service permanently into your product (manual startup, etc) and
use MSI Service tables to install/start/stop/remove.
Sincerely,
Adrian Accinelli
Thank you for your most helpful reply. This is pretty much what I was
afraid of -- that some activities are restricted by MSI. I had the mistaken
impression that once an installer was started, it was trusted and could do
anything if approved via UAC. D'oh!

I've heard of similar problems being solved by creating a one-time Windows
scheduled task to perform the work, but I'm not sure if the MSI process
could create a scheduled task, or if that task could lauch in elevated mode
without another UAC prompt.

So I think we'll be taking the easy way out and eliminate the reason for the
symbolic link. That was a stop-gap solution that allowed us to make our
application Vista UAC-compatible and apparently worked only because we were
still using a non-MSI-based installer. Knowing for sure that MSI doesn't
allow the creation of symbolic links makes it easier to justify the effort.

Thanks again for the really fast reply.

--- Uwe

Loading...