mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
MDEV-221 - Properly escape command line when starting mysql_install_db
since password characters can contain quotes or spaces. The proper quoting method for command line arguments used here was extracted from http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx Additionally, mysql_install_db.exe now passes root password to "mysqld.exe --bootstrap" in hexadecimal form, to handle potential special chars inside password string literal.
This commit is contained in:
@@ -316,9 +316,9 @@ static int create_myini()
|
|||||||
|
|
||||||
|
|
||||||
static const char update_root_passwd_part1[]=
|
static const char update_root_passwd_part1[]=
|
||||||
"UPDATE mysql.user SET Password = PASSWORD('";
|
"UPDATE mysql.user SET Password = PASSWORD(";
|
||||||
static const char update_root_passwd_part2[]=
|
static const char update_root_passwd_part2[]=
|
||||||
"') where User='root';\n";
|
") where User='root';\n";
|
||||||
static const char remove_default_user_cmd[]=
|
static const char remove_default_user_cmd[]=
|
||||||
"DELETE FROM mysql.user where User='';\n";
|
"DELETE FROM mysql.user where User='';\n";
|
||||||
static const char allow_remote_root_access_cmd[]=
|
static const char allow_remote_root_access_cmd[]=
|
||||||
@@ -589,11 +589,19 @@ static int create_db_instance()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Change root password if requested. */
|
/* Change root password if requested. */
|
||||||
if (opt_password)
|
if (opt_password && opt_password[0])
|
||||||
{
|
{
|
||||||
verbose("Changing root password",remove_default_user_cmd);
|
verbose("Setting root password",remove_default_user_cmd);
|
||||||
fputs(update_root_passwd_part1, in);
|
fputs(update_root_passwd_part1, in);
|
||||||
fputs(opt_password, in);
|
|
||||||
|
/* Use hex encoding for password, to avoid escaping problems.*/
|
||||||
|
fputc('0', in);
|
||||||
|
fputc('x', in);
|
||||||
|
for(int i= 0; opt_password[i]; i++)
|
||||||
|
{
|
||||||
|
fprintf(in,"%02x",opt_password[i]);
|
||||||
|
}
|
||||||
|
|
||||||
fputs(update_root_passwd_part2, in);
|
fputs(update_root_passwd_part2, in);
|
||||||
fflush(in);
|
fflush(in);
|
||||||
}
|
}
|
||||||
|
@@ -71,6 +71,82 @@ LExit:
|
|||||||
return WcaFinalize(er);
|
return WcaFinalize(er);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Escape command line parameter fpr pass to CreateProcess().
|
||||||
|
|
||||||
|
We assume out has enough space to include encoded string
|
||||||
|
2*wcslen(in) is enough.
|
||||||
|
|
||||||
|
It is assumed that called will add double quotation marks before and after
|
||||||
|
the string.
|
||||||
|
*/
|
||||||
|
static void EscapeCommandLine(const wchar_t *in, wchar_t *out)
|
||||||
|
{
|
||||||
|
const wchar_t special_chars[]=L" \t\n\v\"";
|
||||||
|
bool needs_escaping= false;
|
||||||
|
size_t pos;
|
||||||
|
|
||||||
|
for(int i=0; i< sizeof(special_chars) -1; i++)
|
||||||
|
{
|
||||||
|
if (wcschr(in, special_chars[i]))
|
||||||
|
{
|
||||||
|
needs_escaping = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!needs_escaping)
|
||||||
|
{
|
||||||
|
wcscpy(out, in);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos= 0;
|
||||||
|
for(int i = 0 ; ; i++)
|
||||||
|
{
|
||||||
|
size_t n_backslashes = 0;
|
||||||
|
wchar_t c;
|
||||||
|
while (in[i] == L'\\')
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
n_backslashes++;
|
||||||
|
}
|
||||||
|
|
||||||
|
c= in[i];
|
||||||
|
if (c == 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Escape all backslashes, but let the terminating double quotation mark
|
||||||
|
that caller adds be interpreted as a metacharacter.
|
||||||
|
*/
|
||||||
|
for(int j= 0; j < 2*n_backslashes;j++)
|
||||||
|
{
|
||||||
|
out[pos++]=L'\\';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (c == L'"')
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Escape all backslashes and the following double quotation mark.
|
||||||
|
*/
|
||||||
|
for(int j= 0; j < 2*n_backslashes + 1; j++)
|
||||||
|
{
|
||||||
|
out[pos++]=L'\\';
|
||||||
|
}
|
||||||
|
out[pos++]= L'"';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Backslashes aren't special here. */
|
||||||
|
for (int j=0; j < n_backslashes; j++)
|
||||||
|
out[pos++] = L'\\';
|
||||||
|
|
||||||
|
out[pos++]= c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out[pos++]= 0;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
Check for if directory is empty during install,
|
Check for if directory is empty during install,
|
||||||
sets "<PROPERTY>_NOT_EMPTY" otherise
|
sets "<PROPERTY>_NOT_EMPTY" otherise
|
||||||
@@ -460,6 +536,8 @@ unsigned long long GetMaxBufferSize(unsigned long long totalPhys)
|
|||||||
return totalPhys;
|
return totalPhys;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Checks SERVICENAME, PORT and BUFFERSIZE parameters
|
Checks SERVICENAME, PORT and BUFFERSIZE parameters
|
||||||
*/
|
*/
|
||||||
@@ -468,6 +546,8 @@ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall)
|
|||||||
wchar_t ServiceName[MAX_PATH]={0};
|
wchar_t ServiceName[MAX_PATH]={0};
|
||||||
wchar_t SkipNetworking[MAX_PATH]={0};
|
wchar_t SkipNetworking[MAX_PATH]={0};
|
||||||
wchar_t QuickConfig[MAX_PATH]={0};
|
wchar_t QuickConfig[MAX_PATH]={0};
|
||||||
|
wchar_t Password[MAX_PATH]={0};
|
||||||
|
wchar_t EscapedPassword[2*MAX_PATH+2];
|
||||||
wchar_t Port[6];
|
wchar_t Port[6];
|
||||||
wchar_t BufferPoolSize[16];
|
wchar_t BufferPoolSize[16];
|
||||||
DWORD PortLen=6;
|
DWORD PortLen=6;
|
||||||
@@ -510,8 +590,12 @@ extern "C" UINT __stdcall CheckDatabaseProperties (MSIHANDLE hInstall)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD SkipNetworkingLen= MAX_PATH;
|
DWORD PasswordLen= MAX_PATH;
|
||||||
|
MsiGetPropertyW (hInstall, L"PASSWORD", Password, &PasswordLen);
|
||||||
|
EscapeCommandLine(Password, EscapedPassword);
|
||||||
|
MsiSetPropertyW(hInstall,L"ESCAPEDPASSWORD",EscapedPassword);
|
||||||
|
|
||||||
|
DWORD SkipNetworkingLen= MAX_PATH;
|
||||||
MsiGetPropertyW(hInstall, L"SKIPNETWORKING", SkipNetworking,
|
MsiGetPropertyW(hInstall, L"SKIPNETWORKING", SkipNetworking,
|
||||||
&SkipNetworkingLen);
|
&SkipNetworkingLen);
|
||||||
MsiGetPropertyW(hInstall, L"PORT", Port, &PortLen);
|
MsiGetPropertyW(hInstall, L"PORT", Port, &PortLen);
|
||||||
|
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
<!-- Root password -->
|
<!-- Root password -->
|
||||||
<Property Id="PASSWORD" Hidden="yes" Secure="yes" />
|
<Property Id="PASSWORD" Hidden="yes" Secure="yes" />
|
||||||
|
<Property Id="ESCAPEDPASSWORD" Hidden="yes" Secure="yes" />
|
||||||
<!-- Database port -->
|
<!-- Database port -->
|
||||||
<Property Id="PORT" Value="3306" Secure="yes"/>
|
<Property Id="PORT" Value="3306" Secure="yes"/>
|
||||||
<!-- Whether to allow remote access for root user -->
|
<!-- Whether to allow remote access for root user -->
|
||||||
@@ -668,7 +669,7 @@
|
|||||||
<CustomAction Id='PresetDatabaseProperties' BinaryKey='wixca.dll' DllEntry='PresetDatabaseProperties' />
|
<CustomAction Id='PresetDatabaseProperties' BinaryKey='wixca.dll' DllEntry='PresetDatabaseProperties' />
|
||||||
<CustomAction Id="CreateDatabaseCommand" Property="CreateDatabase"
|
<CustomAction Id="CreateDatabaseCommand" Property="CreateDatabase"
|
||||||
Value=
|
Value=
|
||||||
""[#F.bin.mysql_install_db.exe]" "--service=[SERVICENAME]" --port=[PORT] "--password=[PASSWORD]" "--datadir=[DATADIR]\" [SKIPNETWORKING] [ALLOWREMOTEROOTACCESS] [DEFAULTUSER]"
|
""[#F.bin.mysql_install_db.exe]" "--service=[SERVICENAME]" --port=[PORT] "--password=[ESCAPEDPASSWORD]" "--datadir=[DATADIR]\" [SKIPNETWORKING] [ALLOWREMOTEROOTACCESS] [DEFAULTUSER]"
|
||||||
Execute="immediate"
|
Execute="immediate"
|
||||||
HideTarget="yes"
|
HideTarget="yes"
|
||||||
/>
|
/>
|
||||||
@@ -703,7 +704,7 @@
|
|||||||
<![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED=""]]>
|
<![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED=""]]>
|
||||||
</Custom>
|
</Custom>
|
||||||
<Custom Action="ErrorDataDirNotEmpty" After="CheckDataDirectoryEmpty" >DATADIRNOTEMPTY</Custom>
|
<Custom Action="ErrorDataDirNotEmpty" After="CheckDataDirectoryEmpty" >DATADIRNOTEMPTY</Custom>
|
||||||
|
<Custom Action="CheckDatabaseProperties" Before="CreateDatabaseCommand">SERVICENAME</Custom>
|
||||||
<Custom Action="CreateDatabaseCommand" After="CostFinalize" >
|
<Custom Action="CreateDatabaseCommand" After="CostFinalize" >
|
||||||
<![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED=""]]>
|
<![CDATA[&DBInstance=3 AND NOT !DBInstance=3 AND OLDERVERSIONBEINGUPGRADED=""]]>
|
||||||
</Custom>
|
</Custom>
|
||||||
|
Reference in New Issue
Block a user