Thursday, December 28, 2006

Validate Windows Domain Account in C#

In C# we can validate windows domain account using following code snippet.

public class WinAPI{
// Use NTLM security provider to check
public const int LOGON32_PROVIDER_DEFAULT = 0x0;
// To validate the account
public const int LOGON32_LOGON_NETWORK = 0x3;

// API declaration for validating user credentials
[DllImport("advapi32.dll", SetLastError = true)] public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out int phToken);
//API to close the credential token
[DllImport("kernel32", EntryPoint="CloseHandle")] public static extern long CloseHandle (long hObject);
};


int hToken=2;
bool ret = WinAPI.LogonUser(strUserName,strDomain,strPwd, WinAPI.LOGON32_LOGON_NETWORK ,
WinAPI.LOGON32_PROVIDER_DEFAULT,
out hToken);

if(ret==true)
{
MessageBox.Show (" Valid Windows domain User ");
WinAPI.CloseHandle (hToken);
}
else
{
MessageBox.Show (" Not an valid Windows domain User ");
}

Explanation


We call LogonUser Win32 API to validate the user credentials. The class WinAPI declares the required Win32 API's and the constants used.

LogonUser takes username, password and password as plain text and validates the user name against the domain with the given password, if the user name is correct then it returns a handle to the user token in hToken out parameter which can be used by the user to Impersonate or create process using his account. If this is not used then hToken should be closed using CloseHandle Win32 API.

Satellite Assemblies

Assemblies which contains only resources (no executable code) are called as Satellite assemblies. These are created with the help of al.exe (Assembly Linker). The .resources files are compiled using al.exe to create assemblies, these are generally used for localizing the applications.

Satellite assemblies are created for different cultures and at run time the localization will select appropriate assembly based on current resource.
For more info

Wednesday, December 27, 2006

Windows environment variables

Windows has two kinds of environment variables
1) User specific environment variables
2) System wide environment variables

User specific environment variables are available only to the user for which it is created and System wide are available to all the users.

These environment variables are stored in the following registry location

You can modify user environment variables by editing the following Registry key: HKEY_CURRENT_USER \Environment

You can modify system environment variables by editing the following Registry key: HKEY_LOCAL_MACHINE \SYSTEM \CurrentControlSet \Control \Session Manager \Environment

Note: If you modify the environment variables it won't reflect immediately till you log-off and log-in again.

Changes to environment variable

To effect the changes to the environment variable immediately without log off, broadcast the WM_SETTINGCHANGE message to all windows in the system, so the system will will peform read from registry again to update the environment variable.

C# code to propagate environment variable changes

/* Declare the Win32 API for propagating the environment variable */
[DllImport("user32.dll",CharSet=CharSet.Auto, SetLastError=true)] [return:MarshalAs(UnmanagedType.Bool)]
public static extern bool SendMessageTimeout(
IntPtr hWnd,
int Msg,
int wParam,
string lParam,
int fuFlags,
int uTimeout,
int lpdwResult
);
/* Constant to broadcast message to all windows */
public const int HWND_BROADCAST = 0xffff;
public const int WM_SETTINGCHANGE = 0x001A;
public const int SMTO_NORMAL = 0x0000;
public const int SMTO_BLOCK = 0x0001;
public const int SMTO_ABORTIFHUNG = 0x0002;
public const int SMTO_NOTIMEOUTIFNOTHUNG = 0x0008;

/* Call the API passing the last parameter as out parameter */
int result,retun_value;
return_value = SendMessageTimeout( (System.IntPtr)HWND_BROADCAST, WM_SETTINGCHANGE, 0, "Environment",SMTO_BLOCKSMTO_ABORTIFHUNG SMTO_NOTIMEOUTIFNOTHUNG, SomeTimeoutValue, out result);

if(return_value!=0)
MessageBox.Show(" Broadcast to all window successfull! ");
else
MessageBox.Show(" Broadcast to all window failed! ");

For more information check out the following links
MSDN

http://support.microsoft.com/kb/104011

http://www.dotnet247.com/247reference/msgs/32/164585.aspx