@@ -173,3 +173,89 @@ check_secure_file_permission(const char *input_path, struct passwd * pw, int rea
173
173
return ret ;
174
174
}
175
175
176
+ /*
177
+ * The function is similar to check_secure_file_permission.
178
+ * Check the owner of the file is one of these types: Local Administrators groups or system account
179
+ * Check the users have access permission to the file don't violate the following rules:
180
+ 1. no user other than local administrators group and system account have write permission on the folder
181
+ * Returns 0 on success and -1 on failure
182
+ */
183
+ int
184
+ check_secure_folder_permission (const wchar_t * path_utf16 , int read_ok )
185
+ {
186
+ PSECURITY_DESCRIPTOR pSD = NULL ;
187
+ PSID owner_sid = NULL , ti_sid = NULL ;
188
+ PACL dacl = NULL ;
189
+ DWORD error_code = ERROR_SUCCESS ;
190
+ BOOL is_valid_sid = FALSE, is_valid_acl = FALSE;
191
+ wchar_t * bad_user = NULL ;
192
+ int ret = 0 ;
193
+
194
+ /*Get the owner sid of the file.*/
195
+ if ((error_code = GetNamedSecurityInfoW (path_utf16 , SE_FILE_OBJECT ,
196
+ OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION ,
197
+ & owner_sid , NULL , & dacl , NULL , & pSD )) != ERROR_SUCCESS ) {
198
+ printf ("failed to retrieve the owner sid and dacl of file %S with error code: %d" , path_utf16 , error_code );
199
+ errno = EOTHER ;
200
+ ret = -1 ;
201
+ goto cleanup ;
202
+ }
203
+ if (((is_valid_sid = IsValidSid (owner_sid )) == FALSE) || ((is_valid_acl = IsValidAcl (dacl )) == FALSE)) {
204
+ printf ("IsValidSid: %d; is_valid_acl: %d" , is_valid_sid , is_valid_acl );
205
+ ret = -1 ;
206
+ goto cleanup ;
207
+ }
208
+ if (!IsWellKnownSid (owner_sid , WinBuiltinAdministratorsSid ) &&
209
+ !IsWellKnownSid (owner_sid , WinLocalSystemSid )) {
210
+ printf ("Bad owner on %S" , path_utf16 );
211
+ ret = -1 ;
212
+ goto cleanup ;
213
+ }
214
+ /*
215
+ iterate all aces of the file to find out if there is violation of the following rules:
216
+ 1. no others than administrators group and system account have write permission on the file
217
+ */
218
+ for (DWORD i = 0 ; i < dacl -> AceCount ; i ++ ) {
219
+ PVOID current_ace = NULL ;
220
+ PACE_HEADER current_aceHeader = NULL ;
221
+ PSID current_trustee_sid = NULL ;
222
+ ACCESS_MASK current_access_mask = 0 ;
223
+
224
+ if (!GetAce (dacl , i , & current_ace )) {
225
+ printf ("GetAce() failed" );
226
+ errno = EOTHER ;
227
+ ret = -1 ;
228
+ goto cleanup ;
229
+ }
230
+
231
+ current_aceHeader = (PACE_HEADER )current_ace ;
232
+ /* only interested in Allow ACE */
233
+ if (current_aceHeader -> AceType != ACCESS_ALLOWED_ACE_TYPE )
234
+ continue ;
235
+
236
+ PACCESS_ALLOWED_ACE pAllowedAce = (PACCESS_ALLOWED_ACE )current_ace ;
237
+ current_trustee_sid = & (pAllowedAce -> SidStart );
238
+ current_access_mask = pAllowedAce -> Mask ;
239
+
240
+ /*no need to check administrators group and system account*/
241
+ if (IsWellKnownSid (current_trustee_sid , WinBuiltinAdministratorsSid ) ||
242
+ IsWellKnownSid (current_trustee_sid , WinLocalSystemSid )) {
243
+ continue ;
244
+ }
245
+ else if (read_ok && (current_access_mask & (FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA )) == 0 ) {
246
+ /* if read is allowed, allow ACES that do not give write access*/
247
+ continue ;
248
+ }
249
+ else {
250
+ ret = -1 ;
251
+ }
252
+ }
253
+ cleanup :
254
+ if (bad_user )
255
+ LocalFree (bad_user );
256
+ if (pSD )
257
+ LocalFree (pSD );
258
+ if (ti_sid )
259
+ free (ti_sid );
260
+ return ret ;
261
+ }
0 commit comments