Team LiB   Previous Section   Next Section

2.1 How the Registry Is Structured

Since the Registry is such an important part of Windows 2000, understanding how it's put together is crucial to learning how to use, modify, and protect its data. Let's start by examining the basic structures and concepts that underlie the Registry. Once you understand how these pieces fit together, we can move on to the data that actually lives in the Registry.

2.1.1 The Basics

You may find it helpful to think of the Registry as a filesystem; their organizations are similar in many respects. Both have a well-defined hierarchical structure, and they both support the concept of nesting items within other items. Files are identified by names and paths. Likewise, every key in the Registry is identified by a full path that identifies exactly where to find it. Since the Registry can be shared and accessed over a network, this full path can optionally include a computer name, which works as it would for a file share. The data within a file can be interpreted by applications that understand that file type. So it is with Registry keys, whose values can be understood and used by applications, kernel services, and other Registry clients.

2.1.1.1 Root keys

Root keys are like disk volumes: they sit at the root of a hierarchy and aren't contained or "owned" by any other item in the hierarchy. Windows Explorer groups all local disks together under "My Computer," and the Win95 RegEdit app does the same for Registry keys, but these groupings are fake, since the disks and root keys are actually logically separate entities. The groupings just provide a convenience for users. The six root keys that make up the Registry (see Section 2.1.2 later in this chapter) are logically independent of one another; to reinforce this idea, the Windows 2000-specific Registry editor, RegEdt32, shows each root key in an individual window.

In Windows 2000 and Windows NT 4.0, there are six root keys:

HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_CURRENT_CONFIG
HKEY_PERFORMANCE_DATA
HKEY_USERS
HKEY_CLASSES_ROOT

Earlier versions of NT don't have HKEY_CURRENT_CONFIG or HKEY_PERFORMANCE_DATA.

2.1.1.2 Subkeys

Think of a subkey as a subdirectory somewhere on disk. Any key in the Registry may have subkeys. Just as folders are contained inside other folders, these subkeys can in turn hold other subkeys, and so on down the line. (Throughout the rest of the book, I'll call a subkey's parent a parent key.) Naturally, the root keys all have subkeys, but no parent keys; any other key, though, can have both parents and subkeys.

A subkey can have values of its own, or it can be a placeholder for subkeys that contain values themselves. For example, HKEY_CURRENT_USER\Software has subkeys, but it doesn't have any values attached to it. By contrast, HKEY_CURRENT_USER\Software\Netscape\Netscape Navigator is a subkey too, but it has several values of its own in addition to those of its subkeys. For example, the Netscape Navigator key has subkeys named Bookmark List, Mail, and Security, among others. The Bookmark List key in turn has a value named File Location. If you talk about the value named HKEY_CURRENT_USER\Software\Netscape\Netscape Navigator\Bookmark List\File Location, then you've completely described the path to a particular value. Leave off File Location, and you're talking about a subkey.

2.1.1.3 Values

Speaking of values, now would be a good time to mention that any Registry key may have zero or more values attached to it. These values normally have three components:

  • A name, which identifies them both to Windows 2000 and you. Just like files, there can be many Registry values with the same name, but each key can only have one value with a particular name. The combination of the value's name and the path used to reach it must be unique. This means that it's okay to have values named Stuff under both HKEY_CURRENT_USER\Software\SomeVendor\AProduct and HKEY_CURRENT_USER\Software\BigCompetitor\AnotherProduct, but neither of those keys may have more than one value named Stuff.

  • A datatype, which tells the Registry and its clients what kind of data the value represents. The Section 2.1.5 and Section 2.1.6 sections later in this chapter elaborate on the available types for Registry data.

  • Some contents,[1] which are subject to any limitations imposed by the value's type. In Windows 2000, the contents must be smaller than 64K of data. As a practical matter, 2 KB is about the point beyond which performance starts to suffer. In reality, most keys are much smaller--a few dozen bytes at most.

    [1] The contents are just the value's value. This is confusing at best.

As with most other statements that include the word "normally," there's an exception to this three-part rule: Registry keys can have a single value with no name. The Microsoft editing tools show this value with a name of (Default) or <No Name>; applications can still reach it by querying the key it's attached to. This behavior is an artifact from Windows 3.x, but many modern applications still use this unnamed value.

The combination of these components makes it possible for Registry clients (including editors, applications, and the OS itself) to locate specific values, figure out what kind of data they contain, and get that data.

2.1.1.4 Hives

Hives aren't just for beekeepers any more.[2] In the Registry world, a hive is a portion of the Registry tree structure from any subkey under a root key on down. For example, the SOFTWARE hive contains HKEY_LOCAL_MACHINE\Software and all its subkeys, and their subkeys, and their subkeys, on down to the values attached to the "deepest" subkey.

[2] In Managing the Windows NT Registry, I admitted to not knowing where the term "hives" came from. It turns out that the Registry stores its data using a type of database called a b-tree. Where do bees live? In hives, of course.

Hives are significant because each hive corresponds to a disk file that contains the hive's data. Instead of INI files, these hive files are the actual on-disk location for the system's crucial configuration data. Consequently, they're what you need to back up and restore (you'll learn how to do this in Chapter 3). Windows 2000 normally uses eight hives: HARDWARE, SAM, SECURITY, SOFTWARE, SYSTEM, .DEFAULT, and two for the currently logged-in console user (one contains the user's profile, while the other contains the user-specific portion of HKEY_CLASSES_ROOT).

figs/nt4icon.gif Windows NT has only one hive for the logged-on user instead of two; it contains all the user's profile data.

You'll learn what each hive is for and where its corresponding file is stored in Section 2.1.3 later in this chapter. In the mean time, if you look at HKEY_LOCAL_MACHINE\SYSTEM\Control\CurrentControlSet\Control\hivelist, you can get a sneak preview of the list of supported hives.

2.1.1.5 Links

The Windows 2000 shell and filesystem support shortcuts. (You might be familiar with aliases or symbolic links, the Mac and Unix equivalents.) All a shortcut does is point to something else. For example, the Internet Explorer icon on your desktop is actually a shortcut to the real installation of whatever version of IE you have installed, if any. When you double-click it, the shell can resolve the shortcut to find the thing it points to and run that instead.

The Registry equivalent of a shortcut is called a link. These links provide alternate paths and names for Registry subkeys. For example, the entire HKEY_CURRENT_USER root key is a link to the current user's subkey under the HKEY_USERS root. Since links can be built dynamically, it's easy to construct a link whose destination varies depending on some condition or other. Windows 2000 uses these links internally in a number of places; HKEY_LOCAL_MACHINE\System\Controls\CurrentControlSet is a link whose origin depends on which set of device drivers, hardware components, and system software is currently active.

2.1.1.6 Registry road map

Figure 2.1 shows a road map of the root keys and their major hives. As you can see, several keys and subkeys are actually links to areas in different root keys. You may find it helpful to refer back to this figure as we plunge forward into discussing the six root keys themselves.

Figure 2.1. The Registry's overall organization
figs/mwr2_0201.gif

2.1.2 The Big Six

The root keys are, well, the root of the Registry's hierarchy. In the Windows 3.1 Registry, there was only one root key; in Windows NT 3.1 there were four, but Windows 95, NT 4.0, and Windows 2000 all have six. These keys form the foundation upon which all the Registry's capabilities rest. They provide a logical structure for grouping related items, and each of them plays a role in providing configuration data to clients and kernel components.

You'll notice that all the names start with odd nonwords like HKEY and REG. Microsoft uses a system called Hungarian notation for naming variables. In this scheme, the name of every variable, datatype, or constant starts with a short code that identifies the type of data it is. This notation carried over into the Registry's design. HKEY is actually a handle to a key, which seems reasonable for the root keys.

2.1.2.1 HKEY_LOCAL_MACHINE

HKEY_LOCAL_MACHINE (abbreviated HKLM) is the king of the Registry. Its job is to consolidate and store all the systemwide configuration data for a particular computer. HKLM includes the hardware configuration data without which Windows 2000 couldn't even boot. Besides that, it also holds settings for the computer's network connections, security configuration, device driver settings, and more.

There are five major subkeys under HKLM, each of which plays a critical role in keeping Windows 2000 running. They're enumerated in Section 2.2.1 later in the chapter. As you may have noticed in Figure 2.1, some of the other root keys and their subkeys are actually links to subkeys of HKLM ; that's another reason why this root key is so important. For example, HKEY_CLASSES_ROOT is actually a link to HKLM\SOFTWARE\Classes.

2.1.2.2 HKEY_USERS

Under Windows 2000 and NT 4.0, HKEY_USERS (also known as just plain old HKU) contains all the profile and environment settings for users on the local machine. These settings comprise all the per-user controls controllable by the System Policy Editor (see Chapter 6, for more on SPE), plus user-specific environment variables, as well as user-specific software settings. In Windows 2000, many of these profile settings are actually applied by group policy objects, using the rules discussed later in this section. The GPO provides the settings, and those settings are applied to HKU when the policy is downloaded. Changes to the user's settings are stored in her profile, but the GPO-specified settings can always override it. However, HKU still contains much of the user-specific data, since in Windows 2000 it is mapped to the hive file that contains the user's profile.

Each subkey of HKU is named by its security ID, or SID, a long string of digits that uniquely distinguishes every system object, process, user, and computer on an Windows NT/2000 network. Once an object is created, its SID never changes, but, its name can, so Windows 2000 uses the SID to keep track of user account profiles to keep them working when you change your account name from FredSmith to "The Administrator Formerly Known As FredSmith." [3] For a more concrete example, the SID for my account on my desktop machine is S-1-5-21-220523388-1214440339-682003330-1001,[4] so when I log on locally to that desktop machine, I see subkeys with that name under HKU.

[3] I wanted to include that odd-looking symbol used by the Artist Formerly Known as Prince but, strangely, it's not anywhere on my keyboard.

[4] And you thought it was hard to spell "Robichaux!"

In Windows NT 4.0, there are at least two subkeys of HKU. The first, .Default, contains a default group of settings (surprise!) named .DEFAULT that are applied when someone whose profile isn't already in HKU logs in. This facility provides a default profile that any profile-less user gets if there's no default profile in the NETLOGON share. The second group of settings are for the built-in Administrator account.

Windows 2000 is a little different; at any time when a user is logged on to the machine's console, there will be three subkeys under HKU. The first is .DEFAULT, which serves the same function it does in NT 4.0. The other two contain the settings of the logged-on user: one (named with the SID) contains the profile data, and the other (named with the SID with the string "_Classes" appended) contains the user-specific setting stored in HKCR. Windows 2000 users also get settings automatically from a special profile that's available to all users; it's stored in the Documents and Settings\All Users\NTUSER.DAT. Settings in the user's profile override the contents of the All Users profile, so the all-users default for a particular setting applies only if the user hasn't created a conflicting setting.

When you create local accounts on a machine running Windows 2000 (whether Professional or Server), their profiles are stored under HKU when they first log on from that machine's console. When that logon takes place, Windows 2000 copies the standard profile from HKU\.Default and creates a new subkey under HKU, named with the account's SID. Until an account logs on interactively, no profile exists for that account. At this point, you might be wondering what's under the individual subkeys of HKU, since each user on an Windows 2000 machine has her own subkey, which stores her settings independently of everyone else's. Instead of answering that directly, let's see what lives in HKEY_CURRENT_USER.

2.1.2.3 HKEY_CURRENT_USER

Surprise! HKEY_CURRENT_USER (better known as HKCU) is actually a link to the currently logged-in user's subkey in HKU. (On machines running Terminal Server, each user has his own HKCU, and Windows 2000 uses the correct one for each user--one of the benefits of HKCU being a link to a subkey of HKU!) Using a link was a smart decision on Microsoft's part; the link allows applications to look up things they need without needing to obtain the current user's SID first. When faced with the choice of finding data in HKCU\Software\KoolStuff\AnApplication or the mysterious-looking HKU\S-1-5-21-1944135612-1199777195-24521265-500\Software\KoolStuff\AnApplication, the choice is pretty clear. More importantly, since the Windows 9x family lacks the API routines needed to get SIDs, code written to use HKCU can run without modification on Windows 95/98, NT, 2000, and even CE.

Microsoft's guidelines require that applications should put their settings into HKLM and users' settings into HKCU. The idea is that settings that apply to all users on a machine go in that machine's key, while settings that users may--and probably will--change should be stored somewhere else. HKCU provides this mechanism; as an added bonus, a collection of subkeys under HKCU can be used as an individual user profile, and it's easy to store, load, or remove settings on a per-user basis. In fact, when Windows 2000 loads a profile, it actually copies data from the stored profile into HKCU.

2.1.2.4 HKEY_CLASSES_ROOT

HKEY_CLASSES_ROOT (better known as HKCR) made its debut in Windows 3.1 and has been around ever since. It serves as a giant lookup table that maps file extensions to the applications that own them. The Windows 2000 shell components (the desktop interface, Windows Explorer, the File Manager, and Internet Explorer 5.x) all make heavy use of HKCR, as do OLE container and server applications and ActiveX-capable software.

HKCR works because each registered file type or OLE class has two subkeys associated with it. File extensions are registered under their own name; for example, Microsoft registers HKCR\.doc, HKCR\.xls, and HKCR\.ppt (among others) as keys for Office 2000 document types. The file extension key's value specifies the default file type to associate with the extension. For example, the default value of HKCR\.doc is WordPad.Document.1, since WordPad comes with the standard Windows 2000 installation.

Besides the associated name, the file extension's key can contain a subkey called ShellNew. The Windows 2000 shell uses this subkey's value to figure out how to create a new instance of that file type when the user requests it. In addition to ShellNew, the file extension key can contain one or more document type keys that tie the extension to particular document types. This allows a single extension such as .doc or .bmp to be shared by several applications on the same machine. Each of these document type keys contain a ShellNew key.

The file extension key tells the shell what type corresponds to a document, but so what? The Windows 3.1 File Manager could do that too. In order to support OLE embedding and linking, HKCR has some additional tricks that center on the file type key. This key's name matches the default value of an extension key: when you install WordPad, you'll get a new key named HKCR\WordPad.Document.1, which matches the file type specified in HKCR\.doc. Its structure looks like this:

  • The CLSID key specifies the globally unique class ID of this particular OLE object type. Windows 2000, and thus OLE and ActiveX clients and servers, use these class IDs to figure out what type of object to create when you create a new embedded or linked object.

  • The DefaultIcon key's value tells the Windows 2000 shell where to find the icon for the file type. This is usually the name of the program or DLL that created the file; the value must also include the integer ID of the icon to use, since the executable can contain many different icons.

  • The Insertable key specifies that this particular type of OLE object may be inserted and embedded in other OLE document types. For example, WordPad documents are insertable, but XML documents aren't because HKCR\xmlfile doesn't have an Insertable key.

  • The BrowseInPlace key is almost the opposite of Insertable; its presence indicates that the specified object type can be browsed using in-place activation instead of inserting.

  • Protocol stores information OLE needs to support embedding, linking, and in-place editing, including which OLE verbs (open, in-place activate, deactivate, etc.) the object supports. OLE containers use this data to decide which commands to pass on to embedded or linked objects.

  • Shell holds subkeys that list the types of operations that can be done on the file type from the shell. In the case of WordPad, there are three: Shell\Open, Shell\Print, and Shell\PrintTo. Each of these has a Command subkey that contains the actual command line the shell can use to carry out the associated action. When you select a file in Explorer and open, print, or right-click on it, Explorer look up the file's type in the Registry, then looks for a subkey of Shell for that file and the requested command. For example, if you double-click a Microsoft Word 2000 document, Explorer looks for HKCR\Word.Document\Shell\Open\Command and executes the command it finds there.

2.1.2.5 HKEY_PERFORMANCE_DATA

HKEY_PERFORMANCE_DATA, or HKPD for short, was originally introduced as HKEY_DYN_DATA in Windows 95. It provides a central clearinghouse for dynamic data that is rebuilt anew each time the OS starts. In Win95, it stores performance data plus some other useful information; under Windows 2000 and NT 4.0 (it's not present in NT 3.x), HKPD stores performance data only. "Stores" is perhaps a misnomer; none of the data in HKPD is ever written to disk. Instead, when an application requests a subkey value for any of HKPD's subkeys, the kernel gathers the appropriate dynamic data, makes a fake subkey under HKPD, and passes it back to the requester. Since the data doesn't exist until it's requested, you could even argue that it's not stored in memory.

There's another catch, too: alone among the Big Six, HKPD doesn't appear in the Windows 2000 Registry editors. (It does appear in the Windows NT version of RegEdit, though it's labeled as HKEY_DYN_DATA.) You can't directly enumerate or expand HKPD, either, as you can in Win95; only kernel clients can get or set values for keys under HKPD, making it pretty worthless to most of us.

2.1.2.6 HKEY_CURRENT_CONFIG

HKEY_CURRENT_CONFIG, abbreviated HKCC, is the one-stop shopping center for data about the computer's current hardware configuration. If you've defined hardware profiles using the Hardware tab of the System control panel, when Windows 2000 boots you can choose whatever hardware profile reflects your current hardware setup. The profile is actually a subset of HKLM; when you choose a profile, it's stored in the key HKCC actually links to, HKLM\SYSTEM\CurrentControlSet\Hardware Profiles\Current. Like HKDD, HKCC is new in NT 4.0 and later; it's not present on NT 3.51 machines.

Now that you've made it through one and a half chapters, it's time to start using the conventional abbreviations for the root keys. From now on, I'll refer to root keys with the abbreviations given above, even when they're in paths. Get used to reading HKCU\Software\Microsoft... instead of the fully spelled-out version.

2.1.3 Hives and Files

The Registry appears to be a single monolithic blob of data, but it's not. Instead, it's made up of several hives. Each hive is a separate file or memory block that contains a Registry subtree. The kernel knits these individual hives together into a single seamless block. When your application (or any other) queries the Registry, it doesn't have to be concerned with which physical hive the desired key lives in.

Windows 2000 maintains a list of which hives exist on a particular machine in HKLM\SYSTEM\CurrentControlSet\Control\hivelist. This key normally contains seven entries, as shown in Table 2.1. Each entry's value contains the full disk path to the corresponding hive file. Interestingly, these paths aren't specified with drive letters; instead, they use paths based on the hierarchy of loaded device drivers. At the time the kernel loads, the driver hierarchy can be set up, but drive letters can't. The entry for the SOFTWARE hive on a machine that boots off the first partition on a SCSI disk with ID looks like this:

\Device\Harddisk0\Partition1\WINNT\System32\Config\Software

The first half of the path, \Device\Harddisk0\Partition1, tells the kernel where to find the disk volume itself (it can either be FAT16, FAT32, or NTFS); the second part, WINNT \System32\Config\Software, points to the hive file itself. By default, hives live in the System32\Config subdirectory of the system's install directory.

Table 2.1. Hives and Files

Hive Name

Hive File

Corresponding Registry Key

.DEFAULT

DEFAULT

HKU\.DEFAULT

HARDWARE

None; this data is dynamically generated and isn't written to disk

HKLM\HARDWARE

SOFTWARE

Software

HKLM\SOFTWARE

SAM

SAM

HKLM\SECURITY\SAM

SYSTEM

System

HKLM\SYSTEM

SECURITY

Security

HKLM\SECURITY

SID

Defaults to Documents And Settings\userName\NTUSER.DAT [5]

HKU\SID

SID_Classes

Same base path as SID key, plus Local Settings\Application Data\Microsoft\Windows\UsrClass.dat

Some data under HKEY_CLASSES_ROOT

[5] For a clean installation of Windows 2000, this is the default location. For an upgrade from Windows NT, the profiles end up in %systemroot%\profiles\userName\NTUSER.DAT. Microsoft is trying to keep user data out of the system folder.

This table contains a few surprises. First, let's start with the HARDWARE key. It doesn't have a permanent hive because its data is never stored on disk--but there's an entry for it in the hive list anyway. There's undoubtedly a good reason for this, but no one outside Microsoft knows what it is.

Next are the SID and SID_Classes hives. Those aren't their real names; SID is just a placeholder for the SID of the user currently logged into the console. This hive actually points to the user's profile, which can be stored anywhere on the machine but is usually in the Profiles subdirectory of the system directory. For example, when I'm logged into my desktop PC, the hivelist entry for my SID points to ...\Profiles\Paul\ntuser.dat. The exact value of this hive's entry depends on whether the user has an existing profile, whether it can roam, and whether it's mandatory. The ntuser.dat file for an individual user (along with some other files and folders in the same directory) makes up that user's profile, more on which in a bit.

By now, you might be wondering why these files exist as separate entities at all. The answer is twofold. The first reason is that splitting the Registry data into the groupings shown in Table 2.1 provides a clean separation between different types of data. The user's profile data (for example) should go in its own hive, since it doesn't have anything to do with the hardware, software, or security configuration of the machine. Likewise, the SAM database goes in its own hive because its data may not belong just to the local machine; for Windows NT servers that are domain controllers, the SAM hive holds the domain SAM, too. As a bonus, dividing the Registry into several components makes it possible to restore whole sections of the Registry without affecting others. The hive organization was chosen with this in mind. As you'll see in Section 3.3 in Chapter 3, the ability to restore only part of the Registry can be invaluable.

User Profiles Demystified

Windows 2000 and NT support three types of profiles: normal, mandatory, and roaming. Normal profiles are just that: plain, unadorned, ordinary groups of settings that live on a single machine in a user's ntuser.dat file. If you have a normal profile on one machine, it won't follow you to another machine, and you may change or modify it as you wish. Roaming profiles follow users from machine to machine: they live on the network and are downloaded to a machine when a user logs in. That makes it possible for a user's settings to follow her from machine to machine. For example, if you turn on roaming profiles, a new user who logs on for the first time gets a new profile based on the default profile settings in your domain. When she logs out, her profile is copied back to the profile directory you associated with her account, from which it can be downloaded on the next machine she logs into. A mandatory profile is one that can't be changed by the end user. As an administrator, you'll find it useful occasionally to specify unchangeable profile settings for your users and computers. You can combine these types, too: you can have normal or mandatory roaming profiles.

For domain accounts, the workings are a little different. Each account can have a profile location specified. Let's say you're administering Windows 2000 domain named ADMIN that has a few dozen workstations in it. You add a new account for Catbert, your new VP of human resources.[a] There are three possible scenarios:

Catbert doesn't have a mandatory or roaming profile

The first time he logs onto any machine in the ADMIN domain, that machine creates a new profile for him, using the SID of his domain account. The new profile is based on the contents of that machine's default user profile (taken from All Users\ntuser.dat). Changes made to his profile on one machine won't be visible on any other machine.

Catbert has a roaming profile

The first time he logs onto a domain machine, that machine attempts to fetch Catbert's roaming profile from the storage location defined in his account. In a Windows 2000 domain, the location of the profile is part of the Active Directory data that defines Catbert's account, but the profile itself is just a file stored on some server. If he is ever logged on to any other machine in the domain, and if the profile server is available, the logon machine makes a local copy of Catbert's profile under HKU; if not, it makes a new profile based on the domain default profile and uses it instead. On subsequent logons, Windows 2000 compares the locally cached profile with that stored on the server; if they're different, Catbert gets to choose which profile he wants the machine to honor. Any changes he makes to his profile on one machine is copied back to the stored profile on the server, and the changes appear on other machines when he logs into them.

Catbert has a mandatory profile

Mandatory profiles must be used. When setting up an account, the domain admin specifies which mandatory profile Catbert's account will use. When Catbert logs onto a domain machine for the first time, Windows 2000 gets that profile from the profile server and uses it. If the server can't deliver the profile for some reason, Catbert's logon attempt will fail. If Catbert makes changes to the profile, they aren't mirrored back to the server.

When you create a user account, you assign it using Profile button of the User Properties dialog in the User Manager or User Manager for Domains (for NT) or the Active Directory Users and Computers or Local Users and Groups snap-ins in Windows 2000. Once you specify the UNC path to the profile, Windows will automatically download—and upload—the profile so the user has a consistent environment. If you don't explicitly provide a profile for a user account, that account will use the local or domain default profile. This, then, is the profile you should edit if you want to change what profile-free users end up seeing.

The best way to build a default profile for your users is to create a special account for profile editing. Log on as that account and modify the profile to your liking, then log off and back on as Administrator. Once you do that, you can use the Copy To... button on the User Profiles tab of the System control panel to copy the profile account's profile to whatever share you specified in the User Manager. The next time a user with a profile logs in, her workstation gets an updated copy of the profile.

To specify that a profile should be mandatory, name it ntuser.man. You still have to modify each user's account so that it points to the mandatory profile, but one you do Windows 2000 faithfully downloads and applies it when a user logs in. Changes made on the local workstation, however, aren't propagated back to the original profile as they are with regular profiles.

[a] If you don't read the Dilbert comic strip: a) you should, and b) you won't get this joke.

2.1.4 Access Controls and Security

Windows 2000 implements access control and security for the Registry in four overlapping levels. The specifics of how you actually use these settings are discussed in other parts of the book, but it's helpful to understand them at a high level before you begin implementing them.

2.1.4.1 Control via Registry APIs

The simplest and least effective control method is via a key that Microsoft provided, first in Win95 and then in NT 4.0 and Windows 2000, which administrators can use to disallow Registry editing on a machine. The good news is that this key, HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableRegistryTools, exists. The bad news is that this key doesn't actually do anything! Microsoft's Registry editors check the key and refuse to run if it exists; however, there's no enforcement of this method, so third-party Registry editors can, and do, ignore this value with no penalty.

Worse still, users can clear this flag themselves if they have access (and permission) to use the System Policy Editor or group policy objects on their local machines. Don't depend on this flag to keep any but the least sophisticated users out of your Registry; even though it's not much help, it's still worth setting.

2.1.4.2 Remote-access control

The next step up the security ladder is to restrict who can attach to, and modify, your Registry remotely. By default, Windows NT machines grant remote read access to their Registries. This stands in sharp contrast to Win95, where you have to manually install the Remote Registry Access service on clients whose Registries you want to edit remotely. Windows 2000 is somewhere in the middle. It also has a remote Registry access service, but it's started by default, and it allows read-only access to ordinary users. Depending on the account permissions you have, you may even be able to make changes to other systems' Registries; however, you may disallow it manually as described in Section 9.4 in Chapter 9.

2.1.4.3 OS-level security controls

In Windows NT and Windows 2000, Registry keys all have access controls and permissions attached to them. Unfortunately, by default, in NT 4.0 prior to Service Pack 3, most keys in the Registry had Everyone:Full Control as their permissions. This led to a security exploit popularly known as the " RedButton" or "MWC" exploit, where an untrusted program could attach to and modify Registries on machines where the exploiter had no Administrator access. SP3 fixes this problem; in addition, Section 9.4 in Chapter 9 explains how to set adequate access controls on your Registry keys.

Windows 2000 doesn't suffer from this problem nearly as much, because it has a much less permissive set of default permissions. With appropriate application of security templates (discussed in more detail in Chapter 9) you can tighten things down even further.

As an additional safety measure, you can--and should--set up auditing events to log changes to the Registry on critical machines. There's a fine line between doing this too much and not enough; there are guidelines in Chapter 9 as well.

2.1.4.4 System Key Security (SYSKEY)

Microsoft has frequently (and not always fairly) been criticized for leaving security holes in its products. In particular, an exploit was reported in mid-1997 that took advantage of the fact that NT 4.0 and earlier stored some account passwords--those for services--in the Registry. Even though the passwords were obfuscated, having them there represented a security risk, since an attacker could, in theory, grab the hive files and figure out the passwords.

To fix this, Microsoft introduced a new feature called System Key Security, or SYSKEY, in Service Pack 3 for NT 4.0. SKS encrypts a portion of the Registry (mainly the SAM and SECURITY subkeys of HKLM) using the CryptoAPI cryptographic services. As a practical matter, this makes it statistically very unlikely that someone can get useful information out of your Registry unless the attacker knows or steal the key used to encrypt it. You can choose your own password (which then must be entered when you boot the machine), or you can have the system generate and store a password. Either way, without that password, the SAM data stored in the Registry is useless. It's important to note that SYSKEY doesn't keep people from browsing the Registry or opening keys with the programming interfaces, and it doesn't prevent them from actually making a copy of the SAM hive itself; it just encrypts the SAM data so it's no longer directly useful for password crackers such as l0phtcrack.[6] (However, a tool such as Todd Sabin's pwdump2, or future versions of l0phtcrack, make it harder to extract these hashes.)

[6] l0phtcrack is a very fast, robust, and full-featured password cracker for Windows NT and Windows 2000. Check it out at http://www.l0pht.com/l0phtcrack.

Service Packs Versus Hotfixes

Microsoft often issues bug fixes and enhancements for its operating system products. These changes come in two flavors. Service packs include a large number of fixes, plus occasional enhancements. While there's no fixed schedule, they usually appear at least every six months, and sometimes more often. As I write this, it's been a little over three years since NT 4.0 shipped, and there have been six service packs released for it. These updates are usually referred to as SPs, and when used with a number (i.e., SP3) you can tell what SP is being discussed.

As of the time of this writing, Windows NT 4.0's current service pack is SP6a. There aren't any service packs available for Windows 2000 yet, even though Microsoft started working on SP1 as soon as they'd released the gold master version of Windows 2000. One important change to Windows 2000 is the new "slipstream" update model, in which each service pack can be incorporated with the base distribution. This makes it possible to create a sharepoint for distributing Windows 2000, then add service packs directly to the sharepoint so that they're installed as part of the normal install instead of adding them after installation.

The service-pack mechanism is the same for Windows 2000 and NT. First, remember that SPs are cumulative. If you install NT 4.0 SP6, it includes all the patches and fixes included in SP1 through SP5. You can use the system utility hotfix.exe to get a quick indication of which SPs are installed on a particular machine; you can also find the same data yourself in HKLM\Software\Microsoft\Windows NT\CurrentVersion\CSDVersion.

Unlike SPs, hotfixes are intended to fix one or two critical problems. For example, the IIS 3.0 denial-of-service attacks that brought down Microsoft's web site several times in 1997 quickly led to the release of a hotfix that repaired that specific problem. In their hurry to get hotfixes out the door, Microsoft can't always do complete tests on them before release; if you install a hotfix that fixes a problem you don't have, you may end up with new problems caused by the hotfix itself!

Regrettably, some SPs have been released without adequate testing as well. My best advice is this: install a new SP on one or two machines to see how it does before rolling it out across your network. If Microsoft releases a hotfix for a problem you're experiencing, get it and install it. If it's a security-related hotfix, get it and install it even if you're not having the problem. Otherwise, leave it alone.

Windows 2000 turns on SYSKEY by default, and there's no way to turn it off. This might seem like an odd thing to do; after all, Windows 2000 uses the Active Directory to store user account information, so why would there be a SAM hive present in the first place? Not every Windows 2000 machine is an AD domain controller; for example, member servers or Windows 2000 Professional machines may still have local accounts on them. So can domain controllers, for that matter. In addition, machines that don't run the AD services have a local SAM hive; domain controllers have one too, with AD information mirrored into it.

figs/nt4icon.gif Once you turn on SKSKEY, it can't be turned off. If you want to turn on SKSKEY on your Windows NT machines, complete instructions are given in Section 9.6 in Chapter 9.

2.1.5 Major Datatypes

The Registry can directly store and manipulate 11 different types of data: seven major and four minor. This doesn't seem like very many at first, but remember that applications can use the seven fundamental types to store whatever kind of data they want. Only the application knows what the data actually means, and Windows 2000 doesn't care; it happily stores and retrieves whatever data you pass it as long as you specify one of the following types for it.

2.1.5.1 REG_DWORD

REG_DWORD is a double word (the DWORD is Hungarian notation for a double word). Since a word is a 16-bit number representing the range 0-65535, a double word is just two 16-bit words, so it's a 32-bit value, probably the most common datatype in the Registry. A REG_DWORD value can hold any integer up to 232. Even though this provides a range of more than four billion possible values, many Registry keys use REG_DWORD to stand in for Boolean[7] values: you'll see a lot of keys whose values can either be 1 or 0. In other cases, the value represents a quantity of something, like the percentage of time a replication request can echo on the network or the number of seconds allowed between replication attempts. The hard part is knowing what the value represents, since without that there's no way to intelligently decide whether it needs to be changed. Chapter 10, points out some of the most significant or interesting Registry keys, and others are documented in Microsoft's knowledge base (http://support.microsoft.com) and in the Windows 2000 and NT Server resource kits.

[7] "Boolean" comes from George Boole, the mathematician who first described formal systems for working with problems whose solutions could only be expressed in terms of truth or falsehood. This makes a good trivia question for springing on coworkers.

There is one other stumbling block: the Registry editors default to showing REG_DWORD values in hexadecimal, not decimal, and you have to use hex values when you're setting them unless you tell the editor you're entering decimal or binary values. This isn't too surprising, since the Registry stores values internally as raw bytes, not in decimal. It can be annoying to have to set Registry values for things such as replication timers: "Start with the time, which is 2 days, 4 hours, 30 minutes--that's 189,000 seconds, which is, ah, 0x2d620 hex."[8]

[8] Yes, I did do that by hand--proof of a misspent youth.

2.1.5.2 REG_SZ

In Hungarian notation, S means "string," and Z means "terminated with a zero byte at the end." Put them together, and you get the REG_SZ datatype, which stores fixed-length strings by tacking on a zero at the end of the string. This extra zero is usually called the string's terminator . The simple string "W2K" actually takes up four bytes when stored as a REG_SZ: three bytes for its contents, and one for the terminator. The terminator is mostly invisible to you (unless you write programs to manipulate Registry values in C or C++); the Registry editing tools add, remove, and store the terminator as appropriate, and they don't display it.

After REG_DWORD, REG_SZ is probably the second most-common Registry datatype. Strings are pretty versatile; they can store human-readable names, file paths, version numbers, and lots of other useful tidbits. These strings can contain Unicode characters, which means they're not limited to the ASCII character set. If you have occasion to edit the Registry on a machine running the Japanese, Korean, or Chinese versions of Windows NT/2000, be prepared to see non-ASCII characters aplenty.

2.1.5.3 REG_MULTI_SZ

Sometimes it's useful to store a group of related strings as a single block. For example, since a single PC can have more than one video BIOS, NT stores the identification strings for each video BIOS it finds in HKLM\HARDWARE\DESCRIPTION\SYSTEM\VideoBiosVersion. To support this aggregation, Windows 2000 supports a special datatype called REG_MULTI_SZ--a fancy name for what is essentially a collection of several Unicode strings. Programs that use REG_MULTI_SZ values get the strings as a block and can add to or remove from the block at will. Of course, you can edit the strings too, using the editor provided as part of RegEdt32; see Figure 2.2.

Figure 2.2. The multiple-string editor in RegEdt32
figs/mwr2_0202.gif
2.1.5.4 REG_EXPAND_SZ

As part of what passes for its system scripting language, Windows 2000 provides a number of system-defined variables. You may already know that these variables can be used in .BAT files, the Environment Variables button on the System control panel's Advanced tab, and directly from Windows 2000's command line, but they can also be used within Registry values of type REG_EXPAND_SZ. For example, the %SystemRoot% environment variable points to the root directory of the OS installation (it's usually C:\WINNT or something similar). If a Registry key has type REG_EXPAND_SZ and a value of %SystemRoot%\Media, any caller who retrieves the value can expand the embedded variable to its true value. You might think, based on the name, that the Registry would expand the embedded variable itself; sadly, this isn't the case. You have to do it yourself, as you'll see in Chapter 8. In all other respects, this type is identical to REG_SZ.

2.1.5.5 REG_BINARY

Programmers often use binary representations directly. For example, using a mask of binary digits is a convenient way to represent features or flags that may or may not be set; each bit in the mask can represent a separate on-off flag, making it possible to pack 32 independent flags into a single DWORD. Of course, it's often useful to store arbitrary binary data--pictures, cryptographic keys, encrypted passwords, and so on--in a binary format. RegEdt32 supports storing and editing binary values with the REG_BINARY type. Binary data is totally raw; there are no terminators, string expansion, or anything else. What you put in is what comes back out. Figure 2.3 shows the binary value editor; you'll learn more about how to use it in Chapter 5.

Figure 2.3. The binary value editor in RegEdt32
figs/mwr2_0203.gif
2.1.5.6 REG_LINK

In Section 2.1.1.5 earlier in this chapter, you learned that the Registry supports links that tie one subtree to another, much the same way you figure out that "Charles Windsor" and "Prince Charles" are actually the same person. These links have their own datatype, REG_LINK, which actually looks just like a REG_SZ. Let's say you have an intranet application that stores its configuration information in HKLM\Software\BigCorp\NiftyApp\version, where version is the application's version number. If you want to read the application's settings without regard to what version was installed, you can create a new key named HKLM\Software\BigCorp\NiftyApp\CurrentVersion and make it a REG_LINK; its link value would be HKLM\Software\BigCorp\NiftyApp\version. To reach the application's communications settings, you can always refer to HKLM\Software\BigCorp\NiftyApp\CurrentVersion\CommSettings, no matter what the actual value of version is; the Registry API routines automatically resolves the link and takes you to the correct destination of HKLM\Software\BigCorp\NiftyApp\version\CommSettings.

As a more immediate example, consider HKCU. Software written for Windows 2000 must be aware that there can be several different user accounts on a single machine, each with its own unique SID. Win9x applications may be aware that multiple users sometimes share a computer, but the Win9x Registry doesn't have SIDs--making it impossible for a Win9x app to find the current user's settings when run under Windows 2000. Enter HKCU, which is a link that Windows 2000 builds at logon time. Instead of having to know what the current user's security ID is and how to resolve that to a name, the application can just look for settings under HKCU.

You can't create a new REG_LINK value from within RegEdit or RegEdt32. You can use the Registry API calls described in Chapter 8 to create these types if you need to; most often, though, you won't.

2.1.5.7 REG_QWORD

If a DWORD is a double word, it stands to reason that a QWORD would be a quad word, right? In fact, that's exactly what it is: four 16-bit words, providing a way to store a 64-bit quantity in a single Registry value. You'll probably see these values only in applications running on Windows 2000 Advanced Server or Datacenter Server, and then only on 64-bit hardware. You can create and manipulate QWORD values with the Registry APIs discussed in Chapter 8, but you can't edit them with RegEdt32 or RegEdit.

2.1.6 Minor Datatypes

In addition to the datatypes presented above, Windows 2000 supports four additional types that are less frequently used but still worth discussing. The first two, REG_NONE and REG_DWORD_BIG_ENDIAN, aren't used very often, but they're available if you need them. The remaining two are reserved for use by Windows 2000; RegEdt32 can display them but won't let you change any of their values.

The Windows 2000 Registry editors won't let you create new values using any of the types described in this section, though you can use the Registry programming APIs to create REG_NONE and REG_DWORD_*_ENDIAN values. If you try creating new values or keys using the resource types, however, the default ACLs won't let you put them in HKLM\HARDWARE, where they belong. You can create them elsewhere, but NT ignores them.

2.1.6.1 REG_NONE

REG_NONE is a nice antidote to the more complicated datatypes featured in this chapter; it's just a big zero. It's used to indicate the presence of a value only; since REG_NONE doesn't store any values, you can't use it to retrieve or store data in a key, but you can see whether the key is there or not. This is useful in some limited situations where the existence or absence of a key indicates something important, but it's a much better idea to use actual value types, and REG_NONE is rare.

2.1.6.2 REG_DWORD_BIG_ENDIAN

It's an often-forgotten fact that Windows NT was designed to work well on other types of CPUs besides the ubiquitous Intel x86. At one point, NT actually ran on five different CPU families: Intergraph's Clipper, the MIPS CPU family, DEC (now Compaq) Alphas, the Apple/IBM/Motorola PowerPC chip, and the x86. Windows 2000 is now available only for x86 CPUs, but its multiplatform heritage lives on.

Not all these platforms order their bytes in the same way, though. "Big-endian" platforms put the most significant byte of a quantity in the lowest address, while "little-endian" platforms put the least significant byte at the low address. Figure 2.4 shows how the hex number 12345678 is represented with both kinds of "endianness."

Figure 2.4. The hex number "12345678" in big- and little-endian form
figs/mwr2_0204.gif

To mix data between little- and big-endian machines, one end or the other has to swap the byte ordering. Even though NT was originally designed for little-endian machines (the x86 and MIPS), Microsoft realized that it might be desirable to run it on big-endian platforms someday. In aid of that goal, they gave us REG_DWORD_BIG_ENDIAN, which is rarely if ever seen on little-endian machines. It stores DWORD values in big-endian order, without translating them back to little-endian order on little-endian machines. Unless you're running Windows NT on a PowerPC or Alpha (or an early beta of Windows 2000 on an Alpha), you probably won't ever see any values of this type in your Registry. In Windows 2000, there's also a corresponding REG_QWORD_LITTLE_ENDIAN type.

There's also a REG_DWORD_LITTLE_ENDIAN type, but you won't ever see it on little-endian machines; it's only there so big-endian machines have a way to store little-endian data. NT automatically converts big- or little-endian data to the correct representation when you query a key's value and tell the Registry you're storing it as an ordinary DWORD.

2.1.6.3 REG_FULL_RESOURCE_DESCRIPTOR

Computers have finite resources; in particular, Intel-based PCs suffer from a limited number of IRQs and direct-memory access (DMA) address ranges. Someone has to be in charge of allocating this finite supply of goodies to requesters; in Windows 2000, it's the hardware abstraction layer (HAL), which loads as part of the boot process, that provides this necessary service. The resource arbitration's goal is (if at all possible) to keep two or more devices from fighting over the same resource.

To make this work, the Windows 2000 kernel stores information about what resources are available in HKLM\ HARDWARE; this information's gathered at boot time and stored in RAM, which is then mapped to Registry keys. Completely describing a resource requires quite a bit of data, and the operating system aggregates all the data for a resource into a resource descriptor. The REG_FULL_RESOURCE_DESCRIPTOR datatype consolidates this data, as shown in Figure 2.5. (These fields may look familiar to you, since Microsoft's old-schoolWinMSD diagnostic tool for Windows NT used a similar format.)

Figure 2.5. The resource descriptor display in RegEdt32
figs/mwr2_0205.gif
2.1.6.4 REG_RESOURCE_LIST

Even though the number of resources on a particular computer is finite, it can still be large. Instead of scattering many values of type REG_FULL_RESOURCE_DESCRIPTOR around, the Registry offers REG_RESOURCE_LIST, a type designed to group related resource descriptors into a single unit. Figure 2.6 shows a sample of RegEdt32 's display for this datatype.

Figure 2.6. The resource list viewer in RegEdt32
figs/mwr2_0206.gif
    Team LiB   Previous Section   Next Section