# HG changeset patch # User Andre Heinecke # Date 1411492549 -7200 # Node ID 0a803c3fb5a631b2a99da0270c1adc990d664471 # Parent e79fc57f1f9c0f3251d661cb0a753919865279bd (issue138) Set the ACL explictly on existing files or directories diff -r e79fc57f1f9c -r 0a803c3fb5a6 cinst/nssstore_win.c --- a/cinst/nssstore_win.c Tue Sep 23 17:05:17 2014 +0200 +++ b/cinst/nssstore_win.c Tue Sep 23 19:15:49 2014 +0200 @@ -756,6 +756,7 @@ *path = NULL; HANDLE hFile = NULL; size_t path_len; + PACL access_control_list = NULL; folder_name = get_program_data_folder(); if (!folder_name) @@ -805,7 +806,7 @@ it might be a symlink to another place that a users wants us to grant read access to or makes us overwrite something */ - if(!create_restricted_directory (path, true)) + if(!create_restricted_directory (path, true, &access_control_list)) { ERRORPRINTF ("Failed to create directory\n"); xfree(path); @@ -816,6 +817,7 @@ { ERRORPRINTF ("Failed to cat dirsep.\n"); xfree(path); + LocalFree(access_control_list); return NULL; } @@ -823,6 +825,7 @@ { ERRORPRINTF ("Failed to cat filename.\n"); xfree(path); + LocalFree(access_control_list); return NULL; } @@ -844,15 +847,68 @@ 0, NULL); } + else + { + /* Opened existing file */ + /* Set our ACL on it */ + PSID admin_SID = NULL; + SID_IDENTIFIER_AUTHORITY admin_identifier = {SECURITY_NT_AUTHORITY}; + + /* Create the SID for the BUILTIN\Administrators group. */ + if(!AllocateAndInitializeSid(&admin_identifier, + 2, + SECURITY_BUILTIN_DOMAIN_RID, /*BUILTIN\ */ + DOMAIN_ALIAS_RID_ADMINS, /*\Administrators */ + 0, 0, 0, 0, 0, 0, /* No other */ + &admin_SID)) + { + PRINTLASTERROR ("Failed to allocate admin sid."); + syslog_error_printf ( "Failed to allocate admin sid."); + if (hFile) + { + CloseHandle (hFile); + } + xfree (path); + LocalFree(access_control_list); + return NULL; + } + + if (SetNamedSecurityInfoW (path, + SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION | + OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION, + admin_SID, /* owner */ + admin_SID, /* group */ + access_control_list, /* the dacl */ + NULL) != ERROR_SUCCESS) + { + ERRORPRINTF ("Failed to set the ACL on the NSS instruction file."); + if (hFile) + { + CloseHandle (hFile); + } + FreeSid(admin_SID); + LocalFree(access_control_list); + xfree (path); + return NULL; + } + FreeSid(admin_SID); + } + + LocalFree(access_control_list); + if (hFile == INVALID_HANDLE_VALUE) { PRINTLASTERROR ("Failed to create file\n"); + syslog_error_printf ( "Failed to create nss instruction file."); xfree(path); return NULL; } if (!write_instructions (to_install, hFile, false)) { ERRORPRINTF ("Failed to write install instructions.\n"); + syslog_error_printf ( "Failed to write nss instruction file."); CloseHandle(hFile); xfree(path); return NULL; @@ -860,6 +916,7 @@ if (!write_instructions (to_remove, hFile, true)) { ERRORPRINTF ("Failed to write remove instructions.\n"); + syslog_error_printf ( "Failed to write nss instruction file removal entries."); CloseHandle(hFile); xfree(path); return NULL; diff -r e79fc57f1f9c -r 0a803c3fb5a6 common/portpath.c --- a/common/portpath.c Tue Sep 23 17:05:17 2014 +0200 +++ b/common/portpath.c Tue Sep 23 19:15:49 2014 +0200 @@ -60,7 +60,7 @@ { return false; } - ret = create_restricted_directory (wchar_path, propagate_acl); + ret = create_restricted_directory (wchar_path, propagate_acl, NULL); xfree (wchar_path); return ret; #endif diff -r e79fc57f1f9c -r 0a803c3fb5a6 common/util.c --- a/common/util.c Tue Sep 23 17:05:17 2014 +0200 +++ b/common/util.c Tue Sep 23 19:15:49 2014 +0200 @@ -656,7 +656,7 @@ #ifdef WIN32 bool -create_restricted_directory (LPWSTR path, bool objects_should_inherit) +create_restricted_directory (LPWSTR path, bool objects_should_inherit, PACL *rACL) { bool retval = false; PSID everyone_SID = NULL, @@ -760,22 +760,56 @@ DWORD err = GetLastError(); if (err == ERROR_ALREADY_EXISTS) { - /* Verify that the directory has the correct rights */ - // TODO (issue138) - retval = true; + if (!objects_should_inherit) + { + /* This means it is a parent directory of something and + we should not touch the DACL. */ + retval = true; + goto done; + } + + /* Set our ACL on the directory */ + err = SetNamedSecurityInfoW (path, + SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION | + OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION, + admin_SID, /* owner */ + admin_SID, /* group */ + access_control_list, /* the dacl */ + NULL); + if (err != ERROR_SUCCESS) + { + ERRORPRINTF ("Failed to set security info on folder. Err: %lu", err); + goto done; + } + } + else + { + ERRORPRINTF ("Failed to create directory. Err: %lu", err); goto done; } - ERRORPRINTF ("Failed to create directory. Err: %lu", err); } retval = true; done: + if (retval != true) + { + ERRORPRINTF ("Failed to create directory for NSS installer instructions."); + syslog_error_printf ("Failed to create directory for NSS installer instructions."); + } + else if (rACL) + { + *rACL = access_control_list; + } + + if (everyone_SID) FreeSid(everyone_SID); if (admin_SID) FreeSid(admin_SID); - if (access_control_list) + if (!rACL && access_control_list) LocalFree(access_control_list); if (descriptor) LocalFree(descriptor); diff -r e79fc57f1f9c -r 0a803c3fb5a6 common/util.h --- a/common/util.h Tue Sep 23 17:05:17 2014 +0200 +++ b/common/util.h Tue Sep 23 19:15:49 2014 +0200 @@ -124,8 +124,9 @@ * in that directory. * Basically a very complicated version of mkdir path -m 644 * - * If the directory exists the permissions of that directory are checked if - * they are acceptable and true or false is returned accordingly. + * If the directory exists and propagate_acl is set the permissions + * of that directory are overwritten with the DACL that would have + * been used to create the directory. * * Code based on msdn example: * http://msdn.microsoft.com/en-us/library/windows/desktop/aa446595%28v=vs.85%29.aspx @@ -133,12 +134,15 @@ * @param[in] path Path of the directory to create * @param[in] propagate_acl weather or not objects should inherit * the ACL of this directory. + * @param[out] rACL optional pointer to an PACL pointer that should be + * the returned value. If rACL is not NULL the caller needs to free the + * returned pointer with LocalFree. * * @returns true on success of if the directory exists, false on error */ -bool create_restricted_directory (LPWSTR path, bool propagate_acl); +bool create_restricted_directory (LPWSTR path, bool propagate_acl, PACL *rACL); -/**@briefu Check the integrity level of the token +/**@brief Check the integrity level of the token * * Returns true if the token has at least SECURITY_MANADTORY_HIGH_RID or * higher.