|
Background:
My application restricts the capabilities of users without administrator privileges and provides an "administrator override" capability that allows an administrator to supply credentials so that restricted operations may be performed without terminating the app. This capability is designed to work on Windows 2000 and XP. The app requests user credentials with a logon dialog box. It then validates them and impersonates the user with administrator privileges using code modified from the samples supplied with Microsoft KB article Q180548. This mechanism works correctly on Windows 2000 SP3.
Problem:
After installing SP4 or some other recent Hotfix, the administrator override capability no longer works. After the app impersonates a user with administrator privileges, it can no longer open a registry key in HKEY_CURRENT_USER for reading and writing. The call:
RegOpenKeyEx (HKEY_CURRENT_USER, pszKeyName, 0,
KEY_READ|KEY_WRITE, &hRegKey);
fails, returning a value of 1346 (0x542), listed in Winerror.h as ERROR_BAD_IMPERSONATION_LEVEL.
What must I change in the app to fix this problem?
|
|
|
|
|
ICantChangeMyAcct wrote:
After the app impersonates a user with administrator privileges...
Are you sure this part still works? The 0x542 error has two meanings: either a required impersonation level was not provided, or the provided impersonation level is invalid.
"The pointy end goes in the other man." - Antonio Banderas (Zorro, 1998)
|
|
|
|
|
I'm not sure what "works" means. The Q180548 code uses secur32.dll functions to generate a "client context" and a "server context", then calls the function ImpersonateSecurityContext() with the *server's* context handle (!?!) This function returns SEC_E_OK, indicating that the impersonation "worked". My app doesn't use the context handle in system calls or do anything that requires administrator privileges.
|
|
|
|
|
Hi.
Do anyone know how I make my programs to only open one time and not multiplie times? Exampel when my program is open and I start it again then the already open program shall show up and not open it again. Just like Windows Media player.
|
|
|
|
|
See here and here.
"The pointy end goes in the other man." - Antonio Banderas (Zorro, 1998)
|
|
|
|
|
I have the following code that I am executing:
DWORD last_err;
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszMenuName = "MainMenu";
wc.lpszClassName = "MainWindowClass";
if (!RegisterClass(&wc))
{
last_err = GetLastError();
}
The RegisterClass call fails and when I run the code in debug and last_err gets set it has a value of 0. I'm expecting it to have a value that designates just what the error was. I got this code fom the following example:
int APIENTRY WinMain(
HINSTANCE hinstance,
HINSTANCE hinstPrev,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = "MainMenu";
wc.lpszClassName = "MainWindowClass";
if (!RegisterClass(&wc))
return FALSE;
}
This comes from the help index under "Using Window Procedures".
Robert
|
|
|
|
|
Do you get the same results when using RegisterClassEx()?
"The pointy end goes in the other man." - Antonio Banderas (Zorro, 1998)
|
|
|
|
|
|
Looks ok to me. Check that your hInstance param is correct and also your WindowProc and lpszMenuName.
----
lpszMenuName
Pointer to a null-terminated character string that specifies the resource name of the class menu, as the name appears in the resource file. If you use an integer to identify the menu, use the MAKEINTRESOURCE macro. If this member is NULL, windows belonging to this class have no default menu.
----
I don't know why GetLastError() returns 0.
If you are using MFC you may want to look at AfxRegisterWndClass() or AfxRegisterClass().
Neville Franks, Author of ED for Windows www.getsoft.com and coming soon: Surfulater www.surfulater.com
|
|
|
|
|
Neville,
My hInstance param comes right from my main window creation, just like the example:
int PASCAL WinMain (HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR szCmdLine, int nShow)
{
hInstance = hInst;
I changed the name of my WindowProc routine to MyWindowProc just so that it wasn't the default anymore. That routine is at the top of the module that contains the code in question:
LRESULT CALLBACK MyWindowProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
int dummy_var;
dummy_var = 1;
return 1;
}
My lpszMenuName is NULL. My intent is to create a window that is invisible later on by calling CreateWindow for the purpose of processing messages only. The reason that I am calling RegisterClass is because I assumed that I needed to do this prior to getting the CreateWindow to work. BTW, that is also returning a 0 when it fails and I check GetLastError. Very strange.
The help message that describes the kind of window that I want to create is here:
From CreateWindow...
hWndParent
[in] Handle to the parent or owner window of the window being created. To create a child window or an owned window, supply a valid window handle. This parameter is optional for pop-up windows.
Windows 2000/XP: To create a message-only window, supply HWND_MESSAGE or a handle to an existing message-only window.
Message-Only Windows
A message-only window enables you to send and receive messages. It is not visible, has no z-order, cannot be enumerated, and does not receive broadcast messages. The window simply dispatches messages.
To create a message-only window, specify the HWND_MESSAGE constant or a handle to an existing message-only window in the hWndParent parameter of the CreateWindowEx function. You can also change an existing window to a message-only window by specifying HWND_MESSAGE in the hWndNewParent parameter of the SetParent function.
To find message-only windows, specify HWND_MESSAGE in the hwndParent parameter of the FindWindowEx function. In addition, FindWindowEx searches message-only windows as well as top-level windows if both the hwndParent and hwndChildAfter parameters are NULL.
As to the last reference to MFC, I am not using it.
Robert
|
|
|
|
|
In your code hbrBackground member is not initialized. It should be either NULL or valid HBRUSH.
Maksim Lepikhin
www.softforpros.com
|
|
|
|
|
This was the problem. I had the following code commented out:
I believe I did this because it didn't compile. I had to add a cast to it:
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
The code was originally from some sample code. Figures it wouldn't compile...
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) MainWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = "MainMenu";
wc.lpszClassName = "MainWindowClass";
Thanks Maksim,
Robert
|
|
|
|
|
Whats the simplist way to encrypt/decrypt a user's plaintext password? I'd like to give them a "Save your password" checkbox so that they won't need to type it again. Saving it as plain text would be a (possibly minor) security flaw, and using a hash wouldn't work because I wouldn't be able to decrypt it before passing it on to the authentication module.
Basically, what I'm getting at is: Are there any "standard" encryption methods for use on plain text passwords?
(NOTE: The encryption doesn't have to be very strong, just something that gives the text a sufficient "jumbling up" would suffice.)
Thanks!
--
Edward Livingston
(aka ExtraLean)
--
"I still maintain that seeing a nipple is far less disturbing than seeing someone get their brains blown out." -- Chris Maunder
|
|
|
|
|
Use MD5 encryption. A lot of free C++ libraries provides it, for example here.
Tip: you shouldn't decrypt the password . Instead, in the authentication module, retrieve a password from user, encrypt it by MD5 and compare it with the saved (encrypted) password.
Robert-Antonio
"CRAY is the only computer, which runs an endless loop in just 4 hours"
|
|
|
|
|
Robert A. T. Káldy wrote:
Tip: you shouldn't decrypt the password . Instead, in the authentication module, retrieve a password from user, encrypt it by MD5 and compare it with the saved (encrypted) password.
Yes, that would be the standard way to do it, but the whole point is that I don't want to retrieve a password from the user. I want them to be able to save their password so that it just logs them in after decrypting their saved password. Also, the authentication module is a third party solution, and it expects the password in plain text. Thanks for the input, any other ideas?
--
Edward Livingston
(aka ExtraLean)
--
"I still maintain that seeing a nipple is far less disturbing than seeing someone get their brains blown out." -- Chris Maunder
|
|
|
|
|
Hmmmm...if you want to save the passwords in a form, which can be algorithmically decrypted, it isn't more secure, that saving it in plaintext . If you only want BFU not to read the saved passwords in Notepad, you should use ROT13. It simply rotates the letters by 13 (A->N, B->O etc.). Or use a Vigenere cipher (see here).
Robert-Antonio
"Science is a differerntial equation.
Religion is a boundary condition."
|
|
|
|
|
Dear All,
The below is a part of my function, i would be updated my access file through CRecordSet class with using SQL command. But it seem like not work.
any problem occour? Do you think the datatpye inside the access file will lead abnormal termination ?
//-------------------------------------------------------------------------
// Name: updateRecord()
// Desc: update the database content into the list box
// modified by Anson on 3/3/04
//--------------------------------------------------------------------------
static void updateRecord(HWND hwnd, CDatabase *db)
{
sprintf(str, "UPDATE PlantInit SET %s = %s WHERE FrameID = %s" ,g_plantDataField[i],ebstr,g_temp[j].frameID);
// Open database my write my DQL command on it
rsta.Open(CRecordset::dynaset, str );
MessageBox(hwnd, "The record has been updated.", "Database Message", MB_OK);
rsta.Close();
}
Regards,
Anson Tong
|
|
|
|
|
Hi,
You should use try{} and catch{} statements and _com_error exception to get full explanation what's wrong in your code.
Sincerely Yours,
RadioShark
|
|
|
|
|
No error checking? If you are using MFC, use a CString object instead of sprintf() . Something like:
static void updateRecord(HWND hwnd, CDatabase *db)
{
CString str;
str.Format("UPDATE PlantInit SET %s = %s WHERE FrameID = %s" ,g_plantDataField[i], ebstr, g_temp[j].frameID);
TRY
{
rsta.Open(CRecordset::dynaset, str);
rsta.Close();
AfxMessageBox("The record has been updated.");
}
CATCH(CDBException, pDBException)
{
AfxMessageBox(pDBException->m_strError);
}
END_CATCH
}
"The pointy end goes in the other man." - Antonio Banderas (Zorro, 1998)
|
|
|
|
|
I keep getting this assertion when terminating a vb app that I'm using to call a c++ dll that I made using mfc. Anyone know what I'm doing wrong?
If it's broken, I probably did it
bdiamond
|
|
|
|
|
You're probably passing crud to delete or free somewhere in your DLL. Check anywhere you do malloc/new that you're eventually calling free/delete (and only once!).
You must not use malloc or new and then pass the allocated thing back to VB, since it can't deal with it correctly (and certainly won't be able to free it properly).
Steve S
|
|
|
|
|
the function is declared as an int and is either returning a 1 or a 0 to vb to indicate failure or success. In VB I have it declared as a long. Could that be the problem?
If it's broken, I probably did it
bdiamond
|
|
|
|
|
Unlikely. In that case the value is being passed back directly in a register.
Your function should be __stdcall, as opposed to __thiscall or __cdecl, but it almost certainly is, or you'd get a different error
Steve S
|
|
|
|
|
this is the error I'm getting in the debug info in my dll:
HEAP[Project1.exe]: Invalid Address specified to RtlFreeHeap( 1150000, 12046d0 )
If it's broken, I probably did it
bdiamond
|
|
|
|
|
Pretty much as I suspected, then.
There are a few causes of this:
o This could be freeing memory twice (more common than you'd expect!)
o Using malloc/new, then altering the pointer before calling free/delete.
o Block overrun (writing past the allocated buffer)
o Accessing memory after freeing it
Also, you might want to read PSS 190799 in the MSDN KB for what you can't pass around via DLLs.
Can you do a debug build of your DLL, and run VB via the debugger or use DBMON/DebugView to see the debug output? It might provide more information...
Steve S
|
|
|
|
|