SQL Server 2012 Fun

Illustration

On clean installation of Windows 8 I had issues with Visual Studio 2012 being completely broken. Almost every day I had to deal with following messages (just an excerpt):

  • The 'Microsoft.VisualStudio.Editor.Implementation.EditorPackage' package did not load correctly.
  • The 'Microsoft.VisualStudio.TestTools.TestCaseManagement.QualityToolsPackage, Microsoft.VisualStudio.QualityTools.TestCaseManagement, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' package did not load correctly.
  • The 'Windows Forms Designer Package' package did not load correctly.
  • The 'Code Analysis Package' package did not load correctly.
  • Internal error occurred. Additional information: ''.
  • NoWarn: Configuration system failed to initialize

I blamed Windows 8 and it is probably best for all that I never killed anybody given how close I live to Microsoft headquarters.

I was wrong.

I installed clean Windows 7 and same problems started again. Visual Studio would work for a while and then it would stop. Repair would fix everything but things would break soon enough. To make things more confusing, another (virtual boot) Windows 7 installation on same machine had Visual Studio 2012 that had no issues at all. So I went into task of comparing everything.

To keep long story short, I found one major difference. I had Visual Studio 2010 installed there. And, by magic, it prevented errors in Visual Studio 2012. And then I remembered that every time something went wrong SQL Server 2012 was just around corner smiling from within its Visual Studio 2010 shell.

For some reason SQL Server 2012 kept destroying Visual Studio 2012 environment. I saw simple solution - just install Visual Studio 2010 side-by-side and problems will go away. Or even simpler one - just remove SQL Server 2012 altogether and go back to SQL Server 2008 R2.

SQL Server team is my newest hate target these days. Not because of this VS 2010 shell issue but because they make uninstall extremely annoying. It consists of at least 15 different components (approximate figure, I was to annoyed to count) and I can only compare procedure to removing malware. And that is broken for quite a few versions now. If they can make single installer, why is single uninstaller impossible task?

LDAP Authentication From C#

using (var ldap = new LdapConnection(new LdapDirectoryIdentifier(this.HostName))) {
    ldap.SessionOptions.ProtocolVersion = 3;

    ldap.AuthType = AuthType.Anonymous;
    ldap.Bind();
    var dn = GetDn(ldap, userName);

    ldap.AuthType = AuthType.Basic;
    try {
        ldap.Bind(new NetworkCredential(dn, password));
        return GetUser(ldap, dn);
    } catch (LdapException) {
        return null;
    }
}

First step is just simple anonymous bind to retrieve distinguished name based on user name. If our UID is jdoe, we simply search for uid=jdoe in dc=localdomain (base DN) using sub-tree search. That should give us location of our user wherever he is. Let’s assume that user is now found at uid=jdoe,ou=People,dc=localdomain.

Full DN of user is then used together with password to authenticate ldap connection. If authentication fails our user cannot logon. If it works than another ldap search (uid=jdoe,ou=People,dc=localdomain) retrieves attributes, packs them into class and returns it back.

Sweet and simple.

P.S. Code in this post is just an excerpt. You can download full code here.

Simplest LDAP Server

One application I am working on needed LDAP authorization support. In order to test before actually deploying it I decided to create local LDAP server in virtual machine.

I decided to use CentOS minimal install as starting point. It is extremely small distribution to start with and it allows for virtual machine with only 256 MB of RAM (although it needs 512 MB in order to install, go figure).

Installation of CentOS is uneventful. Just go next, next, next and it is done. Although it might be wise to skip media check since it takes ages. In matter of minutes OS will boot up and then the fun starts.

Since we will need network access for both using machine as LDAP server and for getting packages of the Internet, we need network access. Getting it to work is as easy as writing ifup eth0. In order to make these changes permanent just edit /etc/sysconfig/network-scripts/ifcfg-eth0 and change line starting with ONBOOT with ONBOOT="yes". It is as easy (if you disregard annoyance of vi editor).

Now we need to install our directory server. First install package (answer y to everything):

yum install 389-ds-base

And then run setup (answer yes to first two questions and just use default for others):

setup-ds.pl

That should leave us with values totally unsuitable for anything but for testing (which is exactly what we want):

Computer name ...............: //localhost.localdomain//
System User .................: //nobody//
System Group ................: //nobody//
Directory server network port: //389//
Directory server identifier .: //localhost//
Suffix ......................: //dc=localdomain//
Directory Manager DN ........: //cn=Directory Manager//

Quick search will prove that our directory server is up and running

ldapsearch -h 127.0.0.1 -x -b "dc=localdomain"
 ...
 # search result
 search: 2
 result: 0 Success
 # numResponses: 10
 # numEntries: 9

Well, now we are ready to add our first user. In order to do this just create user.ldif file with following content:

dn: uid=jdoe,ou=People,dc=localdomain
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
uid: jdoe
cn: John Doe
displayName: John Doe
givenName: John
sn: Doe
userPassword: test

Not all these attributes are mandatory but I find this to be minimum acceptable set for my use. This is not enough if you want to use LDAP server for logons but it is enough for basic password checking. We add user with:

ldapadd -h 127.0.0.1 -x -D "cn=Directory Manager" -W -f user.ldif
 adding new entry "uid=jdoe,ou=People,dc=localdomain"

If something is messed up, just delete the user and add it again:

ldapdelete -h 127.0.0.1 -x -D "cn=Directory Manager" -W "uid=jdoe,ou=people,dc=localdomain"
ldapadd -h 127.0.0.1 -x -D "cn=Directory Manager" -W -f user.ldif
 adding new entry "uid=jdoe,ou=People,dc=localdomain"

Yes, there is an ldapmodify operation but I find it better to start with clean slate during testing.

Another test to verify that our user authentication works and we are good. Password asked here is not your root LDAP password but password of an user (test in my example):

ldapsearch -h 127.0.0.1 -x -D "uid=jdoe,ou=People,dc=localdomain" -W -b "ou=people,dc=localdomain" "uid=jdoe"
 dn: uid=jdoe,ou=People,dc=localdomain
 objectClass: top
 objectClass: person
 objectClass: organizationalPerson
 objectClass: inetOrgPerson
 uid: jdoe
 cn: John Doe
 displayName: John Doe
 givenName: John
 sn: Doe
 search: 2
 result: 0 Success

Congratulations, you have just made your first LDAP authorization.

Since, in current state, our LDAP cannot talk with outside world, we can think of dropping firewall (not something that you should do in production environment):

iptables -F INPUT
service iptables save

And last step would be to ensure that our directory server gets started as soon as machine is booted up:

chkconfig dirsrv on

With this LDAP test server configuration is done.

Pure Laziness

Illustration

Visual Studio 2012 comes with Blend. Even Visual Studio installation is named “Visual Studio 2012 with Blend”.

Therefore I was surprised when I actually started Blend under Windows 7. I got slapped with “… supports only Windows Store app development on Windows 8 …”.

Under assumption that there is some programming API for retrieving actual version of Windows, I cannot think of an excuse other then pure laziness why this item ended up offered as instalaltion option. If you know that your component does not work under certain OS, do not even show it to user. And do not even think about actually installing it.

I understand that Microsoft wants to sweeten deal for early Windows 8 adopters. I find nothing wrong with that. It is actually really sensible thing to do.

But do not install by default stuff that developer cannot use. It will just make him cranky.

P.S. Uninstalling Blend left it’s item and project templates directories behind…

Virtual CloneDrive - Installation Failed!

Illustration

After fresh Windows 7 installation and some initial setup I came around to install programs on top of it. I find Virtual CloneDrive perfect companion for this job since most of software I have is in form of an ISO image.

This time I stumbled upon a problem. Every time I tried to install it I would get “Installation failed!” followed by “Completed!” and setup asking for restart. And CloneDrive would just end up as Unknown device in Device Manager. Every time before this program worked perfectly, why it would not now?

After short analysis I managed to find a problem. As part of install driver is extracted in user’s temporary folder (AppData\Local\Temp). Then system is invoked in order to install it.

Just after Windows install I have enabled encryption on my user profile. When system attempted to install driver it was accessing file in context of another user. Thus it was unable to read encrypted files.

Solution was simple - I just turned off encryption attribute for directory and started setup again. This time everything went in perfect order. After having similar issues with multiple programs, I permanently removed NTFS encryption on temporary folder. It seems that lot of programs use this folder during installation of system components and it was just too annoying to keep it encrypted.

Real solution would be for programs with system components to use Windows\Temp as temporary folder. However, you cannot control what other people do…