1 // Berkeley Open Infrastructure for Network Computing
2 // http://boinc.berkeley.edu
3 // Copyright (C) 2005 University of California
4 //
5 // This is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation;
8 // either version 2.1 of the License, or (at your option) any later version.
9 //
10 // This software is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 // See the GNU Lesser General Public License for more details.
14 //
15 // To view the GNU Lesser General Public License visit
16 // http://www.gnu.org/copyleft/lesser.html
17 // or write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19 //
20 
21 #include "stdafx.h"
22 #include "boinccas.h"
23 #include "CASetPermissionBOINCData.h"
24 #include "dirops.h"
25 
26 #define CUSTOMACTION_NAME               _T("CASetPermissionBOINCData")
27 #define CUSTOMACTION_PROGRESSTITLE      _T("Setting permissions on the BOINC Data directory.")
28 
29 
30 /////////////////////////////////////////////////////////////////////
31 //
32 // Function:
33 //
34 // Description:
35 //
36 /////////////////////////////////////////////////////////////////////
CASetPermissionBOINCData(MSIHANDLE hMSIHandle)37 CASetPermissionBOINCData::CASetPermissionBOINCData(MSIHANDLE hMSIHandle) :
38     BOINCCABase(hMSIHandle, CUSTOMACTION_NAME, CUSTOMACTION_PROGRESSTITLE)
39 {}
40 
41 
42 /////////////////////////////////////////////////////////////////////
43 //
44 // Function:
45 //
46 // Description:
47 //
48 /////////////////////////////////////////////////////////////////////
~CASetPermissionBOINCData()49 CASetPermissionBOINCData::~CASetPermissionBOINCData()
50 {
51     BOINCCABase::~BOINCCABase();
52 }
53 
54 
55 /////////////////////////////////////////////////////////////////////
56 //
57 // Function:
58 //
59 // Description:
60 //
61 /////////////////////////////////////////////////////////////////////
OnExecution()62 UINT CASetPermissionBOINCData::OnExecution()
63 {
64     DWORD               dwRes = 0;
65     PACL                pACL = NULL;
66     ULONGLONG           rgSidSY[(SECURITY_MAX_SID_SIZE+sizeof(ULONGLONG)-1)/sizeof(ULONGLONG)]={0};
67     ULONGLONG           rgSidBA[(SECURITY_MAX_SID_SIZE+sizeof(ULONGLONG)-1)/sizeof(ULONGLONG)]={0};
68     ULONGLONG           rgSidBU[(SECURITY_MAX_SID_SIZE+sizeof(ULONGLONG)-1)/sizeof(ULONGLONG)]={0};
69     PSID                pInstallingUserSID = NULL;
70     DWORD               dwSidSize;
71     EXPLICIT_ACCESS     ea[6];
72     ULONG               ulEntries = 0;
73     tstring             strUserSID;
74     tstring             strBOINCAdminsGroupAlias;
75     tstring             strBOINCUsersGroupAlias;
76     tstring             strBOINCProjectsGroupAlias;
77     tstring             strBOINCDataDirectory;
78     tstring             strEnableProtectedApplicationExecution;
79     tstring             strEnableUseByAllUsers;
80     UINT                uiReturnValue = -1;
81 
82     uiReturnValue = GetProperty( _T("UserSID"), strUserSID );
83     if ( uiReturnValue ) return uiReturnValue;
84 
85     uiReturnValue = GetProperty( _T("BOINC_ADMINS_GROUPNAME"), strBOINCAdminsGroupAlias );
86     if ( uiReturnValue ) return uiReturnValue;
87 
88     uiReturnValue = GetProperty( _T("BOINC_USERS_GROUPNAME"), strBOINCUsersGroupAlias );
89     if ( uiReturnValue ) return uiReturnValue;
90 
91     uiReturnValue = GetProperty( _T("BOINC_PROJECTS_GROUPNAME"), strBOINCProjectsGroupAlias );
92     if ( uiReturnValue ) return uiReturnValue;
93 
94     uiReturnValue = GetProperty( _T("DATADIR"), strBOINCDataDirectory );
95     if ( uiReturnValue ) return uiReturnValue;
96 
97     uiReturnValue = GetProperty( _T("ENABLEPROTECTEDAPPLICATIONEXECUTION3"), strEnableProtectedApplicationExecution );
98     if ( uiReturnValue ) return uiReturnValue;
99 
100     uiReturnValue = GetProperty( _T("ENABLEUSEBYALLUSERS"), strEnableUseByAllUsers );
101     if ( uiReturnValue ) return uiReturnValue;
102 
103 
104     // Initialize an EXPLICIT_ACCESS structure for all ACEs.
105     ZeroMemory(&ea, 6 * sizeof(EXPLICIT_ACCESS));
106 
107     // Create a SID for the SYSTEM.
108     dwSidSize = sizeof( rgSidSY );
109     if(!CreateWellKnownSid(WinLocalSystemSid, NULL, rgSidSY, &dwSidSize))
110     {
111         LogMessage(
112             INSTALLMESSAGE_ERROR,
113             NULL,
114             NULL,
115             NULL,
116             GetLastError(),
117             _T("CreateWellKnownSid Error for SYSTEM")
118         );
119         return ERROR_INSTALL_FAILURE;
120     }
121 
122     // Create a SID for the Administrators group.
123     dwSidSize = sizeof( rgSidBA );
124     if(!CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, rgSidBA, &dwSidSize))
125     {
126         LogMessage(
127             INSTALLMESSAGE_ERROR,
128             NULL,
129             NULL,
130             NULL,
131             GetLastError(),
132             _T("CreateWellKnownSid Error for BUILTIN\\Administrators")
133         );
134         return ERROR_INSTALL_FAILURE;
135     }
136 
137     // Create a SID for the Users group.
138     dwSidSize = sizeof( rgSidBU );
139     if(!CreateWellKnownSid(WinBuiltinUsersSid, NULL, rgSidBU, &dwSidSize))
140     {
141         LogMessage(
142             INSTALLMESSAGE_ERROR,
143             NULL,
144             NULL,
145             NULL,
146             GetLastError(),
147             _T("CreateWellKnownSid Error for BUILTIN\\Users")
148         );
149         return ERROR_INSTALL_FAILURE;
150     }
151 
152     // Create a SID for the current logged in user.
153     if(!ConvertStringSidToSid(strUserSID.c_str(), &pInstallingUserSID))
154     {
155         LogMessage(
156             INSTALLMESSAGE_ERROR,
157             NULL,
158             NULL,
159             NULL,
160             GetLastError(),
161             _T("ConvertStringSidToSid Error for Installing User")
162         );
163         return ERROR_INSTALL_FAILURE;
164     }
165 
166     // Handle the non-service install scenario
167     //
168     if (_T("1") != strEnableProtectedApplicationExecution) {
169 
170         ulEntries = 3;
171 
172         // SYSTEM
173         ea[0].grfAccessPermissions = GENERIC_ALL;
174         ea[0].grfAccessMode = SET_ACCESS;
175         ea[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
176         ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
177         ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
178         ea[0].Trustee.ptstrName = (LPTSTR)rgSidSY;
179 
180         // Administrators
181         ea[1].grfAccessPermissions = GENERIC_ALL;
182         ea[1].grfAccessMode = SET_ACCESS;
183         ea[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
184         ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
185         ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
186         ea[1].Trustee.ptstrName = (LPTSTR)rgSidBA;
187 
188         // Installing User
189         ea[2].grfAccessPermissions = GENERIC_ALL;
190         ea[2].grfAccessMode = SET_ACCESS;
191         ea[2].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
192         ea[2].Trustee.TrusteeForm = TRUSTEE_IS_SID;
193         ea[2].Trustee.TrusteeType = TRUSTEE_IS_USER;
194         ea[2].Trustee.ptstrName = (LPTSTR)pInstallingUserSID;
195 
196         // Users
197         if (_T("1") == strEnableUseByAllUsers) {
198             ulEntries = 4;
199 
200             ea[3].grfAccessPermissions = GENERIC_ALL;
201             ea[3].grfAccessMode = SET_ACCESS;
202             ea[3].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
203             ea[3].Trustee.TrusteeForm = TRUSTEE_IS_SID;
204             ea[3].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
205             ea[3].Trustee.ptstrName  = (LPTSTR)rgSidBU;
206         }
207 
208     } else {
209 
210         ulEntries = 5;
211 
212         // SYSTEM
213         ea[0].grfAccessPermissions = GENERIC_ALL;
214         ea[0].grfAccessMode = SET_ACCESS;
215         ea[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
216         ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
217         ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
218         ea[0].Trustee.ptstrName = (LPTSTR)rgSidSY;
219 
220         // Administrators
221         ea[1].grfAccessPermissions = GENERIC_ALL;
222         ea[1].grfAccessMode = SET_ACCESS;
223         ea[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
224         ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
225         ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
226         ea[1].Trustee.ptstrName = (LPTSTR)rgSidBA;
227 
228         // boinc_admins
229         ea[2].grfAccessPermissions = GENERIC_ALL;
230         ea[2].grfAccessMode = SET_ACCESS;
231         ea[2].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
232         ea[2].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
233         ea[2].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
234         ea[2].Trustee.ptstrName = (LPTSTR)strBOINCAdminsGroupAlias.c_str();
235 
236         // boinc_users
237         ea[3].grfAccessPermissions = GENERIC_READ|GENERIC_EXECUTE;
238         ea[3].grfAccessMode = SET_ACCESS;
239         ea[3].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
240         ea[3].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
241         ea[3].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
242         ea[3].Trustee.ptstrName = (LPTSTR)strBOINCUsersGroupAlias.c_str();
243 
244         // boinc_projects
245         ea[4].grfAccessPermissions = FILE_TRAVERSE;
246         ea[4].grfAccessMode = SET_ACCESS;
247         ea[4].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
248         ea[4].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
249         ea[4].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
250         ea[4].Trustee.ptstrName = (LPTSTR)strBOINCProjectsGroupAlias.c_str();
251 
252         // Users
253         if (_T("1") == strEnableUseByAllUsers) {
254             ulEntries = 6;
255 
256             ea[5].grfAccessPermissions = GENERIC_READ|GENERIC_EXECUTE;
257             ea[5].grfAccessMode = SET_ACCESS;
258             ea[5].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
259             ea[5].Trustee.TrusteeForm = TRUSTEE_IS_SID;
260             ea[5].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
261             ea[5].Trustee.ptstrName  = (LPTSTR)rgSidBU;
262         }
263 
264     }
265 
266     // Create a new ACL that contains the new ACEs.
267     dwRes = SetEntriesInAcl(ulEntries, &ea[0], NULL, &pACL);
268     if (ERROR_SUCCESS != dwRes)
269     {
270         LogMessage(
271             INSTALLMESSAGE_INFO,
272             NULL,
273             NULL,
274             NULL,
275             GetLastError(),
276             _T("SetEntriesInAcl Error")
277         );
278         LogMessage(
279             INSTALLMESSAGE_ERROR,
280             NULL,
281             NULL,
282             NULL,
283             GetLastError(),
284             _T("SetEntriesInAcl Error")
285         );
286         return ERROR_INSTALL_FAILURE;
287     }
288 
289     // Set the ACL on the Data Directory itself.
290     dwRes = SetNamedSecurityInfo(
291         (LPWSTR)strBOINCDataDirectory.c_str(),
292         SE_FILE_OBJECT,
293         DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
294         NULL,
295         NULL,
296         pACL,
297         NULL
298     );
299     if (ERROR_SUCCESS != dwRes)
300     {
301         LogMessage(
302             INSTALLMESSAGE_INFO,
303             NULL,
304             NULL,
305             NULL,
306             GetLastError(),
307             _T("SetNamedSecurityInfo Error")
308         );
309         LogMessage(
310             INSTALLMESSAGE_ERROR,
311             NULL,
312             NULL,
313             NULL,
314             GetLastError(),
315             _T("SetNamedSecurityInfo Error")
316         );
317         return ERROR_INSTALL_FAILURE;
318     }
319 
320     // Set ACLs on all files and sub folders.
321     RecursiveSetPermissions(strBOINCDataDirectory, pACL);
322 
323 
324     if (pACL)
325         LocalFree(pACL);
326     if (pInstallingUserSID != NULL)
327         FreeSid(pInstallingUserSID);
328 
329     return ERROR_SUCCESS;
330 }
331 
332 
333 /////////////////////////////////////////////////////////////////////
334 //
335 // Function:    SetPermissionBOINCData
336 //
337 // Description:
338 //
339 /////////////////////////////////////////////////////////////////////
SetPermissionBOINCData(MSIHANDLE hInstall)340 UINT __stdcall SetPermissionBOINCData(MSIHANDLE hInstall)
341 {
342     UINT uiReturnValue = 0;
343 
344     CASetPermissionBOINCData* pCA = new CASetPermissionBOINCData(hInstall);
345     uiReturnValue = pCA->Execute();
346     delete pCA;
347 
348     return uiReturnValue;
349 }
350 
351