SID and Minimum Amount of Work
Posted by Dan Byström on September 6, 2004
SID means Security IDentifier, although this blog really is about integrating C/C++ code into your .NET project, as well as the pros and cons of being lazy.
My old and dear friend Lars Wirsén is struggling with a Visual Basic .NET program to install a database on a Microsoft SQL Server, or if no one is present, install a Microsoft Desktop Engine (MSDE) on the local machine first. He is the one who taught me the art of computer programming some 22 years ago. While I was struggling with 6502 assembly language for my VIC-20, trying to understand how the carry flag worked, he on the other hand was able to build his own 8kb memory cartridge with a switch on it so that its content could be moved around in memory even as the computer was running. This made it possible for him to make copies of the game ROM cartridges you could buy for that machine. I still haven’t figured out how he did it.
Time changes and software has become as complex as hardware. Apparently, he has discovered that the user needs certain access privileges in order to run his program and wants to check if the user is member of “BUILTIN\Users”. Fine.
The problem is that group names are localized! On a Swedish Windows, it is called “BUILTIN\Användare” instead. Of course, if he just supported English, Swedish and Klingon, then all major languages would be covered for.
I’ve told him 1024 times that once you start to use a database you’re committed to a never ending series of trouble and that you shouldn’t use them at all. Databases – just say NO!
Nevertheless – I thought to myself, how hard can it be to dig up the localized string from Windows if we just ask politely? I know almost nothing of security issues. I, as most developers, run my machines with full administrator privileges. Philip Nelson has wise things to say about this, but this is a story about laziness (the power that makes the world go around) so I’ll continue to run as admin that for a little while longer.
I browsed the Net as well as MSDN for a little while and got confused. There were some huge code examples demonstrating things I thought would be useful. However, I just didn’t feel like digging into this field right then. I had neither the time nor the interest at the moment. I just wanted to get the whole thing solved as quickly as possible. The LookupAccountSid Win32 API function seemed like a good start. But how do you construct a SID to pass to it? The answer seemed to be buried in just too much code. Then I found a nice MSDN article from 1996 with full C code that seemed quite promising (My. Eight years old stuff which I knew null of!). I pasted the whole thing into an empty Visual C++ project and… Voila! It worked like a charm! It used something called RID instead of SID and apparently uses this RID (which is a 32 bit integer by the way) to find the desired SID. Fine by me – I didn’t care what made it tick.
Well then, since the code was running just fine – why not use it just as it was? I created an empty Managed C++ project in Visual Studio .NET, added an unmanaged class and pasted the C code in there. That’s should be almost it I thought. Well, it almost was. But I was surprised to discover just how many small pitfalls there were along the way! Before I had a running solution with a Visual Basic .NET front-end to this Managed C++ DLL, over two hours had passed!
So, I thought I post the whole solution here so you can take a peek in case you need to do the same one day. It is both a Managed C++ DLL with source code as well as a Visual Basic .NET demo project utilizing the DLL. Feel free to use my code as a boilerplate but don’t ask me anything about “SID.cpp”. That file is from MSDN and I still don’t know what a SID really is. But the job got done. Not as fast as I had hoped for, but the next time I write a Managed C++ wrapper I may still remember some of the things that went wrong this time!
So, did I get the job done with a minimal amount of work? Well, if I had converted the whole thing to Visual Basic .NET or C# directly, and written DLLImports for the API functions instead of using Managed C++ I would probably have made it in less than half the time.
One the other hand, I didn’t have to think much. All was familiar playing ground. If I had converted the code, then I would have had to actually understand it. It is just as when you wait for the slow, slow elevator to come down instead of taking the stairs and get up faster as well as gain a little exercise along the way. I must confess myself guilty of sloth – and try to make up for this for the rest of my life. Starting right now.
I sometimes have the privilege to get previews of articles by Jimmy Nilsson. In one exciting forthcoming text I found this:
Do you recognize the “I have a new tool, let’s really use it” syndrome? I do. I’ve been known to suffer from it from time to time. It can be problematic, but I like to think about it not just negatively, but actually a bit positively too. (Do you do that too? I mean, squeeze advantages into your bad habits?) After all, it could be a sign of productive curiosity, healthy progressive thinking and a never-ending appetite for improvements.
I really must pay more attention to what he says – before I forget why I began to write programs in the first place!
Here is the vdSID code sample along with a Visual Basic .NET test project. I have also added two totally irrelevant sample functions showing how to use inline assembly code in a .NET project as well as how you return an array of managed objects (Strings, in this case) from Managed C++ code.
(to be continued…)