Author: hpoussin Date: Thu Oct 12 13:01:16 2006 New Revision: 24493
URL: http://svn.reactos.org/svn/reactos?rev=24493&view=rev Log: Read object security descriptors from .inf file. Apply them for registry keys and services and display a message for files
Modified: trunk/reactos/dll/win32/setupapi/devinst.c trunk/reactos/dll/win32/setupapi/install.c trunk/reactos/dll/win32/setupapi/queue.c trunk/reactos/dll/win32/setupapi/setupapi_private.h
Modified: trunk/reactos/dll/win32/setupapi/devinst.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/setupapi/devinst.... ============================================================================== --- trunk/reactos/dll/win32/setupapi/devinst.c (original) +++ trunk/reactos/dll/win32/setupapi/devinst.c Thu Oct 12 13:01:16 2006 @@ -2270,8 +2270,8 @@ SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto cleanup; } - strcpyW(DriverKey, L"{"); - strcatW(DriverKey, lpGuidString); + DriverKey[0] = '{'; + strcpyW(&DriverKey[1], lpGuidString); strcatW(DriverKey, L"}\"); pDeviceInstance = &DriverKey[strlenW(DriverKey)]; rc = RegOpenKeyExW(RootKey,
Modified: trunk/reactos/dll/win32/setupapi/install.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/setupapi/install.... ============================================================================== --- trunk/reactos/dll/win32/setupapi/install.c (original) +++ trunk/reactos/dll/win32/setupapi/install.c Thu Oct 12 13:01:16 2006 @@ -89,6 +89,7 @@ static const WCHAR ProfileItems[] = {'P','r','o','f','i','l','e','I','t','e','m','s',0}; static const WCHAR Include[] = {'I','n','c','l','u','d','e',0}; static const WCHAR Needs[] = {'N','e','e','d','s',0}; +static const WCHAR DotSecurity[] = {'.','S','e','c','u','r','i','t','y',0};
/*********************************************************************** @@ -386,12 +387,49 @@ static BOOL registry_callback( HINF hinf, PCWSTR field, void *arg ) { struct registry_callback_info *info = arg; - INFCONTEXT context; + LPWSTR security_key, security_descriptor; + INFCONTEXT context, security_context; + PSECURITY_DESCRIPTOR sd = NULL; + SECURITY_ATTRIBUTES security_attributes = { 0, }; HKEY root_key, hkey; + DWORD required;
BOOL ok = SetupFindFirstLineW( hinf, field, NULL, &context ); - - for (; ok; ok = SetupFindNextLine( &context, &context )) + if (!ok) + return TRUE; + + /* Check for .Security section */ + security_key = MyMalloc( (strlenW( field ) + strlenW( DotSecurity )) * sizeof(WCHAR) + sizeof(UNICODE_NULL) ); + if (!security_key) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + strcpyW( security_key, field ); + strcatW( security_key, DotSecurity ); + ok = SetupFindFirstLineW( hinf, security_key, NULL, &security_context ); + MyFree(security_key); + if (ok) + { + if (!SetupGetLineText( &security_context, NULL, NULL, NULL, NULL, 0, &required )) + return FALSE; + security_descriptor = MyMalloc( required * sizeof(WCHAR) ); + if (!security_descriptor) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + if (!SetupGetLineText( &security_context, NULL, NULL, NULL, security_descriptor, required, NULL )) + return FALSE; + ok = ConvertStringSecurityDescriptorToSecurityDescriptorW( security_descriptor, SDDL_REVISION_1, &sd, NULL ); + MyFree( security_descriptor ); + if (!ok) + return FALSE; + security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES); + security_attributes.lpSecurityDescriptor = sd; + } + + for (ok = TRUE; ok; ok = SetupFindNextLine( &context, &context )) { WCHAR buffer[MAX_INF_STRING_LENGTH]; INT flags; @@ -423,7 +461,8 @@ { if (RegOpenKeyW( root_key, buffer, &hkey )) continue; /* ignore if it doesn't exist */ } - else if (RegCreateKeyW( root_key, buffer, &hkey )) + else if (RegCreateKeyExW( root_key, buffer, 0, NULL, 0, MAXIMUM_ALLOWED, + sd ? &security_attributes : NULL, &hkey, NULL )) { ERR( "could not create key %p %s\n", root_key, debugstr_w(buffer) ); continue; @@ -438,10 +477,12 @@ if (!do_reg_operation( hkey, buffer, &context, flags )) { if (hkey != root_key) RegCloseKey( hkey ); + if (sd) LocalFree( sd ); return FALSE; } if (hkey != root_key) RegCloseKey( hkey ); } + if (sd) LocalFree( sd ); return TRUE; }
@@ -1274,6 +1315,8 @@ LPWSTR DisplayName = NULL; LPWSTR Description = NULL; LPWSTR Dependencies = NULL; + LPWSTR SecurityDescriptor = NULL; + PSECURITY_DESCRIPTOR sd = NULL; INT ServiceType, StartType, ErrorControl; DWORD dwRegType; DWORD tagId = (DWORD)-1; @@ -1304,7 +1347,7 @@ hService = OpenServiceW( hSCManager, ServiceName, - GENERIC_READ | GENERIC_WRITE); + DELETE | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | WRITE_DAC); if (hService == NULL && GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST) goto cleanup;
@@ -1322,7 +1365,7 @@ hSCManager, ServiceName, DisplayName, - 0, + WRITE_DAC, ServiceType, StartType, ErrorControl, @@ -1365,6 +1408,17 @@ (ServiceFlags & SPSVCINST_NOCLOBBER_DEPENDENCIES && ServiceConfig->lpDependencies) ? NULL : Dependencies, NULL, NULL, (ServiceFlags & SPSVCINST_NOCLOBBER_DISPLAYNAME && ServiceConfig->lpDisplayName) ? NULL : DisplayName); + if (!ret) + goto cleanup; + } + + /* Set security */ + if (GetLineText(hInf, ServiceSection, L"Security", &SecurityDescriptor)) + { + ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(SecurityDescriptor, SDDL_REVISION_1, &sd, NULL); + if (!ret) + goto cleanup; + ret = SetServiceObjectSecurity(hService, DACL_SECURITY_INFORMATION, sd); if (!ret) goto cleanup; } @@ -1462,12 +1516,15 @@ CloseServiceHandle(hService); if (hGroupOrderListKey != NULL) RegCloseKey(hGroupOrderListKey); + if (sd != NULL) + LocalFree(sd); MyFree(ServiceConfig); MyFree(ServiceBinary); MyFree(LoadOrderGroup); MyFree(DisplayName); MyFree(Description); MyFree(Dependencies); + MyFree(SecurityDescriptor); MyFree(GroupOrder);
TRACE("Returning %d\n", ret);
Modified: trunk/reactos/dll/win32/setupapi/queue.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/setupapi/queue.c?... ============================================================================== --- trunk/reactos/dll/win32/setupapi/queue.c (original) +++ trunk/reactos/dll/win32/setupapi/queue.c Thu Oct 12 13:01:16 2006 @@ -22,6 +22,9 @@
WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
+/* Unicode constants */ +static const WCHAR DotSecurity[] = {'.','S','e','c','u','r','i','t','y',0}; + /* context structure for the default queue callback */ struct default_callback_context { @@ -313,6 +316,7 @@ } if (!op->src_path && !(op->style & SP_COPY_SOURCE_ABSOLUTE)) { + len = len2 = 0; if (!(op->style & SP_COPY_SOURCEPATH_ABSOLUTE)) { /* retrieve relative path for this disk */ @@ -331,7 +335,7 @@ ptr = op->src_path + strlenW(op->src_path); if (len2 && ptr > op->src_path && ptr[-1] != '\') *ptr++ = '\'; } - if (!SetupGetStringFieldW( &disk_ctx, 4, ptr, len2, NULL )) *ptr = 0; + if (!SetupGetStringFieldW( &file_ctx, 2, ptr, len2, NULL )) *ptr = 0; } } if (!op->src_root) op->src_root = PARSER_get_src_root(hinf); @@ -486,6 +490,8 @@ op->src_tag = strdupW( params->SourceTagfile ); op->dst_path = strdupW( params->TargetDirectory ); op->dst_file = strdupW( params->TargetFilename ); + if (params->SecurityDescriptor) + FIXME( "Need to apply %s to %s\n", debugstr_w( params->SecurityDescriptor ), debugstr_w( op->dst_file ));
/* some defaults */ if (!op->src_file) op->src_file = op->dst_file; @@ -731,12 +737,43 @@ PCWSTR section, DWORD style ) { SP_FILE_COPY_PARAMS_W params; - INFCONTEXT context; + LPWSTR security_key, security_descriptor = NULL; + INFCONTEXT context, security_context; WCHAR dest[MAX_PATH], src[MAX_PATH]; INT flags; + DWORD required; + BOOL ret;
TRACE( "hinf=%p/%p section=%s root=%s\n", hinf, hlist, debugstr_w(section), debugstr_w(src_root) ); + + /* Check for .Security section */ + security_key = MyMalloc( (strlenW( section ) + strlenW( DotSecurity )) * sizeof(WCHAR) + sizeof(UNICODE_NULL) ); + if (!security_key) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + strcpyW( security_key, section ); + strcatW( security_key, DotSecurity ); + ret = SetupFindFirstLineW( hinf, security_key, NULL, &security_context ); + MyFree(security_key); + if (ret) + { + if (!SetupGetLineText( &security_context, NULL, NULL, NULL, NULL, 0, &required )) + return FALSE; + security_descriptor = MyMalloc( required * sizeof(WCHAR) ); + if (!security_descriptor) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + if (!SetupGetLineText( &security_context, NULL, NULL, NULL, security_descriptor, required, NULL )) + { + MyFree( security_descriptor ); + return FALSE; + } + }
params.cbSize = sizeof(params); params.QueueHandle = queue; @@ -747,23 +784,29 @@ params.TargetFilename = dest; params.CopyStyle = style; params.LayoutInf = hinf; - params.SecurityDescriptor = NULL; - + params.SecurityDescriptor = security_descriptor; + + ret = FALSE; if (!hlist) hlist = hinf; if (!hinf) hinf = hlist; - if (!SetupFindFirstLineW( hlist, section, NULL, &context )) return FALSE; - if (!(params.TargetDirectory = get_destination_dir( hinf, section ))) return FALSE; + if (!SetupFindFirstLineW( hlist, section, NULL, &context )) goto done; + if (!(params.TargetDirectory = get_destination_dir( hinf, section ))) goto done; do { if (!SetupGetStringFieldW( &context, 1, dest, sizeof(dest)/sizeof(WCHAR), NULL )) - return FALSE; + goto done; if (!SetupGetStringFieldW( &context, 2, src, sizeof(src)/sizeof(WCHAR), NULL )) *src = 0; if (!SetupGetIntField( &context, 4, &flags )) flags = 0; /* FIXME */
params.SourceFilename = *src ? src : NULL; - if (!SetupQueueCopyIndirectW( ¶ms )) return FALSE; + if (!SetupQueueCopyIndirectW( ¶ms )) goto done; } while (SetupFindNextLine( &context, &context )); - return TRUE; + ret = TRUE; + +done: + if (security_descriptor) + MyFree( security_descriptor ); + return ret; }
Modified: trunk/reactos/dll/win32/setupapi/setupapi_private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/setupapi/setupapi... ============================================================================== --- trunk/reactos/dll/win32/setupapi/setupapi_private.h (original) +++ trunk/reactos/dll/win32/setupapi/setupapi_private.h Thu Oct 12 13:01:16 2006 @@ -32,6 +32,7 @@ #include <cfgmgr32.h> #include <fdi.h> #include <regstr.h> +#include <sddl.h> #include <setupapi.h> #include <shlobj.h> #include <wine/debug.h>