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
This commit is contained in:
Hervé Poussineau 2006-10-12 09:01:16 +00:00
parent 32ac32df07
commit 3dce4b0486
4 changed files with 116 additions and 15 deletions

View file

@ -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,

View file

@ -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);

View file

@ -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( &params )) return FALSE;
if (!SetupQueueCopyIndirectW( &params )) goto done;
} while (SetupFindNextLine( &context, &context ));
return TRUE;
ret = TRUE;
done:
if (security_descriptor)
MyFree( security_descriptor );
return ret;
}

View file

@ -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>