Loading VC++Files/mysys/mysys.dsp +4 −0 Original line number Diff line number Diff line Loading @@ -536,6 +536,10 @@ SOURCE=.\my_wincond.c # End Source File # Begin Source File SOURCE=.\my_windac.c # End Source File # Begin Source File SOURCE=.\my_winsem.c # End Source File # Begin Source File Loading include/my_sys.h +8 −0 Original line number Diff line number Diff line Loading @@ -855,6 +855,14 @@ extern void thd_increment_net_big_packet_count(ulong length); #ifdef __WIN__ extern my_bool have_tcpip; /* Is set if tcpip is used */ /* implemented in my_windac.c */ int my_security_attr_create(SECURITY_ATTRIBUTES **psa, const char **perror, DWORD owner_rights, DWORD everybody_rights); void my_security_attr_free(SECURITY_ATTRIBUTES *sa); #endif #ifdef __NETWARE__ void netware_reg_user(const char *ip, const char *user, Loading mysys/Makefile.am +2 −1 Original line number Diff line number Diff line Loading @@ -52,7 +52,8 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ my_net.c my_semaphore.c my_port.c my_sleep.c \ charset.c charset-def.c my_bitmap.c my_bit.c md5.c \ my_gethostbyname.c rijndael.c my_aes.c sha1.c \ my_handler.c my_netware.c my_largepage.c my_handler.c my_netware.c my_largepage.c \ my_windac.c EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ thr_mutex.c thr_rwlock.c libmysys_a_LIBADD = @THREAD_LOBJECTS@ Loading mysys/my_windac.c 0 → 100644 +224 −0 Original line number Diff line number Diff line /* Copyright (C) 2000-2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "mysys_priv.h" #include "m_string.h" #ifdef __WIN__ /* Windows NT/2000 discretionary access control utility functions. */ /* Check if the operating system is built on NT technology. RETURN 0 Windows 95/98/Me 1 otherwise */ static my_bool is_nt() { return GetVersion() < 0x80000000; } /* Auxilary structure to store pointers to the data which we need to keep around while SECURITY_ATTRIBUTES is in use. */ typedef struct st_my_security_attr { PSID everyone_sid; PACL dacl; } My_security_attr; /* Allocate and initialize SECURITY_ATTRIBUTES setting up access rights for the owner and group `Everybody'. SYNOPSIS my_security_attr_create() psa [OUT] pointer to store the pointer to SA in perror [OUT] pointer to store error message if there was an error owner_rights [IN] access rights for the owner everyone_rights [IN] access rights for group Everybody DESCRIPTION Set up the security attributes to provide clients with sufficient access rights to a kernel object. We need this function because if we simply grant all access to everybody (by installing a NULL DACL) a mailicious user can attempt a denial of service attack by taking ownership over the kernel object. Upon successful return `psa' contains a pointer to SECUIRITY_ATTRIBUTES that can be used to create kernel objects with proper access rights. RETURN 0 success, psa is 0 or points to a valid SA structure, perror is left intact !0 error, SA is set to 0, error message is stored in perror */ int my_security_attr_create(SECURITY_ATTRIBUTES **psa, const char **perror, DWORD owner_rights, DWORD everyone_rights) { /* Top-level SID authority */ SID_IDENTIFIER_AUTHORITY world_auth= SECURITY_WORLD_SID_AUTHORITY; PSID everyone_sid= 0; HANDLE htoken= 0; SECURITY_ATTRIBUTES *sa= 0; PACL dacl= 0; DWORD owner_token_length, dacl_length; SECURITY_DESCRIPTOR *sd; PTOKEN_USER owner_token; PSID owner_sid; My_security_attr *attr; if (! is_nt()) { *psa= 0; return 0; } /* Get SID of Everyone group. Easier to retrieve all SIDs each time this function is called than worry about thread safety. */ if (! AllocateAndInitializeSid(&world_auth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &everyone_sid)) { *perror= "Failed to retrieve the SID of Everyone group"; goto error; } /* Get SID of the owner. Using GetSecurityInfo this task can be done in just one call instead of five, but GetSecurityInfo declared in aclapi.h, so I hesitate to use it. SIC: OpenThreadToken works only if there is an active impersonation token, hence OpenProcessToken is used. */ if (! OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &htoken)) { *perror= "Failed to retrieve thread access token"; goto error; } GetTokenInformation(htoken, TokenUser, 0, 0, &owner_token_length); if (! my_multi_malloc(MYF(MY_WME), &sa, ALIGN_SIZE(sizeof(SECURITY_ATTRIBUTES)) + sizeof(My_security_attr), &sd, sizeof(SECURITY_DESCRIPTOR), &owner_token, owner_token_length, 0)) { *perror= "Failed to allocate memory for SECURITY_ATTRIBUTES"; goto error; } bzero(owner_token, owner_token_length); if (! GetTokenInformation(htoken, TokenUser, owner_token, owner_token_length, &owner_token_length)) { *perror= "GetTokenInformation failed"; goto error; } owner_sid= owner_token->User.Sid; if (! IsValidSid(owner_sid)) { *perror= "IsValidSid failed"; goto error; } /* Calculate the amount of memory that must be allocated for the DACL */ dacl_length= sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD)) * 2 + GetLengthSid(everyone_sid) + GetLengthSid(owner_sid); /* Create an ACL */ if (! (dacl= (PACL) my_malloc(dacl_length, MYF(MY_ZEROFILL|MY_WME)))) { *perror= "Failed to allocate memory for DACL"; goto error; } if (! InitializeAcl(dacl, dacl_length, ACL_REVISION)) { *perror= "Failed to initialize DACL"; goto error; } if (! AddAccessAllowedAce(dacl, ACL_REVISION, everyone_rights, everyone_sid)) { *perror= "Failed to set up DACL"; goto error; } if (! AddAccessAllowedAce(dacl, ACL_REVISION, owner_rights, owner_sid)) { *perror= "Failed to set up DACL"; goto error; } if (! InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) { *perror= "Could not initialize security descriptor"; goto error; } if (! SetSecurityDescriptorDacl(sd, TRUE, dacl, FALSE)) { *perror= "Failed to install DACL"; goto error; } sa->nLength= sizeof(*sa); sa->bInheritHandle= TRUE; sa->lpSecurityDescriptor= sd; /* Save pointers to everyone_sid and dacl to be able to clean them up */ attr= (My_security_attr*) (((char*) sa) + ALIGN_SIZE(sizeof(*sa))); attr->everyone_sid= everyone_sid; attr->dacl= dacl; *psa= sa; CloseHandle(htoken); return 0; error: if (everyone_sid) FreeSid(everyone_sid); if (htoken) CloseHandle(htoken); my_free((gptr) sa, MYF(MY_ALLOW_ZERO_PTR)); my_free((gptr) dacl, MYF(MY_ALLOW_ZERO_PTR)); *psa= 0; return 1; } /* Cleanup security attributes freeing used memory. SYNOPSIS my_security_attr_free() sa security attributes */ void my_security_attr_free(SECURITY_ATTRIBUTES *sa) { if (sa) { My_security_attr *attr= (My_security_attr*) (((char*)sa) + ALIGN_SIZE(sizeof(*sa))); FreeSid(attr->everyone_sid); my_free((gptr) attr->dacl, MYF(0)); my_free((gptr) sa, MYF(0)); } } #endif /* __WIN__ */ sql-common/client.c +8 −7 Original line number Diff line number Diff line Loading @@ -405,6 +405,7 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout) char *suffix_pos; DWORD error_allow = 0; DWORD error_code = 0; DWORD event_access_rights= SYNCHRONIZE | EVENT_MODIFY_STATE; char *shared_memory_base_name = mysql->options.shared_memory_base_name; /* Loading @@ -416,13 +417,13 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout) */ suffix_pos = strxmov(tmp,shared_memory_base_name,"_",NullS); strmov(suffix_pos, "CONNECT_REQUEST"); if (!(event_connect_request= OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp))) if (!(event_connect_request= OpenEvent(event_access_rights, FALSE, tmp))) { error_allow = CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR; goto err; } strmov(suffix_pos, "CONNECT_ANSWER"); if (!(event_connect_answer= OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp))) if (!(event_connect_answer= OpenEvent(event_access_rights,FALSE,tmp))) { error_allow = CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR; goto err; Loading Loading @@ -484,35 +485,35 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout) } strmov(suffix_pos, "SERVER_WROTE"); if ((event_server_wrote = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL) if ((event_server_wrote = OpenEvent(event_access_rights,FALSE,tmp)) == NULL) { error_allow = CR_SHARED_MEMORY_EVENT_ERROR; goto err2; } strmov(suffix_pos, "SERVER_READ"); if ((event_server_read = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL) if ((event_server_read = OpenEvent(event_access_rights,FALSE,tmp)) == NULL) { error_allow = CR_SHARED_MEMORY_EVENT_ERROR; goto err2; } strmov(suffix_pos, "CLIENT_WROTE"); if ((event_client_wrote = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL) if ((event_client_wrote = OpenEvent(event_access_rights,FALSE,tmp)) == NULL) { error_allow = CR_SHARED_MEMORY_EVENT_ERROR; goto err2; } strmov(suffix_pos, "CLIENT_READ"); if ((event_client_read = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL) if ((event_client_read = OpenEvent(event_access_rights,FALSE,tmp)) == NULL) { error_allow = CR_SHARED_MEMORY_EVENT_ERROR; goto err2; } strmov(suffix_pos, "CONNECTION_CLOSED"); if ((event_conn_closed = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL) if ((event_conn_closed = OpenEvent(event_access_rights,FALSE,tmp)) == NULL) { error_allow = CR_SHARED_MEMORY_EVENT_ERROR; goto err2; Loading Loading
VC++Files/mysys/mysys.dsp +4 −0 Original line number Diff line number Diff line Loading @@ -536,6 +536,10 @@ SOURCE=.\my_wincond.c # End Source File # Begin Source File SOURCE=.\my_windac.c # End Source File # Begin Source File SOURCE=.\my_winsem.c # End Source File # Begin Source File Loading
include/my_sys.h +8 −0 Original line number Diff line number Diff line Loading @@ -855,6 +855,14 @@ extern void thd_increment_net_big_packet_count(ulong length); #ifdef __WIN__ extern my_bool have_tcpip; /* Is set if tcpip is used */ /* implemented in my_windac.c */ int my_security_attr_create(SECURITY_ATTRIBUTES **psa, const char **perror, DWORD owner_rights, DWORD everybody_rights); void my_security_attr_free(SECURITY_ATTRIBUTES *sa); #endif #ifdef __NETWARE__ void netware_reg_user(const char *ip, const char *user, Loading
mysys/Makefile.am +2 −1 Original line number Diff line number Diff line Loading @@ -52,7 +52,8 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ my_net.c my_semaphore.c my_port.c my_sleep.c \ charset.c charset-def.c my_bitmap.c my_bit.c md5.c \ my_gethostbyname.c rijndael.c my_aes.c sha1.c \ my_handler.c my_netware.c my_largepage.c my_handler.c my_netware.c my_largepage.c \ my_windac.c EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \ thr_mutex.c thr_rwlock.c libmysys_a_LIBADD = @THREAD_LOBJECTS@ Loading
mysys/my_windac.c 0 → 100644 +224 −0 Original line number Diff line number Diff line /* Copyright (C) 2000-2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "mysys_priv.h" #include "m_string.h" #ifdef __WIN__ /* Windows NT/2000 discretionary access control utility functions. */ /* Check if the operating system is built on NT technology. RETURN 0 Windows 95/98/Me 1 otherwise */ static my_bool is_nt() { return GetVersion() < 0x80000000; } /* Auxilary structure to store pointers to the data which we need to keep around while SECURITY_ATTRIBUTES is in use. */ typedef struct st_my_security_attr { PSID everyone_sid; PACL dacl; } My_security_attr; /* Allocate and initialize SECURITY_ATTRIBUTES setting up access rights for the owner and group `Everybody'. SYNOPSIS my_security_attr_create() psa [OUT] pointer to store the pointer to SA in perror [OUT] pointer to store error message if there was an error owner_rights [IN] access rights for the owner everyone_rights [IN] access rights for group Everybody DESCRIPTION Set up the security attributes to provide clients with sufficient access rights to a kernel object. We need this function because if we simply grant all access to everybody (by installing a NULL DACL) a mailicious user can attempt a denial of service attack by taking ownership over the kernel object. Upon successful return `psa' contains a pointer to SECUIRITY_ATTRIBUTES that can be used to create kernel objects with proper access rights. RETURN 0 success, psa is 0 or points to a valid SA structure, perror is left intact !0 error, SA is set to 0, error message is stored in perror */ int my_security_attr_create(SECURITY_ATTRIBUTES **psa, const char **perror, DWORD owner_rights, DWORD everyone_rights) { /* Top-level SID authority */ SID_IDENTIFIER_AUTHORITY world_auth= SECURITY_WORLD_SID_AUTHORITY; PSID everyone_sid= 0; HANDLE htoken= 0; SECURITY_ATTRIBUTES *sa= 0; PACL dacl= 0; DWORD owner_token_length, dacl_length; SECURITY_DESCRIPTOR *sd; PTOKEN_USER owner_token; PSID owner_sid; My_security_attr *attr; if (! is_nt()) { *psa= 0; return 0; } /* Get SID of Everyone group. Easier to retrieve all SIDs each time this function is called than worry about thread safety. */ if (! AllocateAndInitializeSid(&world_auth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &everyone_sid)) { *perror= "Failed to retrieve the SID of Everyone group"; goto error; } /* Get SID of the owner. Using GetSecurityInfo this task can be done in just one call instead of five, but GetSecurityInfo declared in aclapi.h, so I hesitate to use it. SIC: OpenThreadToken works only if there is an active impersonation token, hence OpenProcessToken is used. */ if (! OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &htoken)) { *perror= "Failed to retrieve thread access token"; goto error; } GetTokenInformation(htoken, TokenUser, 0, 0, &owner_token_length); if (! my_multi_malloc(MYF(MY_WME), &sa, ALIGN_SIZE(sizeof(SECURITY_ATTRIBUTES)) + sizeof(My_security_attr), &sd, sizeof(SECURITY_DESCRIPTOR), &owner_token, owner_token_length, 0)) { *perror= "Failed to allocate memory for SECURITY_ATTRIBUTES"; goto error; } bzero(owner_token, owner_token_length); if (! GetTokenInformation(htoken, TokenUser, owner_token, owner_token_length, &owner_token_length)) { *perror= "GetTokenInformation failed"; goto error; } owner_sid= owner_token->User.Sid; if (! IsValidSid(owner_sid)) { *perror= "IsValidSid failed"; goto error; } /* Calculate the amount of memory that must be allocated for the DACL */ dacl_length= sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD)) * 2 + GetLengthSid(everyone_sid) + GetLengthSid(owner_sid); /* Create an ACL */ if (! (dacl= (PACL) my_malloc(dacl_length, MYF(MY_ZEROFILL|MY_WME)))) { *perror= "Failed to allocate memory for DACL"; goto error; } if (! InitializeAcl(dacl, dacl_length, ACL_REVISION)) { *perror= "Failed to initialize DACL"; goto error; } if (! AddAccessAllowedAce(dacl, ACL_REVISION, everyone_rights, everyone_sid)) { *perror= "Failed to set up DACL"; goto error; } if (! AddAccessAllowedAce(dacl, ACL_REVISION, owner_rights, owner_sid)) { *perror= "Failed to set up DACL"; goto error; } if (! InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) { *perror= "Could not initialize security descriptor"; goto error; } if (! SetSecurityDescriptorDacl(sd, TRUE, dacl, FALSE)) { *perror= "Failed to install DACL"; goto error; } sa->nLength= sizeof(*sa); sa->bInheritHandle= TRUE; sa->lpSecurityDescriptor= sd; /* Save pointers to everyone_sid and dacl to be able to clean them up */ attr= (My_security_attr*) (((char*) sa) + ALIGN_SIZE(sizeof(*sa))); attr->everyone_sid= everyone_sid; attr->dacl= dacl; *psa= sa; CloseHandle(htoken); return 0; error: if (everyone_sid) FreeSid(everyone_sid); if (htoken) CloseHandle(htoken); my_free((gptr) sa, MYF(MY_ALLOW_ZERO_PTR)); my_free((gptr) dacl, MYF(MY_ALLOW_ZERO_PTR)); *psa= 0; return 1; } /* Cleanup security attributes freeing used memory. SYNOPSIS my_security_attr_free() sa security attributes */ void my_security_attr_free(SECURITY_ATTRIBUTES *sa) { if (sa) { My_security_attr *attr= (My_security_attr*) (((char*)sa) + ALIGN_SIZE(sizeof(*sa))); FreeSid(attr->everyone_sid); my_free((gptr) attr->dacl, MYF(0)); my_free((gptr) sa, MYF(0)); } } #endif /* __WIN__ */
sql-common/client.c +8 −7 Original line number Diff line number Diff line Loading @@ -405,6 +405,7 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout) char *suffix_pos; DWORD error_allow = 0; DWORD error_code = 0; DWORD event_access_rights= SYNCHRONIZE | EVENT_MODIFY_STATE; char *shared_memory_base_name = mysql->options.shared_memory_base_name; /* Loading @@ -416,13 +417,13 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout) */ suffix_pos = strxmov(tmp,shared_memory_base_name,"_",NullS); strmov(suffix_pos, "CONNECT_REQUEST"); if (!(event_connect_request= OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp))) if (!(event_connect_request= OpenEvent(event_access_rights, FALSE, tmp))) { error_allow = CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR; goto err; } strmov(suffix_pos, "CONNECT_ANSWER"); if (!(event_connect_answer= OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp))) if (!(event_connect_answer= OpenEvent(event_access_rights,FALSE,tmp))) { error_allow = CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR; goto err; Loading Loading @@ -484,35 +485,35 @@ HANDLE create_shared_memory(MYSQL *mysql,NET *net, uint connect_timeout) } strmov(suffix_pos, "SERVER_WROTE"); if ((event_server_wrote = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL) if ((event_server_wrote = OpenEvent(event_access_rights,FALSE,tmp)) == NULL) { error_allow = CR_SHARED_MEMORY_EVENT_ERROR; goto err2; } strmov(suffix_pos, "SERVER_READ"); if ((event_server_read = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL) if ((event_server_read = OpenEvent(event_access_rights,FALSE,tmp)) == NULL) { error_allow = CR_SHARED_MEMORY_EVENT_ERROR; goto err2; } strmov(suffix_pos, "CLIENT_WROTE"); if ((event_client_wrote = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL) if ((event_client_wrote = OpenEvent(event_access_rights,FALSE,tmp)) == NULL) { error_allow = CR_SHARED_MEMORY_EVENT_ERROR; goto err2; } strmov(suffix_pos, "CLIENT_READ"); if ((event_client_read = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL) if ((event_client_read = OpenEvent(event_access_rights,FALSE,tmp)) == NULL) { error_allow = CR_SHARED_MEMORY_EVENT_ERROR; goto err2; } strmov(suffix_pos, "CONNECTION_CLOSED"); if ((event_conn_closed = OpenEvent(EVENT_ALL_ACCESS,FALSE,tmp)) == NULL) if ((event_conn_closed = OpenEvent(event_access_rights,FALSE,tmp)) == NULL) { error_allow = CR_SHARED_MEMORY_EVENT_ERROR; goto err2; Loading