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