Tuesday, May 19, 2009

Backup on shared folders running on a local system account?

I still see a lot of SQL Servers running using the LocalSystem account, particularly, MSDE 2000, which is very popular among third-party applications that requires storing data in a database. Others run a stand-alone SQL Server system and use LocalSystem account for the service accounts. While this may be a security risk, a lot of users still have them configured. And when they need to generate database backups on a shared folder, the SQL Server service's attempt to connect to network resources are denied access because they have no credentials and they are using a null session.Of course, a typical recommendation would be to change the service account to a local Windows or a domain account with least privilege but not everybody is open to that suggestion. So how do you allow SQL Server to generate a backup on a shared folder while using a LocalSystem account? The solution: enable null session shares

While I do not advocate such workarounds as it opens up additional security loopholes, it still is a workaround. And as I usuallly say,
WARNING: This is not a recommended approach. Use at your own risk

Microsoft has a documented procedure to enable null sessions shares and while the KB article mentions Windows 2000, it does work for Windows Server 2003. This should be done on the Windows machine that hosts the shared folder. A word of caution if you intend to use this approach - document every step that you do and make sure you rollback any changes made after generating your database backup. Tasks like enabling the Guest user account (this is disabled by default), modifying the registry, etc. should be rolled back as soon as you're done, otherwise, you're opening up security vulnerabilities across your network.

Tuesday, April 21, 2009

Could not load file or assembly

I was assisting one of our customers move their .NET applications from one server to another and run them using Windows Task Scheduler. I did highlight to them that in order to make the application work, we have to make sure that the correct .NET Framework version was installed on the target server, that the correct .NET Framework version was referenced by the assemblies used (this is very important when the target server has multiple versions of the .NET Framework installed and the assembly was created using an older version) and that the appropriate permissions were given to the accounts that will launch the EXE files from within the Windows Scheduled Tasks. I wasn't surprised when after the move, I saw this error from calling the assembly from the command prompt

System.IO.FileNotFoundException: Could not load file or assembly 'MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0e1d67af9d31f077' or one of its dependencies. The system cannot find the file specified.
File name: 'MyAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0e1d67af9d31f077' ---> System.IO.FileNotFoundException: Could not load file or assembly 'MyAssembly' or one of its dependencies. The system cannot find the file specified.
File name: 'MyAssembly'

This blog post highlights a couple of different reasons why an assembly would not load. What I would like to highlight, though, is the use of a pointer to the correct .NET Framework version in the application's config files.

< version="v1.1.4322" safemode="true">

A lot of developers in the past simply didn't realize that it would be possible to co-exist different versions of the .NET Framework in a single machine yet cause application issues if not handled properly. This Microsoft document, although relatively old, describes how to manage multiple versions of the .NET Framework on a single machine. If unsure, you might want to enable the Assembly binding logging option thru your registry key

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion!EnableLog] (DWORD) = 1

You can also use the Assembly Binding Log Viewer tool if you have the SDK Tools installed on your target machine (of course, as best practice will tell you, you wouldn't install anything unnecessary on your production servers)

Saturday, April 18, 2009

Finding out the .NET Framework version that an assembly uses

There will be cases where you would need to find out the .NET Framework version of an application or assembly running on a machine and you just don't have the right tools. This is especially true when you need to promote your code from test to production environment. If there is only one version of the .NET Framework on the machine, it would be easy. But if you have servers with multiple versions of the .NET Framework installed and the assembly is not configured to bind to the correct framework version, you might end up having an application that might break due to incompatibility issues. This is true for .NET Framework versions 2.0 and below although I haven't really tried out the newer ones but it would be basically the same since .NET Framework 3.0 and 3.5 are just stacks on top of 2.0

If you don't have the tools on the server to check, you can simply copy the assembly on your local machine and use either ILDASM.exe or simply download RedGate's Reflector. Reflector does not need installation as long as you have the appropriate .NET Framework versions in your machine. Just extract the EXE and CONFIG files and you're good to go. A video demonstrating how to use RedGate's Reflector can be found here

Transfering Windows Scheduled Task Jobs between servers

There might be some cases where you need to transfer Windows Scheduled Task jobs like maybe promoting them from test to production. The simplest way to do it is by simply opening the Windows Scheduled Task in Windows Explorer for the source and the destination servers (you can do this by expanding on My Network Places and selecting the destination server. Just remember to open separate window for the two of them). Copying and pasting between windows should do the trick. It would be a bit challenging if the source and target servers are not in the domain as you would need an account that has the appropriate privileges on both machines
Google