Vista printer driver file permissions problem
- From: "gary" <---gwa000---@xxxxxxxxxxx>
- Date: Mon, 11 Dec 2006 00:50:05 GMT
i have an interesting problem under Vista which i can not seem to resolve.
during a printer install, we have some code in IPrintOemUI::PrinterEvent
which spawns off another executable. in this executable, among doing other
stuff, we create a file (if it doesn't exist) in a well-know spot with "wide
open" file permissions. that is, any component/user can write/read the file.
under XP the file is created in:
"Document and Settings\All Users\Application Data\'company'\'file.ini'"
we get to this location by using the SHGetSpecialFolderPath API call.
under Vista this call seems to put the file in the "ProgramData" folder as
such:
"ProgramData\'company'\'file.ini'"
when we create the file we doing some security descriptor stuff which opens
up the permission for the file. under XP, when we check the File
Properties --> Security tab we can see that the file permission is "wide
open".
however, under Vista the file is not created "wide open". and depending on
how the printer is added via the Control Panel --> Printers --> right click,
"Add Printer" or "Run as Administrator --> Add Printer (not running Vista
right now so i'm not postive if the context menu is exactly "Run as
Administrator) we get slightly different access lists for the file. and if
we install the printer via PnP we get another slight variation in the access
list. but, in all three cases the file is not created with "wide open"
permissions.
i'm suspecting that this has something to do with the way we spawn off the
executable under Vista and/or UAC since another developer found that he had
to use WTSGetActiveConsoleSessionId/WTSQueryUserToken instead of
OpenThreadToken to even get our executable to spawn off and run under Vista.
this is the snippet of code in PrinterEvent that we use spawn off our
executable:
BOOL bSuccess = FALSE;
STARTUPINFO startupInfo;
PROCESS_INFORMATION processInfo;
SECURITY_ATTRIBUTES attribs;
SECURITY_DESCRIPTOR sd;
memset(&startupInfo, 0, sizeof(startupInfo));
memset(&processInfo, 0, sizeof(processInfo));
memset(&attribs, 0, sizeof(attribs));
memset(&sd, 0, sizeof(sd));
startupInfo.cb = sizeof(startupInfo);
// Need a security descriptor with a NULL DACL to allow launching
// applications without running into security problems.
attribs.nLength = sizeof(SECURITY_ATTRIBUTES);
attribs.lpSecurityDescriptor = &sd;
attribs.bInheritHandle = FALSE;
if (InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
{
// Add a NULL DACL to the security descriptor.
if (SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE))
{
// Execute the supplied command line either normally, or
// while impersonating the active user.
if (inOptions.bImpersonateActiveUser) // inOptions is
passed into function
{
// Impersonate active user, then execute the command line.
SECURITY_IMPERSONATION_LEVEL impersonationLevel =
SecurityImpersonation;
HANDLE hThreadToken = 0;
HANDLE hToken = 0;
LPVOID pEnvironmentBlock = 0;
if( inOptions.bLaunchFromService ) // Vista
{
int sessionId = WTSGetActiveConsoleSessionId();
bSuccess = WTSQueryUserToken(sessionId, &hThreadToken);
}
else // XP
{
BOOL bTmp = ImpersonateSelf(impersonationLevel);
bSuccess = OpenThreadToken(
GetCurrentThread(), // ThreadHandle
TOKEN_ALL_ACCESS, // DesiredAccess
TRUE, // OpenAsSelf
&hThreadToken); // TokenHandle
bTmp = RevertToSelf();
}
if (bSuccess)
bSuccess = DuplicateTokenEx(
hThreadToken, // hExistingToken
MAXIMUM_ALLOWED, // dwDesiredAccess
&attribs, // lpTokenAttributes
impersonationLevel, //
ImpersonationLevel
TokenPrimary, // TokenType
&hToken); // phNewToken
if (hThreadToken)
CloseHandle(hThreadToken);
hThreadToken = 0;
if (bSuccess)
bSuccess = CreateEnvironmentBlock(&pEnvironmentBlock,
hToken, FALSE);
if (bSuccess)
bSuccess = CreateProcessAsUser(
hToken, // hToken
0, // lpApplicationName
(LPTSTR) inCmdLine, // lpCommandLine
&attribs, //
lpProcessAttributes
&attribs, //
lpThreadAttributes
FALSE, // bInheritHandles
DETACHED_PROCESS|CREATE_UNICODE_ENVIRONMENT,
// dwCreationFlags
pEnvironmentBlock, // lpEnvironment
0, //
lpCurrentDirectory
&startupInfo, // lpStartupInfo
&processInfo); //
lpProcessInformation
if (pEnvironmentBlock)
DestroyEnvironmentBlock(pEnvironmentBlock);
if (hToken)
CloseHandle(hToken);
}
else
{
// Execute the command line without any impersonation.
bSuccess = CreateProcess(
0, // lpApplicationName
(LPTSTR) inCmdLine, // lpCommandLine
&attribs, //
lpProcessAttributes
&attribs, //
lpThreadAttributes
FALSE, // bInheritHandles
DETACHED_PROCESS, // dwCreationFlags
0, // lpEnvironment
0, //
lpCurrentDirectory
&startupInfo, // lpStartupInfo
&processInfo); //
lpProcessInformation
}
in the spawned off executable we have this code to create the file with
"wide open" (at least under XP) file permissions.
TCHAR filePath[MAX_PATH];
if (SHGetSpecialFolderPath(0, filePath, CSIDL_COMMON_APPDATA, TRUE))
{
_tcscat(filePath, _TEXT("\\"));
_tcscat(filePath, INI_VENDOR_FOLDERNAME);
// If the folder does not exist, create it
if (_taccess(filePath, 0) == -1)
_tmkdir(filePath);
_tcscat(filePath, _TEXT("\\"));
_tcscat(filePath, INI_FILENAME);
SECURITY_DESCRIPTOR securityDescriptor;
SECURITY_ATTRIBUTES securityAttributes;
HANDLE hFile;
if (!InitializeSecurityDescriptor(&securityDescriptor,
SECURITY_DESCRIPTOR_REVISION))
{
TRACE(_TEXT("Error: InitializeSecurityDescriptor failed:
%ld\n"), GetLastError());
}
else
{
TRACE(_TEXT("InitializeSecurityDescriptor successful\n"));
}
if (!SetSecurityDescriptorDacl(&securityDescriptor, TRUE, NULL,
FALSE))
{
TRACE(_TEXT("Error: SetSecurityDescriptorDacl failed: %ld\n"),
GetLastError());
}
else
{
TRACE(_TEXT("SetSecurityDescriptorDacl successful\n"));
}
securityAttributes.nLength= sizeof(SECURITY_ATTRIBUTES);
securityAttributes.bInheritHandle = FALSE;
securityAttributes.lpSecurityDescriptor = &securityDescriptor;
hFile = CreateFile(filePath, GENERIC_READ | GENERIC_WRITE, 0,
&securityAttributes,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
TRACE(_TEXT("Error: CreateFile of INI file failed: %ld\n"),
GetLastError());
}
else
{
BOOL rc = CloseHandle(hFile);
if (!rc)
{
TRACE(_TEXT("Error: CloseHandle failed (%ld)\n"),
GetLastError());
}
else
{
TRACE(_TEXT("CloseHandle successful\n"));
}
}
}
else
{
TRACE(_TEXT("Error: SHGetSpecialFolderPath failed\n"));
}
when this code runs i get no errors (i added a bunch of trace statements) so
one would think the file gets created with the "wide open" file permissions,
yet it does not under Vista.
as i said earlier, i think it probably has something to do with the way we
are spawning the file off in PrinterEvent (which is probably running under
the context of the Spooler) and/or something to do with the increased
security with UAC.
it should be noted that if i run the code, under Vista, to create the file
in a normal console application directly, the file does get created with the
"wide open" permissions. so i think the problem is related to the
executable being spawned off from the Spooler.
so my questions are:
1) does anyone know why, under Vista, the code is not creating the file with
"wide open" permissions?
2) what code modifications can be made so that the file is created with
"wide open" permissions?
thanks!
.
- Prev by Date: Re: kernel mode n/w programming
- Next by Date: Re: Problem of KeAcquireSpinLock( ) in Vista
- Previous by thread: Drivers wanted
- Next by thread: DIFx: Determine if a hardware and driver is installed already
- Index(es):
Relevant Pages
|