Archive: Executing CACLS With User Account After UAC Was Successful


Executing CACLS With User Account After UAC Was Successful
Hi there,

I could really use some help here with my NSIS Installation. I've done all the preliminary searches and come up blank before posting this =).

Outline: This topic concerns the NSIS UAC Plugin, the NSIS Windows Version Detection code and the CACLS command. Operating Systems in question are Windows 2000 / XP Professional.

Summary: I have thousands of users who only have limited user accounts. They are in the medical industry, and this is HIPAA standard. I want them to be able to install my program, and I want my program to have access to where it lives in the Program Files directory. My installer uses the UAC Plugin to grant the user administrative rights. Then it installs the program. Then it checks the Windows version. For any Windows version BUT Vista, it executes the CACLS command to grant the Users group access to the Program Files folders (2) that my program must have access to.

Problem: When the installation is run from an administrative account, everything works fine. When the installation is run as a limited user account (even though the user gets administrative rights) the CACLS command does not give full control to "Users" to the specified folders.

Code Samples:


Function To Elevate User Privileges
Function UAC_Elevate
; Gets Administrative Permissions for install
; Aborts of Permissions cannot be obtained

LogText ""
LogText "_____________________________________________"
LogText ""
LogText "User Account Control -- Attempt to Run with Administrative credentials"
LogText "_____________________________________________"
LogText ""
LogText ""

UAC_Elevate:
UAC::RunElevated
StrCmp $0 1223 UAC_ElevationAborted ; UAC dialog aborted by user?
StrCmp $0 0 0 UAC_Err ; Error?
StrCmp $1 1 0 UAC_Success ;Are we the real deal or just the wrapper?
Quit

UAC_Err:
MessageBox mb_iconstop "You must have administrative credentials to install software, and this installer encountered an error when attempting to obtain these credentials$\n$\nError: $0$\n$\nPlease contact your systems administrator, or call NPF, Inc. at (760) 432-0145."
IfSilent +2 0
Abort

UAC_ElevationAborted:
MessageBox mb_iconstop "You must have administrative credentials to install software, and this installer was unable to obtain these credentials.$\n$\nError: Cancelled by user."
IfSilent +2 0
Abort

UAC_Success:
StrCmp $3 1 +5
StrCmp $1 3 0 UAC_ElevationAborted
MessageBox mb_iconstop "You must have administrative credentials to install software, and this installer was unable to obtain these credentials."
goto UAC_Elevate

FunctionEnd



Function to Get Windows Version
Function GetWindowsVersion

LogSet On
LogText ""
LogText ""
LogText "_____________________________________________"
LogText ""
LogText "Getting the Windows version"
LogText "_____________________________________________"
LogText ""
LogText ""

Push $R0
Push $R1

ClearErrors

ReadRegStr $R0 HKLM \
"SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion

IfErrors 0 lbl_winnt

; we are not NT
ReadRegStr $R0 HKLM \
"SOFTWARE\Microsoft\Windows\CurrentVersion" VersionNumber

StrCpy $R1 $R0 1
StrCmp $R1 '4' 0 lbl_error

StrCpy $R1 $R0 3

StrCmp $R1 '4.0' lbl_win32_95
StrCmp $R1 '4.9' lbl_win32_ME lbl_win32_98

lbl_win32_95:
StrCpy $R0 '95'
Goto lbl_done

lbl_win32_98:
StrCpy $R0 '98'
Goto lbl_done

lbl_win32_ME:
StrCpy $R0 'ME'
Goto lbl_done

lbl_winnt:

StrCpy $R1 $R0 1

StrCmp $R1 '3' lbl_winnt_x
StrCmp $R1 '4' lbl_winnt_x

StrCpy $R1 $R0 3

StrCmp $R1 '5.0' lbl_winnt_2000
StrCmp $R1 '5.1' lbl_winnt_XP
StrCmp $R1 '5.2' lbl_winnt_2003
StrCmp $R1 '6.0' lbl_winnt_vista lbl_error

lbl_winnt_x:
StrCpy $R0 "NT $R0" 6
Goto lbl_done

lbl_winnt_2000:
Strcpy $R0 '2000'
Goto lbl_done

lbl_winnt_XP:
Strcpy $R0 'XP'
Goto lbl_done

lbl_winnt_2003:
Strcpy $R0 '2003'
Goto lbl_done

lbl_winnt_vista:
Strcpy $R0 'Vista'
Goto lbl_done

lbl_error:
Strcpy $R0 ''
lbl_done:

Pop $R1
Exch $R0

FunctionEnd


The CACLS Command
Call GetWindowsVersion
Pop $R0
StrCmp $R0 "Vista" 0 +2
execute "ICACLS $INSTDIR /GRANT *S-1-5-32-545:(F)"
StrCmp $R0 "Vista" +3 0
!execute 'CACLS "C:\Program Files\NPF DME" /E /P BUILTIN\Users:F'
!execute 'CACLS "C:\Program Files\NPF" /E /P BUILTIN\Users:F'

Any help would be greatly appreciated.


1)
!execute is a preprocessor command, it takes place on the system you compile your installer on, use ExecWait (or nsExec if you need to hide the dos box)

2) There is already a nsis plugin that should be able to do this for you: http://nsis.sourceforge.net/AccessControl_plug-in


This is great. Thanks for the fast response. I will try this tomorrow at work. I hope it works!


I just tested this, and it worked great!

I did have a little trouble remembering where to extract the plug-in. The author of the plug-in didn't have any documentation on it, and I was unable to easily location documentation elsewhere. I ended up looking for my other plug-in to remember. It turns out I was trying to extract it to the folder of my NSIS editing program (oops).

So, for the benefit of all that may read this:

Once you've downloaded the zip file of the plug-in, you have NSIS installed (not any kind of editing program you may use with NSIS). For me, this location is here:

C:\Program Files\NSIS

With this zip file, I extracted directly into this folder, and it put all the different files from the zip file into all the appropriate sub folders.


Just so you know, it is not good practice to allow normal users to edit files in $programfiles, its easy for a user to replace a exe in there with a trojan and wait for an admin to come along and run it.

If your app is designed to only store config data there, you might want to restrict the .exe's and .dll's in that folder so only admins can replace them (or fix your app ;) )


The app isn't broken, it simply lives in program files and reads / writes to files in its directory in program files. The installer doesn't grant access to the enter "Program Files" directory; just "Program Files\NPF DME". Are you saying there is way to grant access like I have done to the "NPF DME" folder, but still restrict access to the .exe's and .dll's in that folder? Would you care to provide a sample for this?


After you have granted access to all users, remove write access on .exe and dll's


Hi, I have a problem which is more or less somewhat similar to the one who posted it...

I made an installer that works perfectly with XP. It works with Vista as well but only with administrators.

What if the user wants to install this software but doesn't have the administrator's password (user level at VISTA)? I have tried using the UAC plug in, but this would definitely prompt the user for the admin password.

Is there anyway that could make the installer run by the user as if he's the admin?

Please help... thanks...