[PATCH 1 of 3] Move Shell functions into util
Wald Commits
scm-commit at wald.intevation.org
Fri Aug 29 17:13:49 CEST 2014
# HG changeset patch
# User Andre Heinecke <andre.heinecke at intevation.de>
# Date 1409325095 -7200
# Node ID 427e2e18b8c85fdc708f9b1417e10a772d0d16b5
# Parent 85c497b45488fbba1d19e22253fe5590cec8fffb
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.
diff -r 85c497b45488 -r 427e2e18b8c8 cinst/nssstore_win.c
--- a/cinst/nssstore_win.c Fri Aug 29 16:08:50 2014 +0200
+++ b/cinst/nssstore_win.c Fri Aug 29 17:11:35 2014 +0200
@@ -47,7 +47,6 @@
#include <io.h>
#include <accctrl.h>
#include <aclapi.h>
-#include <shlobj.h>
#include "logging.h"
#include "util.h"
@@ -735,147 +734,6 @@
return true;
}
-/**@brief Create a directory with restricted access rights
- *
- * This creates a security attributes structure that restricts
- * write access to the Administrators group but allows everyone to read files
- * 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.
- *
- * Code based on msdn example:
- * http://msdn.microsoft.com/en-us/library/windows/desktop/aa446595%28v=vs.85%29.aspx
- *
- * @param[in] path Path of the directory to create
- *
- * @returns true on success of if the directory exists, false on error
- */
-bool
-create_restricted_directory (LPWSTR path)
-{
- bool retval = false;
- PSID everyone_SID = NULL,
- admin_SID = NULL;
- PACL access_control_list = NULL;
- PSECURITY_DESCRIPTOR descriptor = NULL;
- EXPLICIT_ACCESS explicit_access[2];
- SID_IDENTIFIER_AUTHORITY world_identifier = {SECURITY_WORLD_SID_AUTHORITY},
- admin_identifier = {SECURITY_NT_AUTHORITY};
- SECURITY_ATTRIBUTES security_attributes;
-
- ZeroMemory(&security_attributes, sizeof(security_attributes));
- ZeroMemory(&explicit_access, 2 * sizeof(EXPLICIT_ACCESS));
-
- /* Create a well-known SID for the Everyone group. */
- if(!AllocateAndInitializeSid(&world_identifier, /* top-level identifier */
- 1, /* subauthorties count */
- SECURITY_WORLD_RID, /* Only one authority */
- 0, 0, 0, 0, 0, 0, 0, /* No other authorities*/
- &everyone_SID))
- {
- PRINTLASTERROR ("Failed to allocate world sid.\n");
- return false;
- }
-
- /* Initialize the first EXPLICIT_ACCESS structure for an ACE.
- to allow everyone read access */
- explicit_access[0].grfAccessPermissions = GENERIC_READ; /* Give read access */
- explicit_access[0].grfAccessMode = SET_ACCESS; /* Overwrite other access for all users */
- explicit_access[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; /* make it stick */
- explicit_access[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
- explicit_access[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
- explicit_access[0].Trustee.ptstrName = (LPTSTR) everyone_SID;
-
- /* 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.");
- goto done;
- }
-
- /* explicit_access[1] grants admins full rights for this object and inherits
- it to the children */
- explicit_access[1].grfAccessPermissions = GENERIC_ALL;
- explicit_access[1].grfAccessMode = SET_ACCESS;
- explicit_access[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
- explicit_access[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
- explicit_access[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
- explicit_access[1].Trustee.ptstrName = (LPTSTR) admin_SID;
-
- /* Set up the ACL structure. */
- if (ERROR_SUCCESS != SetEntriesInAcl(2, explicit_access, NULL, &access_control_list))
- {
- PRINTLASTERROR ("Failed to set up Acl.");
- goto done;
- }
-
- /* Initialize a security descriptor */
- descriptor = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
- SECURITY_DESCRIPTOR_MIN_LENGTH);
- if (descriptor == NULL)
- {
- PRINTLASTERROR("Failed to allocate descriptor.");
- goto done;
- }
-
- if (!InitializeSecurityDescriptor(descriptor,
- SECURITY_DESCRIPTOR_REVISION))
- {
- PRINTLASTERROR("Failed to initialize descriptor.");
- goto done;
- }
-
- /* Now we add the ACL to the the descriptor */
- if (!SetSecurityDescriptorDacl(descriptor,
- TRUE, /* bDaclPresent flag */
- access_control_list,
- FALSE)) /* not a default DACL */
- {
- PRINTLASTERROR("Failed to set security descriptor.");
- goto done;
- }
-
- /* Finally set up the security attributes structure */
- security_attributes.nLength = sizeof (SECURITY_ATTRIBUTES);
- security_attributes.lpSecurityDescriptor = descriptor;
- security_attributes.bInheritHandle = FALSE;
-
- /* Use the security attributes to create the directory */
- if (!CreateDirectoryW(path, &security_attributes))
- {
- DWORD err = GetLastError();
- if (err == ERROR_ALREADY_EXISTS)
- {
- /* Verify that the directory has the correct rights */
- // TODO
- retval = true;
- goto done;
- }
- ERRORPRINTF ("Failed to create directory. Err: %lu", err);
- }
- retval = true;
-
-done:
-
- if (everyone_SID)
- FreeSid(everyone_SID);
- if (admin_SID)
- FreeSid(admin_SID);
- if (access_control_list)
- LocalFree(access_control_list);
- if (descriptor)
- LocalFree(descriptor);
-
- return retval;
-}
-
/**@brief Writes the selection file containing the instructions
*
* If the process is running elevated the instructions are
@@ -894,19 +752,13 @@
{
wchar_t *folder_name = NULL,
*path = NULL;
- HRESULT result = E_FAIL;
HANDLE hFile = NULL;
size_t path_len;
- result = SHGetKnownFolderPath (&FOLDERID_ProgramData, /* Get program data dir */
- KF_FLAG_CREATE | /* Create if it does not exist */
- KF_FLAG_INIT, /* Initialize it if created */
- INVALID_HANDLE_VALUE, /* Get it for the default user */
- &folder_name);
-
- if (result != S_OK)
+ folder_name = get_program_data_folder();
+ if (!folder_name)
{
- PRINTLASTERROR ("Failed to get folder path");
+ ERRORPRINTF("Failed to look up ProgramData folder.\n");
return NULL;
}
diff -r 85c497b45488 -r 427e2e18b8c8 common/util.c
--- a/common/util.c Fri Aug 29 16:08:50 2014 +0200
+++ b/common/util.c Fri Aug 29 17:11:35 2014 +0200
@@ -17,6 +17,9 @@
#include <string.h>
#else
#include <windows.h>
+#include <accctrl.h>
+#include <aclapi.h>
+#include <shlobj.h>
#endif
#ifndef APPNAME
@@ -426,6 +429,46 @@
return ret;
}
+#ifdef _WIN32
+char *
+get_program_files_folder ()
+{
+ wchar_t *folder_name = NULL;
+ char *retval = NULL;
+ if (SHGetKnownFolderPath (&FOLDERID_ProgramFiles, /* Get program data dir */
+ KF_FLAG_NO_ALIAS,
+ INVALID_HANDLE_VALUE, /* Get it for the default user */
+ &folder_name) != S_OK)
+ {
+ PRINTLASTERROR ("Failed to get program files folder.");
+ return NULL;
+ }
+
+ retval = wchar_to_utf8 (folder_name, wcslen(folder_name));
+ CoTaskMemFree (folder_name);
+ return retval;
+}
+
+/* This is a bit ridicoulous but necessary as shlobj.h contains an inline
+ definition. So only one C file may include it and thus we have to put
+ all our shlobj calls into one file... */
+wchar_t *
+get_program_data_folder ()
+{
+ wchar_t *folder_name = NULL;
+ if (SHGetKnownFolderPath (&FOLDERID_ProgramData, /* Get program data dir */
+ KF_FLAG_CREATE | /* Create if it does not exist */
+ KF_FLAG_INIT, /* Initialize it if created */
+ INVALID_HANDLE_VALUE, /* Get it for the default user */
+ &folder_name) != S_OK)
+ {
+ PRINTLASTERROR ("Failed to get folder path");
+ return NULL;
+ }
+ return folder_name;
+}
+#endif
+
bool
is_admin()
{
@@ -556,3 +599,128 @@
#endif
}
+#ifdef WIN32
+bool
+create_restricted_directory (LPWSTR path)
+{
+ bool retval = false;
+ PSID everyone_SID = NULL,
+ admin_SID = NULL;
+ PACL access_control_list = NULL;
+ PSECURITY_DESCRIPTOR descriptor = NULL;
+ EXPLICIT_ACCESS explicit_access[2];
+ SID_IDENTIFIER_AUTHORITY world_identifier = {SECURITY_WORLD_SID_AUTHORITY},
+ admin_identifier = {SECURITY_NT_AUTHORITY};
+ SECURITY_ATTRIBUTES security_attributes;
+
+ ZeroMemory(&security_attributes, sizeof(security_attributes));
+ ZeroMemory(&explicit_access, 2 * sizeof(EXPLICIT_ACCESS));
+
+ /* Create a well-known SID for the Everyone group. */
+ if(!AllocateAndInitializeSid(&world_identifier, /* top-level identifier */
+ 1, /* subauthorties count */
+ SECURITY_WORLD_RID, /* Only one authority */
+ 0, 0, 0, 0, 0, 0, 0, /* No other authorities*/
+ &everyone_SID))
+ {
+ PRINTLASTERROR ("Failed to allocate world sid.\n");
+ return false;
+ }
+
+ /* Initialize the first EXPLICIT_ACCESS structure for an ACE.
+ to allow everyone read access */
+ explicit_access[0].grfAccessPermissions = GENERIC_READ; /* Give read access */
+ explicit_access[0].grfAccessMode = SET_ACCESS; /* Overwrite other access for all users */
+ explicit_access[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT; /* make it stick */
+ explicit_access[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ explicit_access[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
+ explicit_access[0].Trustee.ptstrName = (LPTSTR) everyone_SID;
+
+ /* 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.");
+ goto done;
+ }
+
+ /* explicit_access[1] grants admins full rights for this object and inherits
+ it to the children */
+ explicit_access[1].grfAccessPermissions = GENERIC_ALL;
+ explicit_access[1].grfAccessMode = SET_ACCESS;
+ explicit_access[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
+ explicit_access[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ explicit_access[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
+ explicit_access[1].Trustee.ptstrName = (LPTSTR) admin_SID;
+
+ /* Set up the ACL structure. */
+ if (ERROR_SUCCESS != SetEntriesInAcl(2, explicit_access, NULL, &access_control_list))
+ {
+ PRINTLASTERROR ("Failed to set up Acl.");
+ goto done;
+ }
+
+ /* Initialize a security descriptor */
+ descriptor = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
+ SECURITY_DESCRIPTOR_MIN_LENGTH);
+ if (descriptor == NULL)
+ {
+ PRINTLASTERROR("Failed to allocate descriptor.");
+ goto done;
+ }
+
+ if (!InitializeSecurityDescriptor(descriptor,
+ SECURITY_DESCRIPTOR_REVISION))
+ {
+ PRINTLASTERROR("Failed to initialize descriptor.");
+ goto done;
+ }
+
+ /* Now we add the ACL to the the descriptor */
+ if (!SetSecurityDescriptorDacl(descriptor,
+ TRUE, /* bDaclPresent flag */
+ access_control_list,
+ FALSE)) /* not a default DACL */
+ {
+ PRINTLASTERROR("Failed to set security descriptor.");
+ goto done;
+ }
+
+ /* Finally set up the security attributes structure */
+ security_attributes.nLength = sizeof (SECURITY_ATTRIBUTES);
+ security_attributes.lpSecurityDescriptor = descriptor;
+ security_attributes.bInheritHandle = FALSE;
+
+ /* Use the security attributes to create the directory */
+ if (!CreateDirectoryW(path, &security_attributes))
+ {
+ DWORD err = GetLastError();
+ if (err == ERROR_ALREADY_EXISTS)
+ {
+ /* Verify that the directory has the correct rights */
+ // TODO
+ retval = true;
+ goto done;
+ }
+ ERRORPRINTF ("Failed to create directory. Err: %lu", err);
+ }
+ retval = true;
+
+done:
+
+ if (everyone_SID)
+ FreeSid(everyone_SID);
+ if (admin_SID)
+ FreeSid(admin_SID);
+ if (access_control_list)
+ LocalFree(access_control_list);
+ if (descriptor)
+ LocalFree(descriptor);
+
+ return retval;
+}
+#endif
diff -r 85c497b45488 -r 427e2e18b8c8 common/util.h
--- a/common/util.h Fri Aug 29 16:08:50 2014 +0200
+++ b/common/util.h Fri Aug 29 17:11:35 2014 +0200
@@ -100,6 +100,42 @@
*/
char * read_registry_string (const HKEY root, const wchar_t *key,
const wchar_t *name);
+
+/**@brief Get the utf-8 encoded path to the program files folder.
+ *
+ * Uses SHGetKnownFolderPath to look up the ProgramFiles folder.
+ * @returns a newly allocated string containing the value or NULL on
+ * error.
+ */
+char * get_program_files_folder ();
+
+/**@brief Get the path to the program data folder.
+ *
+ * Uses SHGetKnownFolderPath to look up the ProgramData folder.
+ * The return value should be freed with CoTaskMemFree
+ * @returns a reference containing the value or NULL on error.
+ */
+wchar_t * get_program_data_folder ();
+
+/**@brief Create a directory with restricted access rights
+ *
+ * This creates a security attributes structure that restricts
+ * write access to the Administrators group but allows everyone to read files
+ * 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.
+ *
+ * Code based on msdn example:
+ * http://msdn.microsoft.com/en-us/library/windows/desktop/aa446595%28v=vs.85%29.aspx
+ *
+ * @param[in] path Path of the directory to create
+ *
+ * @returns true on success of if the directory exists, false on error
+ */
+bool create_restricted_directory (LPWSTR path);
+
#endif
#ifdef __cplusplus
More information about the Trustbridge-commits
mailing list