MDEV-17008 prepare with datadir, on Windows, does not set ACL

on tablespace files

Fix is to always add Full Control for NetworkService account, for every
file that copyback/moveback copies around.
This commit is contained in:
Vladislav Vaintroub 2019-05-02 19:44:36 +01:00
parent 4b0f010b88
commit 13d7c721a5

View file

@ -989,6 +989,65 @@ run_data_threads(datadir_iter_t *it, os_thread_func_t func, uint n)
return(ret);
}
#ifdef _WIN32
#include <windows.h>
#include <accctrl.h>
#include <aclapi.h>
/*
On Windows, fix permission of the file after "copyback"
We assume that after copyback, mysqld will run as service as NetworkService
user, thus well give full permission on given file to that user.
*/
static int fix_win_file_permissions(const char *file)
{
struct {
TOKEN_USER tokenUser;
BYTE buffer[SECURITY_MAX_SID_SIZE];
} tokenInfoBuffer;
HANDLE hFile = CreateFile(file, READ_CONTROL | WRITE_DAC, 0, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return -1;
ACL* pOldDACL;
SECURITY_DESCRIPTOR* pSD = NULL;
EXPLICIT_ACCESS ea = { 0 };
BOOL isWellKnownSID = FALSE;
PSID pSid = NULL;
GetSecurityInfo(hFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL,
&pOldDACL, NULL, (void**)&pSD);
DWORD size = SECURITY_MAX_SID_SIZE;
pSid = (PSID)tokenInfoBuffer.buffer;
if (!CreateWellKnownSid(WinNetworkServiceSid, NULL, pSid,
&size))
{
return 1;
}
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea.Trustee.ptstrName = (LPTSTR)pSid;
ea.grfAccessMode = GRANT_ACCESS;
ea.grfAccessPermissions = GENERIC_ALL;
ea.grfInheritance = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
ea.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
ACL* pNewDACL = 0;
DWORD err = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
if (pNewDACL)
{
SetSecurityInfo(hFile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL,
pNewDACL, NULL);
}
if (pSD != NULL)
LocalFree((HLOCAL)pSD);
if (pNewDACL != NULL)
LocalFree((HLOCAL)pNewDACL);
CloseHandle(hFile);
return 0;
}
#endif
/************************************************************************
Copy file for backup/restore.
@ -1037,6 +1096,10 @@ copy_file(ds_ctxt_t *datasink,
/* close */
msg(thread_n," ...done");
datafile_close(&cursor);
#ifdef _WIN32
if (xtrabackup_copy_back || xtrabackup_move_back)
ut_a(!fix_win_file_permissions(dstfile->path));
#endif
if (ds_close(dstfile)) {
goto error_close;
}
@ -1107,7 +1170,10 @@ move_file(ds_ctxt_t *datasink,
errbuf);
return(false);
}
#ifdef _WIN32
if (xtrabackup_copy_back || xtrabackup_move_back)
ut_a(!fix_win_file_permissions(dst_file_path_abs));
#endif
msg(thread_n," ...done");
return(true);