From 3dce4b0486e731c5fc938ba611e5db701ebbda1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Thu, 12 Oct 2006 09:01:16 +0000 Subject: [PATCH] Read object security descriptors from .inf file. Apply them for registry keys and services and display a message for files svn path=/trunk/; revision=24493 --- reactos/dll/win32/setupapi/devinst.c | 4 +- reactos/dll/win32/setupapi/install.c | 67 +++++++++++++++++-- reactos/dll/win32/setupapi/queue.c | 59 +++++++++++++--- reactos/dll/win32/setupapi/setupapi_private.h | 1 + 4 files changed, 116 insertions(+), 15 deletions(-) diff --git a/reactos/dll/win32/setupapi/devinst.c b/reactos/dll/win32/setupapi/devinst.c index 0d6acb63aca..95df4c4a9a8 100644 --- a/reactos/dll/win32/setupapi/devinst.c +++ b/reactos/dll/win32/setupapi/devinst.c @@ -2270,8 +2270,8 @@ SetupDiCreateDevRegKeyW( 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, diff --git a/reactos/dll/win32/setupapi/install.c b/reactos/dll/win32/setupapi/install.c index b5fc74c3fbc..34fb83dd0fa 100644 --- a/reactos/dll/win32/setupapi/install.c +++ b/reactos/dll/win32/setupapi/install.c @@ -89,6 +89,7 @@ static const WCHAR UnregisterDlls[] = {'U','n','r','e','g','i','s','t','e','r', 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 do_reg_operation( HKEY hkey, const WCHAR *value, INFCONTEXT *context 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 ); + if (!ok) + return TRUE; - for (; ok; ok = SetupFindNextLine( &context, &context )) + /* 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 @@ static BOOL registry_callback( HINF hinf, PCWSTR field, void *arg ) { 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 @@ static BOOL registry_callback( HINF hinf, PCWSTR field, void *arg ) 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 @@ static BOOL InstallOneService( 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 @@ static BOOL InstallOneService( 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 @@ static BOOL InstallOneService( hSCManager, ServiceName, DisplayName, - 0, + WRITE_DAC, ServiceType, StartType, ErrorControl, @@ -1369,6 +1412,17 @@ static BOOL InstallOneService( 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; + } + /* FIXME: use Description and SPSVCINST_NOCLOBBER_DESCRIPTION */ if (useTag) @@ -1462,12 +1516,15 @@ cleanup: 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); diff --git a/reactos/dll/win32/setupapi/queue.c b/reactos/dll/win32/setupapi/queue.c index e8e8cd298d1..a5757d8388b 100644 --- a/reactos/dll/win32/setupapi/queue.c +++ b/reactos/dll/win32/setupapi/queue.c @@ -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 @@ static void get_src_file_info( HINF hinf, struct file_op *op ) } 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 @@ static void get_src_file_info( HINF hinf, struct file_op *op ) 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 @@ BOOL WINAPI SetupQueueCopyIndirectW( PSP_FILE_COPY_PARAMS_W params ) 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,13 +737,44 @@ BOOL WINAPI SetupQueueCopySectionW( HSPFILEQ queue, PCWSTR src_root, HINF hinf, 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; params.SourceRootPath = src_root; @@ -747,23 +784,29 @@ BOOL WINAPI SetupQueueCopySectionW( HSPFILEQ queue, PCWSTR src_root, HINF hinf, 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; } diff --git a/reactos/dll/win32/setupapi/setupapi_private.h b/reactos/dll/win32/setupapi/setupapi_private.h index 2022aa376c9..74588dce5c7 100644 --- a/reactos/dll/win32/setupapi/setupapi_private.h +++ b/reactos/dll/win32/setupapi/setupapi_private.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include