I am proud to announce that fksec is in need of a new name: it is now no longer mine alone. Simon Fell and Tomas Restrepo are now as much the authors of fksec as I am. Errors are, of course, my responsibility.

Win32 offers two ways to deal with security descriptors and their components: the slow, painful one, and the easy, buggy one. The former relies on the APIs that are now called "low-level" and which only work on binary representations (meaning you have to do everything yourself, including name-to-SID translation, laying out structures, and so on). The latter way uses the APIs introduced in NT 4.0, which offer far more ease of use, at the small price of correctness. Hey, it's just security, who cares whether it works?

Questions related to these APIs and their use came up often enough -- at least in the newsgroups that I trawl -- that I finally broke down and collected some of the bits and pieces I had lying around and uploaded them. The documentation is still in the works, as you will see, and my work schedule is not really ideal for finishing it, but I hope you will find the classes themselves readable, and the docs at least tell you how to merge the things into your code.

Aside from the included test-driver in main.cpp, which exercises plenty of fksec's functionality, I now have a real (and potentially useful) fksec-based sample online, demonstrating taking ownership. The security-related code, including translation of names to SIDs, looking up (and enabling) privileges, and actually changing the owner of a file, is all of five lines of code. :-)

As always, I appreciate suggestions, corrections, bug reports, and just plain feedback. If you have a problem with fksec, a detailed description and a small (!) sample app demonstrating the bug would help tremendously in locating and fixing the error.

Release history:

Date (CET) Change
13 Nov 99 Initial upload
13 Nov 99 Eliminated dead code (already #if-ed out) from priv.cpp. No need to download, since the active code didn't change.
13 Nov 99 Added the exceptions chapter to the documentation.
14 Nov 99 Uploaded the rest of the *.dsp project files, to build fksec as a static library; added docs for that
28 Nov 99 Fixed a bug -- priv::SetState() did check ATP() for a return of TRUE, but GetLastError() wasn't called in this case. Thanks for reminding me, Slava! (Only priv.cpp changed this time around.)
1 Dec 99 Bug fix: When stuffing a sid with a stringified SID ("S-1-..."), RIDs with a value of 0 were flagged as errors. This is obviously bogus, as the World SID, for instance, is S-1-1-0.
Addition: sid::LookupSidType() report whether a sid is built-in (well-known groups, like Administrators, or LocalSystem); local (local users and groups); from the domain that the current machine is a member of (domain users, global groups); or foreign (a domain SID that does not belong to the current machine or its domain).
Big change: I got fed up with Word and imported the documentation into the sources, from where ccdoc generates totally hip HTML documentation. My stock is bound to leap upwards any day now -- at the latest, as soon as I incorporate as fksec-dot-com. :-)
25 Dec 99 Documentation update -- I added descriptions for the priv class (managing privileges) and for the functions in apis.h (getting and setting security on securable objects).
Cosmetic change: priv::operator ==() and priv::operator !=() now return a bool instead of an int.
9 Mar 00 Minor update: ace::operator<<() now presents a cleaner display, and sd::GetControl() makes sure that the SE_xACL_PRESENT bits are cleared when no ACL of a particular kind is present. Next on the list: The code to dump ACEs in a readable form, kindly provided by Tomas Restrepo. No documentation changes, so you can download just ace.cpp and sd.cpp and recompile.
7 Apr 00 *Highly* recommended update, as it includes bug fixes: In particular, ACE sorting finally works the way NT 5.0 wants it for auto-inherited ACEs. Additionally, if an SD that is written back to an object has the SE_xACL_AUTO_INHERITED bit set in its control word (where xACL is either SACL or DACL), the SE_xACL_AUTO_INHERIT_REQ bit will get set, ensuring proper functioning of auto-inheritance.
11 Apr 00 A sample using fksec to take ownership of files is now online.
19 Apr 00 Kudos goes to Ivan Krivyakov for pointing out to me that (a) older SDK headers needed a little help with new constants (see fksec.h line 82ff.) and (b) enabling specific combinations of tests in main.cpp broke due to multiple use of the same name. Only fksec.h and main.cpp have changed this time.
28 Apr 00 Stefan Kuhr suggested a number of changes for compatibility with VC++ 5.0, and to make running the test main.cpp easier for those with localised (non-US) versions of NT. In particular: The domain- and account-names used by main.cpp are now all #defined near line 50 of main.cpp; the existence of those accounts is verified before they are blithely used; and _tmain is now #defined if it is missing. Furthermore, priv::GetState() and priv::GetState() now have an (unreachable) "retun false;" at their ends; VC++ 5.0 did not realise that an unconditional throw statement ended the current code path and insisted on a value being returned.
29 Apr 00 Incorporated Tomas Restrepo's token class -- thanks, Tomas! Unless Tomas fights (and wins), fksec now has two authors. On further reflection, maybe fksec wasn't the best of all possible names ...
6 May 00 Switched to Doxygen by Dimitri van Heesch instead of ccdoc.
5 Jun 00 Simon Fell's debut -- thanks, Simon! How does sftrfksec as a library name sound to you? Simon has kindly supplied two new member functions for the sid class, dealing with determining membership for a given group SID and finding the groups of which a given SID is a member. On top of that, he has extended the ace class to handle the "object ACEs" used by Active Directory, made the appropriate extensions to the acl and sd classes, and added AdsGetObjectSecurity()/AdsSetObjectSecurity() to apis.cpp.
In other news: class ace is now fully documented; class sid now offers a slew of those constant "well-known SIDs"; and acl is (slowly) growing a replacement for the buggy Win32 function GetEffectiveRightsFromAcl().
8 Oct 00 A few minor fixes: token::operator=(const token &) and token::token(const token&) now check the validity of the token object that gets copied into them, and token::operator=() closes the lhs-object's current token handle, if any.
Perry Rapp (prapp, works at smartronix.com) kindly pointed out a bug in sd::operator=(SECURITY_DESCRIPTOR *): if the address passed in was the address of the internal buffer for the absolute or self-relative SDs, that buffer would be released before the code assigned its contents to *this. Similar problems existed in acl::operator=(ACL *), ace::operator=(const void *), and sid::operator=(const PSID). Kudos to Perry!
Following an earlier suggestion from Perry, I added a #define SE_GROUP_RESOURCE to fksec.h -- this flag is supported on NT5 only, and the symbol is undefined unless _WIN32_WINNT is set to a suitable value. Obviously, my definition is properly guarded.
Instructions for generating an HTMLhelp file from the docs were added, as well as the file itself.
13 Oct 00 Documentation for class acl has been added.
Minor fix: when verifying that a potential ACL is less than 64K in size, acl::IsValidAcl() now also takes any requested additional bytes into account.
15 Oct 00 Minor fix: NT4 does not have restricted SIDs in a token; the error returned by GetTokenInformation() is now handled cleanly.
Perry Rapp (prapp, works at smartronix.com) has kindly added a new member function to fksec::ex -- never was it easier to translate a Win32 error code into the corresponding error message.
Other minor changes too small to mention.
16 Oct 00 If you downloaded fksec within the past eight hours (i.e., from 15-Oct-2000 22:00 GMT through 16-Oct-2000 05:30 GMT), download it again -- an important line was missing from token::GetTokenInfo(), basically causing every call to it to fail. Sorry!

And now, without further blather, I give you fksec: Simon Fell's, Tomas Restrepo's, and Felix Kasza's security classes.

System requirements

As of this writing [8 Oct 00], I am using VC++ 6.0 SP4 and the NT5 final release of the Platform SDK. The SDK can be downloaded from MSDN Online's Platform SDK page. Please make sure that your include, library, and executable paths (Tools, Options, Directories tab if you use the IDE) list the Platform SDK stuff before the VC++ headers.

Update [6 May 00]: Thanks to the efforts of Stefan Kuhr, fksec can now be built with VC++ 5.0. As far as I can tell, having a current Platform SDK still is a good idea.

License

The fksec class library, including not only the code written by yours truly, but also the parts written by Simon Fell and Tomas Restrepo, is in the public domain. Read more about this on the license page. (If you like fksec, I am sure Simon and Tomas wouldn't mind a little thank-you note.)

Documentation

Note that the only documented classes are ex (exceptions), priv (privileges), ace (access-control entries), acl (access-control lists), token (process and thread tokens), and sid (SID functionality), plus the global functions in apis.h. I am working on sd, the wrapper for security descriptors, but I do have a day job which I actually like, so bear with me, please.

The vanilla fksec.zip (see next section) contains the data needed to recreate the documentation, assuming that you have Doxygen installed. You can also read ready-made docs online, or download them:

fksecdoc.zip, 438 KB: docs in HTML format. Unzip this file into any empty directory. The home page is index.html.
fksec.chm, 573 KB: docs in compressed-HTML (.CHM) format, suitable for HTMLhelp, in a single file.
Online documentation, plenty KB in many small files: Hey, you know what to do.

To regenerate the documentation, you need to install Doxygen by Dimitri van Heesch (thanks, mate!). Installation basically consists of moving the pre-built doxygen.exe into a directory that is on the PATH. Then, build the doc project in the fksec workspace; the "Win32 Debug" configuration uses a command line which requires 4NT, a cmd.exe replacement, while the "Win32 Release" configuration's command line should work with cmd.exe itself.

To rebuild fksec.chm, the compressed-HTML help file, generate docs as above and then run "hhc <fksec-dir>\html\index.hhp". Rename "<fksec-dir>\html\index.chm" to "fksec.chm". Note: "hhc" is the HTMLhelp compiler's command-line version. It is installed with the HH authoring kit, which you can download from the HTMLhelp download page if you do not have the Platform SDK installed. Unless you put hhc.exe into a directory on your PATH, you will have to specify its full pathname in the build command for the "doc" project.

Complete package, for your convenience

fksec.zip, 104 KB: Everything you need to build fksec and its documentation. Note that fksec.zip contains no documentation per se, only comments that are assembled into documentation by Doxygen. Please see the "Documentation" heading above for pre-generated online and downloadable copies of the docs.