ALL,
Does GRANT-ing permissions supported in MS ACCESS?
I am connecting to accdb with ODBC driver from C++ app and trying to issue a GRANT command, but getting an error saying expecting DELETE, INSERT, PROCEDURE, SELECT or UPDATE.
It is on Windows 8.1 with MSVC 2017 Community.
The command I'm trying is:
GRANT SELECT ON MSysObjects TO Admin;
TIA!!
void uc_to_str_cpy(SQLWCHAR *dest, const std::wstring &src)
{
const wchar_t *temp = src.c_str();
while( *dest )
{
dest++;
}
while( *temp )
{
*dest = *temp;
dest++;
temp++;
}
*dest++ = 0;
*dest = 0;
}
std::wstring query8 = L"GRANT SELECT ON MSysObjects TO Admin;";
query = new SQLWCHAR[query8.length() + 2];
memset( query, '\0', query8.length() + 2 );
uc_to_str_cpy( query, query8 );
ret = SQLExecDirect( m_hstmt, query, SQL_NTS );
delete[] query;
query = NULL;
if( ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO )
{
GetErrorMessage( errorMsg, 1 );
result = 1;
}
Grant does exist for Access. In most cases you can query against MSYSobjects. However, you could try several things:
First, try running your program (.exe) with elevated rights (right click and run as admin).
next up. You don't mention if this is JET (mdb) format, or is ACE (accdb format).
HOWEVER - using ODBC (as opposed to the oleDB driver), to my knowledge DOES NOT support Grant. So, quite sure you are out of luck.
You could I suppose consider creating a ADO object.
I find that EVEN inside of Access, if I use the built in ADO object, then grant will work.
but if I use a straight DAO object, then it does not work.
and for ODBC? Well, I find that grant does not seem to be supported - so, this looks like ODBC does NOT support the grant.
Also, use of GRANT in most cases also means that the connection string needs to include the work group file (it is by default automatic opened - even with ODBC, but using oleDB against such a database (from .net), I again find that GRANT does execute with oleDB - but gives an error message about the workgroup file having not been specified.
However, with ODBC - I get a error - syntax. So, at this point? ODBC does not support the grant DDL.
Related
In console application, I want to write the output at a specific location and there should be no cursor at the console (Windows CMD). To do so, I got following way:
HANDLE hdl = GetStdHandle(STD_OUTPUT_HANDLE);
if (hdl == INVALID_HANDLE_VALUE)
{
printf("Error : Unable to get console handle.\n");
return 0;
}
PCONSOLE_CURSOR_INFO lpConsoleCursorInfo = { NULL };
if (!GetConsoleCursorInfo(hdl, &lpConsoleCursorInfo))
{
printf("Error : Unable to get console cursor information.\n");
return 0;
}
lpConsoleCursorInfo->dwSize = 1; //App exit at this point with error code 0xC0000005h
I got runtime error 0xC0000005h. By searching, I have reach at the conclusion that it is a security level issue, and to setup access level SECURITY_DESCRIPTOR is used.
I am unable to find the way how to set the access level to STD_OUTPUT_HANDLE that already created and associated with my console application by visual studio console application.
Can someone point me in the right direction?
There is no security issue, you simply don't understand how Windows pointer types work. PCONSOLE_CURSOR_INFO is just a pointer, remove the P.
CONSOLE_CURSOR_INFO ConsoleCursorInfo = { NULL };
if (!GetConsoleCursorInfo(hdl, &ConsoleCursorInfo)) ...
else ConsoleCursorInfo.dwSize = ...
I couldn't find much information about Untrusted integrity level in Windows, and have some questions about it:
Is there a place where an untrusted integrity level process can create named objects? (mutexes, events, etc..)
Should untrusted integrity level process be able to open an existing named object, that was given a security descriptor in it's creation time with ACE with SYSTEM_MANDATORY_LABEL_NO_WRITE_UP to MandatoryLevelUntrusted? When I try it, it fails with 0xc0000022(access denied), while with MandatoryLevelLow it works great.
How do usually untrusted integrity processes communicate with their broker process? (like how does a google chrome tab communicates with the google chrome broker?)
Is there a place where an untrusted integrity level process can create
named objects? (mutexes, events, etc..)
by default - no. code with untrusted token (thread or process) can create object only in directory with Untrusted Mandatory Level - no one standard folders have this kind of label. some have Low Mandatory Level but untrusted - no.
but you can easy create this folder yourself. with Untrusted Mandatory Level and NULL DACL - untrusted code can create objects in this folder.
NTSTATUS CreateUntrustedFolder(PHANDLE phObject, PCUNICODE_STRING ObjectName)
{
ULONG cb = MAX_SID_SIZE;
PSID UntrustedSid = (PSID)alloca(MAX_SID_SIZE);
if (CreateWellKnownSid(WinUntrustedLabelSid, 0, UntrustedSid, &cb))
{
PACL Sacl = (PACL)alloca(cb += sizeof(ACL) + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK));
InitializeAcl(Sacl, cb, ACL_REVISION);
if (AddMandatoryAce(Sacl, ACL_REVISION, 0, 0, UntrustedSid))
{
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
SetSecurityDescriptorSacl(&sd, TRUE, Sacl, FALSE);
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, (PUNICODE_STRING)ObjectName, OBJ_CASE_INSENSITIVE|OBJ_OPENIF, &sd };
return ZwCreateDirectoryObject(phObject, DIRECTORY_ALL_ACCESS, &oa);
}
}
return STATUS_UNSUCCESSFUL;
}
about untrusted code creation - if start process at begin with token marked as untrusted integrity level - process fail to start. this when ntdll.dll try load kernel32.dll - it try open section \KnownDlls\kernel32.dll with SECTION_MAP_WRITE as well , but this object have Low Mandatory Level with SYSTEM_MANDATORY_LABEL_NO_WRITE_UP - as result untrusted code fail open this section with write access.
as result you need initially create process say with Low Mandatory Level and then set untrusted level
ULONG SetProcessUntrusted(HANDLE hProcess)
{
TOKEN_MANDATORY_LABEL tml = { { (PSID)alloca(MAX_SID_SIZE), SE_GROUP_INTEGRITY } };
ULONG cb = MAX_SID_SIZE;
HANDLE hToken;
if (!CreateWellKnownSid(WinUntrustedLabelSid, 0, tml.Label.Sid, &cb) ||
!OpenProcessToken(hProcess, TOKEN_ADJUST_DEFAULT, &hToken))
{
return GetLastError();
}
ULONG dwError = NOERROR;
if (!SetTokenInformation(hToken, TokenIntegrityLevel, &tml, sizeof(tml)))
{
dwError = GetLastError();
}
CloseHandle(hToken);
return dwError;
}
Should untrusted integrity level process be able to open an existing
named object
this depend from object label(level and mask) , code intergrity level and required access. if code intergrity level >= object label level - we can open object (if dacl let do this). otherwise need look for object label mask and required access. for example object have Low Mandatory Level with SYSTEM_MANDATORY_LABEL_NO_WRITE_UP and code Untrusted Mandatory Level - this code can open object with read and execute access, but fail open it for write access
I'm having a problem calling Winspool.drv "OpenPrinter" when I run my program in standard user acccount. But when I ran my program in Administrator account. It can properly execute API call.
I am trying to call OpenPrinter using this API
[DllImport("WinSpool.drv", SetLastError = true)]
static extern unsafe bool OpenPrinter (string pPrinterName, int* phPrinter, void* pDefault);
and implementing it using this code
static unsafe int CSOpenPrinter(string printerName)
{
bool bResult;
int hPrinter;
PRINTER_DEFAULTS pd = new PRINTER_DEFAULTS();
//int rawsize = Marshal.SizeOf(pd);
//IntPtr pdPtr = Marshal.AllocHGlobal(rawsize);
//pd.pDatatype = null;
//pd.pDevMode = null;
pd.DesiredAccess = PRINTER_ALL_ACCESS;
bResult = OpenPrinter(printerName, &hPrinter, &pd);
System.Diagnostics.Debug.WriteLine("bResult: " + bResult);
if (!bResult)
{
throw new ApplicationException("Cannot open printer '" +
printerName + "' " +
Marshal.GetLastWin32Error());
}
return hPrinter;
}
Ok again, that code works perfectly when I try to make my program "Run As Administrator". How do I make my application run as a Administrator without right clicking on the application and selecting "Run As Administrator"?
I believe this is a UAC problem, but can you give me an Idea how to solve this? Is adding app.manifest will help? Can you give me an exampple?
Best to all
What are you trying to do with the printer? Your code is asking for full access and so requires admin access.
If you just want to use the printer, request PRINTER_ACCESS_USE access instead.
If it is actually an admin process, then add an appropriate manifest to the executable to tell windows that it needs admin access.
Add manifest file to your project. Like here
In win32 c++; is there a way to determine if a folder/file is accessible? You know how if you try to access a certain folder in the C:/Windows directory & you will get a popup saying "This folder is not accessible".
Maybe there is a file attribute constant that signifies that the file is private? Maybe something like FILE_ATTRIBUTE_PRIVATE?
WIN32_FIND_DATA dirData;
while (FindNextFile( dir, &dirData ) != 0 )
{
// I made the following constant up
if ( !(fileData.dwFileAttributes & FILE_ATTRIBUTE_PRIVATE) )
{
// file is accessible so store filepath
files.push_back( fileData.cFileName );
}
else // file is not accessible so dont store
}
Or is the only way to know by going:
dir = FindFirstFileEx( (LPCTSTR)directory.c_str(), FindExInfoStandard, &dirData, FindExSearchNameMatch, NULL, 0 );
if ( dir == ??? ) { the file is inaccessible } [/code]
Best thing to do is just try to access it.
You can calculate the access granted by the access control list for a particular user account, but this is quite complicated, and the permission could change after you do the access check. So just open the file and handle access denied errors.
It wouldn't be a flag on the file itself because different accounts may have access to different files/directories. Instead, windows uses ACL's (access control lists), which are data structures that determine who has access to what.
ACLs in windows can be used with just about anything that is referred to by a handle (files, directories, processes, mutexes, named pipes...). You can view file ACLs by going to properties of a file and view "Security" tab.
So in your app you don't really want to check for a flag, but to compare file's ACL against the user account under which your app is running. Check out AccessCheck Win32 function. I think it's exactly what you are looking for.
Personally, I've never used that function, but if you are looking for Win32 solution and you want a function call, that's probably your best bet. However, as others have pointed out, it might be too complicated. I've always used _access (or _waccess) which is part of CRT, uber easy to use, and you don't take a performance hit of acquiring a file handle only to close it (depending on how tight your loop is, those calls can actually add up).
int _access(
const char *path,
int mode
);
Simple to use:
http://msdn.microsoft.com/en-us/library/1w06ktdy%28v=vs.80%29.aspx
Yes Aaron Ballman you are a boss! Oh man oh man! Which I could use some useful expletives to expressives my joy right now.
https://blog.aaronballman.com/2011/08/how-to-check-access-rights/ is a link to the example of checking accesss rights in win32 on a fpath. And the explanation behind the poorly documented AccessCheck win32 function. Below is the code.
bool canAccessPath( LPCTSTR folderName, DWORD genericAccessRights )
{
bool bRet = 0;
DWORD length = 0;
if (!::GetFileSecurity( folderName, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, NULL, 0, &length ) &&
ERROR_INSUFFICIENT_BUFFER == ::GetLastError())
{
PSECURITY_DESCRIPTOR security = static_cast< PSECURITY_DESCRIPTOR >( ::malloc( length ) );
if (security && ::GetFileSecurity( folderName, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, security, length, &length ))
{
HANDLE hToken = NULL;
if (::OpenProcessToken( ::GetCurrentProcess(), TOKEN_IMPERSONATE|TOKEN_QUERY|TOKEN_DUPLICATE|STANDARD_RIGHTS_READ, &hToken ))
{
HANDLE hImpersonatedToken = NULL;
if (::DuplicateToken( hToken, SecurityImpersonation, &hImpersonatedToken ))
{
GENERIC_MAPPING mapping = { 0xFFFFFFFF };
PRIVILEGE_SET privileges = { 0 };
DWORD grantedAccess = 0, privilegesLength = sizeof( privileges );
BOOL result = FALSE;
mapping.GenericRead = FILE_GENERIC_READ;
mapping.GenericWrite = FILE_GENERIC_WRITE;
mapping.GenericExecute = FILE_GENERIC_EXECUTE;
mapping.GenericAll = FILE_ALL_ACCESS;
::MapGenericMask( &genericAccessRights, &mapping );
if (::AccessCheck( security, hImpersonatedToken, genericAccessRights,
&mapping, &privileges, &privilegesLength, &grantedAccess, &result ))
{
bRet = result == TRUE;
}
::CloseHandle( hImpersonatedToken );
}
::CloseHandle( hToken );
}
::free( security );
}
}
return bRet;
}
Don't be shy to pop into his website and check out his work. I am sure he has more interesting stuff.
This may not be a purely programming related question, but I come across this often during development. When my app crashes and I choose to kill it, Windows automatically throws up a "Checking for a solution..." dialog box. When I hit the cancel button on that I get another dialog box that says "Restarting the program..." Is there a way to prevent this behavior? When I stop an app I'd prefer if it were silently killed. I'm using Windows 7 if the platform is important.
Although Microsoft recommends using a newer replacement API available only on Windows Vista and later, there is an API which works for all versions of Windows from XP onward: AddERExcludedApplication(). This function takes the module name without path information (e.g., "myprogram.exe") for which error reporting is to be disabled.
The new method available only Windows Vista and later is to call WerAddExcludedApplication() function. This API allows you to specify whether it should change the HKEY_CURRENT_USER registry hive, or the HKEY_LOCAL_MACHINE registry hive. Be sure to set this for the HKCU if the HKLM set fails, such as:
typedef BOOL (*ADD_MER_EXCLUDED_APP_XP) (PCWSTR);
typedef BOOL (*ADD_MER_EXCLUDED_APP_VISTA) (PCWSTR, BOOL);
bool disable_microsoft_error_reporting(PCWSTR wz_app)
{
const WCHAR * const WZ_MER_DLL_XP = L"faultrep.dll";
const char * const SZ_MER_PROC_XP = "AddERExcludedApplicationW";
const WCHAR * const WZ_MER_DLL_VISTA = L"wer.dll";
const char * const SZ_MER_PROC_VISTA = "WerAddExcludedApplicationW";
const int WER_EXCLUDE_FOR_ALL_USERS = TRUE;
const int WER_EXCLUDE_FOR_THIS_USER = FALSE;
HANDLE hlib_error_reports_xp = NULL;
HANDLE hlib_error_reports_vista = NULL;
ADD_MER_EXCLUDED_APP_XP add_mer_excluded_app_xp = NULL;
ADD_MER_EXCLUDED_APP_VISTA add_mer_excluded_app_vista = NULL;
bool success = false;
// First, attempt the API that has been around since XP.
hlib_error_reports_xp = LoadLibrary(WZ_MER_DLL_XP);
if (hlib_error_reports_xp)
{
add_mer_excluded_app_xp = (ADD_MER_EXCLUDED_APP_XP)GetProcAddress(hlib_error_reports_xp, SZ_MER_PROC_XP);
if (add_mer_excluded_app_xp)
success = add_mer_excluded_app_xp(wz_app);
FreeLibrary(hlib_error_reports_xp);
hlib_error_reports_xp = NULL;
add_mer_excluded_app_xp = NULL;
if (success)
return true;
}
// That did not succeed. Attempt the Vista API.
hlib_error_reports_vista = LoadLibrary(WZ_MER_DLL_VISTA);
if (hlib_error_reports_vista)
{
add_mer_excluded_app_vista = (ADD_MER_EXCLUDED_APP_VISTA)GetProcAddress(hlib_error_reports_vista, SZ_MER_PROC_VISTA);
if (add_mer_excluded_app_vista)
{
success = (S_OK == add_mer_excluded_app_vista(wz_app, WER_EXCLUDE_FOR_ALL_USERS));
if (!success)
success = (S_OK == add_mer_excluded_app_vista(wz_app, WER_EXCLUDE_FOR_THIS_USER));
}
FreeLibrary(hlib_error_reports_vista);
hlib_error_reports_vista = NULL;
add_mer_excluded_app_vista = NULL;
if (success)
return true;
}
// Nothing worked. Fail.
return false;
}
To further curtail the execution of the WER components, imeplement an unhandled exception filter and pass it to: SetUnhandledExceptionFilter() function. To shunt WER, your filter must never return EXCEPTION_CONTINUE_SEARCH or EXCEPTION_EXECUTE_HANDLER.
One of the drawbacks of implementing the SetUnhandledExceptionFilter() function is that it interferes with Just-in-time debugging.
You mention you want the app to be "silently killed." In that case:
LONG WINAPI global_exception_filter(struct _EXCEPTION_POINTERS *exception_info)
{
ExitProcess(0xDEDD000D);
}
int WINAPI WinMain(
HINSTANCE _hinstance,
HINSTANCE hinstance_prev,
LPSTR sz_cmd_line,
int cmd_show
)
{
SetUnhandledExceptionFilter(global_exception_filter);
/* ... */
}
Will cause the application to immediately vanish upon unhandled exception. N.B., the exit code to return is a matter of taste.
Check out the answers on these questions:
How do I disable the ‘Debug / Close Application’ dialog on Windows Vista?
Hide Error Report window
I realize that others have answered with ways to work around this, but...
Let's not forget that the best way to protect against this is to write a program that doesn't crash. :-) You shouldn't be seeing this if you are using memory correctly and not hanging the GUI thread.
Altering the behavior of an application crash is a great way to introduce subtle and deadly bugs. See also this blog post from Microsoft's Raymond Chen.
Take a look at the Windows Error Reporting APIs.