Thursday, September 16, 2004

.NET: Using WMI to get MACAddress of a machine

using System;
using System.Management;
namespace GetMACAddress
class Class1
static void Main(string[] args)
ManagementObjectSearcher query = null;
ManagementObjectCollection queryCollection = null;
query = new ManagementObjectSearcher(new ObjectQuery
("Select MacAddress,IPAddress from Win32_NetworkAdapterConfiguration where
IPEnabled=TRUE")) ;
queryCollection = query.Get();
foreach( ManagementObject mo in queryCollection )
if(mo["IPAddress"] != null && mo
["MACAddress"] != null)
Console.WriteLine("IPAddress : " +
Console.WriteLine("MACAddress : " +
catch(Exception ex)

Changing a SQL Server 'server' name after Computer Name has changed

sp_dropserver 'old SQL Server server name'

sp_addserver 'new computer name', 'local'

Stop and Restart SQL Server service

Now Run
to verify the changes

Performance Tools

PERFORMANCE MONITOR -- Counters; Understand thresholds
CLRPROFILER -- Allocations; Survivors; Leaking (Another Profiler is from DevPartner)
WINDBG -- Dumps; Hangs, Crashes, Blocks, Memory, etc
VADUMP -- Working set; Memory, etc
NETMON -- Data on Wire; Bandwidth and Latency

Performance: Calling Unmanaged Code

-- PInvoke is a fast way to invoke unmanaged code

-- The CLR does expensive CAS security stack walks on every call into that method to insure that all callers have unmanaged code access permissions. For non-security sensitive scenarios, disable the security check for better performance.
// Use only when security is not a major concern
[DllImport("kernel32.dll"), SuppressUnmanagedCodeSecurity]
public static extern bool Beep(int frequency, int duration);

*TLBIMP generates interop assemblies
*Disable the CAS stack-walks that by building interop assemblies with the TLBIMP /unsafe switch
*Forces TLBIMP to generate code that create RCWs that perform link demands rather than full demands
*Use with caution! Can open the door to luring attacks

C:\>tlbimp mycomponent.dll /out:UnSafe_MyComponent.dll /unsafe

Securing SQL Server 2000 database and datafiles

Restrict physical access to the SQL Server computer. Always lock the server while not in use.
Make sure, all the file and disk shares on the SQL Server computer are read-only. In case you have read-write shares, make sure only the right people have access to those shares.
Use the NTFS file system as it provides advanced security and recovery features.
Prefer Windows authentication to mixed mode. If mixed mode authentication is inevitable, for backward compatibility reasons, make sure you have complex passwords for sa and all other SQL Server logins. It is recommended to have mixed case passwords with a few numbers and/or special characters, to counter the dictionary based password guessing tools and user identity spoofing by hackers.
Rename the Windows NT/2000 Administrator account on the SQL Server computer to discourage hackers from guessing the administrator password.
In a website environment, keep your databases on a different computer than the one running the web service. In other words, keep your SQL Server off the Internet, for security reasons.
Keep yourself up-to-date with the information on latest service packs and security patches released by Microsoft. Carefully evaluate the service packs and patches before applying them on the production SQL Server. Bookmark this page for the latest in the security area from Microsoft:
If it is appropriate for your environment, hide the SQL Server service from appearing in the server enumeration box in Query Analyzer, using the /HIDDEN:YES switch of NET CONFIG SERVER command.
Enable login auditing at the Operating System and SQL Server level. Examine the audit for login failure events and look for trends to detect any possible intrusion.
If it fits your budget, use Intrusion Detection Systems (IDS), especially on high-risk online database servers. IDS can constantly analyze the inbound network traffic, look for trends and detect Denial of Service (DoS) attacks and port scans. IDS can be configured to alert the administrators upon detecting a particular trend.
Disable guest user account of Windows. Drop guest user from production databases using sp_dropuser
Do not let your applications query and manipulate your database directly using SELECT/INSERT/UPDATE/DELETE statements. Wrap these commands within stored procedures and let your applications call these stored procedures. This helps centralize business logic within the database, at the same time hides the internal database structure from client applications.
Let your users query views instead of giving them access to the underlying base tables.
Discourage applications from executing dynamic SQL statements. To execute a dynamic SQL statement, users need explicit permissions on the underlying tables. This defeats the purpose of restricting access to base tables using stored procedures and views.
Don't let applications accept SQL commands from users and execute them against the database. This could be dangerous (known as SQL injection), as a skilled user can input commands that can destroy the data or gain unauthorized access to sensitive information.
Take advantage of the fixed server and database roles by assigning users to the appropriate roles. You could also create custom database roles that suit your needs.
Carefully choose the members of the sysadmin role, as the members of the sysadmin role can do anything in the SQL Server. Note that, by default, the Windows NT/2000 local administrators group is a part of the sysadmin fixed server role.
Constantly monitor error logs and event logs for security related alerts and errors.
SQL Server error logs can reveal a great deal of information about your server. So, secure your error logs by using NTFS permissions.
Secure your registry by restricting access to the SQL Server specific registry keys like HKEY_LOCAL_MACHINE\Software\Microsoft\MSSQLServer.
If your databases contain sensitive information, consider encrypting the sensitive pieces (like credit card numbers and Social Security Numbers (SSN)). There are undocumented encryption functions in SQL Server, but I wouldn't recommend those. If you have the right skills available in your organization, develop your own encryption/decryption modules using Crypto API or other encryption libraries.
If you are running SQL Server 7.0, you could use the encryption capabilities of the Multi-Protocol net library for encrypted data exchange between the client and SQL Server. SQL Server 2000 supports encryption over all protocols using Secure Socket Layer (SSL). See SQL Server 7.0 and 2000 Books Online (BOL) for more information on this topic. Please note that, enabling encryption is always a tradeoff between security and performance, because of the additional overhead of encryption and decryption.
Prevent unauthorized access to linked servers by deleting the linked server entries that are no longer needed. Pay special attention to the login mapping between the local and remote servers. Use logins with the bare minimum privileges for configuring linked servers.
DBAs generally tend to run SQL Server service using a domain administrator account. That is asking for trouble. A malicious SQL Server user could take advantage of these domain admin privileges. Most of the times, a local administrator account would be more than enough for SQL Server service.
DBAs also tend to drop system stored procedures like xp_cmdshell and all the OLE automation stored procedures (sp_OACreate and the likes). Instead of dropping these procedures, deny EXECUTE permission on them to specific users/roles. Dropping these procedures would break some of the SQL Server functionality.
Be prompt in dropping the SQL Server logins of employees leaving the organization. Especially, in the case of a layoff, drop the logins of those poor souls ASAP as they could do anything to your data out of frustration.
When using mixed mode authentication, consider customizing the system stored procedure sp_password, to prevent users from using simple and easy-to-guess passwords.
To setup secure data replication over Internet or Wide Area Networks (WAN), implement Virtual Private Networks (VPN) . Securing the snapshot folder is important too, as the snapshot agent exports data and object scripts from published databases to this folder in the form of text files. Only the replication agents should have access to the snapshot folder.
It is good to have a tool like Lumigent Log Explorer handy, for a closer look at the transaction log to see who is doing what in the database.
Do not save passwords in your .udf files, as the password gets stored in clear text.
If your database code is proprietary, encrypt the definition of stored procedures, triggers, views and user defined functions using the WITH ENCRYPTION clause. dbLockdown is a tool that automates the insertion of the WITH ENCRYPTION clause and handles all the archiving of encrypted database objects so that they can be restored again in a single click. Click here to find out more information about this product.
In database development environments, use a source code control system like Visual Source Safe (VSS) or Rational Clear Case. Control access to source code by creating users in VSS and giving permissions by project. Reserve the 'destroy permanently' permission for VSS administrator only. After project completion, lock your VSS database or leave your developers with just read-only access.
Store the data files generated by DTS or BCP in a secure folder/share and delete these files once you are done.
Install anti-virus software on the SQL Server computer, but exclude your database folders from regular scans. Keep your anti-virus signature files up to date.
SQL Server 2000 allows you to specify a password for backups. If a backup is created with a password, you must provide that password to restore from that backup. This discourages unauthorized access to backup files.
Windows 2000 introduced Encrypted File System (EFS) that allows you to encrypt individual files and folders on an NTFS partition. Use this feature to encrypt your SQL Server database files. You must encrypt the files using the service account of SQL Server. When you want to change the service account of SQL Server, you must decrypt the files, change the service account and encrypt the files again with the new service account.

SET NOCOUNT ON at the beginning of every SQL stored procedure

Use SET NOCOUNT ON at the beginning of your SQL batches, stored procedures and triggers in production environments, as this suppresses messages like '(1 row(s) affected)' after executing INSERT, UPDATE, DELETE and SELECT statements.

This inturn improves the performance of the stored procedures by reducing the network traffic.

.NET Performance Comparisons and Techniques

Performance Comparison: Data Access Techniques OR MSDN Search: Performance Comparison: Data Access Techniques
DataReader is the best when Forward Read-Only access to data is required.
DataSets are useful when you need the data, schema and maybe updateable options.
The new DataSet is .NET 2.0 also does away with the problem of using a DataSetSurrogate in .NET 1.1 as 1.1 datasets are transmitted in xml across remoting boundaries which is costly for a binary remoting approach.

Performance Comparison: .NET Remoting vs. ASP.NET Web Services
If your application needs interoperability with other platforms or operating systems, you would be better off using ASP.NET Web services, as they are more flexible in that they support SOAP section 5 and Document/Literal. On the other hand, use .NET Remoting when you need the richer object-oriented programming model. See ASP.NET Web Services or .NET Remoting: How to Choose for details. In scenarios where performance is the main requirement with security and process lifecycle management is not a major concern, .NET Remoting TCP/Binary is a viable option; however, keep in mind that you can increase the performance of IIS-hosted implementations by adding a few more machines into the system, which may not be possible when using a .NET Remoting TCP/Binary implementation.

Performance Comparison: Encryption Techniques -- Security Choices
When designing a secure system, the implementation techniques should be chosen based on threat mitigation first and performance second. For instance, basic authentication without SSL could be used for better performance, but no matter how fast it is, it would not be useful in systems that are vulnerable to threats not mitigated by it.

Performance Comparison: Transaction Control
Running a database transaction implemented in a stored procedure offers the best performance because it needs only a single round trip to the database

Improving ASP.NET Performance
This event is used when a client makes a request for any ASP.NET web page/handler. It can be useful for redirecting or validating a page request.
So, the ValidateToken call should be done here. Since the handler (s) will have similar headers this validation logic would be moved to a common area, called on every postback.
This event is used to handle all unhandled exceptions for any ASP.NET web page/handler. So, all ASP.NET global web errors would have to be trapped here. Alwways, implement a Global.asax error handler. Monitor application exceptions. Use try/finally on disposable resources. Write code that avoids exceptions.
Application_AuthenticateRequest:This event occurs when the identity of the current user has been established as valid by the security module(NT/Forms authentication) and is available for custom validation, called on every postback.
Exception Logging:
This event is used when a client makes a request for any ASP.NET web page/handler. It can be useful for redirecting or validating a page request.
So, the ValidateToken call should be done here. Since the handler (s) will have similar headers this validation logic would be moved to a common area.
Response.Flush and Buffer=true behaviour
Microsoft admits that the response.flush waits for the client browser to acknowledge the flush before continuing to process the ASP code. One a very fast internet connection, you don't notice the problem, but a slower modem takes longer to perform that task, and therefore a flush can be bad. So use response.buffer=true, of course but remove or restrict all response.flush commands from the site, and see an instant and dramatic speed improvement for modem connected clients. The acknowledgements from the client occur after the client receives all the content from the server on a flush.
Do not generate user interfaces within global.asax – No Response.Write()'s
Suppress the internal call to Response.End.
The Server.Transfer, Response.Redirect, Response.End methods all raise exceptions. Each of these methods internally call Response.End. The call to Response.End, in turn, causes a ThreadAbortException exception. If you use Response.Redirect, consider using the overloaded method and passing false as the second parameter to suppress the internal call to Response.End.
Inefficient rendering. Interspersing HTML and server code, performing unnecessary initialization code on page postback, and late-bound data binding may all cause significant rendering overhead. This may decrease the perceived and true page performance.
Avoid showing too much exception detail to users. Avoid displaying detailed exception information to users, to help maintain security and to reduce the amount of data that is sent to the client.
The following guidelines relate to the development of individual .aspx and .ascx Web page files.
· Trim your page size. (Reduce/Disable ViewState usage, use a common css file, use use script language="jscript" src="scripts\myscript.js", remove extra white spaces in tables etc eg.helloworld, reduce control id names like dataGrid etc)
· Enable buffering. in a page or in web.config
· Use Page.IsPostBack to minimize redundant processing.
· Partition page content to improve caching efficiency and reduce rendering.
· Ensure pages are batch compiled.
· Ensure debug is set to false. in a page or in web.config
· Optimize expensive loops. Use For instead of ForEach in performance-critical code paths.
· Consider using Server.Transfer instead of Response.Redirect.
· Use client-side validation. reduce the round trips
Avoid Using Page.DataBind Calling Page.DataBind invokes the page-level method. The page-level method in turn calls the
DataBind method of every control on the page that supports data binding. Instead of calling the page-level DataBind, call
DataBind on specific controls.
The following line calls the page level DataBind. The page level DataBind in turn recursively calls DataBind on each control.
Avoid DataBind();
The following line calls DataBind on the specific control.
Minimize Calls to DataBinder.Eval
The DataBinder.Eval method uses reflection to evaluate the arguments that are passed in and to return the results. If you have a table that has 100 rows and 10 columns, you call DataBinder.Eval 1,000 times if you use DataBinder.Eval on each column
Use explicit casting. Using explicit casting (eg. in templates) offers better performance by avoiding the cost of reflection. eg. ((DataRowView)Container.DataItem)["field1"]
Use the ItemDataBound event. If the record that is being data bound contains many fields, it may be more efficient to use the ItemDataBound event. By using this event, you only perform the type conversion protected void Repeater_ItemDataBound(Object sender, RepeaterItemEventArgs e) { ... }
State Management
· Application state. Application state is used for storing application-wide state for all clients. Using application state affects scalability because it causes server affinity.
Application["YourGlobalState"] = somevalue;
Use static properties instead of the Application object to store application state. Use application state to share static, read-only data.
· Session state. Session state is used for storing per-user state on the server. The state information is tracked by using a session cookie or a mangled URL. ASP.NET session state scales across Web servers in a farm. (options:InProc, StateService, SQL Server). Disable if not needed in web.config or in page
· View state. View state is used for storing per-page state information. The state flows with every HTTP POST request and response. Think of serializatrion costs. Disable if not needed in web.config or in page
· Alternatives. Other techniques for state management include client cookies, query strings, and hidden form fields.
PS: Store simple state on the client where possible. Consider serialization costs.
Short Circuit the HTTP Pipeline
The HTTP pipeline sequence is determined by settings in the Machine.config file. Put the modules that you do not use inside comments. For example, if you do not
use Forms authentication, you should explicitly remove the entry in your Web.config file for a particular application using remove tag.
Disable tracing (trace tag) and debugging (compilation tag) in the Web.config files.(during Deployment)
String Management
Use Response.Write for formatting output. Use StringBuilder for temporary buffers. Use HtmlTextWriter when building custom controls. Avoid strings for concatenation, using StringBuilder
Data Access
· Use paging for large result sets.
· Use a DataReader for fast and efficient data binding.
· Prevent users from requesting too much data.
· Consider caching data. (Invalidate cache when appropriate)
HttpModule—the Filter for all Requests The HttpModule does not replace the target of a request, however the HttpModule receives notification at various processing points during the lifespan of a request. Since (as is the case with HttpHandlers) we can map an HttpModule to all application request pages we can use an HttpModule as the foundation for a web application controller.The HttpModule class is accessible via any thread which happens to be serving the current request. Since access to the HttpModule doesn't require a specific thread, the single class instance doesn't represent a bottleneck.
By calling IsReusable, an HTTP factory can query a handler to determine whether the same instance can be used to service multiple requests. [ PS: ASP.NET uses a pool of handlers to service requests. ]

Advantages in using stored procedures(Database)

Yukon is moving towards a subset of the .NET runtime engine inside the SQL Server Database.

So, what's the history behind this move? Stored Procedures -- the pre-cursors -- business logic being embedded in the database is a need -- Why? -- see below.

There are many advantages in using stored procedures, including the following:

· They are typically the most efficient way to access the database.

· They can reduce network round trips.

· They are easy to change in deployed applications.

· They make it is easier to tune the performance of your data access code.

· They provide a better way to give out permissions rather than to give permissions out for base tables.

· They allow the database schema (and schema changes) to be hidden.

· They help to centralize all the data access code.

· If all database access is done through your stored procedures, you get a controlled set of entry points.

· Auditing is easily solved.

· Disconnected pessimistic locking is easily solved.

· Data-close business rules can be put in stored procedures.

· There is no need for triggers, which is good for debuggability and maintainability.

Calling a .NET object from C++

1. Follow the rules in

2. For the .NET interface the following attributes are necessary
[ComVisible(true)] [Guid("e15af71b-9860-36e5-af62-9f405c231daa")] public interface ILoan

3. The interface assembly should be strong named and registered in the GAC
gacutil -i NETInt.dll

4. For the .NET class the following attributes are necessary [ClassInterface(ClassInterfaceType.AutoDual)] [ComVisible(true)] [Guid("18fe2e0a-1130-388b-9f82-171909823cc2")] public class Loan : ILoan

5. The .NET class assembly should be strong named and registered in the GAC[assembly:AssemblyKeyFile(@"..\..\..\sample.snk")]Use:gacutil -i NETclass.dll

6. The .cpp client should
#import "LoanLib\LoanLib.tlb" raw_interfaces_only, no_namespace

7. Two methods of smart ptr creating the .NET object
// Method #1: Declaring and instantiating a Loan object _LoanPtr pILoan( __uuidof(Loan ) );
// Method #2: Declaring and instantiating a Loan object _LoanPtr pILoan = NULL; HRESULT hr = S_OK;
hr = pILoan.CreateInstance( __uuidof(Loan ) );

.NET: Using AD to change a users Password and get Password expiry date

1. Add reference to ActiveDS.tlb (still most AD interfaces are in COM)

2. Following is code from a lot of online sites merged/tested together for a complete working solution.

Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Communication

Use RoleManager for Windows Authentication in ASP.NET 2.0

// Set the search string along with LDAP path. The search is on username.

// You shouldn't bind as the user whose password you want to change, hence use impersonatable-known-user

string path =
"LDAP://"+"ldapserver"+"/CN="+"username-to-test"+"," + "CN=Users,DC=domain1,DC=main-domain";
// Create a 'DirectoryEntry' object to search
DirectoryEntry entry = new DirectoryEntry(path, "impersonatable-known-user", "impersonate-known-password",
//OR DirectoryEntry entry = new DirectoryEntry(path, domain + "\\" +
impersonatable-known-user, impersonate-known-password,

Object obj = null;
//Bind to the native AdsObject to force authentication.
Object obj = entry.NativeObject;
catch (Exception ex)
throw new Exception("Error authenticating user. " + ex.Message);

if (!obj)
//user is not authenicated
return false;
//user is authenicated

// Create the Directory search instance.
DirectorySearcher search = new DirectorySearcher(entry);

//maybe this line is better --> DirectoryEntry result = new DirectoryEntry(path,
// null, null, AuthenticationTypes.None) 'Bind using existing, open connection

// Get the first search result - search is on username.
SearchResult result = search.FindOne();
// If the username has been found in the LDAP server.

if(null != result)
// The result obtained will look like the following:
// CN=group1,CN=group2,DC=domain1,DC=main-domain
// Get the value of 'memberof' from the properties collection
//MSDN Sample: 'System.DirectoryServices.SearchResult'
if (result.Properties.Contains("memberof"))

ASP.NET programs that use Impersonation may not function properly on a Win 2K SP4 Server - Domain Controller

Service Pack 4 (SP4) on a Windows 2000 domain controller does not grant the IWAM account name SeImpersonatePrivilege; programs that use impersonation may not function properly.

Click on the following from Control Panel on the Win 2K SP4 Server - Domain Controller

Administrative Tools -> Domain Controller Security Policy -> Security Settings -> Local Policies -> User Rights Assignment

"Impersonate a Client after Authentication"

Click Add (button) -> Browse (button)
In the Select Users or Groups dialog, select the IWAM account name and click Add.
To apply the policy type the following at a CMD.EXE prompt:
secedit /refreshpolicy machine_policy /enforceIn the CMD.EXE prompt, re-start IIS by typing iisreset

Running with .net 2.0 and .net 1.1 simultaneously

Make sure your run aspnet_regiis -r from the appropriate .net framework dir

For other than ASP.NET issues refer to the registry setting fix of MS OnlyUseLatestCLR = 0 or 1

You can activate this switch either by setting a registry key or by setting an environment variable:
Activate/Deactivate the Switch Using a Registry Key
Turn on the switch using the following registry setting:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\OnlyUseLatestCLR=dword:00000001 Turn off the switch using the followikng registry setting:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\OnlyUseLatestCLR=dword:00000000 Activate/Deactivate the Switch Using an Environment Variable
Activate the switch using the following variable set to "1", as follows: COMPLUS_OnlyUseLatestCLR=1
Deactivate the switch using the following variable set to "0", as follows: COMPLUS_OnlyUseLatestCLR=0
You can find a sample using the registry to activate/deactivate the switch posted on GotDotNet, at the following URL:
and reboot

Handling Unhandled Exceptions in .NET

Depending on the type of application you are creating, .NET has three different global exception handlers.
For ASP.NET look at:System.Web.HttpApplication.Error eventNormally placed in your Global.asax file.
For console applications look at:System.AppDomain.UnhandledException eventUse AddHandler in your Sub Main.
For Windows Forms look at:System.Windows.Forms.Application.ThreadException eventUse AddHandler in your Sub Main.
This is called Vectored Exception handling.

It can be beneficial to combine the above global handlers in your app, as well as wrap your Sub Main in a try catch itself.
There is an article in the June 2004 MSDN Magazine that shows how toimplement the global exception handling in .NET that explains why & when youuse multiple of the above handlers...

Example: In a Win Forms App, have a handler attached to the Application.ThreadException event, plus a Try/Catch in my Main. The Try/Catch in Main only catches exceptions if the constructor of the MainFormraises an exception, the Application.ThreadException handler will catch all uncaught exceptions from any form/control event handlers.