Mercurial > trustbridge
comparison cinst/nssstore_win.c @ 983:427e2e18b8c8
Move Shell functions into util
Due to a bug in mingw only one c file may include shlobj.h as there
is an unguarded inline definition in there leading to multiple
definition errors. Thus the get_program_data get_program_files
utility functions.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Fri, 29 Aug 2014 17:11:35 +0200 |
parents | 698b6a9bd75e |
children | 1743895b39b8 |
comparison
equal
deleted
inserted
replaced
982:85c497b45488 | 983:427e2e18b8c8 |
---|---|
45 #include <stdbool.h> | 45 #include <stdbool.h> |
46 #include <userenv.h> | 46 #include <userenv.h> |
47 #include <io.h> | 47 #include <io.h> |
48 #include <accctrl.h> | 48 #include <accctrl.h> |
49 #include <aclapi.h> | 49 #include <aclapi.h> |
50 #include <shlobj.h> | |
51 | 50 |
52 #include "logging.h" | 51 #include "logging.h" |
53 #include "util.h" | 52 #include "util.h" |
54 #include "strhelp.h" | 53 #include "strhelp.h" |
55 | 54 |
733 if (piProcInfo.hThread) | 732 if (piProcInfo.hThread) |
734 CloseHandle (piProcInfo.hThread); | 733 CloseHandle (piProcInfo.hThread); |
735 return true; | 734 return true; |
736 } | 735 } |
737 | 736 |
738 /**@brief Create a directory with restricted access rights | |
739 * | |
740 * This creates a security attributes structure that restricts | |
741 * write access to the Administrators group but allows everyone to read files | |
742 * in that directory. | |
743 * Basically a very complicated version of mkdir path -m 644 | |
744 * | |
745 * If the directory exists the permissions of that directory are checked if | |
746 * they are acceptable and true or false is returned accordingly. | |
747 * | |
748 * Code based on msdn example: | |
749 * http://msdn.microsoft.com/en-us/library/windows/desktop/aa446595%28v=vs.85%29.aspx | |
750 * | |
751 * @param[in] path Path of the directory to create | |
752 * | |
753 * @returns true on success of if the directory exists, false on error | |
754 */ | |
755 bool | |
756 create_restricted_directory (LPWSTR path) | |
757 { | |
758 bool retval = false; | |
759 PSID everyone_SID = NULL, | |
760 admin_SID = NULL; | |
761 PACL access_control_list = NULL; | |
762 PSECURITY_DESCRIPTOR descriptor = NULL; | |
763 EXPLICIT_ACCESS explicit_access[2]; | |
764 SID_IDENTIFIER_AUTHORITY world_identifier = {SECURITY_WORLD_SID_AUTHORITY}, | |
765 admin_identifier = {SECURITY_NT_AUTHORITY}; | |
766 SECURITY_ATTRIBUTES security_attributes; | |
767 | |
768 ZeroMemory(&security_attributes, sizeof(security_attributes)); | |
769 ZeroMemory(&explicit_access, 2 * sizeof(EXPLICIT_ACCESS)); | |
770 | |
771 /* Create a well-known SID for the Everyone group. */ | |
772 if(!AllocateAndInitializeSid(&world_identifier, /* top-level identifier */ | |
773 1, /* subauthorties count */ | |
774 SECURITY_WORLD_RID, /* Only one authority */ | |
775 0, 0, 0, 0, 0, 0, 0, /* No other authorities*/ | |
776 &everyone_SID)) | |
777 { | |
778 PRINTLASTERROR ("Failed to allocate world sid.\n"); | |
779 return false; | |
780 } | |
781 | |
782 /* Initialize the first EXPLICIT_ACCESS structure for an ACE. | |
783 to allow everyone read access */ | |
784 explicit_access[0].grfAccessPermissions = GENERIC_READ; /* Give read access */ | |
785 explicit_access[0].grfAccessMode = SET_ACCESS; /* Overwrite other access for all users */ | |
786 explicit_access[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; /* make it stick */ | |
787 explicit_access[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; | |
788 explicit_access[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; | |
789 explicit_access[0].Trustee.ptstrName = (LPTSTR) everyone_SID; | |
790 | |
791 /* Create the SID for the BUILTIN\Administrators group. */ | |
792 if(!AllocateAndInitializeSid(&admin_identifier, | |
793 2, | |
794 SECURITY_BUILTIN_DOMAIN_RID, /*BUILTIN\ */ | |
795 DOMAIN_ALIAS_RID_ADMINS, /*\Administrators */ | |
796 0, 0, 0, 0, 0, 0, /* No other */ | |
797 &admin_SID)) | |
798 { | |
799 PRINTLASTERROR ("Failed to allocate admin sid."); | |
800 goto done; | |
801 } | |
802 | |
803 /* explicit_access[1] grants admins full rights for this object and inherits | |
804 it to the children */ | |
805 explicit_access[1].grfAccessPermissions = GENERIC_ALL; | |
806 explicit_access[1].grfAccessMode = SET_ACCESS; | |
807 explicit_access[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; | |
808 explicit_access[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; | |
809 explicit_access[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP; | |
810 explicit_access[1].Trustee.ptstrName = (LPTSTR) admin_SID; | |
811 | |
812 /* Set up the ACL structure. */ | |
813 if (ERROR_SUCCESS != SetEntriesInAcl(2, explicit_access, NULL, &access_control_list)) | |
814 { | |
815 PRINTLASTERROR ("Failed to set up Acl."); | |
816 goto done; | |
817 } | |
818 | |
819 /* Initialize a security descriptor */ | |
820 descriptor = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, | |
821 SECURITY_DESCRIPTOR_MIN_LENGTH); | |
822 if (descriptor == NULL) | |
823 { | |
824 PRINTLASTERROR("Failed to allocate descriptor."); | |
825 goto done; | |
826 } | |
827 | |
828 if (!InitializeSecurityDescriptor(descriptor, | |
829 SECURITY_DESCRIPTOR_REVISION)) | |
830 { | |
831 PRINTLASTERROR("Failed to initialize descriptor."); | |
832 goto done; | |
833 } | |
834 | |
835 /* Now we add the ACL to the the descriptor */ | |
836 if (!SetSecurityDescriptorDacl(descriptor, | |
837 TRUE, /* bDaclPresent flag */ | |
838 access_control_list, | |
839 FALSE)) /* not a default DACL */ | |
840 { | |
841 PRINTLASTERROR("Failed to set security descriptor."); | |
842 goto done; | |
843 } | |
844 | |
845 /* Finally set up the security attributes structure */ | |
846 security_attributes.nLength = sizeof (SECURITY_ATTRIBUTES); | |
847 security_attributes.lpSecurityDescriptor = descriptor; | |
848 security_attributes.bInheritHandle = FALSE; | |
849 | |
850 /* Use the security attributes to create the directory */ | |
851 if (!CreateDirectoryW(path, &security_attributes)) | |
852 { | |
853 DWORD err = GetLastError(); | |
854 if (err == ERROR_ALREADY_EXISTS) | |
855 { | |
856 /* Verify that the directory has the correct rights */ | |
857 // TODO | |
858 retval = true; | |
859 goto done; | |
860 } | |
861 ERRORPRINTF ("Failed to create directory. Err: %lu", err); | |
862 } | |
863 retval = true; | |
864 | |
865 done: | |
866 | |
867 if (everyone_SID) | |
868 FreeSid(everyone_SID); | |
869 if (admin_SID) | |
870 FreeSid(admin_SID); | |
871 if (access_control_list) | |
872 LocalFree(access_control_list); | |
873 if (descriptor) | |
874 LocalFree(descriptor); | |
875 | |
876 return retval; | |
877 } | |
878 | |
879 /**@brief Writes the selection file containing the instructions | 737 /**@brief Writes the selection file containing the instructions |
880 * | 738 * |
881 * If the process is running elevated the instructions are | 739 * If the process is running elevated the instructions are |
882 * written to the global ProgramData directory otherwise | 740 * written to the global ProgramData directory otherwise |
883 * they are written in the directory of the current user. | 741 * they are written in the directory of the current user. |
892 wchar_t * | 750 wchar_t * |
893 write_selection_file (char **to_install, char **to_remove) | 751 write_selection_file (char **to_install, char **to_remove) |
894 { | 752 { |
895 wchar_t *folder_name = NULL, | 753 wchar_t *folder_name = NULL, |
896 *path = NULL; | 754 *path = NULL; |
897 HRESULT result = E_FAIL; | |
898 HANDLE hFile = NULL; | 755 HANDLE hFile = NULL; |
899 size_t path_len; | 756 size_t path_len; |
900 | 757 |
901 result = SHGetKnownFolderPath (&FOLDERID_ProgramData, /* Get program data dir */ | 758 folder_name = get_program_data_folder(); |
902 KF_FLAG_CREATE | /* Create if it does not exist */ | 759 if (!folder_name) |
903 KF_FLAG_INIT, /* Initialize it if created */ | 760 { |
904 INVALID_HANDLE_VALUE, /* Get it for the default user */ | 761 ERRORPRINTF("Failed to look up ProgramData folder.\n"); |
905 &folder_name); | |
906 | |
907 if (result != S_OK) | |
908 { | |
909 PRINTLASTERROR ("Failed to get folder path"); | |
910 return NULL; | 762 return NULL; |
911 } | 763 } |
912 | 764 |
913 path_len = wcslen (folder_name) + wcslen (APPNAME) + 2; /* path + dirsep + \0 */ | 765 path_len = wcslen (folder_name) + wcslen (APPNAME) + 2; /* path + dirsep + \0 */ |
914 path_len += wcslen (SELECTION_FILE_NAME) + 1; /* filename + dirsep */ | 766 path_len += wcslen (SELECTION_FILE_NAME) + 1; /* filename + dirsep */ |